| //======================================================================== |
| // |
| // Form.h |
| // |
| // This file is licensed under the GPLv2 or later |
| // |
| // Copyright 2006 Julien Rebetez <julienr@svn.gnome.org> |
| // Copyright 2007, 2008, 2011 Carlos Garcia Campos <carlosgc@gnome.org> |
| // Copyright 2007-2010, 2012, 2015-2024 Albert Astals Cid <aacid@kde.org> |
| // Copyright 2010 Mark Riedesel <mark@klowner.com> |
| // Copyright 2011 Pino Toscano <pino@kde.org> |
| // Copyright 2012 Fabio D'Urso <fabiodurso@hotmail.it> |
| // Copyright 2013 Adrian Johnson <ajohnson@redneon.com> |
| // Copyright 2015 André Guerreiro <aguerreiro1985@gmail.com> |
| // Copyright 2015 André Esser <bepandre@hotmail.com> |
| // Copyright 2017 Roland Hieber <r.hieber@pengutronix.de> |
| // Copyright 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de> |
| // Copyright 2018 Andre Heinecke <aheinecke@intevation.de> |
| // Copyright 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich |
| // Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@protonmail.com> |
| // Copyright 2019, 2020 Oliver Sander <oliver.sander@tu-dresden.de> |
| // Copyright 2019 João Netto <joaonetto901@gmail.com> |
| // Copyright 2020, 2021 Nelson Benítez León <nbenitezl@gmail.com> |
| // Copyright 2020 Marek Kasik <mkasik@redhat.com> |
| // Copyright 2020 Thorsten Behrens <Thorsten.Behrens@CIB.de> |
| // Copyright 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by Technische Universität Dresden |
| // Copyright 2021 Georgiy Sgibnev <georgiy@sgibnev.com>. Work sponsored by lab50.net. |
| // Copyright 2021 Theofilos Intzoglou <int.teo@gmail.com> |
| // Copyright 2022 Alexander Sulfrian <asulfrian@zedat.fu-berlin.de> |
| // Copyright 2023, 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk> |
| // Copyright 2024 Pratham Gandhi <ppg.1382@gmail.com> |
| // |
| //======================================================================== |
| |
| #ifndef FORM_H |
| #define FORM_H |
| |
| #include "Annot.h" |
| #include "CharTypes.h" |
| #include "CryptoSignBackend.h" |
| #include "Object.h" |
| #include "poppler_private_export.h" |
| #include "SignatureInfo.h" |
| |
| #include <ctime> |
| |
| #include <optional> |
| #include <set> |
| #include <vector> |
| #include <functional> |
| |
| class GooString; |
| class Array; |
| class Dict; |
| class Annot; |
| class AnnotWidget; |
| class Annots; |
| class LinkAction; |
| class GfxResources; |
| class PDFDoc; |
| class X509CertificateInfo; |
| namespace CryptoSign { |
| class VerificationInterface; |
| } |
| |
| enum FormFieldType |
| { |
| formButton, |
| formText, |
| formChoice, |
| formSignature, |
| formUndef |
| }; |
| |
| enum FormButtonType |
| { |
| formButtonCheck, |
| formButtonPush, |
| formButtonRadio |
| }; |
| |
| enum FillValueType |
| { |
| fillValue, |
| fillDefaultValue |
| }; |
| |
| class Form; |
| class FormField; |
| class FormFieldButton; |
| class FormFieldText; |
| class FormFieldSignature; |
| class FormFieldChoice; |
| |
| //------------------------------------------------------------------------ |
| // FormWidget |
| // A FormWidget represents the graphical part of a field and is "attached" |
| // to a page. |
| //------------------------------------------------------------------------ |
| |
| class POPPLER_PRIVATE_EXPORT FormWidget |
| { |
| public: |
| virtual ~FormWidget(); |
| |
| // Check if point is inside the field bounding rect |
| bool inRect(double x, double y) const; |
| |
| // Get the field bounding rect |
| void getRect(double *x1, double *y1, double *x2, double *y2) const; |
| |
| unsigned getID() { return ID; } |
| void setID(unsigned int i) { ID = i; } |
| |
| FormField *getField() { return field; } |
| FormFieldType getType() { return type; } |
| |
| Object *getObj() { return &obj; } |
| Ref getRef() { return ref; } |
| |
| void setChildNum(unsigned i) { childNum = i; } |
| unsigned getChildNum() { return childNum; } |
| |
| const GooString *getPartialName() const; |
| void setPartialName(const GooString &name); |
| const GooString *getAlternateUiName() const; |
| const GooString *getMappingName() const; |
| GooString *getFullyQualifiedName(); |
| |
| bool isModified() const; |
| |
| bool isReadOnly() const; |
| void setReadOnly(bool value); |
| |
| LinkAction *getActivationAction(); // The caller should not delete the result |
| std::unique_ptr<LinkAction> getAdditionalAction(Annot::FormAdditionalActionsType type); |
| bool setAdditionalAction(Annot::FormAdditionalActionsType t, const std::string &js); |
| |
| // return the unique ID corresponding to pageNum/fieldNum |
| static int encodeID(unsigned pageNum, unsigned fieldNum); |
| // decode id and retrieve pageNum and fieldNum |
| static void decodeID(unsigned id, unsigned *pageNum, unsigned *fieldNum); |
| |
| void createWidgetAnnotation(); |
| AnnotWidget *getWidgetAnnotation() const { return widget; } |
| void setWidgetAnnotation(AnnotWidget *_widget) { widget = _widget; } |
| |
| virtual void updateWidgetAppearance() = 0; |
| |
| void print(int indent = 0); |
| |
| protected: |
| FormWidget(PDFDoc *docA, Object *aobj, unsigned num, Ref aref, FormField *fieldA); |
| |
| AnnotWidget *widget; |
| FormField *field; |
| FormFieldType type; |
| Object obj; |
| Ref ref; |
| PDFDoc *doc; |
| XRef *xref; |
| |
| // index of this field in the parent's child list |
| unsigned childNum; |
| |
| /* |
| Field ID is an (unsigned) integer, calculated as follow : |
| the first sizeof/2 bits are the field number, relative to the page |
| the last sizeof/2 bits are the page number |
| [page number | field number] |
| (encoding) id = (pageNum << 4*sizeof(unsigned)) + fieldNum; |
| (decoding) pageNum = id >> 4*sizeof(unsigned); fieldNum = (id << 4*sizeof(unsigned)) >> 4*sizeof(unsigned); |
| */ |
| unsigned ID; |
| }; |
| |
| //------------------------------------------------------------------------ |
| // FormWidgetButton |
| //------------------------------------------------------------------------ |
| |
| class POPPLER_PRIVATE_EXPORT FormWidgetButton : public FormWidget |
| { |
| public: |
| FormWidgetButton(PDFDoc *docA, Object *dictObj, unsigned num, Ref ref, FormField *p); |
| ~FormWidgetButton() override; |
| |
| FormButtonType getButtonType() const; |
| |
| void setState(bool state); |
| bool getState() const; |
| |
| const char *getOnStr() const; |
| void setAppearanceState(const char *state); |
| void updateWidgetAppearance() override; |
| |
| protected: |
| FormFieldButton *parent() const; |
| GooString *onStr; |
| }; |
| |
| //------------------------------------------------------------------------ |
| // FormWidgetText |
| //------------------------------------------------------------------------ |
| |
| class POPPLER_PRIVATE_EXPORT FormWidgetText : public FormWidget |
| { |
| public: |
| FormWidgetText(PDFDoc *docA, Object *dictObj, unsigned num, Ref ref, FormField *p); |
| // return the field's content (UTF16BE) |
| const GooString *getContent() const; |
| |
| // expects a UTF16BE string |
| void setContent(const GooString *new_content); |
| // sets the text inside the field appearance stream |
| void setAppearanceContent(const GooString *new_content); |
| |
| void updateWidgetAppearance() override; |
| |
| bool isMultiline() const; |
| bool isPassword() const; |
| bool isFileSelect() const; |
| bool noSpellCheck() const; |
| bool noScroll() const; |
| bool isComb() const; |
| bool isRichText() const; |
| int getMaxLen() const; |
| // return the font size of the field's text |
| double getTextFontSize(); |
| // set the font size of the field's text (currently only integer values) |
| void setTextFontSize(int fontSize); |
| |
| protected: |
| FormFieldText *parent() const; |
| }; |
| |
| //------------------------------------------------------------------------ |
| // FormWidgetChoice |
| //------------------------------------------------------------------------ |
| |
| class POPPLER_PRIVATE_EXPORT FormWidgetChoice : public FormWidget |
| { |
| public: |
| FormWidgetChoice(PDFDoc *docA, Object *dictObj, unsigned num, Ref ref, FormField *p); |
| ~FormWidgetChoice() override; |
| |
| int getNumChoices() const; |
| // return the display name of the i-th choice (UTF16BE) |
| const GooString *getChoice(int i) const; |
| const GooString *getExportVal(int i) const; |
| // select the i-th choice |
| void select(int i); |
| void setAppearanceChoiceContent(const GooString *new_content); |
| // toggle selection of the i-th choice |
| void toggle(int i); |
| |
| // deselect everything |
| void deselectAll(); |
| |
| // except a UTF16BE string |
| // only work for editable combo box, set the user-entered text as the current choice |
| void setEditChoice(const GooString *new_content); |
| |
| const GooString *getEditChoice() const; |
| |
| void updateWidgetAppearance() override; |
| bool isSelected(int i) const; |
| |
| bool isCombo() const; |
| bool hasEdit() const; |
| bool isMultiSelect() const; |
| bool noSpellCheck() const; |
| bool commitOnSelChange() const; |
| bool isListBox() const; |
| |
| protected: |
| bool _checkRange(int i) const; |
| FormFieldChoice *parent() const; |
| }; |
| |
| //------------------------------------------------------------------------ |
| // FormWidgetSignature |
| //------------------------------------------------------------------------ |
| |
| class POPPLER_PRIVATE_EXPORT FormWidgetSignature : public FormWidget |
| { |
| public: |
| FormWidgetSignature(PDFDoc *docA, Object *dictObj, unsigned num, Ref ref, FormField *p); |
| void updateWidgetAppearance() override; |
| |
| CryptoSign::SignatureType signatureType() const; |
| void setSignatureType(CryptoSign::SignatureType fst); |
| |
| // Use -1 for now as validationTime |
| // ocspRevocation and aiafetch might happen async in the Background |
| // doneCallback will be invoked once there is a result |
| // Note: Validation callback will likely happen from an auxillary |
| // thread and it is the caller of this method who is responsible |
| // for moving back to the main thread |
| // For synchronous code, don't provide validation callback |
| // and just call validateSignatureResult afterwards |
| // The returned SignatureInfo from this method does |
| // not have validated the certificate. |
| SignatureInfo *validateSignatureAsync(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck, bool enableAIA, const std::function<void()> &doneCallback); |
| |
| /// Waits, if needed, on validation callback and |
| /// returns a signatureinfo with validated certificates |
| CertificateValidationStatus validateSignatureResult(); |
| |
| // returns a list with the boundaries of the signed ranges |
| // the elements of the list are of type Goffset |
| std::vector<Goffset> getSignedRangeBounds() const; |
| |
| // Creates or replaces the dictionary name "V" in the signature dictionary and |
| // fills it with the fields of the signature; the field "Contents" is the signature |
| // in PKCS#7 format, which is calculated over the byte range encompassing the whole |
| // document except for the signature itself; this byte range is specified in the |
| // field "ByteRange" in the dictionary "V". |
| // Arguments reason and location are UTF-16 big endian strings with BOM. An empty string and nullptr are acceptable too. |
| // Returns success. |
| std::optional<CryptoSign::SigningError> signDocument(const std::string &filename, const std::string &certNickname, const std::string &password, const GooString *reason = nullptr, const GooString *location = nullptr, |
| const std::optional<GooString> &ownerPassword = {}, const std::optional<GooString> &userPassword = {}); |
| |
| // Same as above but adds text, font color, etc. |
| std::optional<CryptoSign::SigningError> signDocumentWithAppearance(const std::string &filename, const std::string &certNickname, const std::string &password, const GooString *reason = nullptr, const GooString *location = nullptr, |
| const std::optional<GooString> &ownerPassword = {}, const std::optional<GooString> &userPassword = {}, const GooString &signatureText = {}, |
| const GooString &signatureTextLeft = {}, double fontSize = {}, double leftFontSize = {}, std::unique_ptr<AnnotColor> &&fontColor = {}, double borderWidth = {}, |
| std::unique_ptr<AnnotColor> &&borderColor = {}, std::unique_ptr<AnnotColor> &&backgroundColor = {}); |
| |
| // checks the length encoding of the signature and returns the hex encoded signature |
| // if the check passed (and the checked file size as output parameter in checkedFileSize) |
| // otherwise a nullptr is returned |
| std::optional<GooString> getCheckedSignature(Goffset *checkedFileSize); |
| |
| const std::vector<unsigned char> &getSignature() const; |
| |
| private: |
| bool createSignature(Object &vObj, Ref vRef, const GooString &name, int placeholderLength, const GooString *reason, const GooString *location, CryptoSign::SignatureType signatureType); |
| bool getObjectStartEnd(const GooString &filename, int objNum, Goffset *objStart, Goffset *objEnd, const std::optional<GooString> &ownerPassword, const std::optional<GooString> &userPassword); |
| bool updateOffsets(FILE *f, Goffset objStart, Goffset objEnd, Goffset *sigStart, Goffset *sigEnd, Goffset *fileSize); |
| |
| bool updateSignature(FILE *f, Goffset sigStart, Goffset sigEnd, const std::vector<unsigned char> &signature); |
| }; |
| |
| //------------------------------------------------------------------------ |
| // FormField |
| // A FormField implements the logical side of a field and is "attached" to |
| // the Catalog. This is an internal class and client applications should |
| // only interact with FormWidgets. |
| //------------------------------------------------------------------------ |
| |
| class POPPLER_PRIVATE_EXPORT FormField |
| { |
| public: |
| FormField(PDFDoc *docA, Object &&aobj, const Ref aref, FormField *parent, std::set<int> *usedParents, FormFieldType t = formUndef); |
| |
| virtual ~FormField(); |
| |
| // Accessors. |
| FormFieldType getType() const { return type; } |
| Object *getObj() { return &obj; } |
| Ref getRef() { return ref; } |
| |
| void setReadOnly(bool value); |
| bool isReadOnly() const { return readOnly; } |
| void setStandAlone(bool value) { standAlone = value; } |
| bool isStandAlone() const { return standAlone; } |
| |
| GooString *getDefaultAppearance() const { return defaultAppearance.get(); } |
| void setDefaultAppearance(const std::string &appearance); |
| |
| bool hasTextQuadding() const { return hasQuadding; } |
| VariableTextQuadding getTextQuadding() const { return quadding; } |
| |
| const GooString *getPartialName() const { return partialName.get(); } |
| void setPartialName(const GooString &name); |
| const GooString *getAlternateUiName() const { return alternateUiName.get(); } |
| const GooString *getMappingName() const { return mappingName.get(); } |
| GooString *getFullyQualifiedName(); |
| |
| FormWidget *findWidgetByRef(Ref aref); |
| int getNumWidgets() const { return terminal ? numChildren : 0; } |
| FormWidget *getWidget(int i) const { return terminal ? widgets[i] : nullptr; } |
| int getNumChildren() const { return !terminal ? numChildren : 0; } |
| FormField *getChildren(int i) const { return children[i]; } |
| |
| // only implemented in FormFieldButton |
| virtual void fillChildrenSiblingsID(); |
| |
| void createWidgetAnnotations(); |
| |
| void printTree(int indent = 0); |
| virtual void print(int indent = 0); |
| virtual void reset(const std::vector<std::string> &excludedFields); |
| void resetChildren(const std::vector<std::string> &excludedFields); |
| FormField *findFieldByRef(Ref aref); |
| FormField *findFieldByFullyQualifiedName(const std::string &name); |
| |
| bool getNoExport() const { return noExport; } |
| |
| protected: |
| void _createWidget(Object *obj, Ref aref); |
| void createChildren(std::set<int> *usedParents); |
| void updateChildrenAppearance(); |
| bool isAmongExcludedFields(const std::vector<std::string> &excludedFields); |
| |
| FormFieldType type; // field type |
| Ref ref; |
| bool terminal; |
| Object obj; |
| PDFDoc *doc; |
| XRef *xref; |
| FormField **children; |
| FormField *parent; |
| int numChildren; |
| FormWidget **widgets; |
| bool readOnly; |
| bool noExport; |
| |
| std::unique_ptr<GooString> partialName; // T field |
| std::unique_ptr<GooString> alternateUiName; // TU field |
| std::unique_ptr<GooString> mappingName; // TM field |
| GooString *fullyQualifiedName; |
| |
| // Variable Text |
| std::unique_ptr<GooString> defaultAppearance; |
| bool hasQuadding; |
| VariableTextQuadding quadding; |
| |
| // True when FormField is not part of Catalog's Field array (or there isn't one). |
| bool standAlone; |
| |
| private: |
| FormField() { } |
| }; |
| |
| //------------------------------------------------------------------------ |
| // FormFieldButton |
| //------------------------------------------------------------------------ |
| |
| class FormFieldButton : public FormField |
| { |
| public: |
| FormFieldButton(PDFDoc *docA, Object &&dict, const Ref ref, FormField *parent, std::set<int> *usedParents); |
| |
| FormButtonType getButtonType() const { return btype; } |
| |
| bool noToggleToOff() const { return noAllOff; } |
| |
| // returns true if the state modification is accepted |
| bool setState(const char *state, bool ignoreToggleOff = false); |
| bool getState(const char *state) const; |
| |
| const char *getAppearanceState() const { return appearanceState.isName() ? appearanceState.getName() : nullptr; } |
| const char *getDefaultAppearanceState() const { return defaultAppearanceState.isName() ? defaultAppearanceState.getName() : nullptr; } |
| |
| void fillChildrenSiblingsID() override; |
| |
| void setNumSiblings(int num); |
| void setSibling(int i, FormFieldButton *id) { siblings[i] = id; } |
| |
| // For radio buttons, return the fields of the other radio buttons in the same group |
| FormFieldButton *getSibling(int i) const { return siblings[i]; } |
| int getNumSiblings() const { return numSiblings; } |
| |
| void print(int indent) override; |
| void reset(const std::vector<std::string> &excludedFields) override; |
| |
| ~FormFieldButton() override; |
| |
| protected: |
| void updateState(const char *state); |
| |
| FormFieldButton **siblings; // IDs of dependent buttons (each button of a radio field has all the others buttons |
| // of the same field in this array) |
| int numSiblings; |
| |
| FormButtonType btype; |
| int size; |
| int active_child; // only used for combo box |
| bool noAllOff; |
| Object appearanceState; // V |
| Object defaultAppearanceState; // DV |
| }; |
| |
| //------------------------------------------------------------------------ |
| // FormFieldText |
| //------------------------------------------------------------------------ |
| |
| class FormFieldText : public FormField |
| { |
| public: |
| FormFieldText(PDFDoc *docA, Object &&dictObj, const Ref ref, FormField *parent, std::set<int> *usedParents); |
| |
| const GooString *getContent() const { return content.get(); } |
| const GooString *getAppearanceContent() const { return internalContent ? internalContent.get() : content.get(); } |
| void setContentCopy(const GooString *new_content); |
| void setAppearanceContentCopy(const GooString *new_content); |
| ~FormFieldText() override; |
| |
| bool isMultiline() const { return multiline; } |
| bool isPassword() const { return password; } |
| bool isFileSelect() const { return fileSelect; } |
| bool noSpellCheck() const { return doNotSpellCheck; } |
| bool noScroll() const { return doNotScroll; } |
| bool isComb() const { return comb; } |
| bool isRichText() const { return richText; } |
| |
| int getMaxLen() const { return maxLen; } |
| |
| // return the font size of the field's text |
| double getTextFontSize(); |
| // set the font size of the field's text (currently only integer values) |
| void setTextFontSize(int fontSize); |
| |
| void print(int indent) override; |
| void reset(const std::vector<std::string> &excludedFields) override; |
| |
| static int tokenizeDA(const std::string &daString, std::vector<std::string> *daToks, const char *searchTok); |
| |
| protected: |
| int parseDA(std::vector<std::string> *daToks); |
| void fillContent(FillValueType fillType); |
| |
| std::unique_ptr<GooString> content; |
| std::unique_ptr<GooString> internalContent; |
| std::unique_ptr<GooString> defaultContent; |
| bool multiline; |
| bool password; |
| bool fileSelect; |
| bool doNotSpellCheck; |
| bool doNotScroll; |
| bool comb; |
| bool richText; |
| int maxLen; |
| }; |
| |
| //------------------------------------------------------------------------ |
| // FormFieldChoice |
| //------------------------------------------------------------------------ |
| |
| class FormFieldChoice : public FormField |
| { |
| public: |
| FormFieldChoice(PDFDoc *docA, Object &&aobj, const Ref ref, FormField *parent, std::set<int> *usedParents); |
| |
| ~FormFieldChoice() override; |
| |
| int getNumChoices() const { return numChoices; } |
| const GooString *getChoice(int i) const { return choices ? choices[i].optionName.get() : nullptr; } |
| const GooString *getExportVal(int i) const { return choices ? choices[i].exportVal.get() : nullptr; } |
| // For multi-select choices it returns the first one |
| const GooString *getSelectedChoice() const; |
| const GooString *getAppearanceSelectedChoice() const { return appearanceSelectedChoice ? appearanceSelectedChoice.get() : getSelectedChoice(); } |
| |
| void setAppearanceChoiceContentCopy(const GooString *new_content); |
| |
| // select the i-th choice |
| void select(int i); |
| |
| // toggle selection of the i-th choice |
| void toggle(int i); |
| |
| // deselect everything |
| void deselectAll(); |
| |
| // only work for editable combo box, set the user-entered text as the current choice |
| void setEditChoice(const GooString *new_content); |
| |
| const GooString *getEditChoice() const; |
| |
| bool isSelected(int i) const { return choices[i].selected; } |
| |
| int getNumSelected(); |
| |
| bool isCombo() const { return combo; } |
| bool hasEdit() const { return edit; } |
| bool isMultiSelect() const { return multiselect; } |
| bool noSpellCheck() const { return doNotSpellCheck; } |
| bool commitOnSelChange() const { return doCommitOnSelChange; } |
| bool isListBox() const { return !combo; } |
| |
| int getTopIndex() const { return topIdx; } |
| |
| void print(int indent) override; |
| void reset(const std::vector<std::string> &excludedFields) override; |
| |
| protected: |
| void unselectAll(); |
| void updateSelection(); |
| void fillChoices(FillValueType fillType); |
| |
| bool combo; |
| bool edit; |
| bool multiselect; |
| bool doNotSpellCheck; |
| bool doCommitOnSelChange; |
| |
| struct ChoiceOpt |
| { |
| std::unique_ptr<GooString> exportVal; // the export value ("internal" name) |
| std::unique_ptr<GooString> optionName; // displayed name |
| bool selected = false; // if this choice is selected |
| }; |
| |
| int numChoices; |
| ChoiceOpt *choices; |
| bool *defaultChoices; |
| std::unique_ptr<GooString> editedChoice; |
| std::unique_ptr<GooString> appearanceSelectedChoice; |
| int topIdx; // TI |
| }; |
| |
| //------------------------------------------------------------------------ |
| // FormFieldSignature |
| //------------------------------------------------------------------------ |
| |
| class POPPLER_PRIVATE_EXPORT FormFieldSignature : public FormField |
| { |
| public: |
| FormFieldSignature(PDFDoc *docA, Object &&dict, const Ref ref, FormField *parent, std::set<int> *usedParents); |
| |
| // Use -1 for now as validationTime |
| SignatureInfo *validateSignatureAsync(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck, bool enableAIA, const std::function<void()> &doneCallback); |
| |
| CertificateValidationStatus validateSignatureResult(); |
| |
| // returns a list with the boundaries of the signed ranges |
| // the elements of the list are of type Goffset |
| std::vector<Goffset> getSignedRangeBounds() const; |
| |
| // checks the length encoding of the signature and returns the hex encoded signature |
| // if the check passed (and the checked file size as output parameter in checkedFileSize) |
| // otherwise a nullptr is returned |
| std::optional<GooString> getCheckedSignature(Goffset *checkedFileSize); |
| |
| ~FormFieldSignature() override; |
| Object *getByteRange() { return &byte_range; } |
| const std::vector<unsigned char> &getSignature() const { return signature; } |
| void setSignature(std::vector<unsigned char> &&sig); |
| CryptoSign::SignatureType getSignatureType() const { return signature_type; } |
| void setSignatureType(CryptoSign::SignatureType t) { signature_type = t; } |
| |
| const GooString &getCustomAppearanceContent() const; |
| void setCustomAppearanceContent(const GooString &s); |
| |
| const GooString &getCustomAppearanceLeftContent() const; |
| void setCustomAppearanceLeftContent(const GooString &s); |
| |
| double getCustomAppearanceLeftFontSize() const; |
| void setCustomAppearanceLeftFontSize(double size); |
| |
| // Background image (ref to an object of type XObject). Invalid ref if not required. |
| Ref getImageResource() const; |
| void setImageResource(const Ref imageResourceA); |
| |
| void setCertificateInfo(std::unique_ptr<X509CertificateInfo> &); |
| |
| FormWidget *getCreateWidget(); |
| |
| private: |
| void parseInfo(); |
| void hashSignedDataBlock(CryptoSign::VerificationInterface *handler, Goffset block_len); |
| |
| CryptoSign::SignatureType signature_type; |
| Object byte_range; |
| std::vector<unsigned char> signature; |
| SignatureInfo *signature_info; |
| GooString customAppearanceContent; |
| GooString customAppearanceLeftContent; |
| double customAppearanceLeftFontSize = 20; |
| Ref imageResource = Ref::INVALID(); |
| std::unique_ptr<X509CertificateInfo> certificate_info; |
| std::unique_ptr<CryptoSign::VerificationInterface> signature_handler; |
| |
| void print(int indent) override; |
| }; |
| |
| //------------------------------------------------------------------------ |
| // Form |
| // This class handle the document-wide part of Form (things in the acroForm |
| // Catalog entry). |
| //------------------------------------------------------------------------ |
| |
| class POPPLER_PRIVATE_EXPORT Form |
| { |
| public: |
| explicit Form(PDFDoc *doc); |
| |
| ~Form(); |
| |
| Form(const Form &) = delete; |
| Form &operator=(const Form &) = delete; |
| |
| // Look up an inheritable field dictionary entry. |
| static Object fieldLookup(Dict *field, const char *key); |
| |
| /* Creates a new Field of the type specified in obj's dict. |
| used in Form::Form , FormField::FormField and |
| Page::loadStandaloneFields */ |
| static FormField *createFieldFromDict(Object &&obj, PDFDoc *docA, const Ref aref, FormField *parent, std::set<int> *usedParents); |
| |
| // Finds in the default resources dictionary a font named popplerfontXXX that |
| // has the given fontFamily and fontStyle. This makes us relatively sure that we added that font ourselves |
| std::string findFontInDefaultResources(const std::string &fontFamily, const std::string &fontStyle) const; |
| |
| // Finds in the default resources a font that is suitable to create a signature annotation. |
| // If none is found then it is added to the default resources. |
| std::string findPdfFontNameToUseForSigning(); |
| |
| struct AddFontResult |
| { |
| std::string fontName; |
| Ref ref; |
| }; |
| |
| // Finds in the system a font name matching the given fontFamily and fontStyle |
| // And adds it to the default resources dictionary, font name there will be popplerfontXXX except if forceName is true, |
| // in that case the font name will be fontFamily + " " + fontStyle (if fontStyle is empty just fontFamily) |
| AddFontResult addFontToDefaultResources(const std::string &fontFamily, const std::string &fontStyle, bool forceName = false); |
| |
| // Finds in the default resources dictionary a font named popplerfontXXX that |
| // emulates fontToEmulate and can draw the given char |
| std::string getFallbackFontForChar(Unicode uChar, const GfxFont &fontToEmulate) const; |
| |
| // Makes sure the default resources has fonts to draw all the given chars and as close as possible to the given pdfFontNameToEmulate |
| // If needed adds fonts to the default resources dictionary, font names will be popplerfontXXX |
| // If fieldResources is not nullptr, it is used instead of the to query the font to emulate instead of the default resources |
| // Returns a list of all the added fonts (if any) |
| std::vector<AddFontResult> ensureFontsForAllCharacters(const GooString *unicodeText, const std::string &pdfFontNameToEmulate, GfxResources *fieldResources = nullptr); |
| |
| bool getNeedAppearances() const { return needAppearances; } |
| int getNumFields() const { return numFields; } |
| FormField *getRootField(int i) const { return rootFields[i]; } |
| const GooString *getDefaultAppearance() const { return defaultAppearance.get(); } |
| VariableTextQuadding getTextQuadding() const { return quadding; } |
| GfxResources *getDefaultResources() const { return defaultResources; } |
| Object *getDefaultResourcesObj() { return &resDict; } |
| |
| FormWidget *findWidgetByRef(Ref aref); |
| FormField *findFieldByRef(Ref aref) const; |
| FormField *findFieldByFullyQualifiedName(const std::string &name) const; |
| FormField *findFieldByFullyQualifiedNameOrRef(const std::string &field) const; |
| |
| void postWidgetsLoad(); |
| |
| const std::vector<Ref> &getCalculateOrder() const { return calculateOrder; } |
| |
| void reset(const std::vector<std::string> &fields, bool excludeFields); |
| |
| private: |
| // Finds in the system a font name matching the given fontFamily and fontStyle |
| // And adds it to the default resources dictionary, font name there will be popplerfontXXX except if forceName is true, |
| // in that case the font name will be fontFamily + " " + fontStyle (if fontStyle is empty just fontFamily) |
| AddFontResult addFontToDefaultResources(const std::string &filepath, int faceIndex, const std::string &fontFamily, const std::string &fontStyle, bool forceName = false); |
| |
| AddFontResult doGetAddFontToDefaultResources(Unicode uChar, const GfxFont &fontToEmulate); |
| |
| FormField **rootFields; |
| int numFields; |
| int size; |
| PDFDoc *const doc; |
| bool needAppearances; |
| GfxResources *defaultResources; |
| Object resDict; |
| std::vector<Ref> calculateOrder; |
| |
| // Variable Text |
| std::unique_ptr<GooString> defaultAppearance; |
| VariableTextQuadding quadding; |
| }; |
| |
| //------------------------------------------------------------------------ |
| // FormPageWidgets |
| //------------------------------------------------------------------------ |
| |
| class POPPLER_PRIVATE_EXPORT FormPageWidgets |
| { |
| public: |
| FormPageWidgets(Annots *annots, unsigned int page, Form *form); |
| ~FormPageWidgets(); |
| |
| FormPageWidgets(const FormPageWidgets &) = delete; |
| FormPageWidgets &operator=(const FormPageWidgets &) = delete; |
| |
| int getNumWidgets() const { return numWidgets; } |
| FormWidget *getWidget(int i) const { return widgets[i]; } |
| void addWidgets(const std::vector<FormField *> &addedWidgets, unsigned int page); |
| |
| private: |
| FormWidget **widgets; |
| int numWidgets; |
| int size; |
| }; |
| |
| #endif |