Coverage Report

Created: 2026-10-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/poppler/Gfx.h
Line
Count
Source
1
//========================================================================
2
//
3
// Gfx.h
4
//
5
// Copyright 1996-2003 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
//========================================================================
10
//
11
// Modified under the Poppler project - http://poppler.freedesktop.org
12
//
13
// All changes made under the Poppler project to this file are licensed
14
// under GPL version 2 or later
15
//
16
// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
17
// Copyright (C) 2007 Iñigo Martínez <inigomartinez@gmail.com>
18
// Copyright (C) 2008 Brad Hards <bradh@kde.org>
19
// Copyright (C) 2008, 2010 Carlos Garcia Campos <carlosgc@gnome.org>
20
// Copyright (C) 2009-2013, 2017, 2018, 2021, 2024-2026 Albert Astals Cid <aacid@kde.org>
21
// Copyright (C) 2009, 2010, 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
22
// Copyright (C) 2010 David Benjamin <davidben@mit.edu>
23
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com>
24
// Copyright (C) 2013 Fabio D'Urso <fabiodurso@hotmail.it>
25
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
26
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
27
// Copyright (C) 2019, 2022, 2024 Oliver Sander <oliver.sander@tu-dresden.de>
28
// Copyright (C) 2019 Volker Krause <vkrause@kde.org>
29
// Copyright (C) 2026 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
30
// Copyright (C) 2026 Stefan Brüns <stefan.bruens@rwth-aachen.de>
31
//
32
// To see a description of the changes please see the Changelog file that
33
// came with your tarball or type make ChangeLog if you are building from git
34
//
35
//========================================================================
36
37
#ifndef GFX_H
38
#define GFX_H
39
40
#include "poppler-config.h"
41
#include "poppler_private_export.h"
42
#include "GfxState.h"
43
#include "Object.h"
44
#include "PopplerCache.h"
45
46
#include <stack>
47
#include <vector>
48
49
class PDFDoc;
50
class XRef;
51
class Array;
52
class Stream;
53
class Parser;
54
class Dict;
55
class Function;
56
class OutputDev;
57
class GfxFontDict;
58
class GfxFont;
59
class GfxPattern;
60
class GfxTilingPattern;
61
class GfxShadingPattern;
62
class GfxShading;
63
class GfxFunctionShading;
64
class GfxAxialShading;
65
class GfxRadialShading;
66
class GfxGouraudTriangleShading;
67
class GfxPatchMeshShading;
68
struct GfxPatch;
69
class GfxState;
70
struct GfxColor;
71
class GfxColorSpace;
72
class Gfx;
73
class PDFRectangle;
74
class AnnotBorder;
75
class AnnotColor;
76
class Catalog;
77
struct MarkedContentStack;
78
79
//------------------------------------------------------------------------
80
81
enum GfxClipType
82
{
83
    clipNone,
84
    clipNormal,
85
    clipEO
86
};
87
88
enum TchkType
89
{
90
    tchkBool, // boolean
91
    tchkInt, // integer
92
    tchkNum, // number (integer or real)
93
    tchkString, // string
94
    tchkName, // name
95
    tchkArray, // array
96
    tchkProps, // properties (dictionary or name)
97
    tchkSCN, // scn/SCN args (number of name)
98
    tchkNone // used to avoid empty initializer lists
99
};
100
101
8.40M
#define maxArgs 33
102
103
struct Operator
104
{
105
    char name[4];
106
    int numArgs;
107
    TchkType tchk[maxArgs];
108
    void (Gfx::*func)(Object args[], int numArgs);
109
};
110
111
//------------------------------------------------------------------------
112
113
class POPPLER_PRIVATE_EXPORT GfxResources
114
{
115
public:
116
    GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA);
117
    ~GfxResources();
118
119
    GfxResources(const GfxResources &) = delete;
120
    GfxResources &operator=(const GfxResources &other) = delete;
121
122
    std::shared_ptr<GfxFont> lookupFont(std::string_view name);
123
    std::shared_ptr<const GfxFont> lookupFont(std::string_view name) const;
124
    Object lookupXObject(std::string_view name);
125
    Object lookupXObjectNF(std::string_view name);
126
    Object lookupMarkedContentNF(std::string_view name);
