//======================================================================== // // Annot.h // // Copyright 2000-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) 2006 Scott Turner // Copyright (C) 2007, 2008 Julien Rebetez // Copyright (C) 2007-2011, 2013, 2015, 2018 Carlos Garcia Campos // Copyright (C) 2007, 2008 Iñigo Martínez // Copyright (C) 2008 Michael Vrable // Copyright (C) 2008 Hugo Mercier // Copyright (C) 2008 Pino Toscano // Copyright (C) 2008 Tomas Are Haavet // Copyright (C) 2009-2011, 2013, 2016-2020 Albert Astals Cid // Copyright (C) 2012, 2013 Fabio D'Urso // Copyright (C) 2012, 2015 Tobias Koenig // Copyright (C) 2013 Thomas Freitag // Copyright (C) 2013, 2017 Adrian Johnson // 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 Dileep Sankhla // Copyright (C) 2018-2020 Tobias Deiminger // Copyright (C) 2018, 2020 Oliver Sander // Copyright (C) 2018 Adam Reichold // Copyright (C) 2019 Umang Malik // Copyright (C) 2019 João Netto // Copyright (C) 2020 Nelson Benítez León // Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, . Work sponsored by Technische Universität Dresden // // 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 ANNOT_H #define ANNOT_H #include #include #include #include #include "Object.h" class XRef; class Gfx; class CharCodeToUnicode; class GfxFont; class GfxResources; class Page; class PDFDoc; class Form; class FormWidget; class FormField; class FormFieldButton; class FormFieldText; class FormFieldChoice; class PDFRectangle; class Movie; class LinkAction; class Sound; class FileSpec; enum AnnotLineEndingStyle { annotLineEndingSquare, // Square annotLineEndingCircle, // Circle annotLineEndingDiamond, // Diamond annotLineEndingOpenArrow, // OpenArrow annotLineEndingClosedArrow, // ClosedArrow annotLineEndingNone, // None annotLineEndingButt, // Butt annotLineEndingROpenArrow, // ROpenArrow annotLineEndingRClosedArrow, // RClosedArrow annotLineEndingSlash // Slash }; enum AnnotExternalDataType { annotExternalDataMarkupUnknown, annotExternalDataMarkup3D // Markup3D }; //------------------------------------------------------------------------ // AnnotCoord //------------------------------------------------------------------------ class AnnotCoord { public: AnnotCoord() : x(0), y(0) { } AnnotCoord(double _x, double _y) : x(_x), y(_y) { } double getX() const { return x; } double getY() const { return y; } protected: double x, y; }; //------------------------------------------------------------------------ // AnnotPath //------------------------------------------------------------------------ class AnnotPath { public: AnnotPath(); AnnotPath(Array *array); AnnotPath(std::vector &&coords); ~AnnotPath(); AnnotPath(const AnnotPath &) = delete; AnnotPath &operator=(const AnnotPath &other) = delete; double getX(int coord) const; double getY(int coord) const; AnnotCoord *getCoord(int coord); int getCoordsLength() const { return coords.size(); } protected: std::vector coords; void parsePathArray(Array *array); }; //------------------------------------------------------------------------ // AnnotCalloutLine //------------------------------------------------------------------------ class AnnotCalloutLine { public: AnnotCalloutLine(double x1, double y1, double x2, double y2); virtual ~AnnotCalloutLine(); AnnotCalloutLine(const AnnotCalloutLine &) = delete; AnnotCalloutLine &operator=(const AnnotCalloutLine &other) = delete; double getX1() const { return coord1.getX(); } double getY1() const { return coord1.getY(); } double getX2() const { return coord2.getX(); } double getY2() const { return coord2.getY(); } protected: AnnotCoord coord1, coord2; }; //------------------------------------------------------------------------ // AnnotCalloutMultiLine //------------------------------------------------------------------------ class AnnotCalloutMultiLine : public AnnotCalloutLine { public: AnnotCalloutMultiLine(double x1, double y1, double x2, double y2, double x3, double y3); ~AnnotCalloutMultiLine() override; double getX3() const { return coord3.getX(); } double getY3() const { return coord3.getY(); } protected: AnnotCoord coord3; }; //------------------------------------------------------------------------ // AnnotBorderEffect //------------------------------------------------------------------------ class AnnotBorderEffect { public: enum AnnotBorderEffectType { borderEffectNoEffect, // S borderEffectCloudy // C }; AnnotBorderEffect(Dict *dict); AnnotBorderEffectType getEffectType() const { return effectType; } double getIntensity() const { return intensity; } private: AnnotBorderEffectType effectType; // S (Default S) double intensity; // I (Default 0) }; //------------------------------------------------------------------------ // AnnotQuadrilateral //------------------------------------------------------------------------ class AnnotQuadrilaterals { public: class AnnotQuadrilateral { public: AnnotQuadrilateral(); AnnotQuadrilateral(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); AnnotCoord coord1, coord2, coord3, coord4; }; AnnotQuadrilaterals(Array *array, PDFRectangle *rect); AnnotQuadrilaterals(std::unique_ptr &&quads, int quadsLength); ~AnnotQuadrilaterals(); AnnotQuadrilaterals(const AnnotQuadrilaterals &) = delete; AnnotQuadrilaterals &operator=(const AnnotQuadrilaterals &other) = delete; double getX1(int quadrilateral); double getY1(int quadrilateral); double getX2(int quadrilateral); double getY2(int quadrilateral); double getX3(int quadrilateral); double getY3(int quadrilateral); double getX4(int quadrilateral); double getY4(int quadrilateral); int getQuadrilateralsLength() const { return quadrilateralsLength; } protected: std::unique_ptr quadrilaterals; int quadrilateralsLength; }; //------------------------------------------------------------------------ // AnnotBorder //------------------------------------------------------------------------ class AnnotBorder { public: enum AnnotBorderType { typeArray, typeBS }; enum AnnotBorderStyle { borderSolid, // Solid borderDashed, // Dashed borderBeveled, // Beveled borderInset, // Inset borderUnderlined // Underlined }; virtual ~AnnotBorder(); AnnotBorder(const AnnotBorder &) = delete; AnnotBorder &operator=(const AnnotBorder &other) = delete; virtual void setWidth(double new_width) { width = new_width; } virtual AnnotBorderType getType() const = 0; virtual double getWidth() const { return width; } virtual int getDashLength() const { return dashLength; } virtual double *getDash() const { return dash; } virtual AnnotBorderStyle getStyle() const { return style; } virtual Object writeToObject(XRef *xref) const = 0; protected: AnnotBorder(); bool parseDashArray(Object *dashObj); AnnotBorderType type; double width; static const int DASH_LIMIT = 10; // implementation note 82 in Appendix H. int dashLength; double *dash; AnnotBorderStyle style; }; //------------------------------------------------------------------------ // AnnotBorderArray //------------------------------------------------------------------------ class AnnotBorderArray : public AnnotBorder { public: AnnotBorderArray(); AnnotBorderArray(Array *array); void setHorizontalCorner(double hc) { horizontalCorner = hc; } void setVerticalCorner(double vc) { verticalCorner = vc; } double getHorizontalCorner() const { return horizontalCorner; } double getVerticalCorner() const { return verticalCorner; } private: AnnotBorderType getType() const override { return typeArray; } Object writeToObject(XRef *xref) const override; double horizontalCorner; // (Default 0) double verticalCorner; // (Default 0) // double width; // (Default 1) (inherited from AnnotBorder) }; //------------------------------------------------------------------------ // AnnotBorderBS //------------------------------------------------------------------------ class AnnotBorderBS : public AnnotBorder { public: AnnotBorderBS(); AnnotBorderBS(Dict *dict); private: AnnotBorderType getType() const override { return typeBS; } Object writeToObject(XRef *xref) const override; const char *getStyleName() const; // double width; // W (Default 1) (inherited from AnnotBorder) // AnnotBorderStyle style; // S (Default S) (inherited from AnnotBorder) // double *dash; // D (Default [3]) (inherited from AnnotBorder) }; //------------------------------------------------------------------------ // AnnotColor //------------------------------------------------------------------------ class AnnotColor { public: enum AnnotColorSpace { colorTransparent = 0, colorGray = 1, colorRGB = 3, colorCMYK = 4 }; AnnotColor(); AnnotColor(double gray); AnnotColor(double r, double g, double b); AnnotColor(double c, double m, double y, double k); AnnotColor(Array *array, int adjust = 0); void adjustColor(int adjust); AnnotColorSpace getSpace() const { return (AnnotColorSpace)length; } const double *getValues() const { return values; } Object writeToObject(XRef *xref) const; private: double values[4]; int length; }; //------------------------------------------------------------------------ // DefaultAppearance //------------------------------------------------------------------------ class DefaultAppearance { public: DefaultAppearance(Object &&fontNameA, double fontPtSizeA, std::unique_ptr fontColorA); DefaultAppearance(GooString *da); void setFontName(Object &&fontNameA); const Object &getFontName() const { return fontName; } void setFontPtSize(double fontPtSizeA); double getFontPtSize() const { return fontPtSize; } void setFontColor(std::unique_ptr fontColorA); const AnnotColor *getFontColor() const { return fontColor.get(); } GooString *toAppearanceString() const; DefaultAppearance(const DefaultAppearance &) = delete; DefaultAppearance &operator=(const DefaultAppearance &) = delete; private: Object fontName; double fontPtSize; std::unique_ptr fontColor; }; //------------------------------------------------------------------------ // AnnotIconFit //------------------------------------------------------------------------ class AnnotIconFit { public: enum AnnotIconFitScaleWhen { scaleAlways, // A scaleBigger, // B scaleSmaller, // S scaleNever // N }; enum AnnotIconFitScale { scaleAnamorphic, // A scaleProportional // P }; AnnotIconFit(Dict *dict); AnnotIconFitScaleWhen getScaleWhen() { return scaleWhen; } AnnotIconFitScale getScale() { return scale; } double getLeft() { return left; } double getBottom() { return bottom; } bool getFullyBounds() { return fullyBounds; } protected: AnnotIconFitScaleWhen scaleWhen; // SW (Default A) AnnotIconFitScale scale; // S (Default P) double left; // A (Default [0.5 0.5] double bottom; // Only if scale is P bool fullyBounds; // FB (Default false) }; //------------------------------------------------------------------------ // AnnotAppearance //------------------------------------------------------------------------ class AnnotAppearance { public: enum AnnotAppearanceType { appearNormal, appearRollover, appearDown }; AnnotAppearance(PDFDoc *docA, Object *dict); ~AnnotAppearance(); // State is ignored if no subdictionary is present Object getAppearanceStream(AnnotAppearanceType type, const char *state); // Access keys in normal appearance subdictionary (N) std::unique_ptr getStateKey(int i); int getNumStates(); // Removes all associated streams in the xref table. Caller is required to // reset parent annotation's AP and AS after this call. void removeAllStreams(); // Test if this AnnotAppearance references the specified stream bool referencesStream(Ref refToStream); private: static bool referencesStream(const Object *stateObj, Ref refToStream); void removeStream(Ref refToStream); void removeStateStreams(const Object *state); protected: PDFDoc *doc; Object appearDict; // Annotation's AP }; //------------------------------------------------------------------------ // AnnotAppearanceCharacs //------------------------------------------------------------------------ class AnnotAppearanceCharacs { public: enum AnnotAppearanceCharacsTextPos { captionNoIcon, // 0 captionNoCaption, // 1 captionBelow, // 2 captionAbove, // 3 captionRight, // 4 captionLeft, // 5 captionOverlaid // 6 }; AnnotAppearanceCharacs(Dict *dict); ~AnnotAppearanceCharacs(); AnnotAppearanceCharacs(const AnnotAppearanceCharacs &) = delete; AnnotAppearanceCharacs &operator=(const AnnotAppearanceCharacs &) = delete; int getRotation() const { return rotation; } const AnnotColor *getBorderColor() const { return borderColor.get(); } const AnnotColor *getBackColor() const { return backColor.get(); } const GooString *getNormalCaption() const { return normalCaption.get(); } const GooString *getRolloverCaption() { return rolloverCaption.get(); } const GooString *getAlternateCaption() { return alternateCaption.get(); } const AnnotIconFit *getIconFit() { return iconFit.get(); } AnnotAppearanceCharacsTextPos getPosition() const { return position; } protected: int rotation; // R (Default 0) std::unique_ptr borderColor; // BC std::unique_ptr backColor; // BG std::unique_ptr normalCaption; // CA std::unique_ptr rolloverCaption; // RC std::unique_ptr alternateCaption; // AC // I // RI // IX std::unique_ptr iconFit; // IF AnnotAppearanceCharacsTextPos position; // TP (Default 0) }; //------------------------------------------------------------------------ // AnnotAppearanceBBox //------------------------------------------------------------------------ class AnnotAppearanceBBox { public: AnnotAppearanceBBox(PDFRectangle *rect); void setBorderWidth(double w) { borderWidth = w; } // The following functions operate on coords relative to [origX origY] void extendTo(double x, double y); void getBBoxRect(double bbox[4]) const; // Get boundaries in page coordinates double getPageXMin() const; double getPageYMin() const; double getPageXMax() const; double getPageYMax() const; private: double origX, origY, borderWidth; double minX, minY, maxX, maxY; }; //------------------------------------------------------------------------ // AnnotAppearanceBuilder //------------------------------------------------------------------------ class Matrix; class AnnotAppearanceBuilder { public: AnnotAppearanceBuilder(); ~AnnotAppearanceBuilder(); AnnotAppearanceBuilder(const AnnotAppearanceBuilder &) = delete; AnnotAppearanceBuilder &operator=(const AnnotAppearanceBuilder &) = delete; void setDrawColor(const AnnotColor *color, bool fill); void setLineStyleForBorder(const AnnotBorder *border); void setTextFont(const Object &fontName, double fontSize); void drawCircle(double cx, double cy, double r, bool fill); void drawEllipse(double cx, double cy, double rx, double ry, bool fill, bool stroke); void drawCircleTopLeft(double cx, double cy, double r); void drawCircleBottomRight(double cx, double cy, double r); void drawLineEnding(AnnotLineEndingStyle endingStyle, double x, double y, double size, bool fill, const Matrix &m); void drawLineEndSquare(double x, double y, double size, bool fill, const Matrix &m); void drawLineEndCircle(double x, double y, double size, bool fill, const Matrix &m); void drawLineEndDiamond(double x, double y, double size, bool fill, const Matrix &m); void drawLineEndArrow(double x, double y, double size, int orientation, bool isOpen, bool fill, const Matrix &m); void drawLineEndSlash(double x, double y, double size, const Matrix &m); void drawFieldBorder(const FormField *field, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect); bool drawFormField(const FormField *field, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource); static double lineEndingXShorten(AnnotLineEndingStyle endingStyle, double size); static double lineEndingXExtendBBox(AnnotLineEndingStyle endingStyle, double size); void writeString(const GooString &str); void append(const char *text); void appendf(const char *fmt, ...) GOOSTRING_FORMAT; const GooString *buffer() const; private: bool drawListBox(const FormFieldChoice *fieldChoice, const AnnotBorder *border, const PDFRectangle *rect, const GooString *da, const GfxResources *resources, int quadding); bool drawFormFieldButton(const FormFieldButton *field, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource); bool drawFormFieldText(const FormFieldText *fieldText, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect); bool drawFormFieldChoice(const FormFieldChoice *fieldChoice, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect); bool drawText(const GooString *text, const GooString *da, const GfxResources *resources, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, bool multiline, int comb, int quadding, bool txField, bool forceZapfDingbats, XRef *xref, bool *addedDingbatsResource, // xref and addedDingbatsResource both must not be null if forceZapfDingbats is passed bool password); void drawArrowPath(double x, double y, const Matrix &m, int orientation = 1); GooString *appearBuf; }; //------------------------------------------------------------------------ // Annot //------------------------------------------------------------------------ class Annot { friend class Annots; friend class Page; public: enum AnnotFlag { flagUnknown = 0x0000, flagInvisible = 0x0001, flagHidden = 0x0002, flagPrint = 0x0004, flagNoZoom = 0x0008, flagNoRotate = 0x0010, flagNoView = 0x0020, flagReadOnly = 0x0040, flagLocked = 0x0080, flagToggleNoView = 0x0100, flagLockedContents = 0x0200 }; enum AnnotSubtype { typeUnknown, // 0 typeText, // Text 1 typeLink, // Link 2 typeFreeText, // FreeText 3 typeLine, // Line 4 typeSquare, // Square 5 typeCircle, // Circle 6 typePolygon, // Polygon 7 typePolyLine, // PolyLine 8 typeHighlight, // Highlight 9 typeUnderline, // Underline 10 typeSquiggly, // Squiggly 11 typeStrikeOut, // StrikeOut 12 typeStamp, // Stamp 13 typeCaret, // Caret 14 typeInk, // Ink 15 typePopup, // Popup 16 typeFileAttachment, // FileAttachment 17 typeSound, // Sound 18 typeMovie, // Movie 19 typeWidget, // Widget 20 typeScreen, // Screen 21 typePrinterMark, // PrinterMark 22 typeTrapNet, // TrapNet 23 typeWatermark, // Watermark 24 type3D, // 3D 25 typeRichMedia // RichMedia 26 }; /** * Describes the additional actions of a screen or widget annotation. */ enum AdditionalActionsType { actionCursorEntering, ///< Performed when the cursor enters the annotation's active area actionCursorLeaving, ///< Performed when the cursor exists the annotation's active area actionMousePressed, ///< Performed when the mouse button is pressed inside the annotation's active area actionMouseReleased, ///< Performed when the mouse button is released inside the annotation's active area actionFocusIn, ///< Performed when the annotation receives the input focus actionFocusOut, ///< Performed when the annotation loses the input focus actionPageOpening, ///< Performed when the page containing the annotation is opened actionPageClosing, ///< Performed when the page containing the annotation is closed actionPageVisible, ///< Performed when the page containing the annotation becomes visible actionPageInvisible ///< Performed when the page containing the annotation becomes invisible }; enum FormAdditionalActionsType { actionFieldModified, ///< Performed when the when the user modifies the field actionFormatField, ///< Performed before the field is formatted to display its value actionValidateField, ///< Performed when the field value changes actionCalculateField, ///< Performed when the field needs to be recalculated }; Annot(PDFDoc *docA, PDFRectangle *rectA); Annot(PDFDoc *docA, Object &&dictObject); Annot(PDFDoc *docA, Object &&dictObject, const Object *obj); bool isOk() { return ok; } void incRefCnt(); void decRefCnt(); virtual void draw(Gfx *gfx, bool printing); // Get the resource dict of the appearance stream virtual Object getAppearanceResDict(); bool match(const Ref *refA) const { return ref == *refA; } double getXMin(); double getYMin(); double getXMax(); double getYMax(); void setRect(const PDFRectangle *rect); void setRect(double x1, double y1, double x2, double y2); // Sets the annot contents to new_content // new_content should never be NULL virtual void setContents(GooString *new_content); void setName(GooString *new_name); void setModified(GooString *new_modified); void setFlags(unsigned int new_flags); void setBorder(std::unique_ptr &&new_border); void setColor(std::unique_ptr &&new_color); void setAppearanceState(const char *state); // getters PDFDoc *getDoc() const { return doc; } bool getHasRef() const { return hasRef; } Ref getRef() const { return ref; } const Object &getAnnotObj() const { return annotObj; } AnnotSubtype getType() const { return type; } PDFRectangle *getRect() const { return rect.get(); } void getRect(double *x1, double *y1, double *x2, double *y2) const; const GooString *getContents() const { return contents.get(); } int getPageNum() const { return page; } const GooString *getName() const { return name.get(); } const GooString *getModified() const { return modified.get(); } unsigned int getFlags() const { return flags; } AnnotAppearance *getAppearStreams() const { return appearStreams.get(); } const GooString *getAppearState() const { return appearState.get(); } AnnotBorder *getBorder() const { return border.get(); } AnnotColor *getColor() const { return color.get(); } int getTreeKey() const { return treeKey; } int getId() { return ref.num; } // Check if point is inside the annot rectangle. bool inRect(double x, double y) const; static void layoutText(const GooString *text, GooString *outBuf, int *i, const GfxFont *font, double *width, double widthLimit, int *charCount, bool noReencode); private: void readArrayNum(Object *pdfArray, int key, double *value); // write vStr[i:j[ in appearBuf void initialize(PDFDoc *docA, Dict *dict); void setPage(int pageIndex, bool updateP); // Called by Page::addAnnot and Annots ctor protected: virtual ~Annot(); virtual void removeReferencedObjects(); // Called by Page::removeAnnot Object createForm(const GooString *appearBuf, double *bbox, bool transparencyGroup, Dict *resDict); Object createForm(const GooString *appearBuf, double *bbox, bool transparencyGroup, Object &&resDictObject); // overload to support incRef/decRef Dict *createResourcesDict(const char *formName, Object &&formStream, const char *stateName, double opacity, const char *blendMode); bool isVisible(bool printing); int getRotation() const; // Updates the field key of the annotation dictionary // and sets M to the current time void update(const char *key, Object &&value); // Delete appearance streams and reset appearance state void invalidateAppearance(); Object annotObj; std::atomic_int refCnt; // required data AnnotSubtype type; // Annotation type std::unique_ptr rect; // Rect // optional data std::unique_ptr contents; // Contents std::unique_ptr name; // NM std::unique_ptr modified; // M int page; // P unsigned int flags; // F (must be a 32 bit unsigned int) std::unique_ptr appearStreams; // AP Object appearance; // a reference to the Form XObject stream // for the normal appearance std::unique_ptr appearBBox; // BBox of generated appearance std::unique_ptr appearState; // AS int treeKey; // Struct Parent; Object oc; // OC PDFDoc *doc; Ref ref; // object ref identifying this annotation std::unique_ptr border; // Border, BS std::unique_ptr color; // C bool ok; bool hasRef; mutable std::recursive_mutex mutex; }; //------------------------------------------------------------------------ // AnnotPopup //------------------------------------------------------------------------ class AnnotPopup : public Annot { public: AnnotPopup(PDFDoc *docA, PDFRectangle *rect); AnnotPopup(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotPopup() override; bool hasParent() const { return parentRef != Ref::INVALID(); } void setParent(Annot *parentA); bool getOpen() const { return open; } void setOpen(bool openA); protected: void initialize(PDFDoc *docA, Dict *dict); Ref parentRef; // Parent bool open; // Open }; //------------------------------------------------------------------------ // AnnotMarkup //------------------------------------------------------------------------ class AnnotMarkup : public Annot { public: enum AnnotMarkupReplyType { replyTypeR, // R replyTypeGroup // Group }; AnnotMarkup(PDFDoc *docA, PDFRectangle *rect); AnnotMarkup(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotMarkup() override; // getters const GooString *getLabel() const { return label.get(); } AnnotPopup *getPopup() const { return popup.get(); } double getOpacity() const { return opacity; } // getRC const GooString *getDate() const { return date.get(); } bool isInReplyTo() const { return inReplyTo != Ref::INVALID(); } int getInReplyToID() const { return inReplyTo.num; } const GooString *getSubject() const { return subject.get(); } AnnotMarkupReplyType getReplyTo() const { return replyTo; } AnnotExternalDataType getExData() const { return exData; } // The annotation takes the ownership of new_popup void setPopup(std::unique_ptr &&new_popup); void setLabel(GooString *new_label); void setOpacity(double opacityA); void setDate(GooString *new_date); protected: void removeReferencedObjects() override; std::unique_ptr label; // T (Default author) std::unique_ptr popup; // Popup double opacity; // CA (Default 1.0) // RC std::unique_ptr date; // CreationDate Ref inReplyTo; // IRT std::unique_ptr subject; // Subj AnnotMarkupReplyType replyTo; // RT (Default R) // this object is overridden by the custom intent fields defined in some // annotation types. // GooString *intent; // IT AnnotExternalDataType exData; // ExData private: void initialize(PDFDoc *docA, Dict *dict); }; //------------------------------------------------------------------------ // AnnotText //------------------------------------------------------------------------ class AnnotText : public AnnotMarkup { public: enum AnnotTextState { stateUnknown, // Marked state model stateMarked, // Marked stateUnmarked, // Unmarked // Review state model stateAccepted, // Accepted stateRejected, // Rejected stateCancelled, // Cancelled stateCompleted, // Completed stateNone // None }; AnnotText(PDFDoc *docA, PDFRectangle *rect); AnnotText(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotText() override; void draw(Gfx *gfx, bool printing) override; // getters bool getOpen() const { return open; } const GooString *getIcon() const { return icon.get(); } AnnotTextState getState() const { return state; } void setOpen(bool openA); void setIcon(GooString *new_icon); private: void initialize(PDFDoc *docA, Dict *dict); bool open; // Open (Default false) std::unique_ptr icon; // Name (Default Note) AnnotTextState state; // State (Default Umarked if // StateModel Marked // None if StareModel Review) }; //------------------------------------------------------------------------ // AnnotMovie //------------------------------------------------------------------------ class AnnotMovie : public Annot { public: AnnotMovie(PDFDoc *docA, PDFRectangle *rect, Movie *movieA); AnnotMovie(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotMovie() override; void draw(Gfx *gfx, bool printing) override; const GooString *getTitle() const { return title.get(); } Movie *getMovie() { return movie.get(); } private: void initialize(PDFDoc *docA, Dict *dict); std::unique_ptr title; // T std::unique_ptr movie; // Movie + A }; //------------------------------------------------------------------------ // AnnotScreen //------------------------------------------------------------------------ class AnnotScreen : public Annot { public: AnnotScreen(PDFDoc *docA, PDFRectangle *rect); AnnotScreen(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotScreen() override; const GooString *getTitle() const { return title.get(); } AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs.get(); } LinkAction *getAction() { return action.get(); } // The caller should not delete the result std::unique_ptr getAdditionalAction(AdditionalActionsType type); private: void initialize(PDFDoc *docA, Dict *dict); std::unique_ptr title; // T std::unique_ptr appearCharacs; // MK std::unique_ptr action; // A Object additionalActions; // AA }; //------------------------------------------------------------------------ // AnnotLink //------------------------------------------------------------------------ class AnnotLink : public Annot { public: enum AnnotLinkEffect { effectNone, // N effectInvert, // I effectOutline, // O effectPush // P }; AnnotLink(PDFDoc *docA, PDFRectangle *rect); AnnotLink(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotLink() override; void draw(Gfx *gfx, bool printing) override; // getters LinkAction *getAction() const { return action.get(); } AnnotLinkEffect getLinkEffect() const { return linkEffect; } AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals.get(); } protected: void initialize(PDFDoc *docA, Dict *dict); std::unique_ptr action; // A, Dest AnnotLinkEffect linkEffect; // H (Default I) // Dict *uriAction; // PA std::unique_ptr quadrilaterals; // QuadPoints }; //------------------------------------------------------------------------ // AnnotFreeText //------------------------------------------------------------------------ class AnnotFreeText : public AnnotMarkup { public: enum AnnotFreeTextQuadding { quaddingLeftJustified, // 0 quaddingCentered, // 1 quaddingRightJustified // 2 }; enum AnnotFreeTextIntent { intentFreeText, // FreeText intentFreeTextCallout, // FreeTextCallout intentFreeTextTypeWriter // FreeTextTypeWriter }; static const double undefinedFontPtSize; AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, const DefaultAppearance &da); AnnotFreeText(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotFreeText() override; void draw(Gfx *gfx, bool printing) override; Object getAppearanceResDict() override; void setContents(GooString *new_content) override; void setDefaultAppearance(const DefaultAppearance &da); void setQuadding(AnnotFreeTextQuadding new_quadding); void setStyleString(GooString *new_string); void setCalloutLine(AnnotCalloutLine *line); void setIntent(AnnotFreeTextIntent new_intent); // getters std::unique_ptr getDefaultAppearance() const; AnnotFreeTextQuadding getQuadding() const { return quadding; } // return rc const GooString *getStyleString() const { return styleString.get(); } AnnotCalloutLine *getCalloutLine() const { return calloutLine.get(); } AnnotFreeTextIntent getIntent() const { return intent; } AnnotBorderEffect *getBorderEffect() const { return borderEffect.get(); } PDFRectangle *getRectangle() const { return rectangle.get(); } AnnotLineEndingStyle getEndStyle() const { return endStyle; } protected: void initialize(PDFDoc *docA, Dict *dict); void generateFreeTextAppearance(); // required std::unique_ptr appearanceString; // DA // optional AnnotFreeTextQuadding quadding; // Q (Default 0) // RC std::unique_ptr styleString; // DS std::unique_ptr calloutLine; // CL AnnotFreeTextIntent intent; // IT std::unique_ptr borderEffect; // BE std::unique_ptr rectangle; // RD // inherited from Annot // AnnotBorderBS border; // BS AnnotLineEndingStyle endStyle; // LE (Default None) }; //------------------------------------------------------------------------ // AnnotLine //------------------------------------------------------------------------ class AnnotLine : public AnnotMarkup { public: enum AnnotLineIntent { intentLineArrow, // LineArrow intentLineDimension // LineDimension }; enum AnnotLineCaptionPos { captionPosInline, // Inline captionPosTop // Top }; AnnotLine(PDFDoc *docA, PDFRectangle *rect); AnnotLine(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotLine() override; void draw(Gfx *gfx, bool printing) override; Object getAppearanceResDict() override; void setContents(GooString *new_content) override; void setVertices(double x1, double y1, double x2, double y2); void setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end); void setInteriorColor(std::unique_ptr &&new_color); void setLeaderLineLength(double len); void setLeaderLineExtension(double len); void setCaption(bool new_cap); void setIntent(AnnotLineIntent new_intent); // getters AnnotLineEndingStyle getStartStyle() const { return startStyle; } AnnotLineEndingStyle getEndStyle() const { return endStyle; } AnnotColor *getInteriorColor() const { return interiorColor.get(); } double getLeaderLineLength() const { return leaderLineLength; } double getLeaderLineExtension() const { return leaderLineExtension; } bool getCaption() const { return caption; } AnnotLineIntent getIntent() const { return intent; } double getLeaderLineOffset() const { return leaderLineOffset; } AnnotLineCaptionPos getCaptionPos() const { return captionPos; } Dict *getMeasure() const { return measure; } double getCaptionTextHorizontal() const { return captionTextHorizontal; } double getCaptionTextVertical() const { return captionTextVertical; } double getX1() const { return coord1->getX(); } double getY1() const { return coord1->getY(); } double getX2() const { return coord2->getX(); } double getY2() const { return coord2->getY(); } protected: void initialize(PDFDoc *docA, Dict *dict); void generateLineAppearance(); // required std::unique_ptr coord1; std::unique_ptr coord2; // optional // inherited from Annot // AnnotBorderBS border; // BS AnnotLineEndingStyle startStyle; // LE (Default [/None /None]) AnnotLineEndingStyle endStyle; // std::unique_ptr interiorColor; // IC double leaderLineLength; // LL (Default 0) double leaderLineExtension; // LLE (Default 0) bool caption; // Cap (Default false) AnnotLineIntent intent; // IT double leaderLineOffset; // LLO AnnotLineCaptionPos captionPos; // CP (Default Inline) Dict *measure; // Measure double captionTextHorizontal; // CO (Default [0, 0]) double captionTextVertical; // }; //------------------------------------------------------------------------ // AnnotTextMarkup //------------------------------------------------------------------------ class AnnotTextMarkup : public AnnotMarkup { public: AnnotTextMarkup(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType); AnnotTextMarkup(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotTextMarkup() override; void draw(Gfx *gfx, bool printing) override; // typeHighlight, typeUnderline, typeSquiggly or typeStrikeOut void setType(AnnotSubtype new_type); void setQuadrilaterals(AnnotQuadrilaterals *quadPoints); AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals.get(); } protected: void initialize(PDFDoc *docA, Dict *dict); std::unique_ptr quadrilaterals; // QuadPoints private: bool shouldCreateApperance(Gfx *gfx) const; }; //------------------------------------------------------------------------ // AnnotStamp //------------------------------------------------------------------------ class AnnotStamp : public AnnotMarkup { public: AnnotStamp(PDFDoc *docA, PDFRectangle *rect); AnnotStamp(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotStamp() override; void setIcon(GooString *new_icon); // getters const GooString *getIcon() const { return icon.get(); } private: void initialize(PDFDoc *docA, Dict *dict); std::unique_ptr icon; // Name (Default Draft) }; //------------------------------------------------------------------------ // AnnotGeometry //------------------------------------------------------------------------ class AnnotGeometry : public AnnotMarkup { public: AnnotGeometry(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType); AnnotGeometry(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotGeometry() override; void draw(Gfx *gfx, bool printing) override; void setType(AnnotSubtype new_type); // typeSquare or typeCircle void setInteriorColor(std::unique_ptr &&new_color); // getters AnnotColor *getInteriorColor() const { return interiorColor.get(); } AnnotBorderEffect *getBorderEffect() const { return borderEffect.get(); } PDFRectangle *getGeometryRect() const { return geometryRect.get(); } private: void initialize(PDFDoc *docA, Dict *dict); std::unique_ptr interiorColor; // IC std::unique_ptr borderEffect; // BE std::unique_ptr geometryRect; // RD (combined with Rect) }; //------------------------------------------------------------------------ // AnnotPolygon //------------------------------------------------------------------------ class AnnotPolygon : public AnnotMarkup { public: enum AnnotPolygonIntent { polygonCloud, // PolygonCloud polylineDimension, // PolyLineDimension polygonDimension // PolygonDimension }; AnnotPolygon(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType); AnnotPolygon(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotPolygon() override; void draw(Gfx *gfx, bool printing) override; void generatePolyLineAppearance(AnnotAppearanceBuilder *appearBuilder); void setType(AnnotSubtype new_type); // typePolygon or typePolyLine void setVertices(AnnotPath *path); void setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end); void setInteriorColor(std::unique_ptr &&new_color); void setIntent(AnnotPolygonIntent new_intent); // getters AnnotPath *getVertices() const { return vertices.get(); } AnnotLineEndingStyle getStartStyle() const { return startStyle; } AnnotLineEndingStyle getEndStyle() const { return endStyle; } AnnotColor *getInteriorColor() const { return interiorColor.get(); } AnnotBorderEffect *getBorderEffect() const { return borderEffect.get(); } AnnotPolygonIntent getIntent() const { return intent; } private: void initialize(PDFDoc *docA, Dict *dict); // required std::unique_ptr vertices; // Vertices // optional AnnotLineEndingStyle startStyle; // LE (Default [/None /None]) AnnotLineEndingStyle endStyle; // // inherited from Annot // AnnotBorderBS border; // BS std::unique_ptr interiorColor; // IC std::unique_ptr borderEffect; // BE AnnotPolygonIntent intent; // IT // Measure }; //------------------------------------------------------------------------ // AnnotCaret //------------------------------------------------------------------------ class AnnotCaret : public AnnotMarkup { public: enum AnnotCaretSymbol { symbolNone, // None symbolP // P }; AnnotCaret(PDFDoc *docA, PDFRectangle *rect); AnnotCaret(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotCaret() override; void setSymbol(AnnotCaretSymbol new_symbol); // getters AnnotCaretSymbol getSymbol() const { return symbol; } PDFRectangle *getCaretRect() const { return caretRect.get(); } private: void initialize(PDFDoc *docA, Dict *dict); AnnotCaretSymbol symbol; // Sy (Default None) std::unique_ptr caretRect; // RD (combined with Rect) }; //------------------------------------------------------------------------ // AnnotInk //------------------------------------------------------------------------ class AnnotInk : public AnnotMarkup { public: AnnotInk(PDFDoc *docA, PDFRectangle *rect); AnnotInk(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotInk() override; void draw(Gfx *gfx, bool printing) override; void setInkList(AnnotPath **paths, int n_paths); // getters AnnotPath **getInkList() const { return inkList; } int getInkListLength() const { return inkListLength; } private: void initialize(PDFDoc *docA, Dict *dict); void writeInkList(AnnotPath **paths, int n_paths, Array *dest_array); void parseInkList(Array *src_array); void freeInkList(); // required AnnotPath **inkList; // InkList int inkListLength; // optional // inherited from Annot // AnnotBorderBS border; // BS }; //------------------------------------------------------------------------ // AnnotFileAttachment //------------------------------------------------------------------------ class AnnotFileAttachment : public AnnotMarkup { public: AnnotFileAttachment(PDFDoc *docA, PDFRectangle *rect, GooString *filename); AnnotFileAttachment(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotFileAttachment() override; void draw(Gfx *gfx, bool printing) override; // getters Object *getFile() { return &file; } const GooString *getName() const { return name.get(); } private: void initialize(PDFDoc *docA, Dict *dict); // required Object file; // FS // optional std::unique_ptr name; // Name }; //------------------------------------------------------------------------ // AnnotSound //------------------------------------------------------------------------ class AnnotSound : public AnnotMarkup { public: AnnotSound(PDFDoc *docA, PDFRectangle *rect, Sound *soundA); AnnotSound(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotSound() override; void draw(Gfx *gfx, bool printing) override; // getters Sound *getSound() { return sound.get(); } const GooString *getName() const { return name.get(); } private: void initialize(PDFDoc *docA, Dict *dict); // required std::unique_ptr sound; // Sound // optional std::unique_ptr name; // Name }; //------------------------------------------------------------------------ // AnnotWidget //------------------------------------------------------------------------ class AnnotWidget : public Annot { public: enum AnnotWidgetHighlightMode { highlightModeNone, // N highlightModeInvert, // I highlightModeOutline, // O highlightModePush // P,T }; AnnotWidget(PDFDoc *docA, Object &&dictObject, const Object *obj); AnnotWidget(PDFDoc *docA, Object *dictObject, Object *obj, FormField *fieldA); ~AnnotWidget() override; void draw(Gfx *gfx, bool printing) override; void generateFieldAppearance(bool *addedDingbatsResource); void updateAppearanceStream(); AnnotWidgetHighlightMode getMode() { return mode; } AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs.get(); } LinkAction *getAction() { return action.get(); } // The caller should not delete the result std::unique_ptr getAdditionalAction(AdditionalActionsType type); std::unique_ptr getFormAdditionalAction(FormAdditionalActionsType type); Dict *getParent() { return parent; } void setNewAppearance(Object &&newAppearance); bool setFormAdditionalAction(FormAdditionalActionsType type, const GooString &js); void setField(FormField *f) { field = f; }; private: void initialize(PDFDoc *docA, Dict *dict); Form *form; FormField *field; // FormField object for this annotation AnnotWidgetHighlightMode mode; // H (Default I) std::unique_ptr appearCharacs; // MK std::unique_ptr action; // A Object additionalActions; // AA // inherited from Annot // AnnotBorderBS border; // BS Dict *parent; // Parent Ref updatedAppearanceStream; // {-1,-1} if updateAppearanceStream has never been called }; //------------------------------------------------------------------------ // Annot3D //------------------------------------------------------------------------ class Annot3D : public Annot { class Activation { public: enum ActivationATrigger { aTriggerUnknown, aTriggerPageOpened, // PO aTriggerPageVisible, // PV aTriggerUserAction // XA }; enum ActivationAState { aStateUnknown, aStateEnabled, // I aStateDisabled // L }; enum ActivationDTrigger { dTriggerUnknown, dTriggerPageClosed, // PC dTriggerPageInvisible, // PI dTriggerUserAction // XD }; enum ActivationDState { dStateUnknown, dStateUninstantiaded, // U dStateInstantiated, // I dStateLive // L }; Activation(Dict *dict); private: ActivationATrigger aTrigger; // A (Default XA) ActivationAState aState; // AIS (Default L) ActivationDTrigger dTrigger; // D (Default PI) ActivationDState dState; // DIS (Default U) bool displayToolbar; // TB (Default true) bool displayNavigation; // NP (Default false); }; public: Annot3D(PDFDoc *docA, PDFRectangle *rect); Annot3D(PDFDoc *docA, Object &&dictObject, const Object *obj); ~Annot3D() override; // getters private: void initialize(PDFDoc *docA, Dict *dict); std::unique_ptr activation; // 3DA }; //------------------------------------------------------------------------ // AnnotRichMedia //------------------------------------------------------------------------ class AnnotRichMedia : public Annot { public: class Params { public: Params(Dict *dict); ~Params(); Params(const Params &) = delete; Params &operator=(const Params &) = delete; const GooString *getFlashVars() const; private: // optional std::unique_ptr flashVars; // FlashVars }; class Instance { public: enum Type { type3D, // 3D typeFlash, // Flash typeSound, // Sound typeVideo // Video }; Instance(Dict *dict); ~Instance(); Instance(const Instance &) = delete; Instance &operator=(const Instance &) = delete; Type getType() const; Params *getParams() const; private: // optional Type type; // Subtype std::unique_ptr params; // Params }; class Configuration { public: enum Type { type3D, // 3D typeFlash, // Flash typeSound, // Sound typeVideo // Video }; Configuration(Dict *dict); ~Configuration(); Configuration(const Configuration &) = delete; Configuration &operator=(const Configuration &) = delete; Type getType() const; const GooString *getName() const; int getInstancesCount() const; Instance *getInstance(int index) const; private: // optional Type type; // Subtype std::unique_ptr name; // Name Instance **instances; // Instances int nInstances; }; class Content; class Asset { public: Asset(); ~Asset(); Asset(const Asset &) = delete; Asset &operator=(const Asset &) = delete; const GooString *getName() const; Object *getFileSpec() const; private: friend class AnnotRichMedia::Content; std::unique_ptr name; Object fileSpec; }; class Content { public: Content(Dict *dict); ~Content(); Content(const Content &) = delete; Content &operator=(const Content &) = delete; int getConfigurationsCount() const; Configuration *getConfiguration(int index) const; int getAssetsCount() const; Asset *getAsset(int index) const; private: // optional Configuration **configurations; // Configurations int nConfigurations; Asset **assets; // Assets int nAssets; }; class Activation { public: enum Condition { conditionPageOpened, // PO conditionPageVisible, // PV conditionUserAction // XA }; Activation(Dict *dict); Condition getCondition() const; private: // optional Condition condition; }; class Deactivation { public: enum Condition { conditionPageClosed, // PC conditionPageInvisible, // PI conditionUserAction // XD }; Deactivation(Dict *dict); Condition getCondition() const; private: // optional Condition condition; }; class Settings { public: Settings(Dict *dict); ~Settings(); Settings(const Settings &) = delete; Settings &operator=(const Settings &) = delete; Activation *getActivation() const; Deactivation *getDeactivation() const; private: // optional std::unique_ptr activation; std::unique_ptr deactivation; }; AnnotRichMedia(PDFDoc *docA, PDFRectangle *rect); AnnotRichMedia(PDFDoc *docA, Object &&dictObject, const Object *obj); ~AnnotRichMedia() override; Content *getContent() const; Settings *getSettings() const; private: void initialize(PDFDoc *docA, Dict *dict); // required std::unique_ptr content; // RichMediaContent // optional std::unique_ptr settings; // RichMediaSettings }; //------------------------------------------------------------------------ // Annots //------------------------------------------------------------------------ class Annots { public: // Build a list of Annot objects and call setPage on them Annots(PDFDoc *docA, int page, Object *annotsObj); ~Annots(); Annots(const Annots &) = delete; Annots &operator=(const Annots &) = delete; // Iterate through list of annotations. int getNumAnnots() const { return annots.size(); } Annot *getAnnot(int i) { return annots[i]; } void appendAnnot(Annot *annot); bool removeAnnot(Annot *annot); private: Annot *createAnnot(Object &&dictObject, const Object *obj); Annot *findAnnot(Ref *ref); PDFDoc *doc; std::vector annots; }; #endif