/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 |