mirror of
https://github.com/qpdf/qpdf.git
synced 2025-02-09 15:18:29 +00:00
In QPDFJob::handleUnderOverlay flatten nested under/overlay_pagenos maps
Also, in QPDFJob::getUOPagenos tweak vector access and change signature to return result and make parameter const. In doUnderOverlayForPage make pagenos parameter a const&.
This commit is contained in:
parent
b84a08f447
commit
09ddce19e8
@ -514,16 +514,15 @@ class QPDFJob
|
|||||||
void handlePageSpecs(QPDF& pdf, std::vector<std::unique_ptr<QPDF>>& page_heap);
|
void handlePageSpecs(QPDF& pdf, std::vector<std::unique_ptr<QPDF>>& page_heap);
|
||||||
bool shouldRemoveUnreferencedResources(QPDF& pdf);
|
bool shouldRemoveUnreferencedResources(QPDF& pdf);
|
||||||
void handleRotations(QPDF& pdf);
|
void handleRotations(QPDF& pdf);
|
||||||
void getUOPagenos(
|
std::map<std::pair<int, size_t>, std::vector<int>>
|
||||||
std::vector<UnderOverlay>& uo, std::map<int, std::map<size_t, std::vector<int>>>& pagenos);
|
getUOPagenos(std::vector<UnderOverlay> const& uo);
|
||||||
void handleUnderOverlay(QPDF& pdf);
|
void handleUnderOverlay(QPDF& pdf);
|
||||||
std::string doUnderOverlayForPage(
|
std::string doUnderOverlayForPage(
|
||||||
QPDF& pdf,
|
QPDF& pdf,
|
||||||
std::map<unsigned long long int, std::unique_ptr<QPDFAcroFormDocumentHelper>>& afdh,
|
std::map<unsigned long long int, std::unique_ptr<QPDFAcroFormDocumentHelper>>& afdh,
|
||||||
UnderOverlay& uo,
|
UnderOverlay& uo,
|
||||||
std::map<int, std::map<size_t, std::vector<int>>>& pagenos,
|
std::map<std::pair<int, size_t>, std::vector<int>> const& pagenos,
|
||||||
size_t page_idx,
|
std::pair<int, size_t> pageno_uo_idx,
|
||||||
size_t uo_idx,
|
|
||||||
std::map<int, std::map<size_t, QPDFObjectHandle>>& fo,
|
std::map<int, std::map<size_t, QPDFObjectHandle>>& fo,
|
||||||
std::vector<QPDFPageObjectHelper>&& pages,
|
std::vector<QPDFPageObjectHelper>&& pages,
|
||||||
QPDFPageObjectHelper& dest_page);
|
QPDFPageObjectHelper& dest_page);
|
||||||
|
@ -1886,15 +1886,14 @@ QPDFJob::doUnderOverlayForPage(
|
|||||||
QPDF& pdf,
|
QPDF& pdf,
|
||||||
std::map<unsigned long long int, std::unique_ptr<QPDFAcroFormDocumentHelper>>& afdh,
|
std::map<unsigned long long int, std::unique_ptr<QPDFAcroFormDocumentHelper>>& afdh,
|
||||||
UnderOverlay& uo,
|
UnderOverlay& uo,
|
||||||
std::map<int, std::map<size_t, std::vector<int>>>& pagenos,
|
std::map<std::pair<int, size_t>, std::vector<int>> const& pagenos,
|
||||||
size_t page_idx,
|
std::pair<int, size_t> pageno_uo_idx,
|
||||||
size_t uo_idx,
|
|
||||||
std::map<int, std::map<size_t, QPDFObjectHandle>>& fo,
|
std::map<int, std::map<size_t, QPDFObjectHandle>>& fo,
|
||||||
std::vector<QPDFPageObjectHelper>&& pages,
|
std::vector<QPDFPageObjectHelper>&& pages,
|
||||||
QPDFPageObjectHelper& dest_page)
|
QPDFPageObjectHelper& dest_page)
|
||||||
{
|
{
|
||||||
int pageno = 1 + QIntC::to_int(page_idx);
|
auto pagenos_it = pagenos.find(pageno_uo_idx);
|
||||||
if (!(pagenos.count(pageno) && pagenos[pageno].count(uo_idx))) {
|
if (pagenos_it == pagenos.end()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1906,13 +1905,14 @@ QPDFJob::doUnderOverlayForPage(
|
|||||||
std::string content;
|
std::string content;
|
||||||
int min_suffix = 1;
|
int min_suffix = 1;
|
||||||
QPDFObjectHandle resources = dest_page.getAttribute("/Resources", true);
|
QPDFObjectHandle resources = dest_page.getAttribute("/Resources", true);
|
||||||
for (Page from_page: pagenos[pageno][uo_idx]) {
|
for (Page from_page: pagenos_it->second) {
|
||||||
doIfVerbose([&](Pipeline& v, std::string const& prefix) {
|
doIfVerbose([&](Pipeline& v, std::string const& prefix) {
|
||||||
v << " " << uo.filename << " " << uo.which << " " << from_page.no << "\n";
|
v << " " << uo.filename << " " << uo.which << " " << from_page.no << "\n";
|
||||||
});
|
});
|
||||||
auto from_page_ph = pages.at(from_page.idx);
|
auto from_page_ph = pages.at(from_page.idx);
|
||||||
if (fo[from_page.no].count(uo_idx) == 0) {
|
if (fo[from_page.no].count(pageno_uo_idx.second) == 0) {
|
||||||
fo[from_page.no][uo_idx] = pdf.copyForeignObject(from_page_ph.getFormXObjectForPage());
|
fo[from_page.no][pageno_uo_idx.second] =
|
||||||
|
pdf.copyForeignObject(from_page_ph.getFormXObjectForPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the same page is overlaid or underlaid multiple times, we'll generate multiple names
|
// If the same page is overlaid or underlaid multiple times, we'll generate multiple names
|
||||||
@ -1920,13 +1920,16 @@ QPDFJob::doUnderOverlayForPage(
|
|||||||
std::string name = resources.getUniqueResourceName("/Fx", min_suffix);
|
std::string name = resources.getUniqueResourceName("/Fx", min_suffix);
|
||||||
QPDFMatrix cm;
|
QPDFMatrix cm;
|
||||||
std::string new_content = dest_page.placeFormXObject(
|
std::string new_content = dest_page.placeFormXObject(
|
||||||
fo[from_page.no][uo_idx], name, dest_page.getTrimBox().getArrayAsRectangle(), cm);
|
fo[from_page.no][pageno_uo_idx.second],
|
||||||
|
name,
|
||||||
|
dest_page.getTrimBox().getArrayAsRectangle(),
|
||||||
|
cm);
|
||||||
dest_page.copyAnnotations(from_page_ph, cm, dest_afdh, make_afdh(from_page_ph));
|
dest_page.copyAnnotations(from_page_ph, cm, dest_afdh, make_afdh(from_page_ph));
|
||||||
if (!new_content.empty()) {
|
if (!new_content.empty()) {
|
||||||
resources.mergeResources("<< /XObject << >> >>"_qpdf);
|
resources.mergeResources("<< /XObject << >> >>"_qpdf);
|
||||||
auto xobject = resources.getKey("/XObject");
|
auto xobject = resources.getKey("/XObject");
|
||||||
if (xobject.isDictionary()) {
|
if (xobject.isDictionary()) {
|
||||||
xobject.replaceKey(name, fo[from_page.no][uo_idx]);
|
xobject.replaceKey(name, fo[from_page.no][pageno_uo_idx.second]);
|
||||||
}
|
}
|
||||||
++min_suffix;
|
++min_suffix;
|
||||||
content += new_content;
|
content += new_content;
|
||||||
@ -1935,27 +1938,29 @@ QPDFJob::doUnderOverlayForPage(
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
std::map<std::pair<int, size_t>, std::vector<int>>
|
||||||
QPDFJob::getUOPagenos(
|
QPDFJob::getUOPagenos(std::vector<QPDFJob::UnderOverlay> const& uos)
|
||||||
std::vector<QPDFJob::UnderOverlay>& uos,
|
|
||||||
std::map<int, std::map<size_t, std::vector<int>>>& pagenos)
|
|
||||||
{
|
{
|
||||||
|
std::map<std::pair<int, size_t>, std::vector<int>> pagenos;
|
||||||
size_t uo_idx = 0;
|
size_t uo_idx = 0;
|
||||||
for (auto const& uo: uos) {
|
for (auto const& uo: uos) {
|
||||||
size_t page_idx = 0;
|
size_t page_idx = 0;
|
||||||
size_t from_size = uo.from_pagenos.size();
|
auto from_it = uo.from_pagenos.cbegin();
|
||||||
|
auto from_end = uo.from_pagenos.cend();
|
||||||
|
auto from_size = uo.from_pagenos.size();
|
||||||
size_t repeat_size = uo.repeat_pagenos.size();
|
size_t repeat_size = uo.repeat_pagenos.size();
|
||||||
for (int to_pageno: uo.to_pagenos) {
|
for (int to_pageno: uo.to_pagenos) {
|
||||||
if (page_idx < from_size) {
|
if (from_it != from_end) {
|
||||||
pagenos[to_pageno][uo_idx].push_back(uo.from_pagenos.at(page_idx));
|
pagenos[{to_pageno, uo_idx}].emplace_back(*from_it++);
|
||||||
} else if (repeat_size) {
|
} else if (repeat_size) {
|
||||||
pagenos[to_pageno][uo_idx].push_back(
|
pagenos[{to_pageno, uo_idx}].push_back(
|
||||||
uo.repeat_pagenos.at((page_idx - from_size) % repeat_size));
|
uo.repeat_pagenos.at((page_idx - from_size) % repeat_size));
|
||||||
}
|
}
|
||||||
++page_idx;
|
++page_idx;
|
||||||
}
|
}
|
||||||
++uo_idx;
|
++uo_idx;
|
||||||
}
|
}
|
||||||
|
return pagenos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1973,10 +1978,8 @@ QPDFJob::handleUnderOverlay(QPDF& pdf)
|
|||||||
|
|
||||||
// First map key is 1-based page number. Second is index into the overlay/underlay vector. Watch
|
// First map key is 1-based page number. Second is index into the overlay/underlay vector. Watch
|
||||||
// out to not reverse the keys or be off by one.
|
// out to not reverse the keys or be off by one.
|
||||||
std::map<int, std::map<size_t, std::vector<int>>> underlay_pagenos;
|
auto underlay_pagenos = getUOPagenos(m->underlay);
|
||||||
std::map<int, std::map<size_t, std::vector<int>>> overlay_pagenos;
|
auto overlay_pagenos = getUOPagenos(m->overlay);
|
||||||
getUOPagenos(m->underlay, underlay_pagenos);
|
|
||||||
getUOPagenos(m->overlay, overlay_pagenos);
|
|
||||||
doIfVerbose([&](Pipeline& v, std::string const& prefix) {
|
doIfVerbose([&](Pipeline& v, std::string const& prefix) {
|
||||||
v << prefix << ": processing underlay/overlay\n";
|
v << prefix << ": processing underlay/overlay\n";
|
||||||
});
|
});
|
||||||
@ -1997,7 +2000,10 @@ QPDFJob::handleUnderOverlay(QPDF& pdf)
|
|||||||
for (Page page; page.idx < main_npages; ++page) {
|
for (Page page; page.idx < main_npages; ++page) {
|
||||||
doIfVerbose(
|
doIfVerbose(
|
||||||
[&](Pipeline& v, std::string const& prefix) { v << " page " << page.no << "\n"; });
|
[&](Pipeline& v, std::string const& prefix) { v << " page " << page.no << "\n"; });
|
||||||
if (underlay_pagenos[page.no].empty() && overlay_pagenos[page.no].empty()) {
|
if (underlay_pagenos.lower_bound({page.no, 0}) ==
|
||||||
|
underlay_pagenos.lower_bound({page.no + 1, 0}) &&
|
||||||
|
overlay_pagenos.lower_bound({page.no, 0}) ==
|
||||||
|
overlay_pagenos.lower_bound({page.no + 1, 0})) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// This code converts the original page, any underlays, and any overlays to form XObjects.
|
// This code converts the original page, any underlays, and any overlays to form XObjects.
|
||||||
@ -2022,8 +2028,7 @@ QPDFJob::handleUnderOverlay(QPDF& pdf)
|
|||||||
afdh,
|
afdh,
|
||||||
underlay,
|
underlay,
|
||||||
underlay_pagenos,
|
underlay_pagenos,
|
||||||
page.idx,
|
{page.no, uo_idx},
|
||||||
uo_idx,
|
|
||||||
underlay_fo,
|
underlay_fo,
|
||||||
get_pages(underlay, uo_idx),
|
get_pages(underlay, uo_idx),
|
||||||
dest_page);
|
dest_page);
|
||||||
@ -2043,8 +2048,7 @@ QPDFJob::handleUnderOverlay(QPDF& pdf)
|
|||||||
afdh,
|
afdh,
|
||||||
overlay,
|
overlay,
|
||||||
overlay_pagenos,
|
overlay_pagenos,
|
||||||
page.idx,
|
{page.no, uo_idx},
|
||||||
uo_idx,
|
|
||||||
overlay_fo,
|
overlay_fo,
|
||||||
get_pages(overlay, uo_idx),
|
get_pages(overlay, uo_idx),
|
||||||
dest_page);
|
dest_page);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user