summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/pdfinput/pdf-parser.h
blob: 77c73f26acbb5cca48d87f31f5fe99b3ada5a473 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
// SPDX-License-Identifier: GPL-2.0-or-later
/** @file
 * PDF parsing using libpoppler.
 *//*
 * Authors:
 * see git history
 * 
 * Derived from Gfx.h from poppler (?) which derives from Xpdf, Copyright 1996-2003 Glyph & Cog, LLC, which is under GPL2+.
 *
 * Copyright (C) 2018 Authors
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */

#ifndef PDF_PARSER_H
#define PDF_PARSER_H

#ifdef HAVE_CONFIG_H
# include "config.h"  // only include where actually required!
#endif

#ifdef HAVE_POPPLER
#include "poppler-transition-api.h"

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

namespace Inkscape {
    namespace Extension {
        namespace Internal {
                class SvgBuilder;
        }
    }
}

// TODO clean up and remove using:
using Inkscape::Extension::Internal::SvgBuilder;

#include "glib/poppler-features.h"
#include "Object.h"

#include <map>
#include <memory>
#include <string>

#define Operator Operator_Gfx
#include <Gfx.h>
#undef Operator

class PDFDoc;
class Page;
class GooString;
class XRef;
class Array;
class Stream;
class Parser;
class Dict;
class Function;
class OutputDev;
class GfxFont;
class GfxPattern;
class GfxTilingPattern;
class GfxShadingPattern;
class GfxShading;
class GfxFunctionShading;
class GfxAxialShading;
class GfxRadialShading;
class GfxGouraudTriangleShading;
class GfxPatchMeshShading;
struct GfxPatch;
class GfxState;
struct GfxColor;
class GfxColorSpace;
class Gfx;
class GfxResources;
class PDFRectangle;
class AnnotBorderStyle;
class CairoFontEngine;

class PdfParser;

//------------------------------------------------------------------------

#define maxOperatorArgs 33

struct PdfOperator {
    char name[4];
    int numArgs;
    TchkType tchk[maxOperatorArgs];
    void (PdfParser::*func)(Object args[], int numArgs);
};

#undef maxOperatorArgs

struct OpHistoryEntry {
    const char *name;       // operator's name
    GfxState *state;        // saved state, NULL if none
    GBool executed;         // whether the operator has been executed

    OpHistoryEntry *next;   // next entry on stack
    unsigned depth;         // total number of entries descending from this
};

//------------------------------------------------------------------------
// PdfParser
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// constants
//------------------------------------------------------------------------

#define pdfFunctionShading  1
#define pdfAxialShading     2
#define pdfRadialShading    3
#define pdfGouraudTriangleShading  4
#define pdfPatchMeshShading 5
#define pdfNumShadingTypes 5

/**
 * PDF parsing module using libpoppler's facilities.
 */
class PdfParser {
public:

  // Constructor for regular output.
    PdfParser(std::shared_ptr<PDFDoc> pdf_doc, SvgBuilder *builderA, Page *page, _POPPLER_CONST PDFRectangle *cropBox);
    // Constructor for a sub-page object.
    PdfParser(XRef *xrefA, SvgBuilder *builderA, Dict *resDict, _POPPLER_CONST PDFRectangle *box);

    virtual ~PdfParser();

    // Interpret a stream or array of streams.
    void parse(Object *obj, GBool topLevel = gTrue);

    // Save graphics state.
    void saveState();

    // Restore graphics state.
    void restoreState();

    // Get the current graphics state object.
    GfxState *getState() { return state; }

    // Set the precision of approximation for specific shading fills.
    void setApproximationPrecision(int shadingType, double colorDelta, int maxDepth);
    void loadOptionalContentLayers(Dict *resources);
    void loadPatternColorProfiles(Dict *resources);
    void loadColorProfile();
    void loadColorSpaceProfile(GfxColorSpace *space, Object *obj);
    GfxPattern *lookupPattern(Object *obj, GfxState *state);

    static void debug_array(const Array *array, int depth = 0, XRef *xref = nullptr);
    static void debug_dict(const Dict *dict, int depth = 0, XRef *xref = nullptr);
    static void debug_object(const Object *obj, int depth = 0, XRef *xref = nullptr);

    std::shared_ptr<CairoFontEngine> getFontEngine();
private:
    std::shared_ptr<PDFDoc> _pdf_doc;
    std::shared_ptr<CairoFontEngine> _font_engine;

    XRef *xref;          // the xref table for this PDF file
    SvgBuilder *builder; // SVG generator
    GBool subPage;       // is this a sub-page object?
    GBool printCommands; // print the drawing commands (for debugging)
    GfxResources *res;   // resource stack

    GfxState *state;         // current graphics state
    GBool fontChanged;       // set if font or text matrix has changed
    GfxClipType clip;        // do a clip?
    int ignoreUndef;         // current BX/EX nesting level
    Geom::Affine baseMatrix; // default matrix for most recent
                             //   page/form/pattern
    int formDepth;

    Parser *parser; // parser for page content stream(s)

    static PdfOperator opTab[]; // table of operators

    int colorDeltas[pdfNumShadingTypes];
    // max deltas allowed in any color component
    // for the approximation of shading fills
    int maxDepths[pdfNumShadingTypes]; // max recursive depths

    OpHistoryEntry *operatorHistory; // list containing the last N operators

    //! Caches color spaces by name
    std::map<std::string, std::unique_ptr<GfxColorSpace>> colorSpacesCache;

    GfxColorSpace *lookupColorSpaceCopy(Object &);

    void setDefaultApproximationPrecision(); // init color deltas
    void pushOperator(const char *name);
    OpHistoryEntry *popOperator();
    const char *getPreviousOperator(unsigned int look_back = 1); // returns the nth previous operator's name

    void go(GBool topLevel);
    void execOp(Object *cmd, Object args[], int numArgs);
    PdfOperator *findOp(const char *name);
    GBool checkArg(Object *arg, TchkType type);
    int getPos();

    void opOptionalContentGroup(Object args[], int numArgs);

    // graphics state operators
    void opSave(Object args[], int numArgs);
    void opRestore(Object args[], int numArgs);
    void opConcat(Object args[], int numArgs);
    void opSetDash(Object args[], int numArgs);
    void opSetFlat(Object args[], int numArgs);
    void opSetLineJoin(Object args[], int numArgs);
    void opSetLineCap(Object args[], int numArgs);
    void opSetMiterLimit(Object args[], int numArgs);
    void opSetLineWidth(Object args[], int numArgs);
    void opSetExtGState(Object args[], int numArgs);
    void doSoftMask(Object *str, GBool alpha, GfxColorSpace *blendingColorSpace, GBool isolated, GBool knockout,
                    Function *transferFunc, GfxColor *backdropColor);
    void opSetRenderingIntent(Object args[], int numArgs);

    // color operators
    void opSetFillGray(Object args[], int numArgs);
    void opSetStrokeGray(Object args[], int numArgs);
    void opSetFillCMYKColor(Object args[], int numArgs);
    void opSetStrokeCMYKColor(Object args[], int numArgs);
    void opSetFillRGBColor(Object args[], int numArgs);
    void opSetStrokeRGBColor(Object args[], int numArgs);
    void opSetFillColorSpace(Object args[], int numArgs);
    void opSetStrokeColorSpace(Object args[], int numArgs);
    void opSetFillColor(Object args[], int numArgs);
    void opSetStrokeColor(Object args[], int numArgs);
    void opSetFillColorN(Object args[], int numArgs);
    void opSetStrokeColorN(Object args[], int numArgs);

    // path segment operators
    void opMoveTo(Object args[], int numArgs);
    void opLineTo(Object args[], int numArgs);
    void opCurveTo(Object args[], int numArgs);
    void opCurveTo1(Object args[], int numArgs);
    void opCurveTo2(Object args[], int numArgs);
    void opRectangle(Object args[], int numArgs);
    void opClosePath(Object args[], int numArgs);

    // path painting operators
    void opEndPath(Object args[], int numArgs);
    void opStroke(Object args[], int numArgs);
    void opCloseStroke(Object args[], int numArgs);
    void opFill(Object args[], int numArgs);
    void opEOFill(Object args[], int numArgs);
    void opFillStroke(Object args[], int numArgs);
    void opCloseFillStroke(Object args[], int numArgs);
    void opEOFillStroke(Object args[], int numArgs);
    void opCloseEOFillStroke(Object args[], int numArgs);
    void doFillAndStroke(GBool eoFill);
    void doPatternFillFallback(GBool eoFill);
    void doPatternStrokeFallback();
    void doShadingPatternFillFallback(GfxShadingPattern *sPat, GBool stroke, GBool eoFill);
    void opShFill(Object args[], int numArgs);
    void doFunctionShFill(GfxFunctionShading *shading);
    void doFunctionShFill1(GfxFunctionShading *shading, double x0, double y0, double x1, double y1, GfxColor *colors,
                           int depth);
    void doGouraudTriangleShFill(GfxGouraudTriangleShading *shading);
    void gouraudFillTriangle(double x0, double y0, GfxColor *color0, double x1, double y1, GfxColor *color1, double x2,
                             double y2, GfxColor *color2, int nComps, int depth);
    void doPatchMeshShFill(GfxPatchMeshShading *shading);
    void fillPatch(_POPPLER_CONST GfxPatch *patch, int nComps, int depth);
    void doEndPath();

    // path clipping operators
    void opClip(Object args[], int numArgs);
    void opEOClip(Object args[], int numArgs);

    // text object operators
    void opBeginText(Object args[], int numArgs);
    void opEndText(Object args[], int numArgs);

    // text state operators
    void opSetCharSpacing(Object args[], int numArgs);
    void opSetFont(Object args[], int numArgs);
    void opSetTextLeading(Object args[], int numArgs);
    void opSetTextRender(Object args[], int numArgs);
    void opSetTextRise(Object args[], int numArgs);
    void opSetWordSpacing(Object args[], int numArgs);
    void opSetHorizScaling(Object args[], int numArgs);

    // text positioning operators
    void opTextMove(Object args[], int numArgs);
    void opTextMoveSet(Object args[], int numArgs);
    void opSetTextMatrix(Object args[], int numArgs);
    void opTextNextLine(Object args[], int numArgs);

    // text string operators
    void doUpdateFont();
    void opShowText(Object args[], int numArgs);
    void opMoveShowText(Object args[], int numArgs);
    void opMoveSetShowText(Object args[], int numArgs);
    void opShowSpaceText(Object args[], int numArgs);
#if POPPLER_CHECK_VERSION(0,64,0)
  void doShowText(const GooString *s);
#else
  void doShowText(GooString *s);
#endif
  

  // XObject operators
  void opXObject(Object args[], int numArgs);
  void doImage(Object *ref, Stream *str, GBool inlineImg);
  void doForm(Object *str);
  void doForm1(Object *str, Dict *resDict, double *matrix, double *bbox,
	       GBool transpGroup = gFalse, GBool softMask = gFalse,
	       GfxColorSpace *blendingColorSpace = nullptr,
	       GBool isolated = gFalse, GBool knockout = gFalse,
	       GBool alpha = gFalse, Function *transferFunc = nullptr,
	       GfxColor *backdropColor = nullptr);

  // in-line image operators
  void opBeginImage(Object args[], int numArgs);
  Stream *buildImageStream();
  void opImageData(Object args[], int numArgs);
  void opEndImage(Object args[], int numArgs);

  // type 3 font operators
  void opSetCharWidth(Object args[], int numArgs);
  void opSetCacheDevice(Object args[], int numArgs);

  // compatibility operators
  void opBeginIgnoreUndef(Object args[], int numArgs);
  void opEndIgnoreUndef(Object args[], int numArgs);

  // marked content operators
  void opBeginMarkedContent(Object args[], int numArgs);
  void opEndMarkedContent(Object args[], int numArgs);
  void opMarkPoint(Object args[], int numArgs);

  void pushResources(Dict *resDict);
  void popResources();
};

#endif /* HAVE_POPPLER */

#endif /* PDF_PARSER_H */