Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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
10
#pragma once
11
12
#include <drawinglayer/processor2d/baseprocessor2d.hxx>
13
#include <basegfx/color/bcolormodifier.hxx>
14
#include <tools/long.hxx>
15
#include <sal/config.h>
16
#include <vcl/vclptr.hxx>
17
18
// cairo-specific
19
#include <cairo.h>
20
21
namespace drawinglayer::primitive2d
22
{
23
class PolyPolygonColorPrimitive2D;
24
class PolygonHairlinePrimitive2D;
25
class BitmapPrimitive2D;
26
class UnifiedTransparencePrimitive2D;
27
class BackgroundColorPrimitive2D;
28
class TransparencePrimitive2D;
29
class InvertPrimitive2D;
30
class MaskPrimitive2D;
31
class ModifiedColorPrimitive2D;
32
class TransformPrimitive2D;
33
class PointArrayPrimitive2D;
34
class MarkerArrayPrimitive2D;
35
class PolygonStrokePrimitive2D;
36
class LineRectanglePrimitive2D;
37
class FilledRectanglePrimitive2D;
38
class SingleLinePrimitive2D;
39
class FillGradientPrimitive2D;
40
class PolyPolygonRGBAGradientPrimitive2D;
41
class FillGraphicPrimitive2D;
42
class PolyPolygonRGBAPrimitive2D;
43
class PolyPolygonAlphaGradientPrimitive2D;
44
class BitmapAlphaPrimitive2D;
45
class ControlPrimitive2D;
46
class TextSimplePortionPrimitive2D;
47
class TextDecoratedPortionPrimitive2D;
48
class TextLayouterDevice;
49
class SvgLinearGradientPrimitive2D;
50
class SvgRadialGradientPrimitive2D;
51
class SvgGradientHelper;
52
class PatternFillPrimitive2D;
53
}
54
55
namespace basegfx
56
{
57
class B2DPolyPolygon;
58
}
59
60
namespace basegfx::utils
61
{
62
class B2DHomMatrixBufferedOnDemandDecompose;
63
}
64
65
class Bitmap;
66
class OutputDevice;
67
class SalLayout;
68
69
namespace drawinglayer::processor2d
70
{
71
class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) CairoPixelProcessor2D final : public BaseProcessor2D
72
{
73
    // the OutputDevice if this renderer is associated with one, else nullptr
74
    VclPtr<OutputDevice> mpTargetOutputDevice;
75
76
    // the modifiedColorPrimitive stack
77
    basegfx::BColorModifierStack maBColorModifierStack;
78
79
    // cairo_surface_t created when initial clip from the constructor
80
    // parameters is requested, or by the constructor that creates an
81
    // owned surface
82
    cairo_surface_t* mpOwnedSurface;
83
84
    // cairo specific data, the render target
85
    cairo_t* mpRT;
86
87
    // get text render config settings
88
    bool mbRenderSimpleTextDirect;
89
    bool mbRenderDecoratedTextDirect;
90
91
    // recursion counter for CairoPixelProcessor2D::processMaskPrimitive2D,
92
    // see comment there
93
    sal_uInt16 mnClipRecursionCount;
94
95
    // calculated result of if we are in outsideCairoCoordinateLimits mode
96
    bool mbCairoCoordinateLimitWorkaroundActive;
97
98
    // helpers for direct paints
99
    void paintPolyPolygonRGBA(const basegfx::B2DPolyPolygon& rPolyPolygon,
100
                              const basegfx::BColor& rColor, double fTransparency = 0.0);
101
    void processPolygonHairlinePrimitive2D(
102
        const primitive2d::PolygonHairlinePrimitive2D& rPolygonHairlinePrimitive2D);
103
    void processPolyPolygonColorPrimitive2D(
104
        const primitive2d::PolyPolygonColorPrimitive2D& rPolyPolygonColorPrimitive2D);
105
    void processBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate);
106
    void
107
    processTransparencePrimitive2D(const primitive2d::TransparencePrimitive2D& rTransCandidate);
