1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SDEXT_SOURCE_PDFIMPORT_INC_GENERICELEMENTS_HXX
21 #define INCLUDED_SDEXT_SOURCE_PDFIMPORT_INC_GENERICELEMENTS_HXX
23 #include "pdfihelper.hxx"
24 #include "treevisiting.hxx"
26 #include <com/sun/star/task/XStatusIndicator.hpp>
27 #include <com/sun/star/uno/XComponentContext.hpp>
28 #include <com/sun/star/i18n/BreakIterator.hpp>
29 #include <basegfx/polygon/b2dpolypolygon.hxx>
30 #include <rtl/ustring.hxx>
31 #include <rtl/ustrbuf.hxx>
47 XmlEmitter
& _rEmitter
,
48 StyleContainer
& _rStyles
,
49 ImageContainer
& _rImages
,
50 PDFIProcessor
& _rProcessor
,
51 const css::uno::Reference
<
52 css::task::XStatusIndicator
>& _xStatusIndicator
,
53 css::uno::Reference
< css::uno::XComponentContext
> const & xContext
)
58 rProcessor(_rProcessor
),
59 xStatusIndicator(_xStatusIndicator
),
64 StyleContainer
& rStyles
;
65 ImageContainer
& rImages
;
66 PDFIProcessor
& rProcessor
;
68 css::task::XStatusIndicator
> xStatusIndicator
;
70 css::uno::XComponentContext
> m_xContext
;
76 explicit Element( Element
* pParent
)
77 : x( 0 ), y( 0 ), w( 0 ), h( 0 ), StyleId( -1 ), Parent( pParent
)
80 pParent
->Children
.emplace_back( this );
87 To be implemented by every tree node that needs to be
90 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& rParentIt
) = 0;
91 /// Apply visitor to all children
92 void applyToChildren( ElementTreeVisitor
& );
93 /// Union element geometry with given element
94 void updateGeometryWith( const Element
* pMergeFrom
);
96 /// To avoid some dynamic_cast cost
97 virtual const TextElement
* dynCastAsTextElement() const { return nullptr; }
98 virtual TextElement
* dynCastAsTextElement() { return nullptr; }
100 #if OSL_DEBUG_LEVEL > 0
101 // xxx refact TODO: move code to visitor
102 virtual void emitStructure( int nLevel
);
104 /** el must be a valid dereferenceable iterator of el->Parent->Children
105 pNewParent must not be NULL
107 static void setParent( std::list
<std::unique_ptr
<Element
>>::iterator
const & el
, Element
* pNewParent
);
112 std::list
<std::unique_ptr
<Element
>> Children
;
115 struct ListElement final
: public Element
117 ListElement() : Element( nullptr ) {}
118 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& ) override
;
121 struct HyperlinkElement final
: public Element
123 friend class ElementFactory
;
124 HyperlinkElement( Element
* pParent
, const OUString
& rURI
)
125 : Element( pParent
), URI( rURI
) {}
127 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& ) override
;
132 struct GraphicalElement
: public Element
135 GraphicalElement(Element
* pParent
, sal_Int32 nGCId
)
138 , MirrorVertical(false)
150 sal_Int32 TextStyleId
;
153 struct DrawElement
: public GraphicalElement
156 DrawElement( Element
* pParent
, sal_Int32 nGCId
)
157 : GraphicalElement( pParent
, nGCId
), isCharacter(false), ZOrder(0) {}
164 struct FrameElement final
: public DrawElement
166 friend class ElementFactory
;
167 FrameElement( Element
* pParent
, sal_Int32 nGCId
)
168 : DrawElement( pParent
, nGCId
) {}
171 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& ) override
;
174 struct TextElement final
: public GraphicalElement
176 friend class ElementFactory
;
177 TextElement( Element
* pParent
, sal_Int32 nGCId
, sal_Int32 nFontId
)
178 : GraphicalElement( pParent
, nGCId
), FontId( nFontId
) {}
181 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& ) override
;
183 virtual const TextElement
* dynCastAsTextElement() const override
{ return this; }
184 virtual TextElement
* dynCastAsTextElement() override
{ return this; }
190 struct ParagraphElement final
: public Element
192 friend class ElementFactory
;
193 explicit ParagraphElement( Element
* pParent
) : Element( pParent
), Type( Normal
), bRtl( false ) {}
196 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& rParentIt
) override
;
198 // returns true only if only a single line is contained
199 bool isSingleLined( PDFIProcessor
const & rProc
) const;
200 // returns the highest line height of the contained textelements
201 // line height is font height if the text element is itself multilined
202 double getLineHeight( PDFIProcessor
& rProc
) const;
203 // returns the first text element child; does not recurse through subparagraphs
204 TextElement
* getFirstTextChild() const;
206 enum ParagraphType
{ Normal
, Headline
};
211 struct PolyPolyElement final
: public DrawElement
213 friend class ElementFactory
;
214 PolyPolyElement( Element
* pParent
, sal_Int32 nGCId
,
215 const basegfx::B2DPolyPolygon
& rPolyPoly
,
216 sal_Int8 nAction
, ImageId nFillImage
,
217 double nTileWidth
, double nTileHeight
);
219 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& rParentIt
) override
;
221 void updateGeometry();
223 #if OSL_DEBUG_LEVEL > 0
224 virtual void emitStructure( int nLevel
) override
;
227 basegfx::B2DPolyPolygon PolyPoly
;
234 struct ImageElement final
: public DrawElement
236 friend class ElementFactory
;
237 ImageElement( Element
* pParent
, sal_Int32 nGCId
, ImageId nImage
)
238 : DrawElement( pParent
, nGCId
), Image( nImage
) {}
241 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& ) override
;
246 struct PageElement final
: public Element
248 friend class ElementFactory
;
249 PageElement( Element
* pParent
, sal_Int32 nPageNr
)
250 : Element( pParent
), PageNumber( nPageNr
), Hyperlinks(),
251 TopMargin( 0.0 ), BottomMargin( 0.0 ), LeftMargin( 0.0 ), RightMargin( 0.0 )
254 // helper method for resolveHyperlinks
255 bool resolveHyperlink( const std::list
<std::unique_ptr
<Element
>>::iterator
& link_it
, std::list
<std::unique_ptr
<Element
>>& rElements
);
257 virtual ~PageElement() override
;
259 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& rParentIt
) override
;
261 void resolveHyperlinks();
262 void resolveFontStyles( PDFIProcessor
const & rProc
);
263 void resolveUnderlines( PDFIProcessor
const & rProc
);
265 sal_Int32 PageNumber
;
266 ListElement Hyperlinks
; // contains not yet realized links on this page
271 std::unique_ptr
<Element
> HeaderElement
;
272 std::unique_ptr
<Element
> FooterElement
;
275 struct DocumentElement final
: public Element
277 friend class ElementFactory
;
279 DocumentElement() : Element( nullptr ) {}
280 virtual ~DocumentElement() override
;
282 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& ) override
;
285 // this class is the differentiator of document types: it will create
286 // Element objects with an optimize() method suitable for the document type
290 ElementFactory() = delete;
292 static HyperlinkElement
* createHyperlinkElement( Element
* pParent
, const OUString
& rURI
)
293 { return new HyperlinkElement( pParent
, rURI
); }
295 static TextElement
* createTextElement( Element
* pParent
, sal_Int32 nGCId
, sal_Int32 nFontId
)
296 { return new TextElement( pParent
, nGCId
, nFontId
); }
297 static ParagraphElement
* createParagraphElement( Element
* pParent
)
298 { return new ParagraphElement( pParent
); }
300 static FrameElement
* createFrameElement( Element
* pParent
, sal_Int32 nGCId
)
301 { return new FrameElement( pParent
, nGCId
); }
302 static PolyPolyElement
*
303 createPolyPolyElement( Element
* pParent
,
305 const basegfx::B2DPolyPolygon
& rPolyPoly
,
306 sal_Int8 nAction
, ImageId nFillImage
,
307 double nTileWidth
, double nTileHeight
)
308 { return new PolyPolyElement( pParent
, nGCId
, rPolyPoly
, nAction
,
309 nFillImage
, nTileWidth
, nTileHeight
); }
310 static ImageElement
* createImageElement( Element
* pParent
, sal_Int32 nGCId
, ImageId nImage
)
311 { return new ImageElement( pParent
, nGCId
, nImage
); }
313 static PageElement
* createPageElement( Element
* pParent
,
315 { return new PageElement( pParent
, nPageNr
); }
316 static std::shared_ptr
<DocumentElement
> createDocumentElement()
317 { return std::make_shared
<DocumentElement
>(); }
320 bool isComplex(const css::uno::Reference
<css::i18n::XBreakIterator
>& rBreakIterator
, TextElement
* const pTextElem
);
325 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */