//======================================================================== // // Gfx.h // // Copyright 1996-2003 Glyph & Cog, LLC // //======================================================================== //======================================================================== // // Modified under the Poppler project - http://poppler.freedesktop.org // // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // // Copyright (C) 2005 Jonathan Blandford // Copyright (C) 2007 Iñigo Martínez // Copyright (C) 2008 Brad Hards // Copyright (C) 2008, 2010 Carlos Garcia Campos // Copyright (C) 2009-2013, 2017, 2018, 2021, 2024-2026 Albert Astals Cid // Copyright (C) 2009, 2010, 2012, 2013 Thomas Freitag // Copyright (C) 2010 David Benjamin // Copyright (C) 2010 Christian Feuersänger // Copyright (C) 2013 Fabio D'Urso // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, . Work sponsored by the LiMux project of the city of Munich // Copyright (C) 2018 Adam Reichold // Copyright (C) 2019, 2022, 2024 Oliver Sander // Copyright (C) 2019 Volker Krause // Copyright (C) 2026 g10 Code GmbH, Author: Sune Stolborg Vuorela // Copyright (C) 2026 Stefan Brüns // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git // //======================================================================== #ifndef GFX_H #define GFX_H #include "poppler-config.h" #include "poppler_private_export.h" #include "GfxState.h" #include "Object.h" #include "PopplerCache.h" #include #include class GooString; class PDFDoc; class XRef; class Array; class Stream; class Parser; class Dict; class Function; class OutputDev; class GfxFontDict; 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 PDFRectangle; class AnnotBorder; class AnnotColor; class Catalog; struct MarkedContentStack; //------------------------------------------------------------------------ enum GfxClipType { clipNone, clipNormal, clipEO }; enum TchkType { tchkBool, // boolean tchkInt, // integer tchkNum, // number (integer or real) tchkString, // string tchkName, // name tchkArray, // array tchkProps, // properties (dictionary or name) tchkSCN, // scn/SCN args (number of name) tchkNone // used to avoid empty initializer lists }; #define maxArgs 33 struct Operator { char name[4]; int numArgs; TchkType tchk[maxArgs]; void (Gfx::*func)(Object args[], int numArgs); }; //------------------------------------------------------------------------ class POPPLER_PRIVATE_EXPORT GfxResources { public: GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA); ~GfxResources(); GfxResources(const GfxResources &) = delete; GfxResources &operator=(const GfxResources &other) = delete; std::shared_ptr lookupFont(std::string_view name); std::shared_ptr lookupFont(std::string_view name) const; Object lookupXObject(std::string_view name); Object lookupXObjectNF(std::string_view name); Object lookupMarkedContentNF(std::string_view name); Object lookupColorSpace(std::string_view name); std::unique_ptr lookupPattern(std::string_view name, OutputDev *out, GfxState *state); std::unique_ptr lookupShading(std::string_view name, OutputDev *out, GfxState *state); Object lookupGState(std::string_view name); Object lookupGStateNF(std::string_view name); GfxResources *getNext() const { return next; } private: std::shared_ptr doLookupFont(std::string_view name) const; Ref fontDictRef; mutable std::unique_ptr fonts; Object fontDict; Object xObjDict; Object colorSpaceDict; Object patternDict; Object shadingDict; Object gStateDict; PopplerCache gStateCache; XRef *xref; Object propertiesDict; GfxResources *next; }; //------------------------------------------------------------------------ // Gfx //------------------------------------------------------------------------ class POPPLER_PRIVATE_EXPORT Gfx { public: // Constructor for regular output. 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, XRef *xrefA = nullptr); // Constructor for a sub-page object. Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict, const PDFRectangle &box, const PDFRectangle *cropBox, bool (*abortCheckCbkA)(void *data) = nullptr, void *abortCheckCbkDataA = nullptr, Gfx *gfxA = nullptr); #if USE_CMS void initDisplayProfile(); #endif ~Gfx(); Gfx(const Gfx &) = delete; Gfx &operator=(const Gfx &other) = delete; XRef *getXRef() { return xref; } // Interpret a stream or array of streams. enum class DisplayType { TopLevel, Type3Font, Form }; void display(Object *obj, DisplayType displayType = DisplayType::TopLevel); // Display an annotation, given its appearance (a Form XObject), // border style, and bounding box (in default user space). void drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor, double xMin, double yMin, double xMax, double yMax, int rotate); // Save graphics state. void saveState(); // Push a new state guard void pushStateGuard(); // Restore graphics state. void restoreState(); // Pop to state guard and pop guard void popStateGuard(); // Get the current graphics state object. GfxState *getState() { return state; } bool checkTransparencyGroup(Dict *resDict); // if softMask is true backdropColor must not be null void drawForm(Object *str, Dict *resDict, const std::array &matrix, const std::array &bbox, bool transpGroup = false, bool softMask = false, GfxColorSpace *blendingColorSpace = nullptr, bool isolated = false, bool knockout = false, bool alpha = false, Function *transferFunc = nullptr, const GfxColor *backdropColor = nullptr); void pushResources(Dict *resDict); void popResources(); private: PDFDoc *doc; XRef *xref; // the xref table for this PDF file Catalog *catalog; // the Catalog for this PDF file OutputDev *out; // output device bool subPage; // is this a sub-page object? const bool printCommands; // print the drawing commands (for debugging) const bool profileCommands; // profile the drawing commands (for debugging) bool commandAborted; // did the previous command abort the drawing? GfxResources *res; // resource stack int updateLevel; std::stack displayTypes; std::stack type3FontIsD1; GfxState *state; // current graphics state int stackHeight; // the height of the current graphics stack std::vector stateGuards; // a stack of state limits; to guard against unmatched pops bool fontChanged; // set if font or text matrix has changed GfxClipType clip; // do a clip? int ignoreUndef; // current BX/EX nesting level std::array baseMatrix; // default matrix for most recent // page/form/pattern int displayDepth; bool ocState; // true if drawing is enabled, false if // disabled MarkedContentStack *mcStack; // current BMC/EMC stack Parser *parser; // parser for page content stream(s) std::set formsDrawing; // the forms/patterns that are being drawn std::set charProcDrawing; // the charProc that are being drawn bool // callback to check for an abort (*abortCheckCbk)(void *data); void *abortCheckCbkData; static const Operator opTab[]; // table of operators void go(DisplayType displayType); void execOp(Object *cmd, Object args[], int numArgs); static const Operator *findOp(const char *name); static bool checkArg(Object *arg, TchkType type); Goffset getPos(); int bottomGuard(); // 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, bool alpha, GfxColorSpace *blendingColorSpace, bool isolated, bool knockout, Function *transferFunc, const 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 doPatternFill(bool eoFill); void doPatternStroke(); void doPatternText(); void doPatternImageMask(Object *ref, Stream *str, int width, int height, bool invert, bool inlineImg); void doTilingPatternFill(GfxTilingPattern *tPat, bool stroke, bool eoFill, bool text); void doShadingPatternFill(GfxShadingPattern *sPat, bool stroke, bool eoFill, bool text); 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 doAxialShFill(GfxAxialShading *shading); void doRadialShFill(GfxRadialShading *shading); 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, GfxState::ReusablePathIterator *path); 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, GfxState::ReusablePathIterator *path); void doPatchMeshShFill(GfxPatchMeshShading *shading); void fillPatch(const GfxPatch *patch, int colorComps, int patchColorComps, double refineColorThreshold, int depth, const GfxPatchMeshShading *shading); 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 opShowText(Object args[], int numArgs); void opMoveShowText(Object args[], int numArgs); void opMoveSetShowText(Object args[], int numArgs); void opShowSpaceText(Object args[], int numArgs); void doShowText(const std::string &s); void doIncCharCount(const std::string &s); // XObject operators void opXObject(Object args[], int numArgs); void doImage(Object *ref, Stream *str, bool inlineImg); void doForm(Object *str); // in-line image operators void opBeginImage(Object args[], int numArgs); std::unique_ptr 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); GfxState *saveStateStack(); void restoreStateStack(GfxState *oldState); bool contentIsHidden(); void pushMarkedContent(); void popMarkedContent(); }; #endif