1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef INCLUDED_PDFI_GENERICELEMENTS_HXX
25 #define INCLUDED_PDFI_GENERICELEMENTS_HXX
26 
27 #include "pdfihelper.hxx"
28 #include "treevisiting.hxx"
29 
30 #include <com/sun/star/task/XStatusIndicator.hpp>
31 #include <com/sun/star/uno/XComponentContext.hpp>
32 #include <basegfx/polygon/b2dpolypolygon.hxx>
33 #include <basegfx/range/b2drange.hxx>
34 #include <rtl/ustring.hxx>
35 #include <rtl/ustrbuf.hxx>
36 
37 #include <list>
38 
39 namespace pdfi
40 {
41     class XmlEmitter;
42     class StyleContainer;
43     class ImageContainer;
44     class PDFIProcessor;
45     class ElementFactory;
46 
47 
48     struct EmitContext
49     {
EmitContextpdfi::EmitContext50         EmitContext(
51             XmlEmitter&                              _rEmitter,
52             StyleContainer&                          _rStyles,
53             ImageContainer&                          _rImages,
54             PDFIProcessor&                           _rProcessor,
55             const com::sun::star::uno::Reference<
56             com::sun::star::task::XStatusIndicator>& _xStatusIndicator,
57             com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >  xContext)
58 		:
59             rEmitter(_rEmitter),
60             rStyles(_rStyles),
61             rImages(_rImages),
62             rProcessor(_rProcessor),
63             xStatusIndicator(_xStatusIndicator),
64 	    m_xContext(xContext)
65         {}
66 
67         XmlEmitter&     rEmitter;
68         StyleContainer& rStyles;
69         ImageContainer& rImages;
70         PDFIProcessor&  rProcessor;
71         com::sun::star::uno::Reference<
72             com::sun::star::task::XStatusIndicator> xStatusIndicator;
73         com::sun::star::uno::Reference<
74             com::sun::star::uno::XComponentContext >  m_xContext;
75     };
76 
77     struct Element : public ElementTreeVisitable
78     {
79     protected:
Elementpdfi::Element80         Element( Element* pParent )
81             : x( 0 ), y( 0 ), w( 0 ), h( 0 ), StyleId( -1 ), Parent( pParent )
82         {
83             if( pParent )
84                 pParent->Children.push_back( this );
85         }
86 
87     public:
88         virtual ~Element();
89 
90         /// Apply visitor to all children
91         void applyToChildren( ElementTreeVisitor& );
92         /// Union element geometry with given element
93         void updateGeometryWith( const Element* pMergeFrom );
94 
95 #if OSL_DEBUG_LEVEL > 1
96         // xxx refac TODO: move code to visitor
97         virtual void emitStructure( int nLevel );
98 #endif
99         /** el must be a valid dereferencable iterator of el->Parent->Children
100             pNewParent must not be NULL
101         */
102         static void setParent( std::list<Element*>::iterator& el, Element* pNewParent );
103 
104         double              x, y, w, h;
105         sal_Int32           StyleId;
106         Element*            Parent;
107         std::list<Element*> Children;
108     };
109 
110     struct ListElement : public Element
111     {
ListElementpdfi::ListElement112         ListElement() : Element( NULL ) {}
113         // ElementTreeVisitable
114         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
115     };
116 
117     struct HyperlinkElement : public Element
118     {
119         friend class ElementFactory;
120     protected:
HyperlinkElementpdfi::HyperlinkElement121         HyperlinkElement( Element* pParent, const rtl::OUString& rURI )
122         : Element( pParent ), URI( rURI ) {}
123     public:
124         // ElementTreeVisitable
125         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
126 
127         rtl::OUString URI;
128     };
129 
130     struct GraphicalElement : public Element
131     {
132     protected:
GraphicalElementpdfi::GraphicalElement133         GraphicalElement( Element* pParent, sal_Int32 nGCId )
134         : Element( pParent ), GCId( nGCId ), MirrorVertical( false ) {}
135 
136     public:
137         sal_Int32 GCId;
138         bool      MirrorVertical;
139     };
140 
141     struct DrawElement : public GraphicalElement
142     {
143     protected:
DrawElementpdfi::DrawElement144         DrawElement( Element* pParent, sal_Int32 nGCId )
145         : GraphicalElement( pParent, nGCId ), isCharacter(false), ZOrder(0) {}
146 
147     public:
148         bool      isCharacter;
149         sal_Int32 ZOrder;
150     };
151 
152     struct FrameElement : public DrawElement
153     {
154         friend class ElementFactory;
155     protected:
FrameElementpdfi::FrameElement156         FrameElement( Element* pParent, sal_Int32 nGCId )
157         : DrawElement( pParent, nGCId ) {}
158 
159     public:
160         // ElementTreeVisitable
161         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
162     };
163 
164     struct TextElement : public GraphicalElement
165     {
166         friend class ElementFactory;
167     protected:
TextElementpdfi::TextElement168         TextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId )
169         : GraphicalElement( pParent, nGCId ), FontId( nFontId ) {}
170 
171     public:
172         // ElementTreeVisitable
173         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
174 
175         rtl::OUStringBuffer Text;
176         sal_Int32           FontId;
177     };
178 
179     struct ParagraphElement : public Element
180     {
181         friend class ElementFactory;
182     protected:
ParagraphElementpdfi::ParagraphElement183         ParagraphElement( Element* pParent ) : Element( pParent ), Type( Normal ), bRtl( false ) {}
184 
185     public:
186         // ElementTreeVisitable
187         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& rParentIt );
188 
189         // returns true only if only a single line is contained
190         bool isSingleLined( PDFIProcessor& rProc ) const;
191         // returns the highest line height of the contained textelements
192         // line height is font height if the text element is itself multilined
193         double getLineHeight( PDFIProcessor& rProc ) const;
194         // returns the first text element child; does not recurse through subparagraphs
195         TextElement* getFirstTextChild() const;
196 
197         enum ParagraphType { Normal, Headline };
198         ParagraphType       Type;
199 	bool bRtl;
200     };
201 
202     struct PolyPolyElement : public DrawElement
203     {
204         friend class ElementFactory;
205     protected:
206         PolyPolyElement( Element* pParent, sal_Int32 nGCId,
207                          const basegfx::B2DPolyPolygon& rPolyPoly,
208                          sal_Int8 nAction );
209     public:
210         // ElementTreeVisitable
211         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& rParentIt );
212 
213         void updateGeometry();
214 
215 #if OSL_DEBUG_LEVEL > 1
216         virtual void emitStructure( int nLevel );
217 #endif
218 
219         basegfx::B2DPolyPolygon PolyPoly;
220         sal_Int8                Action;
221     };
222 
223     struct ImageElement : public DrawElement
224     {
225         friend class ElementFactory;
226     protected:
ImageElementpdfi::ImageElement227         ImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage )
228         : DrawElement( pParent, nGCId ), Image( nImage ) {}
229 
230     public:
231         // ElementTreeVisitable
232         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
233 
234         ImageId Image;
235     };
236 
237     struct PageElement : public Element
238     {
239         friend class ElementFactory;
240     protected:
PageElementpdfi::PageElement241         PageElement( Element* pParent, sal_Int32 nPageNr )
242         : Element( pParent ), PageNumber( nPageNr ), Hyperlinks(),
243         TopMargin( 0.0 ), BottomMargin( 0.0 ), LeftMargin( 0.0 ), RightMargin( 0.0 ),
244         HeaderElement( NULL ), FooterElement( NULL )
245         {}
246     private:
247         // helper method for resolveHyperlinks
248         bool resolveHyperlink( std::list<Element*>::iterator link_it, std::list<Element*>& rElements );
249         public:
250         virtual ~PageElement();
251 
252         // ElementTreeVisitable
253         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& rParentIt );
254 
255         void emitPageAnchoredElements( EmitContext& rEmitContext );
256         static void updateParagraphGeometry( Element* pEle );
257         void resolveHyperlinks();
258         void resolveFontStyles( PDFIProcessor& rProc );
259         void resolveUnderlines( PDFIProcessor& rProc );
260 
261         sal_Int32      PageNumber;
262         ListElement    Hyperlinks; // contains not yet realized links on this page
263         double         TopMargin;
264         double         BottomMargin;
265         double         LeftMargin;
266         double         RightMargin;
267         Element*       HeaderElement;
268         Element*       FooterElement;
269     };
270 
271     struct DocumentElement : public Element
272     {
273         friend class ElementFactory;
274     protected:
DocumentElementpdfi::DocumentElement275         DocumentElement() : Element( NULL ) {}
276     public:
277         virtual ~DocumentElement();
278 
279         // ElementTreeVisitable
280         virtual void visitedBy( ElementTreeVisitor&, const std::list< Element* >::const_iterator& );
281 
282     };
283 
284     // this class is the differentiator of document types: it will create
285     // Element objects with an optimize() method suitable for the document type
286     class ElementFactory
287     {
288     public:
ElementFactory()289         ElementFactory() {}
290         virtual ~ElementFactory();
291 
createHyperlinkElement(Element * pParent,const rtl::OUString & rURI)292         virtual HyperlinkElement* createHyperlinkElement( Element* pParent, const rtl::OUString& rURI )
293         { return new HyperlinkElement( pParent, rURI ); }
294 
createTextElement(Element * pParent,sal_Int32 nGCId,sal_Int32 nFontId)295         virtual TextElement* createTextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId )
296         { return new TextElement( pParent, nGCId, nFontId ); }
createParagraphElement(Element * pParent)297         virtual ParagraphElement* createParagraphElement( Element* pParent )
298         { return new ParagraphElement( pParent ); }
299 
createFrameElement(Element * pParent,sal_Int32 nGCId)300         virtual FrameElement* createFrameElement( Element* pParent, sal_Int32 nGCId )
301         { return new FrameElement( pParent, nGCId ); }
302         virtual PolyPolyElement*
createPolyPolyElement(Element * pParent,sal_Int32 nGCId,const basegfx::B2DPolyPolygon & rPolyPoly,sal_Int8 nAction)303             createPolyPolyElement( Element* pParent,
304                                    sal_Int32 nGCId,
305                                    const basegfx::B2DPolyPolygon& rPolyPoly,
306                                    sal_Int8 nAction)
307         { return new PolyPolyElement( pParent, nGCId, rPolyPoly, nAction ); }
createImageElement(Element * pParent,sal_Int32 nGCId,ImageId nImage)308         virtual ImageElement* createImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage )
309         { return new ImageElement( pParent, nGCId, nImage ); }
310 
createPageElement(Element * pParent,sal_Int32 nPageNr)311         virtual PageElement* createPageElement( Element* pParent,
312                                                 sal_Int32 nPageNr )
313         { return new PageElement( pParent, nPageNr ); }
createDocumentElement()314         virtual DocumentElement* createDocumentElement()
315         { return new DocumentElement(); }
316     };
317 }
318 
319 #endif
320