1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef INCLUDED_SDEXT_SOURCE_PDFIMPORT_INC_GENERICELEMENTS_HXX
#define INCLUDED_SDEXT_SOURCE_PDFIMPORT_INC_GENERICELEMENTS_HXX
#include "pdfihelper.hxx"
#include "treevisiting.hxx"
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include <list>
namespace pdfi
{
class XmlEmitter;
class StyleContainer;
class ImageContainer;
class PDFIProcessor;
class ElementFactory;
struct EmitContext
{
EmitContext(
XmlEmitter& _rEmitter,
StyleContainer& _rStyles,
ImageContainer& _rImages,
PDFIProcessor& _rProcessor,
const css::uno::Reference<
css::task::XStatusIndicator>& _xStatusIndicator,
css::uno::Reference< css::uno::XComponentContext > const & xContext)
:
rEmitter(_rEmitter),
rStyles(_rStyles),
rImages(_rImages),
rProcessor(_rProcessor),
xStatusIndicator(_xStatusIndicator),
m_xContext(xContext)
{}
XmlEmitter& rEmitter;
StyleContainer& rStyles;
ImageContainer& rImages;
PDFIProcessor& rProcessor;
css::uno::Reference<
css::task::XStatusIndicator> xStatusIndicator;
css::uno::Reference<
css::uno::XComponentContext > m_xContext;
};
struct Element
{
protected:
explicit Element( Element* pParent )
: x( 0 ), y( 0 ), w( 0 ), h( 0 ), StyleId( -1 ), Parent( pParent )
{
if( pParent )
pParent->Children.emplace_back( this );
}
public:
virtual ~Element();
/**
To be implemented by every tree node that needs to be
visitable.
*/
virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& rParentIt ) = 0;
/// Apply visitor to all children
void applyToChildren( ElementTreeVisitor& );
/// Union element geometry with given element
void updateGeometryWith( const Element* pMergeFrom );
#if OSL_DEBUG_LEVEL > 0
// xxx refact TODO: move code to visitor
virtual void emitStructure( int nLevel );
#endif
/** el must be a valid dereferenceable iterator of el->Parent->Children
pNewParent must not be NULL
*/
static void setParent( std::list<std::unique_ptr<Element>>::iterator const & el, Element* pNewParent );
double x, y, w, h;
sal_Int32 StyleId;
Element* Parent;
std::list<std::unique_ptr<Element>> Children;
};
struct ListElement final : public Element
{
ListElement() : Element( nullptr ) {}
virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override;
};
struct HyperlinkElement final : public Element
{
friend class ElementFactory;
HyperlinkElement( Element* pParent, const OUString& rURI )
: Element( pParent ), URI( rURI ) {}
public:
virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override;
OUString URI;
};
struct GraphicalElement : public Element
{
protected:
GraphicalElement(Element* pParent, sal_Int32 nGCId)
: Element(pParent)
, GCId(nGCId)
, MirrorVertical(false)
, IsForText(false)
, FontSize(0.0)
, TextStyleId(0)
{
}
public:
sal_Int32 GCId;
bool MirrorVertical;
bool IsForText;
double FontSize;
sal_Int32 TextStyleId;
};
struct DrawElement : public GraphicalElement
{
protected:
DrawElement( Element* pParent, sal_Int32 nGCId )
: GraphicalElement( pParent, nGCId ), isCharacter(false), ZOrder(0) {}
public:
bool isCharacter;
sal_Int32 ZOrder;
};
struct FrameElement final : public DrawElement
{
friend class ElementFactory;
FrameElement( Element* pParent, sal_Int32 nGCId )
: DrawElement( pParent, nGCId ) {}
public:
virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override;
};
struct TextElement final : public GraphicalElement
{
friend class ElementFactory;
TextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId )
: GraphicalElement( pParent, nGCId ), FontId( nFontId ) {}
public:
virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override;
OUStringBuffer Text;
sal_Int32 FontId;
};
struct ParagraphElement final : public Element
{
friend class ElementFactory;
explicit ParagraphElement( Element* pParent ) : Element( pParent ), Type( Normal ), bRtl( false ) {}
public:
virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& rParentIt ) override;
// returns true only if only a single line is contained
bool isSingleLined( PDFIProcessor const & rProc ) const;
// returns the highest line height of the contained textelements
// line height is font height if the text element is itself multilined
double getLineHeight( PDFIProcessor& rProc ) const;
// returns the first text element child; does not recurse through subparagraphs
TextElement* getFirstTextChild() const;
enum ParagraphType { Normal, Headline };
ParagraphType Type;
bool bRtl;
};
struct PolyPolyElement final : public DrawElement
{
friend class ElementFactory;
PolyPolyElement( Element* pParent, sal_Int32 nGCId,
const basegfx::B2DPolyPolygon& rPolyPoly,
sal_Int8 nAction );
public:
virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& rParentIt ) override;
void updateGeometry();
#if OSL_DEBUG_LEVEL > 0
virtual void emitStructure( int nLevel ) override;
#endif
basegfx::B2DPolyPolygon PolyPoly;
sal_Int8 Action;
};
struct ImageElement final : public DrawElement
{
friend class ElementFactory;
ImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage )
: DrawElement( pParent, nGCId ), Image( nImage ) {}
public:
virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override;
ImageId Image;
};
struct PageElement final : public Element
{
friend class ElementFactory;
PageElement( Element* pParent, sal_Int32 nPageNr )
: Element( pParent ), PageNumber( nPageNr ), Hyperlinks(),
TopMargin( 0.0 ), BottomMargin( 0.0 ), LeftMargin( 0.0 ), RightMargin( 0.0 )
{}
private:
// helper method for resolveHyperlinks
bool resolveHyperlink( const std::list<std::unique_ptr<Element>>::iterator& link_it, std::list<std::unique_ptr<Element>>& rElements );
public:
virtual ~PageElement() override;
virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& rParentIt ) override;
void resolveHyperlinks();
void resolveFontStyles( PDFIProcessor const & rProc );
void resolveUnderlines( PDFIProcessor const & rProc );
sal_Int32 PageNumber;
ListElement Hyperlinks; // contains not yet realized links on this page
double TopMargin;
double BottomMargin;
double LeftMargin;
double RightMargin;
std::unique_ptr<Element> HeaderElement;
std::unique_ptr<Element> FooterElement;
};
struct DocumentElement final : public Element
{
friend class ElementFactory;
public:
DocumentElement() : Element( nullptr ) {}
virtual ~DocumentElement() override;
virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override;
};
// this class is the differentiator of document types: it will create
// Element objects with an optimize() method suitable for the document type
class ElementFactory
{
public:
ElementFactory() = delete;
static HyperlinkElement* createHyperlinkElement( Element* pParent, const OUString& rURI )
{ return new HyperlinkElement( pParent, rURI ); }
static TextElement* createTextElement( Element* pParent, sal_Int32 nGCId, sal_Int32 nFontId )
{ return new TextElement( pParent, nGCId, nFontId ); }
static ParagraphElement* createParagraphElement( Element* pParent )
{ return new ParagraphElement( pParent ); }
static FrameElement* createFrameElement( Element* pParent, sal_Int32 nGCId )
{ return new FrameElement( pParent, nGCId ); }
static PolyPolyElement*
createPolyPolyElement( Element* pParent,
sal_Int32 nGCId,
const basegfx::B2DPolyPolygon& rPolyPoly,
sal_Int8 nAction)
{ return new PolyPolyElement( pParent, nGCId, rPolyPoly, nAction ); }
static ImageElement* createImageElement( Element* pParent, sal_Int32 nGCId, ImageId nImage )
{ return new ImageElement( pParent, nGCId, nImage ); }
static PageElement* createPageElement( Element* pParent,
sal_Int32 nPageNr )
{ return new PageElement( pParent, nPageNr ); }
static std::shared_ptr<DocumentElement> createDocumentElement()
{ return std::make_shared<DocumentElement>(); }
};
}
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|