Commit e62cf819fd8fcf9a0c04adf08a6104fdf8bedd2a
1 parent
c1150a44
Refactor `QPDFJob::handleUnderlaysAndOverlays`: streamline logic for handling pa…
…ges, replace redundant variables, and improve code readability.
Showing
1 changed file
with
16 additions
and
15 deletions
libqpdf/QPDFJob.cc
| @@ -1995,6 +1995,8 @@ QPDFJob::handleUnderOverlay(QPDF& pdf) | @@ -1995,6 +1995,8 @@ QPDFJob::handleUnderOverlay(QPDF& pdf) | ||
| 1995 | validateUnderOverlay(pdf, &uo); | 1995 | validateUnderOverlay(pdf, &uo); |
| 1996 | } | 1996 | } |
| 1997 | 1997 | ||
| 1998 | + auto const& main_pages = pdf.getAllPages(); | ||
| 1999 | + | ||
| 1998 | // First map key is 1-based page number. Second is index into the overlay/underlay vector. Watch | 2000 | // First map key is 1-based page number. Second is index into the overlay/underlay vector. Watch |
| 1999 | // out to not reverse the keys or be off by one. | 2001 | // out to not reverse the keys or be off by one. |
| 2000 | std::map<int, std::map<size_t, std::vector<int>>> underlay_pagenos; | 2002 | std::map<int, std::map<size_t, std::vector<int>>> underlay_pagenos; |
| @@ -2020,29 +2022,27 @@ QPDFJob::handleUnderOverlay(QPDF& pdf) | @@ -2020,29 +2022,27 @@ QPDFJob::handleUnderOverlay(QPDF& pdf) | ||
| 2020 | 2022 | ||
| 2021 | std::map<int, std::map<size_t, QPDFObjectHandle>> underlay_fo; | 2023 | std::map<int, std::map<size_t, QPDFObjectHandle>> underlay_fo; |
| 2022 | std::map<int, std::map<size_t, QPDFObjectHandle>> overlay_fo; | 2024 | std::map<int, std::map<size_t, QPDFObjectHandle>> overlay_fo; |
| 2023 | - QPDFPageDocumentHelper main_pdh(pdf); | ||
| 2024 | - auto main_pages = main_pdh.getAllPages(); | ||
| 2025 | - size_t main_npages = main_pages.size(); | ||
| 2026 | - for (PageNo page; page.idx < main_npages; ++page) { | ||
| 2027 | - doIfVerbose( | ||
| 2028 | - [&](Pipeline& v, std::string const& prefix) { v << " page " << page.no << "\n"; }); | ||
| 2029 | - if (underlay_pagenos[page.no].empty() && overlay_pagenos[page.no].empty()) { | 2025 | + PageNo dest_page_no; |
| 2026 | + for (QPDFPageObjectHelper dest_page: main_pages) { | ||
| 2027 | + doIfVerbose([&](Pipeline& v, std::string const& prefix) { | ||
| 2028 | + v << " page " << dest_page_no.no << "\n"; | ||
| 2029 | + }); | ||
| 2030 | + if (underlay_pagenos[dest_page_no.no].empty() && overlay_pagenos[dest_page_no.no].empty()) { | ||
| 2031 | + ++dest_page_no; | ||
| 2030 | continue; | 2032 | continue; |
| 2031 | } | 2033 | } |
| 2032 | // This code converts the original page, any underlays, and any overlays to form XObjects. | 2034 | // This code converts the original page, any underlays, and any overlays to form XObjects. |
| 2033 | // Then it concatenates display of all underlays, the original page, and all overlays. Prior | 2035 | // Then it concatenates display of all underlays, the original page, and all overlays. Prior |
| 2034 | // to 11.3.0, the original page contents were wrapped in q/Q, but this didn't work if the | 2036 | // to 11.3.0, the original page contents were wrapped in q/Q, but this didn't work if the |
| 2035 | // original page had unbalanced q/Q operators. See GitHub issue #904. | 2037 | // original page had unbalanced q/Q operators. See GitHub issue #904. |
| 2036 | - auto& dest_page = main_pages.at(page.idx); | ||
| 2037 | - auto dest_page_oh = dest_page.getObjectHandle(); | ||
| 2038 | auto this_page_fo = dest_page.getFormXObjectForPage(); | 2038 | auto this_page_fo = dest_page.getFormXObjectForPage(); |
| 2039 | // The resulting form xobject lazily reads the content from the original page, which we are | 2039 | // The resulting form xobject lazily reads the content from the original page, which we are |
| 2040 | // going to replace. Therefore, we have to explicitly copy it. | 2040 | // going to replace. Therefore, we have to explicitly copy it. |
| 2041 | auto content_data = this_page_fo.getRawStreamData(); | 2041 | auto content_data = this_page_fo.getRawStreamData(); |
| 2042 | this_page_fo.replaceStreamData(content_data, QPDFObjectHandle(), QPDFObjectHandle()); | 2042 | this_page_fo.replaceStreamData(content_data, QPDFObjectHandle(), QPDFObjectHandle()); |
| 2043 | - auto resources = | ||
| 2044 | - dest_page_oh.replaceKeyAndGetNew("/Resources", "<< /XObject << >> >>"_qpdf); | ||
| 2045 | - resources.getKey("/XObject").replaceKeyAndGetNew("/Fx0", this_page_fo); | 2043 | + auto resources = dest_page.getObjectHandle().replaceKeyAndGetNew( |
| 2044 | + "/Resources", Dictionary({{"/XObject", Dictionary({{"/Fx0", this_page_fo}})}})); | ||
| 2045 | + | ||
| 2046 | size_t uo_idx{0}; | 2046 | size_t uo_idx{0}; |
| 2047 | std::string content; | 2047 | std::string content; |
| 2048 | for (auto& underlay: m->underlay) { | 2048 | for (auto& underlay: m->underlay) { |
| @@ -2050,7 +2050,7 @@ QPDFJob::handleUnderOverlay(QPDF& pdf) | @@ -2050,7 +2050,7 @@ QPDFJob::handleUnderOverlay(QPDF& pdf) | ||
| 2050 | pdf, | 2050 | pdf, |
| 2051 | underlay, | 2051 | underlay, |
| 2052 | underlay_pagenos, | 2052 | underlay_pagenos, |
| 2053 | - page.idx, | 2053 | + dest_page_no.idx, |
| 2054 | uo_idx, | 2054 | uo_idx, |
| 2055 | underlay_fo, | 2055 | underlay_fo, |
| 2056 | upages[uo_idx], | 2056 | upages[uo_idx], |
| @@ -2070,14 +2070,15 @@ QPDFJob::handleUnderOverlay(QPDF& pdf) | @@ -2070,14 +2070,15 @@ QPDFJob::handleUnderOverlay(QPDF& pdf) | ||
| 2070 | pdf, | 2070 | pdf, |
| 2071 | overlay, | 2071 | overlay, |
| 2072 | overlay_pagenos, | 2072 | overlay_pagenos, |
| 2073 | - page.idx, | 2073 | + dest_page_no.idx, |
| 2074 | uo_idx, | 2074 | uo_idx, |
| 2075 | overlay_fo, | 2075 | overlay_fo, |
| 2076 | opages[uo_idx], | 2076 | opages[uo_idx], |
| 2077 | dest_page); | 2077 | dest_page); |
| 2078 | ++uo_idx; | 2078 | ++uo_idx; |
| 2079 | } | 2079 | } |
| 2080 | - dest_page_oh.replaceKey("/Contents", pdf.newStream(content)); | 2080 | + dest_page.getObjectHandle().replaceKey("/Contents", pdf.newStream(content)); |
| 2081 | + ++dest_page_no; | ||
| 2081 | } | 2082 | } |
| 2082 | } | 2083 | } |
| 2083 | 2084 |