1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef INCLUDED_PDFI_GENERICELEMENTS_HXX
29 #define INCLUDED_PDFI_GENERICELEMENTS_HXX
30 
31 #include "pdfihelper.hxx"
32 #include "treevisiting.hxx"
33 
34 #include <com/sun/star/task/XStatusIndicator.hpp>
35 #include <com/sun/star/uno/XComponentContext.hpp>
36 #include <basegfx/polygon/b2dpolypolygon.hxx>
37 #include <basegfx/range/b2drange.hxx>
38 #include <rtl/ustring.hxx>
39 #include <rtl/ustrbuf.hxx>
40 
41 #include <list>
42 
43 namespace pdfi
44 {
45     class XmlEmitter;
46     class StyleContainer;
47     class ImageContainer;
48     class PDFIProcessor;
49     class ElementFactory;
50 
51 
52     struct EmitContext
53     {
54         EmitContext(
55             XmlEmitter&                              _rEmitter,
56             StyleContainer&                          _rStyles,
57             ImageContainer&                          _rImages,
58             PDFIProcessor&                           _rProcessor,
59             const com::sun::star::uno::Reference<
60             com::sun::star::task::XStatusIndicator>& _xStatusIndicator,
61             com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >  xContext)
62 		:
63             rEmitter(_rEmitter),
64             rStyles(_rStyles),
65             rImages(_rImages),
66             rProcessor(_rProcessor),
67             xStatusIndicator(_xStatusIndicator),
68 	    m_xContext(xContext)
69         {}
70 
71         XmlEmitter&     rEmitter;
72         StyleContainer& rStyles;
73         ImageContainer& rImages;
74         PDFIProcessor&  rProcessor;
75         com::sun::star::uno::Reference<
76             com::sun::star::task::XStatusIndicator> xStatusIndicator;
77         com::sun::star::uno::Reference<
78             com::sun::star::uno::XComponentContext >  m_xContext;
79     };
80 
81     struct Element : public ElementTreeVisitable
82     {
83     protected:
84         Element( Element* pParent )
85             : x( 0 ), y( 0 ), w( 0 ), h( 0 ), StyleId( -1 ), Parent( pParent )
86         {
87             if( pParent )
88                 pParent->Children.push_back( this );
89         }
90 
91     public:
92         virtual ~Element();
93 
94         /// Apply visitor to all children
95         void applyToChildren( ElementTreeVisitor& );
96         /// Union element geometry with given element
97         void updateGeometryWith( const Element* pMergeFrom );
98 
99 #if OSL_DEBUG_LEVEL > 1
100         // xxx refac TODO: move code to visitor
101         virtual void emitStructure( int nLevel );
102 #endif
103         /** el must be a valid dereferencable iterator of el->Parent->Children
104             pNewParent must not be NULL
105         */
106         static void setParent( std::list<Element*>::iterator& el, Element* pNewParent );
107 
108         double              x, y, w, h;
109         sal_Int32           StyleId;
110         Element*            Parent;
111         std::list<Element*> Children;
112     };
113 
114     struct ListElement : public Element
115     {
116         ListElement() : Element( NULL ) {}
117         // ElementTreeVisitable
118         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
119     };
120 
121     struct HyperlinkElement : public Element
122     {
123         friend class ElementFactory;
124     protected:
125         HyperlinkElement( Element* pParent, const rtl::OUString& rURI )
126         : Element( pParent ), URI( rURI ) {}
127     public:
128         // ElementTreeVisitable
129         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
130 
131         rtl::OUString URI;
132     };
133 
134     struct GraphicalElement : public Element
135     {
136     protected:
137         GraphicalElement( Element* pParent, sal_Int32 nGCId )
138         : Element( pParent ), GCId( nGCId ), MirrorVertical( false ) {}
139 
140     public:
141         sal_Int32 GCId;
142         bool      MirrorVertical;
143     };
144 
145     struct DrawElement : public GraphicalElement
146     {
147     protected:
148         DrawElement( Element* pParent, sal_Int32 nGCId )
149         : GraphicalElement( pParent, nGCId ), isCharacter(false), ZOrder(0) {}
150 
151     public:
152         bool      isCharacter;
153         sal_Int32 ZOrder;
154     };
155 
156     struct FrameElement : public DrawElement
157     {
158         friend class ElementFactory;
159     protected:
160         FrameElement( Element* pParent, sal_Int32 nGCId )
161         : DrawElement( pParent, nGCId ) {}
162 
163     public:
164         // ElementTreeVisitable
165         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
166     };
167 
168     struct TextElement : public GraphicalElement
169     {
170         friend class ElementFactory;
171     protected:
172         TextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId )
173         : GraphicalElement( pParent, nGCId ), FontId( nFontId ) {}
174 
175     public:
176         // ElementTreeVisitable
177         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
178 
179         rtl::OUStringBuffer Text;
180         sal_Int32           FontId;
181     };
182 
183     struct ParagraphElement : public Element
184     {
185         friend class ElementFactory;
186     protected:
187         ParagraphElement( Element* pParent ) : Element( pParent ), Type( Normal ), bRtl( false ) {}
188 
189     public:
190         // ElementTreeVisitable
191         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& rParentIt );
192 
193         // returns true only if only a single line is contained
194         bool isSingleLined( PDFIProcessor& rProc ) const;
195         // returns the highest line height of the contained textelements
196         // line height is font height if the text element is itself multilined
197         double getLineHeight( PDFIProcessor& rProc ) const;
198         // returns the first text element child; does not recurse through subparagraphs
199         TextElement* getFirstTextChild() const;
200 
201         enum ParagraphType { Normal, Headline };
202         ParagraphType       Type;
203 	bool bRtl;
204     };
205 
206     struct PolyPolyElement : public DrawElement
207     {
208         friend class ElementFactory;
209     protected:
210         PolyPolyElement( Element* pParent, sal_Int32 nGCId,
211                          const basegfx::B2DPolyPolygon& rPolyPoly,
212                          sal_Int8 nAction );
213     public:
214         // ElementTreeVisitable
215         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& rParentIt );
216 
217         void updateGeometry();
218 
219 #if OSL_DEBUG_LEVEL > 1
220         virtual void emitStructure( int nLevel );
221 #endif
222 
223         basegfx::B2DPolyPolygon PolyPoly;
224         sal_Int8                Action;
225     };
226 
227     struct ImageElement : public DrawElement
228     {
229         friend class ElementFactory;
230     protected:
231         ImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage )
232         : DrawElement( pParent, nGCId ), Image( nImage ) {}
233 
234     public:
235         // ElementTreeVisitable
236         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
237 
238         ImageId Image;
239     };
240 
241     struct PageElement : public Element
242     {
243         friend class ElementFactory;
244     protected:
245         PageElement( Element* pParent, sal_Int32 nPageNr )
246         : Element( pParent ), PageNumber( nPageNr ), Hyperlinks(),
247         TopMargin( 0.0 ), BottomMargin( 0.0 ), LeftMargin( 0.0 ), RightMargin( 0.0 ),
248         HeaderElement( NULL ), FooterElement( NULL )
249         {}
250     private:
251         // helper method for resolveHyperlinks
252         bool resolveHyperlink( std::list<Element*>::iterator link_it, std::list<Element*>& rElements );
253         public:
254         virtual ~PageElement();
255 
256         // ElementTreeVisitable
257         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& rParentIt );
258 
259         void emitPageAnchoredElements( EmitContext& rEmitContext );
260         static void updateParagraphGeometry( Element* pEle );
261         void resolveHyperlinks();
262         void resolveFontStyles( PDFIProcessor& rProc );
263         void resolveUnderlines( PDFIProcessor& rProc );
264 
265         sal_Int32      PageNumber;
266         ListElement    Hyperlinks; // contains not yet realized links on this page
267         double         TopMargin;
268         double         BottomMargin;
269         double         LeftMargin;
270         double         RightMargin;
271         Element*       HeaderElement;
272         Element*       FooterElement;
273     };
274 
275     struct DocumentElement : public Element
276     {
277         friend class ElementFactory;
278     protected:
279         DocumentElement() : Element( NULL ) {}
280     public:
281         virtual ~DocumentElement();
282 
283         // ElementTreeVisitable
284         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
285 
286     };
287 
288     // this class is the differentiator of document types: it will create
289     // Element objects with an optimize() method suitable for the document type
290     class ElementFactory
291     {
292     public:
293         ElementFactory() {}
294         virtual ~ElementFactory();
295 
296         virtual HyperlinkElement* createHyperlinkElement( Element* pParent, const rtl::OUString& rURI )
297         { return new HyperlinkElement( pParent, rURI ); }
298 
299         virtual TextElement* createTextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId )
300         { return new TextElement( pParent, nGCId, nFontId ); }
301         virtual ParagraphElement* createParagraphElement( Element* pParent )
302         { return new ParagraphElement( pParent ); }
303 
304         virtual FrameElement* createFrameElement( Element* pParent, sal_Int32 nGCId )
305         { return new FrameElement( pParent, nGCId ); }
306         virtual PolyPolyElement*
307             createPolyPolyElement( Element* pParent,
308                                    sal_Int32 nGCId,
309                                    const basegfx::B2DPolyPolygon& rPolyPoly,
310                                    sal_Int8 nAction)
311         { return new PolyPolyElement( pParent, nGCId, rPolyPoly, nAction ); }
312         virtual ImageElement* createImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage )
313         { return new ImageElement( pParent, nGCId, nImage ); }
314 
315         virtual PageElement* createPageElement( Element* pParent,
316                                                 sal_Int32 nPageNr )
317         { return new PageElement( pParent, nPageNr ); }
318         virtual DocumentElement* createDocumentElement()
319         { return new DocumentElement(); }
320     };
321 }
322 
323 #endif
324