Coverage Report

Created: 2026-06-07 08:13

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
358k
    void setMinLineWidth(double w) { minLineWidth = w; }
235
236
    // Setter/Getter for thin line mode
237
358k
    void setThinLineMode(SplashThinLineMode thinLineModeA) { thinLineMode = thinLineModeA; }
238
182k
    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
#if 1 //~tmp: turn off anti-aliasing temporarily
248
0
    void setInShading(bool sh) { inShading = sh; }
249
86.3k
    bool getVectorAntialias() const { return vectorAntialias; }
250
232k
    void setVectorAntialias(bool vaa) { vectorAntialias = vaa; }
251
#endif
252
253
    // Do shaded fills with dynamic patterns
254
    //
255
    // clipToStrokePath: Whether the current clip region is a stroke path.
256
    //   In that case, strokeAlpha is used rather than fillAlpha.
257
    SplashError shadedFill(const SplashPath &path, bool hasBBox, const SplashPattern &pattern, bool clipToStrokePath);
258
    // Draw a gouraud triangle shading.
259
    bool gouraudTriangleShadedFill(SplashGouraudColor *shading);
260
261
private:
262
    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);
263
    void pipeRun(SplashPipe *pipe);
264
    void pipeRunSimpleMono1(SplashPipe *pipe);
265
    void pipeRunSimpleMono8(SplashPipe *pipe);
266
    void pipeRunSimpleRGB8(SplashPipe *pipe);
267
    void pipeRunSimpleXBGR8(SplashPipe *pipe);
268
    void pipeRunSimpleBGR8(SplashPipe *pipe);
269
    void pipeRunSimpleCMYK8(SplashPipe *pipe);
270
    void pipeRunSimpleDeviceN8(SplashPipe *pipe);
271
    void pipeRunAAMono1(SplashPipe *pipe);
272
    void pipeRunAAMono8(SplashPipe *pipe);
273
    void pipeRunAARGB8(SplashPipe *pipe);
274
    void pipeRunAAXBGR8(SplashPipe *pipe);
275
    void pipeRunAABGR8(SplashPipe *pipe);
276
    void pipeRunAACMYK8(SplashPipe *pipe);
277
    void pipeRunAADeviceN8(SplashPipe *pipe);
278
    void pipeSetXY(SplashPipe *pipe, int x, int y);
279
    void pipeIncX(SplashPipe *pipe);
280
    void drawPixel(SplashPipe *pipe, int x, int y, bool noClip);
281
    void drawAAPixelInit();
282
    void drawAAPixel(SplashPipe *pipe, int x, int y);
283
    void drawSpan(SplashPipe *pipe, int x0, int x1, int y, bool noClip);
284
    void drawAALine(SplashPipe *pipe, int x0, int x1, int y, bool adjustLine = false, unsigned char lineOpacity = 0);
285
    static void transform(const std::array<double, 6> &matrix, double xi, double yi, double *xo, double *yo);
286
    void strokeNarrow(const SplashPath &path);
287
    void strokeWide(const SplashPath &path, double w);
288
    static std::unique_ptr<SplashPath> flattenPath(const SplashPath &path, const std::array<double, 6> &matrix, double flatness);
289
    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);
290
    std::unique_ptr<SplashPath> makeDashedPath(const SplashPath &xPath);
291
    void getBBoxFP(const SplashPath &path, double *xMinA, double *yMinA, double *xMaxA, double *yMaxA);
292
    SplashError fillWithPattern(SplashPath *path, bool eo, SplashPattern *pattern, double alpha);
293
    bool pathAllOutside(const SplashPath &path);
294
    void fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph, bool noclip);
295
    void arbitraryTransformMask(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, const std::array<double, 6> &mat, bool glyphMode);
296
    static std::unique_ptr<SplashBitmap> scaleMask(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight);
297
    static void scaleMaskYdownXdown(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
298
    static void scaleMaskYdownXup(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
299
    static void scaleMaskYupXdown(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
300
    static void scaleMaskYupXup(SplashImageMaskSource src, void *srcData, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
301
    void blitMask(const SplashBitmap &src, int xDest, int yDest, SplashClipResult clipRes);
302
    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,
303
                                        bool tilingPattern = false);
304
    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,
305
                                             bool tilingPattern = false);
306
    static bool scaleImageYdownXdown(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
307
    static bool scaleImageYdownXup(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
308
    static bool scaleImageYupXdown(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
309
    static bool scaleImageYupXup(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
310
    static bool scaleImageYupXupBilinear(SplashImageSource src, void *srcData, SplashColorMode srcMode, int nComps, bool srcAlpha, int srcWidth, int srcHeight, int scaledWidth, int scaledHeight, SplashBitmap *dest);
311
    static void vertFlipImage(SplashBitmap *img, int width, int height, int nComps);
312
    void blitImage(const SplashBitmap &src, bool srcAlpha, int xDest, int yDest, SplashClipResult clipRes);
313
    void blitImageClipped(const SplashBitmap &src, bool srcAlpha, int xSrc, int ySrc, int xDest, int yDest, int w, int h);
314
    static void dumpPath(const SplashPath &path);
315
    static void dumpXPath(const SplashXPath &path);
316
317
    static SplashPipeResultColorCtrl pipeResultColorNoAlphaBlend[];
318
    static SplashPipeResultColorCtrl pipeResultColorAlphaNoBlend[];
319
    static SplashPipeResultColorCtrl pipeResultColorAlphaBlend[];
320
    static int pipeNonIsoGroupCorrection[];
321
322
    SplashBitmap *bitmap;
323
    SplashState *state;
324
    SplashBitmap *aaBuf;
325
    int aaBufY;
326
    SplashBitmap *alpha0Bitmap; // for non-isolated groups, this is the
327
                                //   bitmap containing the alpha0 values
328
    int alpha0X, alpha0Y; // offset within alpha0Bitmap
329
    double minLineWidth;
330
    SplashThinLineMode thinLineMode;
331
    SplashClipResult opClipRes;
332
    SplashBitmap *groupBackBitmap; // backdrop bitmap for knockout/non-isolated groups
333
    int groupBackX, groupBackY; // offset within groupBackBitmap
334
    bool vectorAntialias;
335
    bool inShading;
336
    bool debugMode;
337
};
338
339
#endif