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,6 +225,7 @@ class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper
225 std::set<QPDFObjGen>* new_fields = nullptr); 225 std::set<QPDFObjGen>* new_fields = nullptr);
226 226
227 private: 227 private:
  228 + friend class QPDF::Doc;
228 class Members; 229 class Members;
229 230
230 std::shared_ptr<Members> m; 231 std::shared_ptr<Members> m;
libqpdf/QPDF.cc
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 #include <sstream> 11 #include <sstream>
12 #include <vector> 12 #include <vector>
13 13
  14 +#include <qpdf/AcroForm.hh>
14 #include <qpdf/FileInputSource.hh> 15 #include <qpdf/FileInputSource.hh>
15 #include <qpdf/InputSource_private.hh> 16 #include <qpdf/InputSource_private.hh>
16 #include <qpdf/OffsetInputSource.hh> 17 #include <qpdf/OffsetInputSource.hh>
@@ -147,6 +148,21 @@ QPDF::QPDF() : @@ -147,6 +148,21 @@ QPDF::QPDF() :
147 m->unique_id = unique_id.fetch_add(1ULL); 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 // Provide access to disconnect(). Disconnect will in due course be merged into the current ObjCache 166 // Provide access to disconnect(). Disconnect will in due course be merged into the current ObjCache
151 // (future Objects::Entry) to centralize all QPDF access to QPDFObject. 167 // (future Objects::Entry) to centralize all QPDF access to QPDFObject.
152 class Disconnect: BaseHandle 168 class Disconnect: BaseHandle
libqpdf/QPDFAcroFormDocumentHelper.cc
@@ -18,14 +18,7 @@ using namespace qpdf; @@ -18,14 +18,7 @@ using namespace qpdf;
18 using namespace qpdf::impl; 18 using namespace qpdf::impl;
19 using namespace std::literals; 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 QPDFAcroFormDocumentHelper::QPDFAcroFormDocumentHelper(QPDF& qpdf) : 23 QPDFAcroFormDocumentHelper::QPDFAcroFormDocumentHelper(QPDF& qpdf) :
31 QPDFDocumentHelper(qpdf), 24 QPDFDocumentHelper(qpdf),
@@ -36,7 +29,7 @@ QPDFAcroFormDocumentHelper::QPDFAcroFormDocumentHelper(QPDF&amp; qpdf) : @@ -36,7 +29,7 @@ QPDFAcroFormDocumentHelper::QPDFAcroFormDocumentHelper(QPDF&amp; qpdf) :
36 QPDFAcroFormDocumentHelper& 29 QPDFAcroFormDocumentHelper&
37 QPDFAcroFormDocumentHelper::get(QPDF& qpdf) 30 QPDFAcroFormDocumentHelper::get(QPDF& qpdf)
38 { 31 {
39 - return qpdf.doc().acroform(); 32 + return qpdf.doc().acroform_dh();
40 } 33 }
41 34
42 void 35 void
libqpdf/QPDFJob.cc
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 #include <iostream> 4 #include <iostream>
5 #include <memory> 5 #include <memory>
6 6
  7 +#include <qpdf/AcroForm.hh>
7 #include <qpdf/ClosedFileInputSource.hh> 8 #include <qpdf/ClosedFileInputSource.hh>
8 #include <qpdf/FileInputSource.hh> 9 #include <qpdf/FileInputSource.hh>
9 #include <qpdf/Pipeline_private.hh> 10 #include <qpdf/Pipeline_private.hh>
@@ -1866,7 +1867,7 @@ QPDFJob::doUnderOverlayForPage( @@ -1866,7 +1867,7 @@ QPDFJob::doUnderOverlayForPage(
1866 if (!(uo.pdf && pagenos[pageno.idx].contains(uo_idx))) { 1867 if (!(uo.pdf && pagenos[pageno.idx].contains(uo_idx))) {
1867 return ""; 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 auto const& pages = uo.pdf->doc().pages().all(); 1872 auto const& pages = uo.pdf->doc().pages().all();
1872 std::string content; 1873 std::string content;
@@ -1887,7 +1888,8 @@ QPDFJob::doUnderOverlayForPage( @@ -1887,7 +1888,8 @@ QPDFJob::doUnderOverlayForPage(
1887 QPDFMatrix cm; 1888 QPDFMatrix cm;
1888 std::string new_content = dest_page.placeFormXObject( 1889 std::string new_content = dest_page.placeFormXObject(
1889 fo[from_no.no][uo_idx], name, dest_page.getTrimBox().getArrayAsRectangle(), cm); 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 if (!new_content.empty()) { 1893 if (!new_content.empty()) {
1892 resources.mergeResources(Dictionary({{"/XObject", Dictionary::empty()}})); 1894 resources.mergeResources(Dictionary({{"/XObject", Dictionary::empty()}}));
1893 auto xobject = resources.getKey("/XObject"); 1895 auto xobject = resources.getKey("/XObject");
@@ -2107,7 +2109,7 @@ QPDFJob::handleTransformations(QPDF&amp; pdf) @@ -2107,7 +2109,7 @@ QPDFJob::handleTransformations(QPDF&amp; pdf)
2107 QPDFAcroFormDocumentHelper* afdh_ptr = nullptr; 2109 QPDFAcroFormDocumentHelper* afdh_ptr = nullptr;
2108 auto afdh = [&]() -> QPDFAcroFormDocumentHelper& { 2110 auto afdh = [&]() -> QPDFAcroFormDocumentHelper& {
2109 if (!afdh_ptr) { 2111 if (!afdh_ptr) {
2110 - afdh_ptr = &pdf.doc().acroform(); 2112 + afdh_ptr = &pdf.doc().acroform_dh();
2111 } 2113 }
2112 return *afdh_ptr; 2114 return *afdh_ptr;
2113 }; 2115 };
@@ -2978,8 +2980,7 @@ QPDFJob::doSplitPages(QPDF&amp; pdf) @@ -2978,8 +2980,7 @@ QPDFJob::doSplitPages(QPDF&amp; pdf)
2978 QPDF outpdf; 2980 QPDF outpdf;
2979 outpdf.doc().config(m->d_cfg); 2981 outpdf.doc().config(m->d_cfg);
2980 outpdf.emptyPDF(); 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 for (size_t pageno = first; pageno <= last; ++pageno) { 2984 for (size_t pageno = first; pageno <= last; ++pageno) {
2984 QPDFObjectHandle page = pages.at(pageno - 1); 2985 QPDFObjectHandle page = pages.at(pageno - 1);
2985 outpdf.addPage(page, false); 2986 outpdf.addPage(page, false);
libqpdf/QPDF_pages.cc
1 #include <qpdf/QPDFPageDocumentHelper.hh> 1 #include <qpdf/QPDFPageDocumentHelper.hh>
2 #include <qpdf/QPDF_private.hh> 2 #include <qpdf/QPDF_private.hh>
3 3
4 -#include <qpdf/QPDFAcroFormDocumentHelper.hh> 4 +#include <qpdf/AcroForm.hh>
5 #include <qpdf/QPDFExc.hh> 5 #include <qpdf/QPDFExc.hh>
6 #include <qpdf/QPDFObjectHandle_private.hh> 6 #include <qpdf/QPDFObjectHandle_private.hh>
7 #include <qpdf/QTC.hh> 7 #include <qpdf/QTC.hh>
@@ -660,7 +660,7 @@ void @@ -660,7 +660,7 @@ void
660 Pages::flatten_annotations_for_page( 660 Pages::flatten_annotations_for_page(
661 QPDFPageObjectHelper& page, 661 QPDFPageObjectHelper& page,
662 QPDFObjectHandle& resources, 662 QPDFObjectHandle& resources,
663 - QPDFAcroFormDocumentHelper& afdh, 663 + impl::AcroForm& afdh,
664 int required_flags, 664 int required_flags,
665 int forbidden_flags) 665 int forbidden_flags)
666 { 666 {
libqpdf/qpdf/AcroForm.hh
@@ -546,7 +546,7 @@ namespace qpdf::impl @@ -546,7 +546,7 @@ namespace qpdf::impl
546 /// @param inherit If set to `true`, the function will attempt to retrieve `/V` by 546 /// @param inherit If set to `true`, the function will attempt to retrieve `/V` by
547 /// inheritance from the parent hierarchy of the form field. Defaults to `true`. 547 /// inheritance from the parent hierarchy of the form field. Defaults to `true`.
548 /// @return Returns the field's value if found; otherwise, returns a default-constructed 548 /// @return Returns the field's value if found; otherwise, returns a default-constructed
549 - /// object handle. 549 + /// object handle.
550 QPDFObjectHandle const& 550 QPDFObjectHandle const&
551 V(bool inherit = true) const 551 V(bool inherit = true) const
552 { 552 {
@@ -557,7 +557,7 @@ namespace qpdf::impl @@ -557,7 +557,7 @@ namespace qpdf::impl
557 } 557 }
558 558
559 /// @brief Retrieves the field value `/V` attribute of the form field, considering 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 /// This function extracts the value of the form field, accounting for potential inheritance 562 /// This function extracts the value of the form field, accounting for potential inheritance
563 /// through the form hierarchy. It returns the value if it is a String, and an empty string 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,7 +567,7 @@ namespace qpdf::impl
567 /// an empty string if the value is not present or not a String. 567 /// an empty string if the value is not present or not a String.
568 std::string value() const; 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 /// accounting for inheritance through the hierarchy of ancestor nodes in the form 571 /// accounting for inheritance through the hierarchy of ancestor nodes in the form
572 /// field tree. 572 /// field tree.
573 /// 573 ///
@@ -592,14 +592,14 @@ namespace qpdf::impl @@ -592,14 +592,14 @@ namespace qpdf::impl
592 } 592 }
593 593
594 /// @brief Retrieves the default value `/DV` attribute of the form field, considering 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 /// This function extracts the default value of the form field, accounting for potential 597 /// This function extracts the default value of the form field, accounting for potential
598 /// inheritance through the form hierarchy. It returns the value if it is a String, and an 598 /// inheritance through the form hierarchy. It returns the value if it is a String, and an
599 /// empty string otherwise. 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 std::string default_value() const; 603 std::string default_value() const;
604 604
605 /// @brief Returns the default appearance string for the form field, considering inheritance 605 /// @brief Returns the default appearance string for the form field, considering inheritance
@@ -711,4 +711,13 @@ namespace qpdf::impl @@ -711,4 +711,13 @@ namespace qpdf::impl
711 }; // class FormNode 711 }; // class FormNode
712 } // namespace qpdf::impl 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 #endif // ACRO_FORM_HH 723 #endif // ACRO_FORM_HH
libqpdf/qpdf/QPDF_private.hh
@@ -28,8 +28,9 @@ namespace qpdf @@ -28,8 +28,9 @@ namespace qpdf
28 28
29 namespace impl 29 namespace impl
30 { 30 {
  31 + class AcroForm;
31 using Doc = QPDF::Doc; 32 using Doc = QPDF::Doc;
32 - } 33 + } // namespace impl
33 34
34 class Doc: public QPDF 35 class Doc: public QPDF
35 { 36 {
@@ -374,11 +375,33 @@ class QPDF::Doc @@ -374,11 +375,33 @@ class QPDF::Doc
374 bool reconstructed_xref() const; 375 bool reconstructed_xref() const;
375 376
376 QPDFAcroFormDocumentHelper& 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 acroform() 400 acroform()
378 { 401 {
379 if (!acroform_) { 402 if (!acroform_) {
380 no_inspection(); 403 no_inspection();
381 - acroform_ = std::make_unique<QPDFAcroFormDocumentHelper>(qpdf); 404 + init_acroform();
382 } 405 }
383 return *acroform_; 406 return *acroform_;
384 } 407 }
@@ -438,8 +461,11 @@ class QPDF::Doc @@ -438,8 +461,11 @@ class QPDF::Doc
438 qpdf::Doc::Config cf; 461 qpdf::Doc::Config cf;
439 462
440 private: 463 private:
  464 + void init_acroform();
  465 +
441 // Document Helpers; 466 // Document Helpers;
442 - std::unique_ptr<QPDFAcroFormDocumentHelper> acroform_; 467 + std::unique_ptr<QPDFAcroFormDocumentHelper> acroform_dh_;
  468 + impl::AcroForm* acroform_{nullptr};
443 std::unique_ptr<QPDFEmbeddedFileDocumentHelper> embedded_files_; 469 std::unique_ptr<QPDFEmbeddedFileDocumentHelper> embedded_files_;
444 std::unique_ptr<QPDFOutlineDocumentHelper> outlines_; 470 std::unique_ptr<QPDFOutlineDocumentHelper> outlines_;
445 std::unique_ptr<QPDFPageDocumentHelper> page_dh_; 471 std::unique_ptr<QPDFPageDocumentHelper> page_dh_;
@@ -1173,7 +1199,7 @@ class QPDF::Doc::Pages: Common @@ -1173,7 +1199,7 @@ class QPDF::Doc::Pages: Common
1173 void flatten_annotations_for_page( 1199 void flatten_annotations_for_page(
1174 QPDFPageObjectHelper& page, 1200 QPDFPageObjectHelper& page,
1175 QPDFObjectHandle& resources, 1201 QPDFObjectHandle& resources,
1176 - QPDFAcroFormDocumentHelper& afdh, 1202 + impl::AcroForm& afdh,
1177 int required_flags, 1203 int required_flags,
1178 int forbidden_flags); 1204 int forbidden_flags);
1179 1205