127
    Object lookupColorSpace(std::string_view name);
128
    std::unique_ptr<GfxPattern> lookupPattern(std::string_view name, OutputDev *out, GfxState *state);
129
    std::unique_ptr<GfxShading> lookupShading(std::string_view name, OutputDev *out, GfxState *state);
130
    Object lookupGState(std::string_view name);
131
    Object lookupGStateNF(std::string_view name);
132
133
38.7k
    GfxResources *getNext() const { return next; }
134
135
private:
136
    std::shared_ptr<GfxFont> doLookupFont(std::string_view name) const;
137
138
    Ref fontDictRef;
139
    mutable std::unique_ptr<GfxFontDict> fonts;
140
    Object fontDict;
141
    Object xObjDict;
142
    Object colorSpaceDict;
143
    Object patternDict;
144
    Object shadingDict;
145
    Object gStateDict;
146
    PopplerCache<Ref, Object> gStateCache;
147
    XRef *xref;
148
    Object propertiesDict;
149
    GfxResources *next;
150
};
151
152
//------------------------------------------------------------------------
153
// Gfx
154
//------------------------------------------------------------------------
155
156
class POPPLER_PRIVATE_EXPORT Gfx
157
{
158
public:
159
    // Constructor for regular output.
160
    Gfx(PDFDoc *docA, OutputDev *outA, int pageNum, Dict *resDict, double hDPI, double vDPI, const PDFRectangle &box, const PDFRectangle *cropBox, int rotate, bool (*abortCheckCbkA)(void *data) = nullptr, void *abortCheckCbkDataA = nullptr,
161
        XRef *xrefA = nullptr);
162
163
    // Constructor for a sub-page object.
164
    Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict, const PDFRectangle &box, const PDFRectangle *cropBox, bool (*abortCheckCbkA)(void *data) = nullptr, void *abortCheckCbkDataA = nullptr, Gfx *gfxA = nullptr);
165
#if USE_CMS
166
    void initDisplayProfile();
167
#endif
168
    ~Gfx();
169
170
    Gfx(const Gfx &) = delete;
171
    Gfx &operator=(const Gfx &other) = delete;
172
173
11.8k
    XRef *getXRef() { return xref; }
174
175
    // Interpret a stream or array of streams.
176
    enum class DisplayType
177
    {
178
        TopLevel,
179
        Type3Font,
180
        Form
181
    };
182
    void display(Object *obj, DisplayType displayType = DisplayType::TopLevel);
183
184
    // Display an annotation, given its appearance (a Form XObject),
185
    // border style, and bounding box (in default user space).
186
    void drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor, double xMin, double yMin, double xMax, double yMax, int rotate);
187
188
    // Save graphics state.
189
    void saveState();
190
191
    // Push a new state guard
192
    void pushStateGuard();
193
194
    // Restore graphics state.
195
    void restoreState();
196
197
    // Pop to state guard and pop guard
198
    void popStateGuard();
199
200
    // Get the current graphics state object.
201
0
    GfxState *getState() { return state; }
202
203
    bool checkTransparencyGroup(Dict *resDict);
204
205
    // if softMask is true backdropColor must not be null
206
    void drawForm(Object *str, Dict *resDict, const std::array<double, 6> &matrix, const std::array<double, 4> &bbox, bool transpGroup = false, bool softMask = false, GfxColorSpace *blendingColorSpace = nullptr, bool isolated = false,
207
                  bool knockout = false, bool alpha = false, Function *transferFunc = nullptr, const GfxColor *backdropColor = nullptr);
208
209
    void pushResources(Dict *resDict);
210
    void popResources();
211
212
private:
213
    PDFDoc *doc;
214
    XRef *xref; // the xref table for this PDF file
215
    Catalog *catalog; // the Catalog for this PDF file
216
    OutputDev *out; // output device
217
    bool subPage; // is this a sub-page object?
218
    const bool printCommands; // print the drawing commands (for debugging)
219
    const bool profileCommands; // profile the drawing commands (for debugging)
220
    bool commandAborted; // did the previous command abort the drawing?
221
    GfxResources *res; // resource stack
222
    int updateLevel;
223
224
    std::stack<DisplayType> displayTypes;
