Coverage Report

Created: 2026-10-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/splash/Splash.h
Line
Count
Source
1
//========================================================================
2
//
3
// Splash.h
4
//
5
//========================================================================
6
7
//========================================================================
8
//
9
// Modified under the Poppler project - http://poppler.freedesktop.org
10
//
11
// All changes made under the Poppler project to this file are licensed
12
// under GPL version 2 or later
13
//
14
// Copyright (C) 2005 Marco Pesenti Gritti <mpg@redhat.com>
15
// Copyright (C) 2007, 2011, 2018, 2019, 2021, 2022, 2025, 2026 Albert Astals Cid <aacid@kde.org>
16
// Copyright (C) 2010-2013, 2015 Thomas Freitag <Thomas.Freitag@alfa.de>
17
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com>
18
// Copyright (C) 2012, 2017 Adrian Johnson <ajohnson@redneon.com>
19
// Copyright (C) 2020 Oliver Sander <oliver.sander@tu-dresden.de>
20
// Copyright (C) 2020 Tobias Deiminger <haxtibal@posteo.de>
21
// Copyright (C) 2026 Taufeeque Sifat <entity069@protonmail.com>
22
// Copyright (C) 2026 Stefan Brüns <stefan.bruens@rwth-aachen.de>
23
//
24
// To see a description of the changes please see the Changelog file that
25
// came with your tarball or type make ChangeLog if you are building from git
26
//
27
//========================================================================
28
29
#ifndef SPLASH_H
30
#define SPLASH_H
31
32
#include "SplashTypes.h"
33
#include "SplashClip.h"
34
#include "SplashPattern.h"
35
#include "poppler_private_export.h"
36
37
class SplashBitmap;
38
struct SplashGlyphBitmap;
39
class SplashState;
40
class SplashScreen;
41
class SplashPath;
42
class SplashXPath;
43
class SplashFont;
44
struct SplashPipe;
45
46
//------------------------------------------------------------------------
47
48
// Retrieves the next line of pixels in an image mask.  Normally,
49
// fills in *<line> and returns true.  If the image stream is
50
// exhausted, returns false.
51
using SplashImageMaskSource = bool (*)(void *data, SplashColorPtr pixel);
52
53
// Retrieves the next line of pixels in an image.  Normally, fills in
54
// *<line> and returns true.  If the image stream is exhausted,
55
// returns false.
56
using SplashImageSource = bool (*)(void *data, SplashColorPtr colorLine, unsigned char *alphaLine);
57
58
// Use ICCColorSpace to transform a bitmap
59
using SplashICCTransform = void (*)(void *data, SplashBitmap *bitmap);
60
61
//------------------------------------------------------------------------
62
63
enum SplashPipeResultColorCtrl
64
{
65
    splashPipeResultColorNoAlphaBlendCMYK,
66
    splashPipeResultColorNoAlphaBlendDeviceN,
67
    splashPipeResultColorNoAlphaBlendRGB,
68
    splashPipeResultColorNoAlphaBlendMono,
69
    splashPipeResultColorAlphaNoBlendMono,
70
    splashPipeResultColorAlphaNoBlendRGB,
71
    splashPipeResultColorAlphaNoBlendCMYK,
72
    splashPipeResultColorAlphaNoBlendDeviceN,
73
    splashPipeResultColorAlphaBlendMono,
74
    splashPipeResultColorAlphaBlendRGB,
75
    splashPipeResultColorAlphaBlendCMYK,
76
    splashPipeResultColorAlphaBlendDeviceN
77
};
78
79
//------------------------------------------------------------------------
80
// Splash
81
//------------------------------------------------------------------------
82
83
class POPPLER_PRIVATE_EXPORT Splash
84
{
85
public:
86
    // Create a new rasterizer object.
87
    Splash(SplashBitmap *bitmapA, bool vectorAntialiasA, SplashScreenParams *screenParams = nullptr);
88
    Splash(SplashBitmap *bitmapA, bool vectorAntialiasA, const SplashScreen &screenA);
89
90
    ~Splash();
91
92
    Splash(const Splash &) = delete;
93
    Splash &operator=(const Splash &) = delete;
94
95
    //----- state read
96
97
    const std::array<double, 6> &getMatrix() const;
98
    SplashPattern *getStrokePattern();
99
    SplashPattern *getFillPattern();
100
    const SplashScreen &getScreen() const;
101
    SplashBlendFunc getBlendFunc();
102
    double getStrokeAlpha();
103
    double getFillAlpha();
104
    double getLineWidth();
105
    SplashLineCap getLineCap();
106
    SplashLineJoin getLineJoin();
107
    double getMiterLimit();
108
    double getFlatness();
109
    double getLineDashPhase();
110
    bool getStrokeAdjust();
111
    const SplashClip &getClip() const;
112
    SplashBitmap *getSoftMask();
113
    bool getInNonIsolatedGroup();
114
    bool getInKnockoutGroup();
115
116
    //----- state write
117
118
    void setMatrix(const std::array<double, 6> &matrix);
119
    void setStrokePattern(SplashPattern *strokePattern);
120
    void setFillPattern(SplashPattern *fillPattern);
121
    void setBlendFunc(SplashBlendFunc func);
122
    void setStrokeAlpha(double alpha);
123
    void setFillAlpha(double alpha);
124
    void setPatternAlpha(double strokeAlpha, double fillAlpha);
125
    void clearPatternAlpha();
126
    void setFillOverprint(bool fop);
127
    void setStrokeOverprint(bool sop);
128
    void setOverprintMode(int opm);
129
    void setLineWidth(double lineWidth);
130
    void setLineCap(SplashLineCap lineCap);
131
    void setLineJoin(SplashLineJoin lineJoin);
132
    void setMiterLimit(double miterLimit);
133
    void setFlatness(double flatness);
134
    // the <lineDash> array will be copied
135
    void setLineDash(std::vector<double> &&lineDash, double lineDashPhase);
136
    void setStrokeAdjust(bool strokeAdjust);
137
    // NB: uses transformed coordinates.
138
    void clipResetToRect(double x0, double y0, double x1, double y1);
139
    // NB: uses transformed coordinates.
140
    SplashError clipToRect(double x0, double y0, double x1, double y1);
141
    // NB: uses untransformed coordinates.
142
    SplashError clipToPath(const SplashPath &path, bool eo);
143
    void setSoftMask(SplashBitmap *softMask);
144
    void setInTransparencyGroup(SplashBitmap *groupBackBitmapA, int groupBackXA, int groupBackYA, bool nonIsolated, bool knockout);
145
    void setTransfer(unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *gray);
146
    void setOverprintMask(unsigned int overprintMask, bool additive);
147
148
    //----- state save/restore
149
150
    void saveState();
151
    SplashError restoreState();
152
153
    //----- drawing operations
154
155
    // Fill the bitmap with <color>.  This is not subject to clipping.
156
    void clear(SplashColorPtr color, unsigned char alpha = 0x00);
157
158
    // Stroke a path using the current stroke pattern.
159
    SplashError stroke(const SplashPath &path);
160
161
    // Fill a path using the current fill pattern.
162
    SplashError fill(SplashPath *path, bool eo);
163
164
    // Draw a character, using the current fill pattern.
165
    SplashError fillChar(double x, double y, int c, SplashFont *font);
166
167
    // Draw a glyph, using the current fill pattern.  This function does
168
    // not free any data, i.e., it ignores glyph->freeData.
169
    void fillGlyph(double x, double y, SplashGlyphBitmap *glyph);
170
171
    // Draws an image mask using the fill color.  This will read <h>
172
    // lines of <w> pixels from <src>, starting with the top line.  "1"
173
    // pixels will be drawn with the current fill color; "0" pixels are
174
    // transparent.  The matrix:
175
    //    [ mat[0] mat[1] 0 ]
176
    //    [ mat[2] mat[3] 0 ]
177
    //    [ mat[4] mat[5] 1 ]
178
    // maps a unit square to the desired destination for the image, in
179
    // PostScript style:
180
    //    [x' y' 1] = [x y 1] * mat
181
    // Note that the Splash y axis points downward, and the image source
182
    // is assumed to produce pixels in raster order, starting from the
183
    // top line.
184
    SplashError fillImageMask(SplashImageMaskSource src, void *srcData, int w, int h, const std::array<double, 6> &mat, bool glyphMode);
185
186
    // Draw an image.  This will read <h> lines of <w> pixels from
187
    // <src>, starting with the top line.  These pixels are assumed to
188
    // be in the source mode, <srcMode>.  If <srcAlpha> is true, the
189
    // alpha values returned by <src> are used; otherwise they are
190
    // ignored.  The following combinations of source and target modes
191
    // are supported:
192
    //    source       target
193
    //    ------       ------
194
    //    Mono1        Mono1
195
    //    Mono8        Mono1   -- with dithering
196
    //    Mono8        Mono8
197
    //    RGB8         RGB8
198
    //    BGR8         BGR8
199
    //    CMYK8        CMYK8
200
    // The matrix behaves as for fillImageMask.
201
    SplashError drawImage(SplashImageSource src, SplashICCTransform tf, void *srcData, SplashColorMode srcMode, bool srcAlpha, int w, int h, const std::array<double, 6> &mat, bool interpolate, bool tilingPattern = false);
202
203
    // Composite a rectangular region from <src> onto this Splash
204
    // object.
205
    SplashError composite(const SplashBitmap &src, int xSrc, int ySrc, int xDest, int yDest, int w, int h, bool noClip, bool nonIsolated, bool knockout = false, double knockoutOpacity = 1.0);
206
207
    // Composite this Splash object onto a background color.  The
208
    // background alpha is assumed to be 1.
209
    void compositeBackground(SplashColorConstPtr color);
210
211
    // Copy a rectangular region from <src> onto the bitmap belonging to
212
    // this Splash object.  On success, the destination alpha values are all set to
213
    // zero.
214
    SplashError blitTransparent(const SplashBitmap &src, int xSrc, int ySrc, int xDest, int yDest, int w, int h);
215
    void blitImage(const SplashBitmap &src, bool srcAlpha, int xDest, int yDest);
216
217
    // Copy a rectangular region from the current bitmap to <dest>,
218
    // correcting the alpha values for a non-isolated transparency group
219
    // nested inside another non-isolated group.
220
    SplashError blitCorrectedAlpha(SplashBitmap *dest, int xSrc, int ySrc, int xDest, int yDest, int w, int h);
221
222
    //----- misc
223
224
    // Construct a path for a stroke, given the path to be stroked and
225
    // the line width <w>.  All other stroke parameters are taken from
226
    // the current state.  If <flatten> is true, this function will
227
    // first flatten the path and handle the linedash.
228
    std::unique_ptr<SplashPath> makeStrokePath(const SplashPath &path, double w, bool flatten = true);
229
230
    // Return the associated bitmap.
231
0
    SplashBitmap *getBitmap() { return bitmap; }
232
233
    // Set the minimum line width.
234
0
    void setMinLineWidth(double w) { minLineWidth = w; }
235
236
    // Setter/Getter for thin line mode
237
0
    void setThinLineMode(SplashThinLineMode thinLineModeA) { thinLineMode = thinLineModeA; }
238
0
    SplashThinLineMode getThinLineMode() { return thinLineMode; }
239
240
    // Get clipping status for the last drawing operation subject to
241
    // clipping.
242
0
    SplashClipResult getClipRes() { return opClipRes; }
243
244
    // Toggle debug mode on or off.
245
0
    void setDebugMode(bool debugModeA) { debugMode = debugModeA; }
246
247
0
    void setInShading(bool sh) { inShading = sh; }
248
0
    bool getVectorAntialias() const { return vectorAntialias; }
249
0
    void setVectorAntialias(bool vaa) { vectorAntialias = vaa; }
250
251
    // Do shaded fills with dynamic patterns
252
    //
253
    // clipToStrokePath: Whether the current clip region is a stroke path.
254
    //   In that case, strokeAlpha is used rather than fillAlpha.
255
    SplashError shadedFill(const SplashPath &path, bool hasBBox, const SplashPattern &pattern, bool clipToStrokePath);
256
    // Draw a gouraud triangle shading.
257
    bool gouraudTriangleShadedFill(SplashGouraudColor *shading);
258
259
private:
260
    void pipeInit(SplashPipe *pipe, int x, int y, const SplashPattern *pattern, SplashColorPtr cSrc, unsigned char aInput, bool usesShape, bool nonIsolatedGroup, bool knockout = false, unsigned char knockoutOpacity = 255);
261
    void pipeRun(SplashPipe *pipe);
262
    void pipeRunSimpleMono1(SplashPipe *pipe);
263
    void pipeRunSimpleMono8(SplashPipe *pipe);
264
    void pipeRunSimpleRGB8(SplashPipe *pipe);
265
    void pipeRunSimpleXBGR8(SplashPipe *pipe);
266
    void pipeRunSimpleBGR8(SplashPipe *pipe);
267
    void pipeRunSimpleCMYK8(SplashPipe *pipe);
268
    void pipeRunSimpleDeviceN8(SplashPipe *pipe);
269
    void pipeRunAAMono1(SplashPipe *pipe);
270
    void pipeRunAAMono8(SplashPipe *pipe);
271
    void pipeRunAARGB8(SplashPipe *pipe);
272
    void pipeRunAAXBGR8(SplashPipe *pipe);
273
    void pipeRunAABGR8(SplashPipe *pipe);
274
    void pipeRunAACMYK8(SplashPipe *pipe);
275
    void pipeRunAADeviceN8(SplashPipe *pipe);
276
    void pipeSetXY(SplashPipe *pipe, int x, int y);
277
    void pipeIncX(SplashPipe *pipe);
278
    void drawPixel(SplashPipe *pipe, int x, int y, bool noClip);
279
    void drawAAPixelInit();
280
    void drawAAPixel(SplashPipe *pipe, int x, int y);
281
    void drawSpan(SplashPipe *pipe, int x0, int x1, int y, bool noClip);
282
    void drawAALine(SplashPipe *pipe, int x0, int x1, int y, bool adjustLine = false, unsigned char lineOpacity = 0);
283
    static void transform(const std::array<double, 6> &matrix, double xi, double yi, double *xo, double *yo);
284
    void strokeNarrow(const SplashPath &path);
285
    void strokeWide(const SplashPath &path, double w);
286
    static std::unique_ptr<SplashPath> flattenPath(const SplashPath &path, const std::array<double, 6> &matrix, double flatness);
287
    static void flattenCurve(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, const std::array<double, 6> &matrix, double flatness2, SplashPath *fPath);
288
    std::unique_ptr<SplashPath> makeDashedPath(const SplashPath &xPath);
289
    void getBBoxFP(const SplashPath &path, double *xMinA, double *yMinA, double *xMaxA, double *yMaxA);
290
    SplashError fillWithPattern(SplashPath *path, bool eo, SplashPattern *pattern, double alpha);
291
    bool pathAllOutside(const SplashPath &path);
292
    void fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph, bool noclip);
