Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */