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
,
218 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& rParentIt
) override
;
220 void updateGeometry();
222 #if OSL_DEBUG_LEVEL > 0
223 virtual void emitStructure( int nLevel
) override
;
226 basegfx::B2DPolyPolygon PolyPoly
;
230 struct ImageElement final
: public DrawElement
232 friend class ElementFactory
;
233 ImageElement( Element
* pParent
, sal_Int32 nGCId
, ImageId nImage
)
234 : DrawElement( pParent
, nGCId
), Image( nImage
) {}
237 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& ) override
;
242 struct PageElement final
: public Element
244 friend class ElementFactory
;
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 )
250 // helper method for resolveHyperlinks
251 bool resolveHyperlink( const std::list
<std::unique_ptr
<Element
>>::iterator
& link_it
, std::list
<std::unique_ptr
<Element
>>& rElements
);
253 virtual ~PageElement() override
;
255 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& rParentIt
) override
;
257 void resolveHyperlinks();
258 void resolveFontStyles( PDFIProcessor
const & rProc
);
259 void resolveUnderlines( PDFIProcessor
const & rProc
);
261 sal_Int32 PageNumber
;
262 ListElement Hyperlinks
; // contains not yet realized links on this page
267 std::unique_ptr
<Element
> HeaderElement
;
268 std::unique_ptr
<Element
> FooterElement
;
271 struct DocumentElement final
: public Element
273 friend class ElementFactory
;
275 DocumentElement() : Element( nullptr ) {}
276 virtual ~DocumentElement() override
;
278 virtual void visitedBy( ElementTreeVisitor
&, const std::list
< std::unique_ptr
<Element
> >::const_iterator
& ) override
;
281 // this class is the differentiator of document types: it will create
282 // Element objects with an optimize() method suitable for the document type
286 ElementFactory() = delete;
288 static HyperlinkElement
* createHyperlinkElement( Element
* pParent
, const OUString
& rURI
)
289 { return new HyperlinkElement( pParent
, rURI
); }
291 static TextElement
* createTextElement( Element
* pParent
, sal_Int32 nGCId
, sal_Int32 nFontId
)
292 { return new TextElement( pParent
, nGCId
, nFontId
); }
293 static ParagraphElement
* createParagraphElement( Element
* pParent
)
294 { return new ParagraphElement( pParent
); }
296 static FrameElement
* createFrameElement( Element
* pParent
, sal_Int32 nGCId
)
297 { return new FrameElement( pParent
, nGCId
); }
298 static PolyPolyElement
*
299 createPolyPolyElement( Element
* pParent
,
301 const basegfx::B2DPolyPolygon
& rPolyPoly
,
303 { return new PolyPolyElement( pParent
, nGCId
, rPolyPoly
, nAction
); }
304 static ImageElement
* createImageElement( Element
* pParent
, sal_Int32 nGCId
, ImageId nImage
)
305 { return new ImageElement( pParent
, nGCId
, nImage
); }
307 static PageElement
* createPageElement( Element
* pParent
,
309 { return new PageElement( pParent
, nPageNr
); }
310 static std::shared_ptr
<DocumentElement
> createDocumentElement()
311 { return std::make_shared
<DocumentElement
>(); }
314 bool isComplex(const css::uno::Reference
<css::i18n::XBreakIterator
>& rBreakIterator
, TextElement
* const pTextElem
);
319 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */