Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/cppcanvas/source/inc/implrenderer.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
#pragma once
21
22
#include <sal/config.h>
23
24
#include <sal/types.h>
25
#include <tools/stream.hxx>
26
#include <utility>
27
#include <vcl/kernarray.hxx>
28
#include <vcl/metaactiontypes.hxx>
29
#include <cppcanvas/renderer.hxx>
30
#include <cppcanvas/canvas.hxx>
31
32
#include "canvasgraphichelper.hxx"
33
#include "action.hxx"
34
#include "outdevstate.hxx"
35
36
#include <osl/diagnose.h>
37
38
#include <memory>
39
#include <span>
40
#include <vector>
41
42
class GDIMetaFile;
43
class VirtualDevice;
44
class Gradient;
45
namespace tools { class Rectangle; }
46
namespace vcl { class Font; }
47
namespace tools { class PolyPolygon; }
48
class Point;
49
50
namespace basegfx {
51
    class B2DPolyPolygon;
52
    class B2DPolygon;
53
}
54
55
namespace cppcanvas::internal
56
    {
57
        struct ActionFactoryParameters;
58
59
        // state stack of OutputDevice, to correctly handle
60
        // push/pop actions
61
        class VectorOfOutDevStates
62
        {
63
        public:
64
            OutDevState& getState();
65
            const OutDevState& getState() const;
66
            void pushState(vcl::PushFlags nFlags);
67
            void popState();
68
            void clearStateStack();
69
        private:
70
            std::vector< OutDevState > m_aStates;
71
        };
72
73
        // EMF+
74
        // Transformation matrix (used for Affine Transformation)
75
        //      [ eM11, eM12, eDx ]
76
        //      [ eM21, eM22, eDy ]
77
        //      [ 0,    0,    1   ]
78
        // that consists of a linear map (eM11, eM12, eM21, eM22)
79
        // More info: https://en.wikipedia.org/wiki/Linear_map
80
        // followed by a translation (eDx, eDy)
81
82
        struct XForm
83
        {
84
            float   eM11; // M1,1 value in the matrix. Increases or decreases the size of the pixels horizontally.
85
            float   eM12; // M1,2 value in the matrix. This effectively angles the X axis up or down.
86
            float   eM21; // M2,1 value in the matrix. This effectively angles the Y axis left or right.
87
            float   eM22; // M2,2 value in the matrix. Increases or decreases the size of the pixels vertically.
88
            float   eDx;  // Delta x (Dx) value in the matrix. Moves the whole coordinate system horizontally.
89
            float   eDy;  // Delta y (Dy) value in the matrix. Moves the whole coordinate system vertically.
90
            XForm()
91
0
            {
92
0
                SetIdentity ();
93
0
            }
94
95
            void SetIdentity ()
96
0
            {
97
0
                eM11 =  eM22 = 1.0f;
98
0
                eDx = eDy = eM12 = eM21 = 0.0f;
99
0
            }
100
101
            friend SvStream& ReadXForm( SvStream& rIn, XForm& rXForm )
102
0
            {
103
0
                if ( sizeof( float ) != 4 )
104
0
                {
105
0
                    OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" );
106
0
                    rXForm = XForm();
107
0
                }
108
0
                else
109
0
                {
110
0
                    rIn.ReadFloat( rXForm.eM11 ).ReadFloat( rXForm.eM12 ).ReadFloat( rXForm.eM21 ).ReadFloat( rXForm.eM22 )
111
0
                       .ReadFloat( rXForm.eDx ).ReadFloat( rXForm.eDy );
112
0
                }
113
0
                return rIn;
114
0
            }
115
        };
116
117
        // EMF+
118
119
        class ImplRenderer : public virtual Renderer, protected CanvasGraphicHelper
120
        {
121
        public:
122
            ImplRenderer( const CanvasSharedPtr&    rCanvas,
123
                          const GDIMetaFile&        rMtf,
124
                          const Parameters&         rParms );
125
126
            virtual ~ImplRenderer() override;
127
128
            virtual bool                draw() const override;
129
            virtual bool                drawSubset( sal_Int32   nStartIndex,
130
                                                    sal_Int32   nEndIndex ) const override;
131
            virtual ::basegfx::B2DRange getSubsetArea( sal_Int32    nStartIndex,
132
                                                       sal_Int32    nEndIndex ) const override;
133
134
135
            // element of the Renderer's action vector. Need to be
136
            // public, since some functors need it, too.
137
            struct MtfAction
138
            {
139
                MtfAction( std::shared_ptr<Action>  xAction,
140
                           sal_Int32                nOrigIndex ) :
141
0
                    mpAction(std::move( xAction )),
142
0
                    mnOrigIndex( nOrigIndex )
143
0
                {
144
0
                }
145
146
                std::shared_ptr<Action> mpAction;
147
                sal_Int32       mnOrigIndex;
148
            };
149
150
            // prefetched and prepared canvas actions
151
            // (externally not visible)
152
            typedef std::vector< MtfAction >      ActionVector;
153
154
        private:
155
            ImplRenderer(const ImplRenderer&) = delete;
156
            ImplRenderer& operator=( const ImplRenderer& ) = delete;
157
158
            static void updateClipping( const ::basegfx::B2DPolyPolygon&   rClipPoly,
159
                                 const ActionFactoryParameters&     rParms,
160
                                 bool                               bIntersect );
161
162
            static void updateClipping( const ::tools::Rectangle&                 rClipRect,
163
                                 const ActionFactoryParameters&     rParms,
164
                                 bool                               bIntersect );
165
166
            static css::uno::Reference<
167
                css::rendering::XCanvasFont > createFont( double&                         o_rFontRotation,
168
                                                          const vcl::Font&                rFont,
169
                                                          const ActionFactoryParameters&  rParms );
170
            void createActions( GDIMetaFile&                    rMtf,
171
                                const ActionFactoryParameters&  rParms,
172
                                bool                            bSubsettableActions );
173
            bool createFillAndStroke( const ::basegfx::B2DPolyPolygon& rPolyPoly,
174
                                      const ActionFactoryParameters&   rParms );
175
            bool createFillAndStroke( const ::basegfx::B2DPolygon&   rPoly,
176
                                      const ActionFactoryParameters& rParms );
177
            static void skipContent( GDIMetaFile& rMtf,
178
                              const char*  pCommentString,
179
                              sal_Int32&   io_rCurrActionIndex );
180
181
            static bool isActionContained( GDIMetaFile& rMtf,
182
                                    const char*     pCommentString,
183
                                    MetaActionType  nType );
184
185
            void createGradientAction( const ::tools::PolyPolygon&    rPoly,
186
                                       const ::Gradient&              rGradient,
187
                                       const ActionFactoryParameters& rParms,
188
                                       bool                           bIsPolygonRectangle,
189
                                       bool                           bSubsettableActions );
190
191
            void createTextAction( const ::Point&                 rStartPoint,
192
                                   const OUString&                rString,
193
                                   int                            nIndex,
194
                                   int                            nLength,
195
                                   KernArraySpan                pCharWidths,
196
                                   std::span<const sal_Bool>     pKashidaArray,
197
                                   const ActionFactoryParameters& rParms,
198
                                   bool                           bSubsettable );
199
200
            bool getSubsetIndices( sal_Int32&                    io_rStartIndex,
201
                                   sal_Int32&                    io_rEndIndex,
202
                                   ActionVector::const_iterator& o_rRangeBegin,
203
                                   ActionVector::const_iterator& o_rRangeEnd ) const;
204
205
            ActionVector maActions;
206
207
            /* EMF+ */
208
            XForm           aBaseTransform;
209
            /* EMF+ emf header info */
210
            sal_Int32       nFrameLeft;
211
            sal_Int32       nFrameTop;
212
            sal_Int32       nFrameRight;
213
            sal_Int32       nFrameBottom;
214
            sal_Int32       nPixX;
215
            sal_Int32       nPixY;
216
            sal_Int32       nMmX;
217
            sal_Int32       nMmY;
218
        };
219
220
221
        /// Common parameters when creating actions
222
        struct ActionFactoryParameters
223
        {
224
            ActionFactoryParameters( VectorOfOutDevStates&       rStates,
225
                                     const CanvasSharedPtr&      rCanvas,
226
                                     ::VirtualDevice&            rVDev,
227
                                     const Renderer::Parameters& rParms,
228
                                     sal_Int32&                  io_rCurrActionIndex ) :
229
0
                mrStates(rStates),
230
0
                mrCanvas(rCanvas),
231
0
                mrVDev(rVDev),
232
0
                mrParms(rParms),
233
0
                mrCurrActionIndex(io_rCurrActionIndex)
234
0
            {}
235
236
            VectorOfOutDevStates&       mrStates;
237
            const CanvasSharedPtr&      mrCanvas;
238
            ::VirtualDevice&            mrVDev;
239
            const Renderer::Parameters& mrParms;
240
            sal_Int32&                  mrCurrActionIndex;
241
        };
242
243
}
244
245
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */