Commit 1111240a2e9780fc012471c07bce4569963228b8

Authored by m-holger
1 parent c5b728f8

Refactor document helper access through `QPDF::Doc`

Replace direct access to document helpers (`acroform()`, `pages()`, `embedded_files()`, etc.) with calls through `QPDF::doc()` for better encapsulation. Adjust related methods, constructors, and memory management accordingly.
include/qpdf/QPDF.hh
@@ -62,11 +62,6 @@ class BitWriter; @@ -62,11 +62,6 @@ class BitWriter;
62 class BufferInputSource; 62 class BufferInputSource;
63 class QPDFLogger; 63 class QPDFLogger;
64 class QPDFParser; 64 class QPDFParser;
65 -class QPDFAcroFormDocumentHelper;  
66 -class QPDFEmbeddedFileDocumentHelper;  
67 -class QPDFOutlineDocumentHelper;  
68 -class QPDFPageDocumentHelper;  
69 -class QPDFPageLabelDocumentHelper;  
70 65
71 class QPDF 66 class QPDF
72 { 67 {
@@ -803,11 +798,6 @@ class QPDF @@ -803,11 +798,6 @@ class QPDF
803 class JobSetter; 798 class JobSetter;
804 799
805 inline bool reconstructed_xref() const; 800 inline bool reconstructed_xref() const;
806 - inline QPDFAcroFormDocumentHelper& acroform();  
807 - inline QPDFEmbeddedFileDocumentHelper& embedded_files();  
808 - inline QPDFOutlineDocumentHelper& outlines();  
809 - inline QPDFPageDocumentHelper& pages();  
810 - inline QPDFPageLabelDocumentHelper& page_labels();  
811 inline Doc& doc(); 801 inline Doc& doc();
812 802
813 // For testing only -- do not add to DLL 803 // For testing only -- do not add to DLL
libqpdf/QPDFAcroFormDocumentHelper.cc
@@ -45,7 +45,7 @@ QPDFAcroFormDocumentHelper::QPDFAcroFormDocumentHelper(QPDF& qpdf) : @@ -45,7 +45,7 @@ QPDFAcroFormDocumentHelper::QPDFAcroFormDocumentHelper(QPDF& qpdf) :
45 QPDFAcroFormDocumentHelper& 45 QPDFAcroFormDocumentHelper&
46 QPDFAcroFormDocumentHelper::get(QPDF& qpdf) 46 QPDFAcroFormDocumentHelper::get(QPDF& qpdf)
47 { 47 {
48 - return qpdf.acroform(); 48 + return qpdf.doc().acroform();
49 } 49 }
50 50
51 void 51 void
libqpdf/QPDFEmbeddedFileDocumentHelper.cc
@@ -53,7 +53,7 @@ QPDFEmbeddedFileDocumentHelper::QPDFEmbeddedFileDocumentHelper(QPDF& qpdf) : @@ -53,7 +53,7 @@ QPDFEmbeddedFileDocumentHelper::QPDFEmbeddedFileDocumentHelper(QPDF& qpdf) :
53 QPDFEmbeddedFileDocumentHelper& 53 QPDFEmbeddedFileDocumentHelper&
54 QPDFEmbeddedFileDocumentHelper::get(QPDF& qpdf) 54 QPDFEmbeddedFileDocumentHelper::get(QPDF& qpdf)
55 { 55 {
56 - return qpdf.embedded_files(); 56 + return qpdf.doc().embedded_files();
57 } 57 }
58 58
59 void 59 void
libqpdf/QPDFFormFieldObjectHelper.cc
@@ -337,7 +337,7 @@ QPDFFormFieldObjectHelper::setV(QPDFObjectHandle value, bool need_appearances) @@ -337,7 +337,7 @@ QPDFFormFieldObjectHelper::setV(QPDFObjectHandle value, bool need_appearances)
337 QPDF& qpdf = oh().getQPDF( 337 QPDF& qpdf = oh().getQPDF(
338 "QPDFFormFieldObjectHelper::setV called with need_appearances = " 338 "QPDFFormFieldObjectHelper::setV called with need_appearances = "
339 "true on an object that is not associated with an owning QPDF"); 339 "true on an object that is not associated with an owning QPDF");
340 - qpdf.acroform().setNeedAppearances(true); 340 + qpdf.doc().acroform().setNeedAppearances(true);
341 } 341 }
342 } 342 }
343 343
libqpdf/QPDFJob.cc
@@ -751,12 +751,13 @@ QPDFJob::doCheck(QPDF& pdf) @@ -751,12 +751,13 @@ QPDFJob::doCheck(QPDF& pdf)
751 } 751 }
752 752
753 // Create all document helper to trigger any validations they carry out. 753 // Create all document helper to trigger any validations they carry out.
754 - auto& pages = pdf.pages();  
755 - (void)pdf.acroform();  
756 - (void)pdf.embedded_files();  
757 - (void)pdf.page_labels();  
758 - (void)pdf.outlines().resolveNamedDest(QPDFObjectHandle::newString("dummy"));  
759 - (void)pdf.outlines().getOutlinesForPage(pages.getAllPages().at(0)); 754 + auto& doc = pdf.doc();
  755 + auto& pages = doc.pages();
  756 + (void)doc.acroform();
  757 + (void)doc.embedded_files();
  758 + (void)doc.page_labels();
  759 + (void)doc.outlines().resolveNamedDest(QPDFObjectHandle::newString("dummy"));
  760 + (void)doc.outlines().getOutlinesForPage(pages.getAllPages().at(0));
760 761
761 // Write the file to nowhere, uncompressing streams. This causes full file traversal and 762 // Write the file to nowhere, uncompressing streams. This causes full file traversal and
762 // decoding of all streams we can decode. 763 // decoding of all streams we can decode.
@@ -839,8 +840,8 @@ QPDFJob::doShowPages(QPDF& pdf) @@ -839,8 +840,8 @@ QPDFJob::doShowPages(QPDF& pdf)
839 { 840 {
840 int pageno = 0; 841 int pageno = 0;
841 auto& cout = *m->log->getInfo(); 842 auto& cout = *m->log->getInfo();
842 - for (auto& ph: pdf.pages().getAllPages()) {  
843 - QPDFObjectHandle page = ph.getObjectHandle(); 843 + for (auto& page: pdf.getAllPages()) {
  844 + QPDFPageObjectHelper ph(page);
844 ++pageno; 845 ++pageno;
845 846
846 cout << "page " << pageno << ": " << page.getObjectID() << " " << page.getGeneration() 847 cout << "page " << pageno << ": " << page.getObjectID() << " " << page.getGeneration()
@@ -871,7 +872,7 @@ QPDFJob::doShowPages(QPDF&amp; pdf) @@ -871,7 +872,7 @@ QPDFJob::doShowPages(QPDF&amp; pdf)
871 void 872 void
872 QPDFJob::doListAttachments(QPDF& pdf) 873 QPDFJob::doListAttachments(QPDF& pdf)
873 { 874 {
874 - auto& efdh = pdf.embedded_files(); 875 + auto& efdh = pdf.doc().embedded_files();
875 if (efdh.hasEmbeddedFiles()) { 876 if (efdh.hasEmbeddedFiles()) {
876 for (auto const& i: efdh.getEmbeddedFiles()) { 877 for (auto const& i: efdh.getEmbeddedFiles()) {
877 std::string const& key = i.first; 878 std::string const& key = i.first;
@@ -911,7 +912,7 @@ QPDFJob::doListAttachments(QPDF&amp; pdf) @@ -911,7 +912,7 @@ QPDFJob::doListAttachments(QPDF&amp; pdf)
911 void 912 void
912 QPDFJob::doShowAttachment(QPDF& pdf) 913 QPDFJob::doShowAttachment(QPDF& pdf)
913 { 914 {
914 - auto& efdh = pdf.embedded_files(); 915 + auto& efdh = pdf.doc().embedded_files();
915 auto fs = efdh.getEmbeddedFile(m->attachment_to_show); 916 auto fs = efdh.getEmbeddedFile(m->attachment_to_show);
916 if (!fs) { 917 if (!fs) {
917 throw std::runtime_error("attachment " + m->attachment_to_show + " not found"); 918 throw std::runtime_error("attachment " + m->attachment_to_show + " not found");
@@ -1030,13 +1031,13 @@ QPDFJob::doJSONPages(Pipeline* p, bool&amp; first, QPDF&amp; pdf) @@ -1030,13 +1031,13 @@ QPDFJob::doJSONPages(Pipeline* p, bool&amp; first, QPDF&amp; pdf)
1030 JSON::writeDictionaryKey(p, first, "pages", 1); 1031 JSON::writeDictionaryKey(p, first, "pages", 1);
1031 bool first_page = true; 1032 bool first_page = true;
1032 JSON::writeArrayOpen(p, first_page, 2); 1033 JSON::writeArrayOpen(p, first_page, 2);
1033 - auto& pldh = pdf.page_labels();  
1034 - auto& odh = pdf.outlines(); 1034 + auto& pldh = pdf.doc().page_labels();
  1035 + auto& odh = pdf.doc().outlines();
1035 int pageno = -1; 1036 int pageno = -1;
1036 - for (auto& ph: pdf.pages().getAllPages()) { 1037 + for (auto& page: pdf.getAllPages()) {
1037 ++pageno; 1038 ++pageno;
1038 JSON j_page = JSON::makeDictionary(); 1039 JSON j_page = JSON::makeDictionary();
1039 - QPDFObjectHandle page = ph.getObjectHandle(); 1040 + QPDFPageObjectHelper ph(page);
1040 j_page.addDictionaryMember("object", page.getJSON(m->json_version)); 1041 j_page.addDictionaryMember("object", page.getJSON(m->json_version));
1041 JSON j_images = j_page.addDictionaryMember("images", JSON::makeArray()); 1042 JSON j_images = j_page.addDictionaryMember("images", JSON::makeArray());
1042 for (auto const& iter2: ph.getImages()) { 1043 for (auto const& iter2: ph.getImages()) {
@@ -1093,8 +1094,8 @@ void @@ -1093,8 +1094,8 @@ void
1093 QPDFJob::doJSONPageLabels(Pipeline* p, bool& first, QPDF& pdf) 1094 QPDFJob::doJSONPageLabels(Pipeline* p, bool& first, QPDF& pdf)
1094 { 1095 {
1095 JSON j_labels = JSON::makeArray(); 1096 JSON j_labels = JSON::makeArray();
1096 - auto& pldh = pdf.page_labels();  
1097 - long long npages = QIntC::to_longlong(pdf.pages().getAllPages().size()); 1097 + auto& pldh = pdf.doc().page_labels();
  1098 + long long npages = QIntC::to_longlong(pdf.getAllPages().size());
1098 if (pldh.hasPageLabels()) { 1099 if (pldh.hasPageLabels()) {
1099 std::vector<QPDFObjectHandle> labels; 1100 std::vector<QPDFObjectHandle> labels;
1100 pldh.getLabelsForPageRange(0, npages - 1, 0, labels); 1101 pldh.getLabelsForPageRange(0, npages - 1, 0, labels);
@@ -1142,13 +1143,12 @@ QPDFJob::doJSONOutlines(Pipeline* p, bool&amp; first, QPDF&amp; pdf) @@ -1142,13 +1143,12 @@ QPDFJob::doJSONOutlines(Pipeline* p, bool&amp; first, QPDF&amp; pdf)
1142 { 1143 {
1143 std::map<QPDFObjGen, int> page_numbers; 1144 std::map<QPDFObjGen, int> page_numbers;
1144 int n = 0; 1145 int n = 0;
1145 - for (auto const& ph: pdf.pages().getAllPages()) {  
1146 - QPDFObjectHandle oh = ph.getObjectHandle();  
1147 - page_numbers[oh.getObjGen()] = ++n; 1146 + for (auto const& oh: pdf.getAllPages()) {
  1147 + page_numbers[oh] = ++n;
1148 } 1148 }
1149 1149
1150 JSON j_outlines = JSON::makeArray(); 1150 JSON j_outlines = JSON::makeArray();
1151 - addOutlinesToJson(pdf.outlines().getTopLevelOutlines(), j_outlines, page_numbers); 1151 + addOutlinesToJson(pdf.doc().outlines().getTopLevelOutlines(), j_outlines, page_numbers);
1152 JSON::writeDictionaryItem(p, first, "outlines", j_outlines, 1); 1152 JSON::writeDictionaryItem(p, first, "outlines", j_outlines, 1);
1153 } 1153 }
1154 1154
@@ -1156,14 +1156,14 @@ void @@ -1156,14 +1156,14 @@ void
1156 QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf) 1156 QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf)
1157 { 1157 {
1158 JSON j_acroform = JSON::makeDictionary(); 1158 JSON j_acroform = JSON::makeDictionary();
1159 - auto& afdh = pdf.acroform(); 1159 + auto& afdh = pdf.doc().acroform();
1160 j_acroform.addDictionaryMember("hasacroform", JSON::makeBool(afdh.hasAcroForm())); 1160 j_acroform.addDictionaryMember("hasacroform", JSON::makeBool(afdh.hasAcroForm()));
1161 j_acroform.addDictionaryMember("needappearances", JSON::makeBool(afdh.getNeedAppearances())); 1161 j_acroform.addDictionaryMember("needappearances", JSON::makeBool(afdh.getNeedAppearances()));
1162 JSON j_fields = j_acroform.addDictionaryMember("fields", JSON::makeArray()); 1162 JSON j_fields = j_acroform.addDictionaryMember("fields", JSON::makeArray());
1163 int pagepos1 = 0; 1163 int pagepos1 = 0;
1164 - for (auto const& page: pdf.pages().getAllPages()) { 1164 + for (auto const& page: pdf.getAllPages()) {
1165 ++pagepos1; 1165 ++pagepos1;
1166 - for (auto& aoh: afdh.getWidgetAnnotationsForPage(page)) { 1166 + for (auto& aoh: afdh.getWidgetAnnotationsForPage({page})) {
1167 QPDFFormFieldObjectHelper ffh = afdh.getFieldForAnnotation(aoh); 1167 QPDFFormFieldObjectHelper ffh = afdh.getFieldForAnnotation(aoh);
1168 if (!ffh.getObjectHandle().isDictionary()) { 1168 if (!ffh.getObjectHandle().isDictionary()) {
1169 continue; 1169 continue;
@@ -1297,7 +1297,7 @@ QPDFJob::doJSONAttachments(Pipeline* p, bool&amp; first, QPDF&amp; pdf) @@ -1297,7 +1297,7 @@ QPDFJob::doJSONAttachments(Pipeline* p, bool&amp; first, QPDF&amp; pdf)
1297 }; 1297 };
1298 1298
1299 JSON j_attachments = JSON::makeDictionary(); 1299 JSON j_attachments = JSON::makeDictionary();
1300 - auto& efdh = pdf.embedded_files(); 1300 + auto& efdh = pdf.doc().embedded_files();
1301 for (auto const& iter: efdh.getEmbeddedFiles()) { 1301 for (auto const& iter: efdh.getEmbeddedFiles()) {
1302 std::string const& key = iter.first; 1302 std::string const& key = iter.first;
1303 auto fsoh = iter.second; 1303 auto fsoh = iter.second;
@@ -1873,7 +1873,7 @@ QPDFJob::doUnderOverlayForPage( @@ -1873,7 +1873,7 @@ QPDFJob::doUnderOverlayForPage(
1873 if (!(uo.pdf && pagenos[pageno.idx].contains(uo_idx))) { 1873 if (!(uo.pdf && pagenos[pageno.idx].contains(uo_idx))) {
1874 return ""; 1874 return "";
1875 } 1875 }
1876 - auto& dest_afdh = dest_page.qpdf()->acroform(); 1876 + auto& dest_afdh = dest_page.qpdf()->doc().acroform();
1877 1877
1878 auto const& pages = uo.pdf->getAllPages(); 1878 auto const& pages = uo.pdf->getAllPages();
1879 std::string content; 1879 std::string content;
@@ -1894,7 +1894,7 @@ QPDFJob::doUnderOverlayForPage( @@ -1894,7 +1894,7 @@ QPDFJob::doUnderOverlayForPage(
1894 QPDFMatrix cm; 1894 QPDFMatrix cm;
1895 std::string new_content = dest_page.placeFormXObject( 1895 std::string new_content = dest_page.placeFormXObject(
1896 fo[from_no.no][uo_idx], name, dest_page.getTrimBox().getArrayAsRectangle(), cm); 1896 fo[from_no.no][uo_idx], name, dest_page.getTrimBox().getArrayAsRectangle(), cm);
1897 - dest_page.copyAnnotations(from_page, cm, &dest_afdh, &from_page.qpdf()->acroform()); 1897 + dest_page.copyAnnotations(from_page, cm, &dest_afdh, &from_page.qpdf()->doc().acroform());
1898 if (!new_content.empty()) { 1898 if (!new_content.empty()) {
1899 resources.mergeResources("<< /XObject << >> >>"_qpdf); 1899 resources.mergeResources("<< /XObject << >> >>"_qpdf);
1900 auto xobject = resources.getKey("/XObject"); 1900 auto xobject = resources.getKey("/XObject");
@@ -2019,7 +2019,7 @@ void @@ -2019,7 +2019,7 @@ void
2019 QPDFJob::addAttachments(QPDF& pdf) 2019 QPDFJob::addAttachments(QPDF& pdf)
2020 { 2020 {
2021 maybe_set_pagemode(pdf, "/UseAttachments"); 2021 maybe_set_pagemode(pdf, "/UseAttachments");
2022 - auto& efdh = pdf.embedded_files(); 2022 + auto& efdh = pdf.doc().embedded_files();
2023 std::vector<std::string> duplicated_keys; 2023 std::vector<std::string> duplicated_keys;
2024 for (auto const& to_add: m->attachments_to_add) { 2024 for (auto const& to_add: m->attachments_to_add) {
2025 if ((!to_add.replace) && efdh.getEmbeddedFile(to_add.key)) { 2025 if ((!to_add.replace) && efdh.getEmbeddedFile(to_add.key)) {
@@ -2063,7 +2063,7 @@ void @@ -2063,7 +2063,7 @@ void
2063 QPDFJob::copyAttachments(QPDF& pdf) 2063 QPDFJob::copyAttachments(QPDF& pdf)
2064 { 2064 {
2065 maybe_set_pagemode(pdf, "/UseAttachments"); 2065 maybe_set_pagemode(pdf, "/UseAttachments");
2066 - auto& efdh = pdf.embedded_files(); 2066 + auto& efdh = pdf.doc().embedded_files();
2067 std::vector<std::string> duplicates; 2067 std::vector<std::string> duplicates;
2068 for (auto const& to_copy: m->attachments_to_copy) { 2068 for (auto const& to_copy: m->attachments_to_copy) {
2069 doIfVerbose([&](Pipeline& v, std::string const& prefix) { 2069 doIfVerbose([&](Pipeline& v, std::string const& prefix) {
@@ -2071,7 +2071,7 @@ QPDFJob::copyAttachments(QPDF&amp; pdf) @@ -2071,7 +2071,7 @@ QPDFJob::copyAttachments(QPDF&amp; pdf)
2071 }); 2071 });
2072 std::unique_ptr<QPDF> other; 2072 std::unique_ptr<QPDF> other;
2073 processFile(other, to_copy.path.c_str(), to_copy.password.c_str(), false, false); 2073 processFile(other, to_copy.path.c_str(), to_copy.password.c_str(), false, false);
2074 - auto& other_efdh = other->embedded_files(); 2074 + auto& other_efdh = other->doc().embedded_files();
2075 auto other_attachments = other_efdh.getEmbeddedFiles(); 2075 auto other_attachments = other_efdh.getEmbeddedFiles();
2076 for (auto const& iter: other_attachments) { 2076 for (auto const& iter: other_attachments) {
2077 std::string new_key = to_copy.prefix + iter.first; 2077 std::string new_key = to_copy.prefix + iter.first;
@@ -2114,7 +2114,7 @@ QPDFJob::handleTransformations(QPDF&amp; pdf) @@ -2114,7 +2114,7 @@ QPDFJob::handleTransformations(QPDF&amp; pdf)
2114 QPDFAcroFormDocumentHelper* afdh_ptr = nullptr; 2114 QPDFAcroFormDocumentHelper* afdh_ptr = nullptr;
2115 auto afdh = [&]() -> QPDFAcroFormDocumentHelper& { 2115 auto afdh = [&]() -> QPDFAcroFormDocumentHelper& {
2116 if (!afdh_ptr) { 2116 if (!afdh_ptr) {
2117 - afdh_ptr = &pdf.acroform(); 2117 + afdh_ptr = &pdf.doc().acroform();
2118 } 2118 }
2119 return *afdh_ptr; 2119 return *afdh_ptr;
2120 }; 2120 };
@@ -2205,7 +2205,7 @@ QPDFJob::handleTransformations(QPDF&amp; pdf) @@ -2205,7 +2205,7 @@ QPDFJob::handleTransformations(QPDF&amp; pdf)
2205 pdf.getRoot().replaceKey("/PageLabels", page_labels); 2205 pdf.getRoot().replaceKey("/PageLabels", page_labels);
2206 } 2206 }
2207 if (!m->attachments_to_remove.empty()) { 2207 if (!m->attachments_to_remove.empty()) {
2208 - auto& efdh = pdf.embedded_files(); 2208 + auto& efdh = pdf.doc().embedded_files();
2209 for (auto const& key: m->attachments_to_remove) { 2209 for (auto const& key: m->attachments_to_remove) {
2210 if (efdh.removeEmbeddedFile(key)) { 2210 if (efdh.removeEmbeddedFile(key)) {
2211 doIfVerbose([&](Pipeline& v, std::string const& prefix) { 2211 doIfVerbose([&](Pipeline& v, std::string const& prefix) {
@@ -2344,7 +2344,7 @@ QPDFJob::Input::initialize(Inputs&amp; in, QPDF* a_qpdf) @@ -2344,7 +2344,7 @@ QPDFJob::Input::initialize(Inputs&amp; in, QPDF* a_qpdf)
2344 if (in.job.m->remove_unreferenced_page_resources != QPDFJob::re_no) { 2344 if (in.job.m->remove_unreferenced_page_resources != QPDFJob::re_no) {
2345 remove_unreferenced = in.job.shouldRemoveUnreferencedResources(*qpdf); 2345 remove_unreferenced = in.job.shouldRemoveUnreferencedResources(*qpdf);
2346 } 2346 }
2347 - if (qpdf->page_labels().hasPageLabels()) { 2347 + if (qpdf->doc().page_labels().hasPageLabels()) {
2348 in.any_page_labels = true; 2348 in.any_page_labels = true;
2349 } 2349 }
2350 } 2350 }
@@ -2574,15 +2574,15 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf) @@ -2574,15 +2574,15 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf)
2574 // original file that we are selecting. 2574 // original file that we are selecting.
2575 std::vector<QPDFObjectHandle> new_labels; 2575 std::vector<QPDFObjectHandle> new_labels;
2576 int out_pageno = 0; 2576 int out_pageno = 0;
2577 - auto& this_afdh = pdf.acroform(); 2577 + auto& this_afdh = pdf.doc().acroform();
2578 std::set<QPDFObjGen> referenced_fields; 2578 std::set<QPDFObjGen> referenced_fields;
2579 for (auto& selection: new_specs.empty() ? m->inputs.selections : new_specs) { 2579 for (auto& selection: new_specs.empty() ? m->inputs.selections : new_specs) {
2580 auto& input = selection.input(); 2580 auto& input = selection.input();
2581 if (input.cfis) { 2581 if (input.cfis) {
2582 input.cfis->stayOpen(true); 2582 input.cfis->stayOpen(true);
2583 } 2583 }
2584 - auto* pldh = m->inputs.any_page_labels ? &input.qpdf->page_labels() : nullptr;  
2585 - auto& other_afdh = input.qpdf->acroform(); 2584 + auto* pldh = m->inputs.any_page_labels ? &input.qpdf->doc().page_labels() : nullptr;
  2585 + auto& other_afdh = input.qpdf->doc().acroform();
2586 doIfVerbose([&](Pipeline& v, std::string const& prefix) { 2586 doIfVerbose([&](Pipeline& v, std::string const& prefix) {
2587 v << prefix << ": adding pages from " << selection.filename() << "\n"; 2587 v << prefix << ": adding pages from " << selection.filename() << "\n";
2588 }); 2588 });
@@ -3012,8 +3012,8 @@ QPDFJob::doSplitPages(QPDF&amp; pdf) @@ -3012,8 +3012,8 @@ QPDFJob::doSplitPages(QPDF&amp; pdf)
3012 QPDFPageDocumentHelper dh(pdf); 3012 QPDFPageDocumentHelper dh(pdf);
3013 dh.removeUnreferencedResources(); 3013 dh.removeUnreferencedResources();
3014 } 3014 }
3015 - auto& pldh = pdf.page_labels();  
3016 - auto& afdh = pdf.acroform(); 3015 + auto& pldh = pdf.doc().page_labels();
  3016 + auto& afdh = pdf.doc().acroform();
3017 std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages(); 3017 std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages();
3018 size_t pageno_len = std::to_string(pages.size()).length(); 3018 size_t pageno_len = std::to_string(pages.size()).length();
3019 size_t num_pages = pages.size(); 3019 size_t num_pages = pages.size();
@@ -3025,7 +3025,8 @@ QPDFJob::doSplitPages(QPDF&amp; pdf) @@ -3025,7 +3025,8 @@ QPDFJob::doSplitPages(QPDF&amp; pdf)
3025 } 3025 }
3026 QPDF outpdf; 3026 QPDF outpdf;
3027 outpdf.emptyPDF(); 3027 outpdf.emptyPDF();
3028 - QPDFAcroFormDocumentHelper* out_afdh = afdh.hasAcroForm() ? &outpdf.acroform() : nullptr; 3028 + QPDFAcroFormDocumentHelper* out_afdh =
  3029 + afdh.hasAcroForm() ? &outpdf.doc().acroform() : nullptr;
3029 if (m->suppress_warnings) { 3030 if (m->suppress_warnings) {
3030 outpdf.setSuppressWarnings(true); 3031 outpdf.setSuppressWarnings(true);
3031 } 3032 }
libqpdf/QPDFOutlineDocumentHelper.cc
@@ -34,7 +34,7 @@ QPDFOutlineDocumentHelper::QPDFOutlineDocumentHelper(QPDF&amp; qpdf) : @@ -34,7 +34,7 @@ QPDFOutlineDocumentHelper::QPDFOutlineDocumentHelper(QPDF&amp; qpdf) :
34 QPDFOutlineDocumentHelper& 34 QPDFOutlineDocumentHelper&
35 QPDFOutlineDocumentHelper::get(QPDF& qpdf) 35 QPDFOutlineDocumentHelper::get(QPDF& qpdf)
36 { 36 {
37 - return qpdf.outlines(); 37 + return qpdf.doc().outlines();
38 } 38 }
39 39
40 void 40 void
libqpdf/QPDFPageDocumentHelper.cc
@@ -18,7 +18,7 @@ QPDFPageDocumentHelper::QPDFPageDocumentHelper(QPDF&amp; qpdf) : @@ -18,7 +18,7 @@ QPDFPageDocumentHelper::QPDFPageDocumentHelper(QPDF&amp; qpdf) :
18 QPDFPageDocumentHelper& 18 QPDFPageDocumentHelper&
19 QPDFPageDocumentHelper::get(QPDF& qpdf) 19 QPDFPageDocumentHelper::get(QPDF& qpdf)
20 { 20 {
21 - return qpdf.pages(); 21 + return qpdf.doc().pages();
22 } 22 }
23 23
24 void 24 void
@@ -72,7 +72,7 @@ QPDFPageDocumentHelper::removePage(QPDFPageObjectHelper page) @@ -72,7 +72,7 @@ QPDFPageDocumentHelper::removePage(QPDFPageObjectHelper page)
72 void 72 void
73 QPDFPageDocumentHelper::flattenAnnotations(int required_flags, int forbidden_flags) 73 QPDFPageDocumentHelper::flattenAnnotations(int required_flags, int forbidden_flags)
74 { 74 {
75 - auto& afdh = qpdf.acroform(); 75 + auto& afdh = qpdf.doc().acroform();
76 if (afdh.getNeedAppearances()) { 76 if (afdh.getNeedAppearances()) {
77 qpdf.getRoot() 77 qpdf.getRoot()
78 .getKey("/AcroForm") 78 .getKey("/AcroForm")
libqpdf/QPDFPageLabelDocumentHelper.cc
@@ -26,7 +26,7 @@ QPDFPageLabelDocumentHelper::QPDFPageLabelDocumentHelper(QPDF&amp; qpdf) : @@ -26,7 +26,7 @@ QPDFPageLabelDocumentHelper::QPDFPageLabelDocumentHelper(QPDF&amp; qpdf) :
26 QPDFPageLabelDocumentHelper& 26 QPDFPageLabelDocumentHelper&
27 QPDFPageLabelDocumentHelper::get(QPDF& qpdf) 27 QPDFPageLabelDocumentHelper::get(QPDF& qpdf)
28 { 28 {
29 - return qpdf.page_labels(); 29 + return qpdf.doc().page_labels();
30 } 30 }
31 31
32 void 32 void
libqpdf/qpdf/QPDF_private.hh
@@ -425,9 +425,61 @@ class QPDF::Doc @@ -425,9 +425,61 @@ class QPDF::Doc
425 { 425 {
426 } 426 }
427 427
  428 + QPDFAcroFormDocumentHelper&
  429 + acroform()
  430 + {
  431 + if (!acroform_) {
  432 + acroform_ = std::make_unique<QPDFAcroFormDocumentHelper>(qpdf);
  433 + }
  434 + return *acroform_;
  435 + }
  436 +
  437 + QPDFEmbeddedFileDocumentHelper&
  438 + embedded_files()
  439 + {
  440 + if (!embedded_files_) {
  441 + embedded_files_ = std::make_unique<QPDFEmbeddedFileDocumentHelper>(qpdf);
  442 + }
  443 + return *embedded_files_;
  444 + }
  445 +
  446 + QPDFOutlineDocumentHelper&
  447 + outlines()
  448 + {
  449 + if (!outlines_) {
  450 + outlines_ = std::make_unique<QPDFOutlineDocumentHelper>(qpdf);
  451 + }
  452 + return *outlines_;
  453 + }
  454 +
  455 + QPDFPageDocumentHelper&
  456 + pages()
  457 + {
  458 + if (!pages_) {
  459 + pages_ = std::make_unique<QPDFPageDocumentHelper>(qpdf);
  460 + }
  461 + return *pages_;
  462 + }
  463 +
  464 + QPDFPageLabelDocumentHelper&
  465 + page_labels()
  466 + {
  467 + if (!page_labels_) {
  468 + page_labels_ = std::make_unique<QPDFPageLabelDocumentHelper>(qpdf);
  469 + }
  470 + return *page_labels_;
  471 + }
  472 +
428 private: 473 private:
429 QPDF& qpdf; 474 QPDF& qpdf;
430 QPDF::Members& m; 475 QPDF::Members& m;
  476 +
  477 + // Document Helpers;
  478 + std::unique_ptr<QPDFAcroFormDocumentHelper> acroform_;
  479 + std::unique_ptr<QPDFEmbeddedFileDocumentHelper> embedded_files_;
  480 + std::unique_ptr<QPDFOutlineDocumentHelper> outlines_;
  481 + std::unique_ptr<QPDFPageDocumentHelper> pages_;
  482 + std::unique_ptr<QPDFPageLabelDocumentHelper> page_labels_;
431 }; 483 };
432 484
433 class QPDF::Members 485 class QPDF::Members
@@ -514,13 +566,6 @@ class QPDF::Members @@ -514,13 +566,6 @@ class QPDF::Members
514 // Optimization data 566 // Optimization data
515 std::map<ObjUser, std::set<QPDFObjGen>> obj_user_to_objects; 567 std::map<ObjUser, std::set<QPDFObjGen>> obj_user_to_objects;
516 std::map<QPDFObjGen, std::set<ObjUser>> object_to_obj_users; 568 std::map<QPDFObjGen, std::set<ObjUser>> object_to_obj_users;
517 -  
518 - // Document Helpers;  
519 - std::unique_ptr<QPDFAcroFormDocumentHelper> acroform;  
520 - std::unique_ptr<QPDFEmbeddedFileDocumentHelper> embedded_files;  
521 - std::unique_ptr<QPDFOutlineDocumentHelper> outlines;  
522 - std::unique_ptr<QPDFPageDocumentHelper> pages;  
523 - std::unique_ptr<QPDFPageLabelDocumentHelper> page_labels;  
524 }; 569 };
525 570
526 // JobSetter class is restricted to QPDFJob. 571 // JobSetter class is restricted to QPDFJob.
@@ -543,51 +588,6 @@ QPDF::reconstructed_xref() const @@ -543,51 +588,6 @@ QPDF::reconstructed_xref() const
543 return m->reconstructed_xref; 588 return m->reconstructed_xref;
544 } 589 }
545 590
546 -inline QPDFAcroFormDocumentHelper&  
547 -QPDF::acroform()  
548 -{  
549 - if (!m->acroform) {  
550 - m->acroform = std::make_unique<QPDFAcroFormDocumentHelper>(*this);  
551 - }  
552 - return *m->acroform;  
553 -}  
554 -  
555 -inline QPDFEmbeddedFileDocumentHelper&  
556 -QPDF::embedded_files()  
557 -{  
558 - if (!m->embedded_files) {  
559 - m->embedded_files = std::make_unique<QPDFEmbeddedFileDocumentHelper>(*this);  
560 - }  
561 - return *m->embedded_files;  
562 -}  
563 -  
564 -inline QPDFOutlineDocumentHelper&  
565 -QPDF::outlines()  
566 -{  
567 - if (!m->outlines) {  
568 - m->outlines = std::make_unique<QPDFOutlineDocumentHelper>(*this);  
569 - }  
570 - return *m->outlines;  
571 -}  
572 -  
573 -inline QPDFPageDocumentHelper&  
574 -QPDF::pages()  
575 -{  
576 - if (!m->pages) {  
577 - m->pages = std::make_unique<QPDFPageDocumentHelper>(*this);  
578 - }  
579 - return *m->pages;  
580 -}  
581 -  
582 -inline QPDFPageLabelDocumentHelper&  
583 -QPDF::page_labels()  
584 -{  
585 - if (!m->page_labels) {  
586 - m->page_labels = std::make_unique<QPDFPageLabelDocumentHelper>(*this);  
587 - }  
588 - return *m->page_labels;  
589 -}  
590 -  
591 inline QPDF::Doc& 591 inline QPDF::Doc&
592 QPDF::doc() 592 QPDF::doc()
593 { 593 {