summaryrefslogtreecommitdiff
path: root/sdext/source/pdfimport/tree/genericelements.hxx
blob: 34fbdf6391dedc9ec98b6ae85f7ba5d3ab1a4206 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: genericelements.hxx,v $
 *
 * $Revision: 1.2 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef INCLUDED_PDFI_GENERICELEMENTS_HXX
#define INCLUDED_PDFI_GENERICELEMENTS_HXX

#include "pdfihelper.hxx"
#include "treevisiting.hxx"

#include <com/sun/star/task/XStatusIndicator.hpp>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/range/b2drange.hxx>
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>

#include <list>

namespace pdfi
{
    class XmlEmitter;
    class StyleContainer;
    class ImageContainer;
    class PDFIProcessor;
    class ElementFactory;


    struct EmitContext
    {
        EmitContext(
            XmlEmitter&                              _rEmitter,
            StyleContainer&                          _rStyles,
            ImageContainer&                          _rImages,
            PDFIProcessor&                           _rProcessor,
            const com::sun::star::uno::Reference<
            com::sun::star::task::XStatusIndicator>& _xStatusIndicator ) :
            rEmitter(_rEmitter),
            rStyles(_rStyles),
            rImages(_rImages),
            rProcessor(_rProcessor),
            xStatusIndicator(_xStatusIndicator)
        {}

        XmlEmitter&     rEmitter;
        StyleContainer& rStyles;
        ImageContainer& rImages;
        PDFIProcessor&  rProcessor;
        com::sun::star::uno::Reference<
            com::sun::star::task::XStatusIndicator> xStatusIndicator;
    };

    struct Element : public ElementTreeVisitable
    {
    protected:
        Element( Element* pParent )
            : x( 0 ), y( 0 ), w( 0 ), h( 0 ), StyleId( -1 ), Parent( pParent )
        {
            if( pParent )
                pParent->Children.push_back( this );
        }

    public:
        virtual ~Element();

        /// Apply visitor to all children
        void applyToChildren( ElementTreeVisitor& );
        /// Union element geometry with given element
        void updateGeometryWith( const Element* pMergeFrom );

#if OSL_DEBUG_LEVEL > 1
        // xxx refac TODO: move code to visitor
        virtual void emitStructure( int nLevel );
#endif
        /** el must be a valid dereferencable iterator of el->Parent->Children
            pNewParent must not be NULL
        */
        static void setParent( std::list<Element*>::iterator& el, Element* pNewParent );

        double              x, y, w, h;
        sal_Int32           StyleId;
        Element*            Parent;
        std::list<Element*> Children;
    };

    struct ListElement : public Element
    {
        ListElement() : Element( NULL ) {}
        // ElementTreeVisitable
        virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
    };

    struct HyperlinkElement : public Element
    {
        friend class ElementFactory;
    protected:
        HyperlinkElement( Element* pParent, const rtl::OUString& rURI )
        : Element( pParent ), URI( rURI ) {}
    public:
        // ElementTreeVisitable
        virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );

        rtl::OUString URI;
    };

    struct GraphicalElement : public Element
    {
    protected:
        GraphicalElement( Element* pParent, sal_Int32 nGCId )
        : Element( pParent ), GCId(nGCId ) {}

    public:
        sal_Int32 GCId;
    };

    struct DrawElement : public GraphicalElement
    {
    protected:
        DrawElement( Element* pParent, sal_Int32 nGCId )
        : GraphicalElement( pParent, nGCId ), isCharacter(false), ZOrder(0) {}

    public:
        bool      isCharacter;
        sal_Int32 ZOrder;
    };

    struct FrameElement : public DrawElement
    {
        friend class ElementFactory;
    protected:
        FrameElement( Element* pParent, sal_Int32 nGCId )
        : DrawElement( pParent, nGCId ) {}

    public:
        // ElementTreeVisitable
        virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
    };

    struct TextElement : public GraphicalElement
    {
        friend class ElementFactory;
    protected:
        TextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId )
        : GraphicalElement( pParent, nGCId ), FontId( nFontId ) {}

    public:
        // ElementTreeVisitable
        virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );

        rtl::OUStringBuffer Text;
        sal_Int32           FontId;
    };

    struct ParagraphElement : public Element
    {
        friend class ElementFactory;
    protected:
        ParagraphElement( Element* pParent ) : Element( pParent ), Type( Normal ) {}

    public:
        // ElementTreeVisitable
        virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& rParentIt );

        // returns true only if only a single line is contained
        bool isSingleLined( PDFIProcessor& rProc ) const;
        // returns the highest line height of the contained textelements
        // line height is font height if the text element is itself multilined
        double getLineHeight( PDFIProcessor& rProc ) const;
        // returns the first text element child; does not recurse through subparagraphs
        TextElement* getFirstTextChild() const;

        enum ParagraphType { Normal, Headline };
        ParagraphType       Type;
    };

    struct PolyPolyElement : public DrawElement
    {
        friend class ElementFactory;
    protected:
        PolyPolyElement( Element* pParent, sal_Int32 nGCId,
                         const basegfx::B2DPolyPolygon& rPolyPoly,
                         sal_Int8 nAction );
    public:
        // ElementTreeVisitable
        virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& rParentIt );

        void updateGeometry();

#if OSL_DEBUG_LEVEL > 1
        virtual void emitStructure( int nLevel );
#endif

        basegfx::B2DPolyPolygon PolyPoly;
        sal_Int8                Action;
    };

    struct ImageElement : public DrawElement
    {
        friend class ElementFactory;
    protected:
        ImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage )
        : DrawElement( pParent, nGCId ), Image( nImage ) {}

    public:
        // ElementTreeVisitable
        virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );

        ImageId Image;
    };

    struct PageElement : public Element
    {
        friend class ElementFactory;
    protected:
        PageElement( Element* pParent, sal_Int32 nPageNr )
        : Element( pParent ), PageNumber( nPageNr ), Hyperlinks(),
        TopMargin( 0.0 ), BottomMargin( 0.0 ), LeftMargin( 0.0 ), RightMargin( 0.0 ),
        HeaderElement( NULL ), FooterElement( NULL )
        {}
    private:
        // helper method for resolveHyperlinks
        bool resolveHyperlink( std::list<Element*>::iterator link_it, std::list<Element*>& rElements );
        public:
        virtual ~PageElement();

        // ElementTreeVisitable
        virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& rParentIt );

        void emitPageAnchoredElements( EmitContext& rEmitContext );
        static void updateParagraphGeometry( Element* pEle );
        void resolveHyperlinks();
        void resolveFontStyles( PDFIProcessor& rProc );
        void resolveUnderlines( PDFIProcessor& rProc );

        sal_Int32      PageNumber;
        ListElement    Hyperlinks; // contains not yet realized links on this page
        double         TopMargin;
        double         BottomMargin;
        double         LeftMargin;
        double         RightMargin;
        Element*       HeaderElement;
        Element*       FooterElement;
    };

    struct DocumentElement : public Element
    {
        friend class ElementFactory;
    protected:
        DocumentElement() : Element( NULL ) {}
    public:
        virtual ~DocumentElement();

        // ElementTreeVisitable
        virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );

    };

    // this class is the differentiator of document types: it will create
    // Element objects with an optimize() method suitable for the document type
    class ElementFactory
    {
    public:
        ElementFactory() {}
        virtual ~ElementFactory();

        virtual HyperlinkElement* createHyperlinkElement( Element* pParent, const rtl::OUString& rURI )
        { return new HyperlinkElement( pParent, rURI ); }

        virtual TextElement* createTextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId )
        { return new TextElement( pParent, nGCId, nFontId ); }
        virtual ParagraphElement* createParagraphElement( Element* pParent )
        { return new ParagraphElement( pParent ); }

        virtual FrameElement* createFrameElement( Element* pParent, sal_Int32 nGCId )
        { return new FrameElement( pParent, nGCId ); }
        virtual PolyPolyElement*
            createPolyPolyElement( Element* pParent,
                                   sal_Int32 nGCId,
                                   const basegfx::B2DPolyPolygon& rPolyPoly,
                                   sal_Int8 nAction)
        { return new PolyPolyElement( pParent, nGCId, rPolyPoly, nAction ); }
        virtual ImageElement* createImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage )
        { return new ImageElement( pParent, nGCId, nImage ); }

        virtual PageElement* createPageElement( Element* pParent,
                                                sal_Int32 nPageNr )
        { return new PageElement( pParent, nPageNr ); }
        virtual DocumentElement* createDocumentElement()
        { return new DocumentElement(); }
    };
}

#endif