108
    void processInvertPrimitive2D(const primitive2d::InvertPrimitive2D& rTransCandidate);
109
    void processUnifiedTransparencePrimitive2D(
110
        const primitive2d::UnifiedTransparencePrimitive2D& rTransCandidate);
111
    void processMaskPrimitive2D(const primitive2d::MaskPrimitive2D& rMaskCandidate);
112
    void processModifiedColorPrimitive2D(
113
        const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate);
114
    void processTransformPrimitive2D(const primitive2d::TransformPrimitive2D& rTransformCandidate);
115
    void
116
    processPointArrayPrimitive2D(const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate);
117
    void
118
    processMarkerArrayPrimitive2D(const primitive2d::MarkerArrayPrimitive2D& rMarkerArrayCandidate);
119
    void processBackgroundColorPrimitive2D(
120
        const primitive2d::BackgroundColorPrimitive2D& rBackgroundColorCandidate);
121
    void processPolygonStrokePrimitive2D(
122
        const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokeCandidate);
123
    void processLineRectanglePrimitive2D(
124
        const primitive2d::LineRectanglePrimitive2D& rLineRectanglePrimitive2D);
125
    void processFilledRectanglePrimitive2D(
126
        const primitive2d::FilledRectanglePrimitive2D& rFilledRectanglePrimitive2D);
127
    void
128
    processSingleLinePrimitive2D(const primitive2d::SingleLinePrimitive2D& rSingleLinePrimitive2D);
129
    void processFillGradientPrimitive2D(
130
        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
131
    void processPatternFillPrimitive2D(const primitive2d::PatternFillPrimitive2D& rPrimitive);
132
    void processFillGraphicPrimitive2D(
133
        const primitive2d::FillGraphicPrimitive2D& rFillGraphicPrimitive2D);
134
    void processPolyPolygonRGBAPrimitive2D(
135
        const primitive2d::PolyPolygonRGBAPrimitive2D& rPolyPolygonRGBAPrimitive2D);
136
    void processPolyPolygonAlphaGradientPrimitive2D(
137
        const primitive2d::PolyPolygonAlphaGradientPrimitive2D&
138
            rPolyPolygonAlphaGradientPrimitive2D);
139
    void paintBitmapAlpha(const Bitmap& rBitmap, const basegfx::B2DHomMatrix& rTransform,
140
                          double fTransparency = 0.0);
141
    void processBitmapAlphaPrimitive2D(
142
        const primitive2d::BitmapAlphaPrimitive2D& rBitmapAlphaPrimitive2D);
143
    void processControlPrimitive2D(const primitive2d::ControlPrimitive2D& rControlPrimitive);
144
145
    void processTextSimplePortionPrimitive2D(
146
        const primitive2d::TextSimplePortionPrimitive2D& rCandidate);
147
    void processTextDecoratedPortionPrimitive2D(
148
        const primitive2d::TextDecoratedPortionPrimitive2D& rCandidate);
149
150
    // helpers for text rendering
151
    void renderTextSimpleOrDecoratedPortionPrimitive2D(
152
        const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate,
153
        const primitive2d::TextDecoratedPortionPrimitive2D* pDecoratedCandidate);
154
    void renderTextBackground(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate,
155
                              double fAscent, double fDescent,
156
                              const basegfx::B2DHomMatrix& rTransform, double fTextWidth);
157
    void renderSalLayout(const std::unique_ptr<SalLayout>& rSalLayout,
158
                         const basegfx::BColor& rTextColor, const basegfx::B2DHomMatrix& rTransform,
159
                         bool bAntiAliase) const;
160
    void renderTextDecorationWithOptionalTransformAndColor(
161
        const primitive2d::TextDecoratedPortionPrimitive2D& rDecoratedCandidate,
162
        const basegfx::utils::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans,
163
        const basegfx::B2DHomMatrix* pOptionalObjectTransform = nullptr,
164
        const basegfx::BColor* pReplacementColor = nullptr);
165
166
    // support for SVG gradients
167
    void processSvgLinearGradientPrimitive2D(
168
        const primitive2d::SvgLinearGradientPrimitive2D& rCandidate);
169
    void processSvgRadialGradientPrimitive2D(
170
        const primitive2d::SvgRadialGradientPrimitive2D& rCandidate);
171
    bool handleSvgGradientHelper(const primitive2d::SvgGradientHelper& rCandidate);
172
173
    /*  the local processor for BasePrimitive2D-Implementation based primitives,
174
        called from the common process()-implementation
175
     */
176
    virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) override;
177
178
    // helpers for gradients
179
    void processFillGradientPrimitive2D_fallback_decompose(
180
        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
181
    void processFillGradientPrimitive2D_drawOutputRange(
182
        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
183
    bool processFillGradientPrimitive2D_isCompletelyBordered(
184
        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
185
    void processFillGradientPrimitive2D_linear_axial(
186
        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
187
    void processFillGradientPrimitive2D_radial_elliptical(
188
        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
189
    void processFillGradientPrimitive2D_square_rect(
190
        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
191
192
    // check if CairoCoordinateLimitWorkaround is needed
193
    void evaluateCairoCoordinateLimitWorkaround();
194
195
    basegfx::BColor getLineColor(const basegfx::BColor& rColor) const;
196
    basegfx::BColor getFillColor(const basegfx::BColor& rColor) const;
197
    basegfx::BColor getTextColor(const basegfx::BColor& rColor) const;
198
    basegfx::BColor getGradientColor(const basegfx::BColor& rColor) const;
199
200
protected:
201
125
    bool hasError() const { return cairo_status(mpRT) != CAIRO_STATUS_SUCCESS; }
202
125
    bool hasRenderTarget() const { return nullptr != mpRT; }
203
204
    // allow to react on changes of ViewInformation2D
205
    virtual void onViewInformation2DChanged() override;
206
207
    // constructor to create a CairoPixelProcessor2D for
208
    // the given cairo_surface_t pTarget. pTarget will not
209
    // be owned and not destroyed, but be used as render
210
    // target. You should check the result using valid()
211
    CairoPixelProcessor2D(
212
        // take over current BColorModifierStack
213
        const basegfx::BColorModifierStack& rBColorModifierStack,
214
215
        // the ViewInformation
216
        const geometry::ViewInformation2D& rViewInformation,
217
218
        // the cairo render target
219
        cairo_surface_t* pTarget);
220
221
public:
222
125
    bool valid() const { return hasRenderTarget() && !hasError(); }
223
224
    // read access to CairoCoordinateLimitWorkaround mechanism
225
    bool isCairoCoordinateLimitWorkaroundActive() const
226
675
    {
227
675
        return mbCairoCoordinateLimitWorkaroundActive;
228
675
    }
229
230
    // constructor to create a CairoPixelProcessor2D which
231
    // allocates and owns a cairo surface of given size. You
232
    // should check the result using valid()
233
    CairoPixelProcessor2D(
234
235
        // the initial ViewInformation
236
        const geometry::ViewInformation2D& rViewInformation,
237
238
        // the pixel size
239
        tools::Long nWidthPixel, tools::Long nHeightPixel,
240
241
        // define RGBA (true) or RGB (false)
242
        bool bUseRGBA);
243
244
    // constructor to create a CairoPixelProcessor2D
245
    // associated with an OutputDevice. You should
246
    // check the result using valid()
247
    CairoPixelProcessor2D(
248
249
        // the OutputDevice this processor shall be associated with
250
        OutputDevice& rOutputDevice,
251
252
        // the initial ViewInformation
253
        const geometry::ViewInformation2D& rViewInformation);
254
255
    virtual ~CairoPixelProcessor2D() override;
256
257
    // access to BColorModifierStack
258
    const basegfx::BColorModifierStack& getBColorModifierStack() const
259
0
    {
260
0
        return maBColorModifierStack;
261
0
    }
262
263
    // try to extract current content as Bitmap
264
    Bitmap extractBitmap() const;
265
};
266
}
267
268
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */