Commit d35c34d89c06ff3d00a3678660bf4586f6ff1b4a

Authored by m-holger
1 parent 8d36ca4d

Refactor `AcroForm` to replace pointer-based method arguments with references fo…

…r improved clarity and safety. Update related methods and references accordingly.
include/qpdf/QPDFAcroFormDocumentHelper.hh
... ... @@ -225,6 +225,7 @@ class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper
225 225 std::set<QPDFObjGen>* new_fields = nullptr);
226 226  
227 227 private:
  228 + friend class QPDF::Doc;
228 229 class Members;
229 230  
230 231 std::shared_ptr<Members> m;
... ...
libqpdf/QPDF.cc
... ... @@ -11,6 +11,7 @@
11 11 #include <sstream>
12 12 #include <vector>
13 13  
  14 +#include <qpdf/AcroForm.hh>
14 15 #include <qpdf/FileInputSource.hh>
15 16 #include <qpdf/InputSource_private.hh>
16 17 #include <qpdf/OffsetInputSource.hh>
... ... @@ -147,6 +148,21 @@ QPDF::QPDF() :
147 148 m->unique_id = unique_id.fetch_add(1ULL);
148 149 }
149 150  
  151 +/// @brief Initializes the AcroForm functionality for the document.
  152 +/// @par
  153 +/// This method creates a unique instance of QPDFAcroFormDocumentHelper and associates it
  154 +/// with the document. It also updates the `acroform_` pointer to reference the AcroForm
  155 +/// instance managed by the helper.
  156 +///
  157 +/// The method has been separated out from `acroform` to avoid it being inlined
  158 +/// unnecessarily.
  159 +void
  160 +QPDF::Doc::init_acroform()
  161 +{
  162 + acroform_dh_ = std::make_unique<QPDFAcroFormDocumentHelper>(qpdf);
  163 + acroform_ = acroform_dh_->m.get();
  164 +}
  165 +
150 166 // Provide access to disconnect(). Disconnect will in due course be merged into the current ObjCache
151 167 // (future Objects::Entry) to centralize all QPDF access to QPDFObject.
152 168 class Disconnect: BaseHandle
... ...
libqpdf/QPDFAcroFormDocumentHelper.cc
... ... @@ -18,14 +18,7 @@ using namespace qpdf;
18 18 using namespace qpdf::impl;
19 19 using namespace std::literals;
20 20  
21   -class QPDFAcroFormDocumentHelper::Members: public AcroForm
22   -{
23   - public:
24   - Members(QPDF& qpdf) :
25   - AcroForm(qpdf.doc())
26   - {
27   - }
28   -};
  21 +using AcroForm = impl::AcroForm;
29 22  
30 23 QPDFAcroFormDocumentHelper::QPDFAcroFormDocumentHelper(QPDF& qpdf) :
31 24 QPDFDocumentHelper(qpdf),
... ... @@ -36,7 +29,7 @@ QPDFAcroFormDocumentHelper::QPDFAcroFormDocumentHelper(QPDF&amp; qpdf) :
36 29 QPDFAcroFormDocumentHelper&
37 30 QPDFAcroFormDocumentHelper::get(QPDF& qpdf)
38 31 {
39   - return qpdf.doc().acroform();
  32 + return qpdf.doc().acroform_dh();
40 33 }
41 34  
42 35 void
... ...
libqpdf/QPDFJob.cc
... ... @@ -4,6 +4,7 @@
4 4 #include <iostream>
5 5 #include <memory>
6 6  
  7 +#include <qpdf/AcroForm.hh>
7 8 #include <qpdf/ClosedFileInputSource.hh>
8 9 #include <qpdf/FileInputSource.hh>
9 10 #include <qpdf/Pipeline_private.hh>
... ... @@ -1866,7 +1867,7 @@ QPDFJob::doUnderOverlayForPage(
1866 1867 if (!(uo.pdf && pagenos[pageno.idx].contains(uo_idx))) {
1867 1868 return "";
1868 1869 }
1869   - auto& dest_afdh = dest_page.qpdf()->doc().acroform();
  1870 + auto& dest_afdh = dest_page.qpdf()->doc().acroform_dh();
1870 1871  
1871 1872 auto const& pages = uo.pdf->doc().pages().all();
1872 1873 std::string content;
... ... @@ -1887,7 +1888,8 @@ QPDFJob::doUnderOverlayForPage(
1887 1888 QPDFMatrix cm;
1888 1889 std::string new_content = dest_page.placeFormXObject(
1889 1890 fo[from_no.no][uo_idx], name, dest_page.getTrimBox().getArrayAsRectangle(), cm);
1890   - dest_page.copyAnnotations(from_page, cm, &dest_afdh, &from_page.qpdf()->doc().acroform());
  1891 + dest_page.copyAnnotations(
  1892 + from_page, cm, &dest_afdh, &from_page.qpdf()->doc().acroform_dh());
1891 1893 if (!new_content.empty()) {
1892 1894 resources.mergeResources(Dictionary({{"/XObject", Dictionary::empty()}}));
1893 1895 auto xobject = resources.getKey("/XObject");
... ... @@ -2107,7 +2109,7 @@ QPDFJob::handleTransformations(QPDF&amp; pdf)
2107 2109 QPDFAcroFormDocumentHelper* afdh_ptr = nullptr;
2108 2110 auto afdh = [&]() -> QPDFAcroFormDocumentHelper& {
2109 2111 if (!afdh_ptr) {
2110   - afdh_ptr = &pdf.doc().acroform();
  2112 + afdh_ptr = &pdf.doc().acroform_dh();
2111 2113 }
2112 2114 return *afdh_ptr;
2113 2115 };
... ... @@ -2978,8 +2980,7 @@ QPDFJob::doSplitPages(QPDF&amp; pdf)
2978 2980 QPDF outpdf;
2979 2981 outpdf.doc().config(m->d_cfg);
2980 2982 outpdf.emptyPDF();
2981   - QPDFAcroFormDocumentHelper* out_afdh =
2982   - afdh.hasAcroForm() ? &outpdf.doc().acroform() : nullptr;
  2983 + impl::AcroForm* out_afdh = afdh.hasAcroForm() ? &outpdf.doc().acroform() : nullptr;
2983 2984 for (size_t pageno = first; pageno <= last; ++pageno) {
2984 2985 QPDFObjectHandle page = pages.at(pageno - 1);
2985 2986 outpdf.addPage(page, false);
... ...
libqpdf/QPDF_pages.cc
1 1 #include <qpdf/QPDFPageDocumentHelper.hh>
2 2 #include <qpdf/QPDF_private.hh>
3 3  
4   -#include <qpdf/QPDFAcroFormDocumentHelper.hh>
  4 +#include <qpdf/AcroForm.hh>
5 5 #include <qpdf/QPDFExc.hh>
6 6 #include <qpdf/QPDFObjectHandle_private.hh>
7 7 #include <qpdf/QTC.hh>
... ... @@ -660,7 +660,7 @@ void
660 660 Pages::flatten_annotations_for_page(
661 661 QPDFPageObjectHelper& page,
662 662 QPDFObjectHandle& resources,
663   - QPDFAcroFormDocumentHelper& afdh,
  663 + impl::AcroForm& afdh,
664 664 int required_flags,
665 665 int forbidden_flags)
666 666 {
... ...
libqpdf/qpdf/AcroForm.hh
... ... @@ -546,7 +546,7 @@ namespace qpdf::impl
546 546 /// @param inherit If set to `true`, the function will attempt to retrieve `/V` by
547 547 /// inheritance from the parent hierarchy of the form field. Defaults to `true`.
548 548 /// @return Returns the field's value if found; otherwise, returns a default-constructed
549   - /// object handle.
  549 + /// object handle.
550 550 QPDFObjectHandle const&
551 551 V(bool inherit = true) const
552 552 {
... ... @@ -557,7 +557,7 @@ namespace qpdf::impl
557 557 }
558 558  
559 559 /// @brief Retrieves the field value `/V` attribute of the form field, considering
560   - /// inheritance, if the value is a String.
  560 + /// inheritance, if the value is a String.
561 561 ///
562 562 /// This function extracts the value of the form field, accounting for potential inheritance
563 563 /// through the form hierarchy. It returns the value if it is a String, and an empty string
... ... @@ -567,7 +567,7 @@ namespace qpdf::impl
567 567 /// an empty string if the value is not present or not a String.
568 568 std::string value() const;
569 569  
570   - /// @brief Retrieves the field default value (`/DV` attribute) of a specified field,
  570 + /// @brief Retrieves the field default value (`/DV` attribute) of a specified field,
571 571 /// accounting for inheritance through the hierarchy of ancestor nodes in the form
572 572 /// field tree.
573 573 ///
... ... @@ -592,14 +592,14 @@ namespace qpdf::impl
592 592 }
593 593  
594 594 /// @brief Retrieves the default value `/DV` attribute of the form field, considering
595   - /// inheritance, if the default value is a String.
  595 + /// inheritance, if the default value is a String.
596 596 ///
597 597 /// This function extracts the default value of the form field, accounting for potential
598 598 /// inheritance through the form hierarchy. It returns the value if it is a String, and an
599 599 /// empty string otherwise.
600 600 ///
601   - /// @return A string containing the actual or inherited `/V` attribute of the form field, or
602   - /// an empty string if the value is not present or not a String.
  601 + /// @return A string containing the actual or inherited `/DV` attribute of the form field,
  602 + /// or an empty string if the value is not present or not a String.
603 603 std::string default_value() const;
604 604  
605 605 /// @brief Returns the default appearance string for the form field, considering inheritance
... ... @@ -711,4 +711,13 @@ namespace qpdf::impl
711 711 }; // class FormNode
712 712 } // namespace qpdf::impl
713 713  
  714 +class QPDFAcroFormDocumentHelper::Members: public qpdf::impl::AcroForm
  715 +{
  716 + public:
  717 + Members(QPDF& qpdf) :
  718 + AcroForm(qpdf.doc())
  719 + {
  720 + }
  721 +};
  722 +
714 723 #endif // ACRO_FORM_HH
... ...
libqpdf/qpdf/QPDF_private.hh
... ... @@ -28,8 +28,9 @@ namespace qpdf
28 28  
29 29 namespace impl
30 30 {
  31 + class AcroForm;
31 32 using Doc = QPDF::Doc;
32   - }
  33 + } // namespace impl
33 34  
34 35 class Doc: public QPDF
35 36 {
... ... @@ -374,11 +375,33 @@ class QPDF::Doc
374 375 bool reconstructed_xref() const;
375 376  
376 377 QPDFAcroFormDocumentHelper&
  378 + acroform_dh()
  379 + {
  380 + if (!acroform_) {
  381 + no_inspection();
  382 + init_acroform();
  383 + }
  384 + return *acroform_dh_;
  385 + }
  386 +
  387 + /// @brief Retrieves the shared impl::AcroForm instance associated with the document.
  388 + ///
  389 + /// @note The AcroForm class caches the form field structure for efficiency. If any part
  390 + /// of the form field structure is modified directly the `validate` method MUST be
  391 + /// called before calling any other AcroForm methods in order to refresh the cache.
  392 + ///
  393 + /// If the AcroForm instance has not already been initialized, the `init_acroform()`
  394 + /// function is called to initialize it.
  395 + ///
  396 + /// @return A reference to the shared AcroForm object of the document.
  397 + ///
  398 + /// @since 12.3
  399 + impl::AcroForm&
377 400 acroform()
378 401 {
379 402 if (!acroform_) {
380 403 no_inspection();
381   - acroform_ = std::make_unique<QPDFAcroFormDocumentHelper>(qpdf);
  404 + init_acroform();
382 405 }
383 406 return *acroform_;
384 407 }
... ... @@ -438,8 +461,11 @@ class QPDF::Doc
438 461 qpdf::Doc::Config cf;
439 462  
440 463 private:
  464 + void init_acroform();
  465 +
441 466 // Document Helpers;
442   - std::unique_ptr<QPDFAcroFormDocumentHelper> acroform_;
  467 + std::unique_ptr<QPDFAcroFormDocumentHelper> acroform_dh_;
  468 + impl::AcroForm* acroform_{nullptr};
443 469 std::unique_ptr<QPDFEmbeddedFileDocumentHelper> embedded_files_;
444 470 std::unique_ptr<QPDFOutlineDocumentHelper> outlines_;
445 471 std::unique_ptr<QPDFPageDocumentHelper> page_dh_;
... ... @@ -1173,7 +1199,7 @@ class QPDF::Doc::Pages: Common
1173 1199 void flatten_annotations_for_page(
1174 1200 QPDFPageObjectHelper& page,
1175 1201 QPDFObjectHandle& resources,
1176   - QPDFAcroFormDocumentHelper& afdh,
  1202 + impl::AcroForm& afdh,
1177 1203 int required_flags,
1178 1204 int forbidden_flags);
1179 1205  
... ...