293
    void arbitraryTransformMask(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, const std::array<double, 6> &mat, bool glyphMode);
294
    static std::unique_ptr<SplashBitmap> scaleMask(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight);
295
    static void scaleMaskYdownXdown(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
296
    static void scaleMaskYdownXup(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
297
    static void scaleMaskYupXdown(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
298
    static void scaleMaskYupXup(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
299
    void blitMask(const SplashBitmap &src, int xDest, int yDest, SplashClipResult clipRes);
300
    SplashError arbitraryTransformImage(SplashImageSource src, SplashICCTransform tf, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, const std::array<double, 6> &mat, bool interpolate,
301
                                        bool tilingPattern = false);
302
    std::unique_ptr<SplashBitmap> scaleImage(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, bool interpolate,
303
                                             bool tilingPattern = false);
304
    static bool scaleImageYdownXdown(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
305
    static bool scaleImageYdownXup(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
306
    static bool scaleImageYupXdown(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
307
    static bool scaleImageYupXup(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
308
    static bool scaleImageYupXupBilinear(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
309
    static void vertFlipImage(SplashBitmap *img, int width, int height, int nComps);
310
    void blitImage(const SplashBitmap &src, bool srcAlpha, int xDest, int yDest, SplashClipResult clipRes);
311
    void blitImageClipped(const SplashBitmap &src, bool srcAlpha, int xSrc, int ySrc, int xDest, int yDest, int w, int h);
312
    static void dumpPath(const SplashPath &path);
313
    static void dumpXPath(const SplashXPath &path);
314
315
    static SplashPipeResultColorCtrl pipeResultColorNoAlphaBlend[];
316
    static SplashPipeResultColorCtrl pipeResultColorAlphaNoBlend[];
317
    static SplashPipeResultColorCtrl pipeResultColorAlphaBlend[];
318
    static int pipeNonIsoGroupCorrection[];
319
320
    SplashBitmap *bitmap;
321
    SplashState *state;
322
    SplashBitmap *aaBuf;
323
    int aaBufY;
324
    SplashBitmap *alpha0Bitmap; // for non-isolated groups, this is the
325
                                //   bitmap containing the alpha0 values
326
    int alpha0X, alpha0Y; // offset within alpha0Bitmap
327
    double minLineWidth;
328
    SplashThinLineMode thinLineMode;
329
    SplashClipResult opClipRes;
330
    SplashBitmap *groupBackBitmap; // backdrop bitmap for knockout/non-isolated groups
331
    int groupBackX, groupBackY; // offset within groupBackBitmap
332
    bool vectorAntialias;
333
    bool inShading;
334
    bool debugMode;
335
};
336
337
#endif