225
    std::stack<bool> type3FontIsD1;
226
227
    GfxState *state; // current graphics state
228
    int stackHeight; // the height of the current graphics stack
229
    std::vector<int> stateGuards; // a stack of state limits; to guard against unmatched pops
230
    bool fontChanged; // set if font or text matrix has changed
231
    GfxClipType clip; // do a clip?
232
    int ignoreUndef; // current BX/EX nesting level
233
    std::array<double, 6> baseMatrix; // default matrix for most recent
234
                                      //   page/form/pattern
235
    int displayDepth;
236
    bool ocState; // true if drawing is enabled, false if
237
                  //   disabled
238
239
    MarkedContentStack *mcStack; // current BMC/EMC stack
240
241
    Parser *parser; // parser for page content stream(s)
242
243
    std::set<int> formsDrawing; // the forms/patterns that are being drawn
244
    std::set<int> charProcDrawing; // the charProc that are being drawn
245
246
    bool // callback to check for an abort
247
            (*abortCheckCbk)(void *data);
248
    void *abortCheckCbkData;
249
250
    static const Operator opTab[]; // table of operators
251
252
    void go(DisplayType displayType);
253
    void execOp(Object *cmd, Object args[], int numArgs);
254
    static const Operator *findOp(const char *name);
255
    static bool checkArg(Object *arg, TchkType type);
256
    Goffset getPos();
257
258
    int bottomGuard();
259
260
    // graphics state operators
261
    void opSave(Object args[], int numArgs);
262
    void opRestore(Object args[], int numArgs);
263
    void opConcat(Object args[], int numArgs);
264
    void opSetDash(Object args[], int numArgs);
265
    void opSetFlat(Object args[], int numArgs);
266
    void opSetLineJoin(Object args[], int numArgs);
267
    void opSetLineCap(Object args[], int numArgs);
268
    void opSetMiterLimit(Object args[], int numArgs);
269
    void opSetLineWidth(Object args[], int numArgs);
270
    void opSetExtGState(Object args[], int numArgs);
271
    void doSoftMask(Object *str, bool alpha, GfxColorSpace *blendingColorSpace, bool isolated, bool knockout, Function *transferFunc, const GfxColor &backdropColor);
272
    void opSetRenderingIntent(Object args[], int numArgs);
273
274
    // color operators
275
    void opSetFillGray(Object args[], int numArgs);
276
    void opSetStrokeGray(Object args[], int numArgs);
277
    void opSetFillCMYKColor(Object args[], int numArgs);
278
    void opSetStrokeCMYKColor(Object args[], int numArgs);
279
    void opSetFillRGBColor(Object args[], int numArgs);
280
    void opSetStrokeRGBColor(Object args[], int numArgs);
281
    void opSetFillColorSpace(Object args[], int numArgs);
282
    void opSetStrokeColorSpace(Object args[], int numArgs);
283
    void opSetFillColor(Object args[], int numArgs);
284
    void opSetStrokeColor(Object args[], int numArgs);
285
    void opSetFillColorN(Object args[], int numArgs);
286
    void opSetStrokeColorN(Object args[], int numArgs);
287
288
    // path segment operators
289
    void opMoveTo(Object args[], int numArgs);
290
    void opLineTo(Object args[], int numArgs);
291
    void opCurveTo(Object args[], int numArgs);
292
    void opCurveTo1(Object args[], int numArgs);
293
    void opCurveTo2(Object args[], int numArgs);
294
    void opRectangle(Object args[], int numArgs);
295
    void opClosePath(Object args[], int numArgs);
296
297
    // path painting operators
298
    void opEndPath(Object args[], int numArgs);
299
    void opStroke(Object args[], int numArgs);
300
    void opCloseStroke(Object args[], int numArgs);
301
    void opFill(Object args[], int numArgs);
302
    void opEOFill(Object args[], int numArgs);
303
    void opFillStroke(Object args[], int numArgs);
304
    void opCloseFillStroke(Object args[], int numArgs);
305
    void opEOFillStroke(Object args[], int numArgs);
306
    void opCloseEOFillStroke(Object args[], int numArgs);
307
    void doPatternFill(bool eoFill);
308
    void doPatternStroke();
309
    void doPatternText();
310
    void doPatternImageMask(Object *ref, Stream *str, int width, int height, bool invert, bool inlineImg);
311
    void doTilingPatternFill(GfxTilingPattern *tPat, bool stroke, bool eoFill, bool text);
312
    void doShadingPatternFill(GfxShadingPattern *sPat, bool stroke, bool eoFill, bool text);
313
    void opShFill(Object args[], int numArgs);
314
    void doFunctionShFill(GfxFunctionShading *shading);
315
    void doFunctionShFill1(GfxFunctionShading *shading, double x0, double y0, double x1, double y1, GfxColor *colors, int depth);
316
    void doAxialShFill(GfxAxialShading *shading);
317
    void doRadialShFill(GfxRadialShading *shading);
318
    void doGouraudTriangleShFill(GfxGouraudTriangleShading *shading);
319
    void gouraudFillTriangle(double x0, double y0, GfxColor *color0, double x1, double y1, GfxColor *color1, double x2, double y2, GfxColor *color2, int nComps, int depth, GfxState::ReusablePathIterator *path);
320
    void gouraudFillTriangle(double x0, double y0, double color0, double x1, double y1, double color1, double x2, double y2, double color2, double refineColorThreshold, int depth, GfxGouraudTriangleShading *shading,
321
                             GfxState::ReusablePathIterator *path);
322
    void doPatchMeshShFill(GfxPatchMeshShading *shading);
323
    void fillPatch(const GfxPatch *patch, int colorComps, int patchColorComps, double refineColorThreshold, int depth, const GfxPatchMeshShading *shading);
324
    void doEndPath();
325
326
    // path clipping operators
327
    void opClip(Object args[], int numArgs);
328
    void opEOClip(Object args[], int numArgs);
329
330
    // text object operators
331
    void opBeginText(Object args[], int numArgs);
332
    void opEndText(Object args[], int numArgs);
333
334
    // text state operators
335
    void opSetCharSpacing(Object args[], int numArgs);
336
    void opSetFont(Object args[], int numArgs);
337
    void opSetTextLeading(Object args[], int numArgs);
338
    void opSetTextRender(Object args[], int numArgs);
339
    void opSetTextRise(Object args[], int numArgs);
340
    void opSetWordSpacing(Object args[], int numArgs);
341
    void opSetHorizScaling(Object args[], int numArgs);
342
343
    // text positioning operators
344
    void opTextMove(Object args[], int numArgs);
345
    void opTextMoveSet(Object args[], int numArgs);
346
    void opSetTextMatrix(Object args[], int numArgs);
347
    void opTextNextLine(Object args[], int numArgs);
348
349
    // text string operators
350
    void opShowText(Object args[], int numArgs);
351
    void opMoveShowText(Object args[], int numArgs);
352
    void opMoveSetShowText(Object args[], int numArgs);
353
    void opShowSpaceText(Object args[], int numArgs);
354
    void doShowText(const std::string &s);
355
    void doIncCharCount(const std::string &s);
356
357
    // XObject operators
358
    void opXObject(Object args[], int numArgs);
359
    void doImage(Object *ref, Stream *str, bool inlineImg);
360
    void doForm(Object *str);
361
362
    // in-line image operators
363
    void opBeginImage(Object args[], int numArgs);
364
    std::unique_ptr<Stream> buildImageStream();
365
    void opImageData(Object args[], int numArgs);
366
    void opEndImage(Object args[], int numArgs);
367
368
    // type 3 font operators
369
    void opSetCharWidth(Object args[], int numArgs);
370
    void opSetCacheDevice(Object args[], int numArgs);
371
372
    // compatibility operators
373
    void opBeginIgnoreUndef(Object args[], int numArgs);
374
    void opEndIgnoreUndef(Object args[], int numArgs);
375
376
    // marked content operators
377
    void opBeginMarkedContent(Object args[], int numArgs);
378
    void opEndMarkedContent(Object args[], int numArgs);
379
    void opMarkPoint(Object args[], int numArgs);
380
    GfxState *saveStateStack();
381
    void restoreStateStack(GfxState *oldState);
382
    bool contentIsHidden();
383
    void pushMarkedContent();
384
    void popMarkedContent();
385
};
386
387
#endif