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