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