/src/libreoffice/sdext/source/pdfimport/inc/genericelements.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #ifndef INCLUDED_SDEXT_SOURCE_PDFIMPORT_INC_GENERICELEMENTS_HXX |
21 | | #define INCLUDED_SDEXT_SOURCE_PDFIMPORT_INC_GENERICELEMENTS_HXX |
22 | | |
23 | | #include "pdfihelper.hxx" |
24 | | #include "treevisiting.hxx" |
25 | | |
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> |
32 | | |
33 | | #include <list> |
34 | | |
35 | | namespace pdfi |
36 | | { |
37 | | class XmlEmitter; |
38 | | class StyleContainer; |
39 | | class ImageContainer; |
40 | | class PDFIProcessor; |
41 | | |
42 | | |
43 | | struct EmitContext |
44 | | { |
45 | | EmitContext( |
46 | | XmlEmitter& _rEmitter, |
47 | | StyleContainer& _rStyles, |
48 | | ImageContainer& _rImages, |
49 | | PDFIProcessor& _rProcessor, |
50 | | const css::uno::Reference< |
51 | | css::task::XStatusIndicator>& _xStatusIndicator, |
52 | | css::uno::Reference< css::uno::XComponentContext > const & xContext) |
53 | | : |
54 | 0 | rEmitter(_rEmitter), |
55 | 0 | rStyles(_rStyles), |
56 | 0 | rImages(_rImages), |
57 | 0 | rProcessor(_rProcessor), |
58 | 0 | xStatusIndicator(_xStatusIndicator), |
59 | 0 | m_xContext(xContext) |
60 | 0 | {} |
61 | | |
62 | | XmlEmitter& rEmitter; |
63 | | StyleContainer& rStyles; |
64 | | ImageContainer& rImages; |
65 | | PDFIProcessor& rProcessor; |
66 | | css::uno::Reference< |
67 | | css::task::XStatusIndicator> xStatusIndicator; |
68 | | css::uno::Reference< |
69 | | css::uno::XComponentContext > m_xContext; |
70 | | }; |
71 | | |
72 | | struct Element |
73 | | { |
74 | | protected: |
75 | | explicit Element( Element* pParent ) |
76 | 0 | : x( 0 ), y( 0 ), w( 0 ), h( 0 ), StyleId( -1 ), Parent( pParent ) |
77 | 0 | { |
78 | 0 | if( pParent ) |
79 | 0 | pParent->Children.emplace_back( this ); |
80 | 0 | } |
81 | | |
82 | | public: |
83 | | virtual ~Element(); |
84 | | |
85 | | /** |
86 | | To be implemented by every tree node that needs to be |
87 | | visitable. |
88 | | */ |
89 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& rParentIt ) = 0; |
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 | | /// To avoid some dynamic_cast cost |
96 | 0 | virtual const TextElement* dynCastAsTextElement() const { return nullptr; } |
97 | 0 | virtual TextElement* dynCastAsTextElement() { return nullptr; } |
98 | | |
99 | | #if OSL_DEBUG_LEVEL > 0 |
100 | | // xxx refact TODO: move code to visitor |
101 | | virtual void emitStructure( int nLevel ); |
102 | | #endif |
103 | | /** el must be a valid dereferenceable iterator of el->Parent->Children |
104 | | pNewParent must not be NULL |
105 | | */ |
106 | | static void setParent( std::list<std::unique_ptr<Element>>::iterator const & el, Element* pNewParent ); |
107 | | |
108 | | double x, y, w, h; |
109 | | sal_Int32 StyleId; |
110 | | Element* Parent; |
111 | | std::list<std::unique_ptr<Element>> Children; |
112 | | }; |
113 | | |
114 | | struct ListElement final : public Element |
115 | | { |
116 | 0 | ListElement() : Element( nullptr ) {} |
117 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; |
118 | | }; |
119 | | |
120 | | struct HyperlinkElement final : public Element |
121 | | { |
122 | | friend class ElementFactory; |
123 | | HyperlinkElement( Element* pParent, const OUString& rURI ) |
124 | 0 | : Element( pParent ), URI( rURI ) {} |
125 | | public: |
126 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; |
127 | | |
128 | | OUString URI; |
129 | | }; |
130 | | |
131 | | struct GraphicalElement : public Element |
132 | | { |
133 | | protected: |
134 | | GraphicalElement(Element* pParent, sal_Int32 nGCId) |
135 | 0 | : Element(pParent) |
136 | 0 | , GCId(nGCId) |
137 | 0 | , MirrorVertical(false) |
138 | 0 | , IsForText(false) |
139 | 0 | , FontSize(0.0) |
140 | 0 | , TextStyleId(0) |
141 | 0 | { |
142 | 0 | } |
143 | | |
144 | | public: |
145 | | sal_Int32 GCId; |
146 | | bool MirrorVertical; |
147 | | bool IsForText; |
148 | | double FontSize; |
149 | | sal_Int32 TextStyleId; |
150 | | }; |
151 | | |
152 | | struct DrawElement : public GraphicalElement |
153 | | { |
154 | | protected: |
155 | | DrawElement( Element* pParent, sal_Int32 nGCId ) |
156 | 0 | : GraphicalElement( pParent, nGCId ), isCharacter(false), ZOrder(0) {} |
157 | | |
158 | | public: |
159 | | bool isCharacter; |
160 | | sal_Int32 ZOrder; |
161 | | }; |
162 | | |
163 | | struct FrameElement final : public DrawElement |
164 | | { |
165 | | friend class ElementFactory; |
166 | | FrameElement( Element* pParent, sal_Int32 nGCId ) |
167 | 0 | : DrawElement( pParent, nGCId ) {} |
168 | | |
169 | | public: |
170 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; |
171 | | }; |
172 | | |
173 | | struct GroupElement final : public DrawElement |
174 | | { |
175 | | friend class ElementFactory; |
176 | | GroupElement( Element* pParent, sal_Int32 nGCId ) |
177 | 0 | : DrawElement( pParent, nGCId ) |
178 | 0 | , isTransparencyGroup(false) |
179 | 0 | , isForSoftMask(false) |
180 | 0 | { |
181 | 0 | } |
182 | | |
183 | | public: |
184 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; |
185 | | bool isTransparencyGroup; |
186 | | bool isForSoftMask; |
187 | | }; |
188 | | |
189 | | struct TextElement final : public GraphicalElement |
190 | | { |
191 | | friend class ElementFactory; |
192 | | TextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId ) |
193 | 0 | : GraphicalElement( pParent, nGCId ), FontId( nFontId ) {} |
194 | | |
195 | | public: |
196 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; |
197 | | |
198 | 0 | virtual const TextElement* dynCastAsTextElement() const override { return this; } |
199 | 0 | virtual TextElement* dynCastAsTextElement() override { return this; } |
200 | | |
201 | | OUStringBuffer Text; |
202 | | sal_Int32 FontId; |
203 | | }; |
204 | | |
205 | | struct ParagraphElement final : public Element |
206 | | { |
207 | | friend class ElementFactory; |
208 | 0 | explicit ParagraphElement( Element* pParent ) : Element( pParent ), Type( Normal ), bRtl( false ) {} |
209 | | |
210 | | public: |
211 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& rParentIt ) override; |
212 | | |
213 | | // returns true only if only a single line is contained |
214 | | bool isSingleLined( PDFIProcessor const & rProc ) const; |
215 | | // returns the highest line height of the contained textelements |
216 | | // line height is font height if the text element is itself multilined |
217 | | double getLineHeight( PDFIProcessor& rProc ) const; |
218 | | // returns the first text element child; does not recurse through subparagraphs |
219 | | TextElement* getFirstTextChild() const; |
220 | | |
221 | | enum ParagraphType { Normal, Headline }; |
222 | | ParagraphType Type; |
223 | | bool bRtl; |
224 | | }; |
225 | | |
226 | | struct PolyPolyElement final : public DrawElement |
227 | | { |
228 | | friend class ElementFactory; |
229 | | PolyPolyElement( Element* pParent, sal_Int32 nGCId, |
230 | | const basegfx::B2DPolyPolygon& rPolyPoly, |
231 | | sal_Int8 nAction, ImageId nFillImage, |
232 | | double nTileWidth, double nTileHeight ); |
233 | | public: |
234 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& rParentIt ) override; |
235 | | |
236 | | void updateGeometry(); |
237 | | |
238 | | #if OSL_DEBUG_LEVEL > 0 |
239 | | virtual void emitStructure( int nLevel ) override; |
240 | | #endif |
241 | | |
242 | | basegfx::B2DPolyPolygon PolyPoly; |
243 | | sal_Int8 Action; |
244 | | ImageId FillImage; |
245 | | double TileWidth; |
246 | | double TileHeight; |
247 | | }; |
248 | | |
249 | | struct ImageElement final : public DrawElement |
250 | | { |
251 | | friend class ElementFactory; |
252 | | ImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage ) |
253 | 0 | : DrawElement( pParent, nGCId ), Image( nImage ) {} |
254 | | |
255 | | public: |
256 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; |
257 | | |
258 | | ImageId Image; |
259 | | }; |
260 | | |
261 | | struct PageElement final : public Element |
262 | | { |
263 | | friend class ElementFactory; |
264 | | PageElement( Element* pParent, sal_Int32 nPageNr ) |
265 | 0 | : Element( pParent ), PageNumber( nPageNr ), Hyperlinks(), |
266 | 0 | TopMargin( 0.0 ), BottomMargin( 0.0 ), LeftMargin( 0.0 ), RightMargin( 0.0 ) |
267 | 0 | {} |
268 | | private: |
269 | | // helper method for resolveHyperlinks |
270 | | bool resolveHyperlink( const std::list<std::unique_ptr<Element>>::iterator& link_it, std::list<std::unique_ptr<Element>>& rElements ); |
271 | | public: |
272 | | virtual ~PageElement() override; |
273 | | |
274 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& rParentIt ) override; |
275 | | |
276 | | void resolveHyperlinks(); |
277 | | void resolveFontStyles( PDFIProcessor const & rProc ); |
278 | | void resolveUnderlines( PDFIProcessor const & rProc ); |
279 | | |
280 | | sal_Int32 PageNumber; |
281 | | ListElement Hyperlinks; // contains not yet realized links on this page |
282 | | double TopMargin; |
283 | | double BottomMargin; |
284 | | double LeftMargin; |
285 | | double RightMargin; |
286 | | std::unique_ptr<Element> HeaderElement; |
287 | | std::unique_ptr<Element> FooterElement; |
288 | | }; |
289 | | |
290 | | struct DocumentElement final : public Element |
291 | | { |
292 | | friend class ElementFactory; |
293 | | public: |
294 | 0 | DocumentElement() : Element( nullptr ) {} |
295 | | virtual ~DocumentElement() override; |
296 | | |
297 | | virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; |
298 | | }; |
299 | | |
300 | | // this class is the differentiator of document types: it will create |
301 | | // Element objects with an optimize() method suitable for the document type |
302 | | class ElementFactory |
303 | | { |
304 | | public: |
305 | | ElementFactory() = delete; |
306 | | |
307 | | static HyperlinkElement* createHyperlinkElement( Element* pParent, const OUString& rURI ) |
308 | 0 | { return new HyperlinkElement( pParent, rURI ); } |
309 | | |
310 | | static TextElement* createTextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId ) |
311 | 0 | { return new TextElement( pParent, nGCId, nFontId ); } |
312 | | static ParagraphElement* createParagraphElement( Element* pParent ) |
313 | 0 | { return new ParagraphElement( pParent ); } |
314 | | |
315 | | static FrameElement* createFrameElement( Element* pParent, sal_Int32 nGCId ) |
316 | 0 | { return new FrameElement( pParent, nGCId ); } |
317 | | static GroupElement* createGroupElement( Element* pParent, sal_Int32 nGCId ) |
318 | 0 | { return new GroupElement( pParent, nGCId ); } |
319 | | static PolyPolyElement* |
320 | | createPolyPolyElement( Element* pParent, |
321 | | sal_Int32 nGCId, |
322 | | const basegfx::B2DPolyPolygon& rPolyPoly, |
323 | | sal_Int8 nAction, ImageId nFillImage, |
324 | | double nTileWidth, double nTileHeight ) |
325 | 0 | { return new PolyPolyElement( pParent, nGCId, rPolyPoly, nAction, |
326 | 0 | nFillImage, nTileWidth, nTileHeight ); } |
327 | | static ImageElement* createImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage ) |
328 | 0 | { return new ImageElement( pParent, nGCId, nImage ); } |
329 | | |
330 | | static PageElement* createPageElement( Element* pParent, |
331 | | sal_Int32 nPageNr ) |
332 | 0 | { return new PageElement( pParent, nPageNr ); } |
333 | | static std::shared_ptr<DocumentElement> createDocumentElement() |
334 | 0 | { return std::make_shared<DocumentElement>(); } |
335 | | }; |
336 | | |
337 | | bool isComplex(const css::uno::Reference<css::i18n::XBreakIterator>& rBreakIterator, const TextElement* pTextElem); |
338 | | } |
339 | | |
340 | | #endif |
341 | | |
342 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |