1//========================================================================
2//
3// Form.h
4//
5// This file is licensed under the GPLv2 or later
6//
7// Copyright 2006 Julien Rebetez <julienr@svn.gnome.org>
8// Copyright 2007, 2008, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
9// Copyright 2007-2010, 2012, 2015-2023 Albert Astals Cid <aacid@kde.org>
10// Copyright 2010 Mark Riedesel <mark@klowner.com>
11// Copyright 2011 Pino Toscano <pino@kde.org>
12// Copyright 2012 Fabio D'Urso <fabiodurso@hotmail.it>
13// Copyright 2013 Adrian Johnson <ajohnson@redneon.com>
14// Copyright 2015 André Guerreiro <aguerreiro1985@gmail.com>
15// Copyright 2015 André Esser <bepandre@hotmail.com>
16// Copyright 2017 Roland Hieber <r.hieber@pengutronix.de>
17// Copyright 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
18// Copyright 2018 Andre Heinecke <aheinecke@intevation.de>
19// Copyright 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
20// Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@protonmail.com>
21// Copyright 2019, 2020 Oliver Sander <oliver.sander@tu-dresden.de>
22// Copyright 2019 João Netto <joaonetto901@gmail.com>
23// Copyright 2020, 2021 Nelson Benítez León <nbenitezl@gmail.com>
24// Copyright 2020 Marek Kasik <mkasik@redhat.com>
25// Copyright 2020 Thorsten Behrens <Thorsten.Behrens@CIB.de>
26// Copyright 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by Technische Universität Dresden
27// Copyright 2021 Georgiy Sgibnev <georgiy@sgibnev.com>. Work sponsored by lab50.net.
28// Copyright 2021 Theofilos Intzoglou <int.teo@gmail.com>
29// Copyright 2022 Alexander Sulfrian <asulfrian@zedat.fu-berlin.de>
30// Copyright 2023, 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
31//
32//========================================================================
33
34#ifndef FORM_H
35#define FORM_H
36
37#include "Annot.h"
38#include "CharTypes.h"
39#include "Object.h"
40#include "poppler_private_export.h"
41#include "SignatureInfo.h"
42
43#include <ctime>
44
45#include <optional>
46#include <set>
47#include <vector>
48#include <functional>
49
50class GooString;
51class Array;
52class Dict;
53class Annot;
54class AnnotWidget;
55class Annots;
56class LinkAction;
57class GfxResources;
58class PDFDoc;
59class X509CertificateInfo;
60namespace CryptoSign {
61class VerificationInterface;
62}
63
64enum FormFieldType
65{
66 formButton,
67 formText,
68 formChoice,
69 formSignature,
70 formUndef
71};
72
73enum FormButtonType
74{
75 formButtonCheck,
76 formButtonPush,
77 formButtonRadio
78};
79
80enum FormSignatureType
81{
82 adbe_pkcs7_sha1,
83 adbe_pkcs7_detached,
84 ETSI_CAdES_detached,
85 unknown_signature_type,
86 unsigned_signature_field
87};
88
89enum FillValueType
90{
91 fillValue,
92 fillDefaultValue
93};
94
95class Form;
96class FormField;
97class FormFieldButton;
98class FormFieldText;
99class FormFieldSignature;
100class FormFieldChoice;
101
102//------------------------------------------------------------------------
103// FormWidget
104// A FormWidget represents the graphical part of a field and is "attached"
105// to a page.
106//------------------------------------------------------------------------
107
108class POPPLER_PRIVATE_EXPORT FormWidget
109{
110public:
111 virtual ~FormWidget();
112
113 // Check if point is inside the field bounding rect
114 bool inRect(double x, double y) const;
115
116 // Get the field bounding rect
117 void getRect(double *x1, double *y1, double *x2, double *y2) const;
118
119 unsigned getID() { return ID; }
120 void setID(unsigned int i) { ID = i; }
121
122 FormField *getField() { return field; }
123 FormFieldType getType() { return type; }
124
125 Object *getObj() { return &obj; }
126 Ref getRef() { return ref; }
127
128 void setChildNum(unsigned i) { childNum = i; }
129 unsigned getChildNum() { return childNum; }
130
131 const GooString *getPartialName() const;
132 void setPartialName(const GooString &name);
133 const GooString *getAlternateUiName() const;
134 const GooString *getMappingName() const;
135 GooString *getFullyQualifiedName();
136
137 bool isModified() const;
138
139 bool isReadOnly() const;
140 void setReadOnly(bool value);
141
142 LinkAction *getActivationAction(); // The caller should not delete the result
143 std::unique_ptr<LinkAction> getAdditionalAction(Annot::FormAdditionalActionsType type);
144 bool setAdditionalAction(Annot::FormAdditionalActionsType t, const std::string &js);
145
146 // return the unique ID corresponding to pageNum/fieldNum
147 static int encodeID(unsigned pageNum, unsigned fieldNum);
148 // decode id and retrieve pageNum and fieldNum
149 static void decodeID(unsigned id, unsigned *pageNum, unsigned *fieldNum);
150
151 void createWidgetAnnotation();
152 AnnotWidget *getWidgetAnnotation() const { return widget; }
153 void setWidgetAnnotation(AnnotWidget *_widget) { widget = _widget; }
154
155 virtual void updateWidgetAppearance() = 0;
156
157 void print(int indent = 0);
158
159protected:
160 FormWidget(PDFDoc *docA, Object *aobj, unsigned num, Ref aref, FormField *fieldA);
161
162 AnnotWidget *widget;
163 FormField *field;
164 FormFieldType type;
165 Object obj;
166 Ref ref;
167 PDFDoc *doc;
168 XRef *xref;
169
170 // index of this field in the parent's child list
171 unsigned childNum;
172
173 /*
174 Field ID is an (unsigned) integer, calculated as follow :
175 the first sizeof/2 bits are the field number, relative to the page
176 the last sizeof/2 bits are the page number
177 [page number | field number]
178 (encoding) id = (pageNum << 4*sizeof(unsigned)) + fieldNum;
179 (decoding) pageNum = id >> 4*sizeof(unsigned); fieldNum = (id << 4*sizeof(unsigned)) >> 4*sizeof(unsigned);
180 */
181 unsigned ID;
182};
183
184//------------------------------------------------------------------------
185// FormWidgetButton
186//------------------------------------------------------------------------
187
188class POPPLER_PRIVATE_EXPORT FormWidgetButton : public FormWidget
189{
190public:
191 FormWidgetButton(PDFDoc *docA, Object *dictObj, unsigned num, Ref ref, FormField *p);
192 ~FormWidgetButton() override;
193
194 FormButtonType getButtonType() const;
195
196 void setState(bool state);
197 bool getState() const;
198
199 const char *getOnStr() const;
200 void setAppearanceState(const char *state);
201 void updateWidgetAppearance() override;
202
203protected:
204 FormFieldButton *parent() const;
205 GooString *onStr;
206};
207
208//------------------------------------------------------------------------
209// FormWidgetText
210//------------------------------------------------------------------------
211
212class POPPLER_PRIVATE_EXPORT FormWidgetText : public FormWidget
213{
214public:
215 FormWidgetText(PDFDoc *docA, Object *dictObj, unsigned num, Ref ref, FormField *p);
216 // return the field's content (UTF16BE)
217 const GooString *getContent() const;
218
219 // expects a UTF16BE string
220 void setContent(const GooString *new_content);
221 // sets the text inside the field appearance stream
222 void setAppearanceContent(const GooString *new_content);
223
224 void updateWidgetAppearance() override;
225
226 bool isMultiline() const;
227 bool isPassword() const;
228 bool isFileSelect() const;
229 bool noSpellCheck() const;
230 bool noScroll() const;
231 bool isComb() const;
232 bool isRichText() const;
233 int getMaxLen() const;
234 // return the font size of the field's text
235 double getTextFontSize();
236 // set the font size of the field's text (currently only integer values)
237 void setTextFontSize(int fontSize);
238
239protected:
240 FormFieldText *parent() const;
241};
242
243//------------------------------------------------------------------------
244// FormWidgetChoice
245//------------------------------------------------------------------------
246
247class POPPLER_PRIVATE_EXPORT FormWidgetChoice : public FormWidget
248{
249public:
250 FormWidgetChoice(PDFDoc *docA, Object *dictObj, unsigned num, Ref ref, FormField *p);
251 ~FormWidgetChoice() override;
252
253 int getNumChoices() const;
254 // return the display name of the i-th choice (UTF16BE)
255 const GooString *getChoice(int i) const;
256 const GooString *getExportVal(int i) const;
257 // select the i-th choice
258 void select(int i);
259
260 // toggle selection of the i-th choice
261 void toggle(int i);
262
263 // deselect everything
264 void deselectAll();
265
266 // except a UTF16BE string
267 // only work for editable combo box, set the user-entered text as the current choice
268 void setEditChoice(const GooString *new_content);
269
270 const GooString *getEditChoice() const;
271
272 void updateWidgetAppearance() override;
273 bool isSelected(int i) const;
274
275 bool isCombo() const;
276 bool hasEdit() const;
277 bool isMultiSelect() const;
278 bool noSpellCheck() const;
279 bool commitOnSelChange() const;
280 bool isListBox() const;
281
282protected:
283 bool _checkRange(int i) const;
284 FormFieldChoice *parent() const;
285};
286
287//------------------------------------------------------------------------
288// FormWidgetSignature
289//------------------------------------------------------------------------
290
291class POPPLER_PRIVATE_EXPORT FormWidgetSignature : public FormWidget
292{
293public:
294 FormWidgetSignature(PDFDoc *docA, Object *dictObj, unsigned num, Ref ref, FormField *p);
295 void updateWidgetAppearance() override;
296
297 FormSignatureType signatureType() const;
298 void setSignatureType(FormSignatureType fst);
299
300 // Use -1 for now as validationTime
301 // ocspRevocation and aiafetch might happen async in the Background
302 // doneCallback will be invoked once there is a result
303 // Note: Validation callback will likely happen from an auxillary
304 // thread and it is the caller of this method who is responsible
305 // for moving back to the main thread
306 // For synchronous code, don't provide validation callback
307 // and just call validateSignatureResult afterwards
308 // The returned SignatureInfo from this method does
309 // not have validated the certificate.
310 SignatureInfo *validateSignatureAsync(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck, bool enableAIA, const std::function<void()> &doneCallback);
311
312 /// Waits, if needed, on validation callback and
313 /// returns a signatureinfo with validated certificates
314 CertificateValidationStatus validateSignatureResult();
315
316 // returns a list with the boundaries of the signed ranges
317 // the elements of the list are of type Goffset
318 std::vector<Goffset> getSignedRangeBounds() const;
319
320 // Creates or replaces the dictionary name "V" in the signature dictionary and
321 // fills it with the fields of the signature; the field "Contents" is the signature
322 // in PKCS#7 format, which is calculated over the byte range encompassing the whole
323 // document except for the signature itself; this byte range is specified in the
324 // field "ByteRange" in the dictionary "V".
325 // Arguments reason and location are UTF-16 big endian strings with BOM. An empty string and nullptr are acceptable too.
326 // Returns success.
327 bool 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 = {},
328 const std::optional<GooString> &userPassword = {});
329
330 // Same as above but adds text, font color, etc.
331 bool signDocumentWithAppearance(const std::string &filename, const std::string &certNickname, const std::string &password, const GooString *reason = nullptr, const GooString *location = nullptr,
332 const std::optional<GooString> &ownerPassword = {}, const std::optional<GooString> &userPassword = {}, const GooString &signatureText = {}, const GooString &signatureTextLeft = {}, double fontSize = {},
333 double leftFontSize = {}, std::unique_ptr<AnnotColor> &&fontColor = {}, double borderWidth = {}, std::unique_ptr<AnnotColor> &&borderColor = {}, std::unique_ptr<AnnotColor> &&backgroundColor = {});
334
335 // checks the length encoding of the signature and returns the hex encoded signature
336 // if the check passed (and the checked file size as output parameter in checkedFileSize)
337 // otherwise a nullptr is returned
338 std::optional<GooString> getCheckedSignature(Goffset *checkedFileSize);
339
340 const GooString *getSignature() const;
341
342private:
343 bool createSignature(Object &vObj, Ref vRef, const GooString &name, int placeholderLength, const GooString *reason = nullptr, const GooString *location = nullptr);
344 bool getObjectStartEnd(const GooString &filename, int objNum, Goffset *objStart, Goffset *objEnd, const std::optional<GooString> &ownerPassword, const std::optional<GooString> &userPassword);
345 bool updateOffsets(FILE *f, Goffset objStart, Goffset objEnd, Goffset *sigStart, Goffset *sigEnd, Goffset *fileSize);
346
347 bool updateSignature(FILE *f, Goffset sigStart, Goffset sigEnd, const GooString &signature);
348};
349
350//------------------------------------------------------------------------
351// FormField
352// A FormField implements the logical side of a field and is "attached" to
353// the Catalog. This is an internal class and client applications should
354// only interact with FormWidgets.
355//------------------------------------------------------------------------
356
357class POPPLER_PRIVATE_EXPORT FormField
358{
359public:
360 FormField(PDFDoc *docA, Object &&aobj, const Ref aref, FormField *parent, std::set<int> *usedParents, FormFieldType t = formUndef);
361
362 virtual ~FormField();
363
364 // Accessors.
365 FormFieldType getType() const { return type; }
366 Object *getObj() { return &obj; }
367 Ref getRef() { return ref; }
368
369 void setReadOnly(bool value);
370 bool isReadOnly() const { return readOnly; }
371 void setStandAlone(bool value) { standAlone = value; }
372 bool isStandAlone() const { return standAlone; }
373
374 GooString *getDefaultAppearance() const { return defaultAppearance; }
375 void setDefaultAppearance(const std::string &appearance);
376
377 bool hasTextQuadding() const { return hasQuadding; }
378 VariableTextQuadding getTextQuadding() const { return quadding; }
379
380 const GooString *getPartialName() const { return partialName; }
381 void setPartialName(const GooString &name);
382 const GooString *getAlternateUiName() const { return alternateUiName; }
383 const GooString *getMappingName() const { return mappingName; }
384 GooString *getFullyQualifiedName();
385
386 FormWidget *findWidgetByRef(Ref aref);
387 int getNumWidgets() const { return terminal ? numChildren : 0; }
388 FormWidget *getWidget(int i) const { return terminal ? widgets[i] : nullptr; }
389 int getNumChildren() const { return !terminal ? numChildren : 0; }
390 FormField *getChildren(int i) const { return children[i]; }
391
392 // only implemented in FormFieldButton
393 virtual void fillChildrenSiblingsID();
394
395 void createWidgetAnnotations();
396
397 void printTree(int indent = 0);
398 virtual void print(int indent = 0);
399 virtual void reset(const std::vector<std::string> &excludedFields);
400 void resetChildren(const std::vector<std::string> &excludedFields);
401 FormField *findFieldByRef(Ref aref);
402 FormField *findFieldByFullyQualifiedName(const std::string &name);
403
404protected:
405 void _createWidget(Object *obj, Ref aref);
406 void createChildren(std::set<int> *usedParents);
407 void updateChildrenAppearance();
408 bool isAmongExcludedFields(const std::vector<std::string> &excludedFields);
409
410 FormFieldType type; // field type
411 Ref ref;
412 bool terminal;
413 Object obj;
414 PDFDoc *doc;
415 XRef *xref;
416 FormField **children;
417 FormField *parent;
418 int numChildren;
419 FormWidget **widgets;
420 bool readOnly;
421
422 GooString *partialName; // T field
423 GooString *alternateUiName; // TU field
424 GooString *mappingName; // TM field
425 GooString *fullyQualifiedName;
426
427 // Variable Text
428 GooString *defaultAppearance;
429 bool hasQuadding;
430 VariableTextQuadding quadding;
431
432 // True when FormField is not part of Catalog's Field array (or there isn't one).
433 bool standAlone;
434
435private:
436 FormField() { }
437};
438
439//------------------------------------------------------------------------
440// FormFieldButton
441//------------------------------------------------------------------------
442
443class FormFieldButton : public FormField
444{
445public:
446 FormFieldButton(PDFDoc *docA, Object &&dict, const Ref ref, FormField *parent, std::set<int> *usedParents);
447
448 FormButtonType getButtonType() const { return btype; }
449
450 bool noToggleToOff() const { return noAllOff; }
451
452 // returns true if the state modification is accepted
453 bool setState(const char *state, bool ignoreToggleOff = false);
454 bool getState(const char *state) const;
455
456 const char *getAppearanceState() const { return appearanceState.isName() ? appearanceState.getName() : nullptr; }
457 const char *getDefaultAppearanceState() const { return defaultAppearanceState.isName() ? defaultAppearanceState.getName() : nullptr; }
458
459 void fillChildrenSiblingsID() override;
460
461 void setNumSiblings(int num);
462 void setSibling(int i, FormFieldButton *id) { siblings[i] = id; }
463
464 // For radio buttons, return the fields of the other radio buttons in the same group
465 FormFieldButton *getSibling(int i) const { return siblings[i]; }
466 int getNumSiblings() const { return numSiblings; }
467
468 void print(int indent) override;
469 void reset(const std::vector<std::string> &excludedFields) override;
470
471 ~FormFieldButton() override;
472
473protected:
474 void updateState(const char *state);
475
476 FormFieldButton **siblings; // IDs of dependent buttons (each button of a radio field has all the others buttons
477 // of the same field in this array)
478 int numSiblings;
479
480 FormButtonType btype;
481 int size;
482 int active_child; // only used for combo box
483 bool noAllOff;
484 Object appearanceState; // V
485 Object defaultAppearanceState; // DV
486};
487
488//------------------------------------------------------------------------
489// FormFieldText
490//------------------------------------------------------------------------
491
492class FormFieldText : public FormField
493{
494public:
495 FormFieldText(PDFDoc *docA, Object &&dictObj, const Ref ref, FormField *parent, std::set<int> *usedParents);
496
497 const GooString *getContent() const { return content; }
498 const GooString *getAppearanceContent() const { return internalContent ? internalContent : content; }
499 void setContentCopy(const GooString *new_content);
500 void setAppearanceContentCopy(const GooString *new_content);
501 ~FormFieldText() override;
502
503 bool isMultiline() const { return multiline; }
504 bool isPassword() const { return password; }
505 bool isFileSelect() const { return fileSelect; }
506 bool noSpellCheck() const { return doNotSpellCheck; }
507 bool noScroll() const { return doNotScroll; }
508 bool isComb() const { return comb; }
509 bool isRichText() const { return richText; }
510
511 int getMaxLen() const { return maxLen; }
512
513 // return the font size of the field's text
514 double getTextFontSize();
515 // set the font size of the field's text (currently only integer values)
516 void setTextFontSize(int fontSize);
517
518 void print(int indent) override;
519 void reset(const std::vector<std::string> &excludedFields) override;
520
521 static int tokenizeDA(const std::string &daString, std::vector<std::string> *daToks, const char *searchTok);
522
523protected:
524 int parseDA(std::vector<std::string> *daToks);
525 void fillContent(FillValueType fillType);
526
527 GooString *content;
528 GooString *internalContent;
529 GooString *defaultContent;
530 bool multiline;
531 bool password;
532 bool fileSelect;
533 bool doNotSpellCheck;
534 bool doNotScroll;
535 bool comb;
536 bool richText;
537 int maxLen;
538};
539
540//------------------------------------------------------------------------
541// FormFieldChoice
542//------------------------------------------------------------------------
543
544class FormFieldChoice : public FormField
545{
546public:
547 FormFieldChoice(PDFDoc *docA, Object &&aobj, const Ref ref, FormField *parent, std::set<int> *usedParents);
548
549 ~FormFieldChoice() override;
550
551 int getNumChoices() const { return numChoices; }
552 const GooString *getChoice(int i) const { return choices ? choices[i].optionName : nullptr; }
553 const GooString *getExportVal(int i) const { return choices ? choices[i].exportVal : nullptr; }
554 // For multi-select choices it returns the first one
555 const GooString *getSelectedChoice() const;
556
557 // select the i-th choice
558 void select(int i);
559
560 // toggle selection of the i-th choice
561 void toggle(int i);
562
563 // deselect everything
564 void deselectAll();
565
566 // only work for editable combo box, set the user-entered text as the current choice
567 void setEditChoice(const GooString *new_content);
568
569 const GooString *getEditChoice() const;
570
571 bool isSelected(int i) const { return choices[i].selected; }
572
573 int getNumSelected();
574
575 bool isCombo() const { return combo; }
576 bool hasEdit() const { return edit; }
577 bool isMultiSelect() const { return multiselect; }
578 bool noSpellCheck() const { return doNotSpellCheck; }
579 bool commitOnSelChange() const { return doCommitOnSelChange; }
580 bool isListBox() const { return !combo; }
581
582 int getTopIndex() const { return topIdx; }
583
584 void print(int indent) override;
585 void reset(const std::vector<std::string> &excludedFields) override;
586
587protected:
588 void unselectAll();
589 void updateSelection();
590 void fillChoices(FillValueType fillType);
591
592 bool combo;
593 bool edit;
594 bool multiselect;
595 bool doNotSpellCheck;
596 bool doCommitOnSelChange;
597
598 struct ChoiceOpt
599 {
600 GooString *exportVal; // the export value ("internal" name)
601 GooString *optionName; // displayed name
602 bool selected; // if this choice is selected
603 };
604
605 int numChoices;
606 ChoiceOpt *choices;
607 bool *defaultChoices;
608 GooString *editedChoice;
609 int topIdx; // TI
610};
611
612//------------------------------------------------------------------------
613// FormFieldSignature
614//------------------------------------------------------------------------
615
616class POPPLER_PRIVATE_EXPORT FormFieldSignature : public FormField
617{
618public:
619 FormFieldSignature(PDFDoc *docA, Object &&dict, const Ref ref, FormField *parent, std::set<int> *usedParents);
620
621 // Use -1 for now as validationTime
622 SignatureInfo *validateSignatureAsync(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck, bool enableAIA, const std::function<void()> &doneCallback);
623
624 CertificateValidationStatus validateSignatureResult();
625
626 // returns a list with the boundaries of the signed ranges
627 // the elements of the list are of type Goffset
628 std::vector<Goffset> getSignedRangeBounds() const;
629
630 // checks the length encoding of the signature and returns the hex encoded signature
631 // if the check passed (and the checked file size as output parameter in checkedFileSize)
632 // otherwise a nullptr is returned
633 std::optional<GooString> getCheckedSignature(Goffset *checkedFileSize);
634
635 ~FormFieldSignature() override;
636 Object *getByteRange() { return &byte_range; }
637 const GooString *getSignature() const { return signature; }
638 void setSignature(const GooString &sig);
639 FormSignatureType getSignatureType() const { return signature_type; }
640 void setSignatureType(FormSignatureType t) { signature_type = t; }
641
642 const GooString &getCustomAppearanceContent() const;
643 void setCustomAppearanceContent(const GooString &s);
644
645 const GooString &getCustomAppearanceLeftContent() const;
646 void setCustomAppearanceLeftContent(const GooString &s);
647
648 double getCustomAppearanceLeftFontSize() const;
649 void setCustomAppearanceLeftFontSize(double size);
650
651 // Background image (ref to an object of type XObject). Invalid ref if not required.
652 Ref getImageResource() const;
653 void setImageResource(const Ref imageResourceA);
654
655 void setCertificateInfo(std::unique_ptr<X509CertificateInfo> &);
656
657 FormWidget *getCreateWidget();
658
659private:
660 void parseInfo();
661 void hashSignedDataBlock(CryptoSign::VerificationInterface *handler, Goffset block_len);
662
663 FormSignatureType signature_type;
664 Object byte_range;
665 GooString *signature;
666 SignatureInfo *signature_info;
667 GooString customAppearanceContent;
668 GooString customAppearanceLeftContent;
669 double customAppearanceLeftFontSize = 20;
670 Ref imageResource = Ref::INVALID();
671 std::unique_ptr<X509CertificateInfo> certificate_info;
672 std::unique_ptr<CryptoSign::VerificationInterface> signature_handler;
673
674 void print(int indent) override;
675};
676
677//------------------------------------------------------------------------
678// Form
679// This class handle the document-wide part of Form (things in the acroForm
680// Catalog entry).
681//------------------------------------------------------------------------
682
683class POPPLER_PRIVATE_EXPORT Form
684{
685public:
686 explicit Form(PDFDoc *doc);
687
688 ~Form();
689
690 Form(const Form &) = delete;
691 Form &operator=(const Form &) = delete;
692
693 // Look up an inheritable field dictionary entry.
694 static Object fieldLookup(Dict *field, const char *key);
695
696 /* Creates a new Field of the type specified in obj's dict.
697 used in Form::Form , FormField::FormField and
698 Page::loadStandaloneFields */
699 static FormField *createFieldFromDict(Object &&obj, PDFDoc *docA, const Ref aref, FormField *parent, std::set<int> *usedParents);
700
701 // Finds in the default resources dictionary a font named popplerfontXXX that
702 // has the given fontFamily and fontStyle. This makes us relatively sure that we added that font ourselves
703 std::string findFontInDefaultResources(const std::string &fontFamily, const std::string &fontStyle) const;
704
705 // Finds in the default resources a font that is suitable to create a signature annotation.
706 // If none is found then it is added to the default resources.
707 std::string findPdfFontNameToUseForSigning();
708
709 struct AddFontResult
710 {
711 std::string fontName;
712 Ref ref;
713 };
714
715 // Finds in the system a font name matching the given fontFamily and fontStyle
716 // And adds it to the default resources dictionary, font name there will be popplerfontXXX except if forceName is true,
717 // in that case the font name will be fontFamily + " " + fontStyle (if fontStyle is empty just fontFamily)
718 AddFontResult addFontToDefaultResources(const std::string &fontFamily, const std::string &fontStyle, bool forceName = false);
719
720 // Finds in the default resources dictionary a font named popplerfontXXX that
721 // emulates fontToEmulate and can draw the given char
722 std::string getFallbackFontForChar(Unicode uChar, const GfxFont &fontToEmulate) const;
723
724 // Makes sure the default resources has fonts to draw all the given chars and as close as possible to the given pdfFontNameToEmulate
725 // If needed adds fonts to the default resources dictionary, font names will be popplerfontXXX
726 // If fieldResources is not nullptr, it is used instead of the to query the font to emulate instead of the default resources
727 // Returns a list of all the added fonts (if any)
728 std::vector<AddFontResult> ensureFontsForAllCharacters(const GooString *unicodeText, const std::string &pdfFontNameToEmulate, GfxResources *fieldResources = nullptr);
729
730 bool getNeedAppearances() const { return needAppearances; }
731 int getNumFields() const { return numFields; }
732 FormField *getRootField(int i) const { return rootFields[i]; }
733 const GooString *getDefaultAppearance() const { return defaultAppearance; }
734 VariableTextQuadding getTextQuadding() const { return quadding; }
735 GfxResources *getDefaultResources() const { return defaultResources; }
736 Object *getDefaultResourcesObj() { return &resDict; }
737
738 FormWidget *findWidgetByRef(Ref aref);
739 FormField *findFieldByRef(Ref aref) const;
740 FormField *findFieldByFullyQualifiedName(const std::string &name) const;
741
742 void postWidgetsLoad();
743
744 const std::vector<Ref> &getCalculateOrder() const { return calculateOrder; }
745
746 void reset(const std::vector<std::string> &fields, bool excludeFields);
747
748private:
749 // Finds in the system a font name matching the given fontFamily and fontStyle
750 // And adds it to the default resources dictionary, font name there will be popplerfontXXX except if forceName is true,
751 // in that case the font name will be fontFamily + " " + fontStyle (if fontStyle is empty just fontFamily)
752 AddFontResult addFontToDefaultResources(const std::string &filepath, int faceIndex, const std::string &fontFamily, const std::string &fontStyle, bool forceName = false);
753
754 AddFontResult doGetAddFontToDefaultResources(Unicode uChar, const GfxFont &fontToEmulate);
755
756 FormField **rootFields;
757 int numFields;
758 int size;
759 PDFDoc *const doc;
760 bool needAppearances;
761 GfxResources *defaultResources;
762 Object resDict;
763 std::vector<Ref> calculateOrder;
764
765 // Variable Text
766 GooString *defaultAppearance;
767 VariableTextQuadding quadding;
768};
769
770//------------------------------------------------------------------------
771// FormPageWidgets
772//------------------------------------------------------------------------
773
774class POPPLER_PRIVATE_EXPORT FormPageWidgets
775{
776public:
777 FormPageWidgets(Annots *annots, unsigned int page, Form *form);
778 ~FormPageWidgets();
779
780 FormPageWidgets(const FormPageWidgets &) = delete;
781 FormPageWidgets &operator=(const FormPageWidgets &) = delete;
782
783 int getNumWidgets() const { return numWidgets; }
784 FormWidget *getWidget(int i) const { return widgets[i]; }
785 void addWidgets(const std::vector<FormField *> &addedWidgets, unsigned int page);
786
787private:
788 FormWidget **widgets;
789 int numWidgets;
790 int size;
791};
792
793#endif
794

source code of poppler/poppler/Form.h