aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDFPageDocumentHelper.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2019-01-03 03:44:10 +0100
committerJay Berkenbilt <ejb@ql.org>2019-01-03 03:49:47 +0100
commitf78ea057ca766e083c53f1c0284944b96a42b1b8 (patch)
tree226c9ac1a88d1189f134c766160179d2f34245b2 /libqpdf/QPDFPageDocumentHelper.cc
parent23bcfeb3362c98d598dd8c5db603238ebac66f19 (diff)
downloadqpdf-f78ea057ca766e083c53f1c0284944b96a42b1b8.tar.zst
Switch annotation flattening to use the form xobjects
Instead of directly putting the contents of the annotation appearance streams into the page's content stream, add commands to render the form xobjects directly. This is a more robust way to do it than the original solution as it works properly with patterns and avoids problems with resource name clashes between the pages and the form xobjects.
Diffstat (limited to 'libqpdf/QPDFPageDocumentHelper.cc')
-rw-r--r--libqpdf/QPDFPageDocumentHelper.cc40
1 files changed, 37 insertions, 3 deletions
diff --git a/libqpdf/QPDFPageDocumentHelper.cc b/libqpdf/QPDFPageDocumentHelper.cc
index 4d117017..7b171e9a 100644
--- a/libqpdf/QPDFPageDocumentHelper.cc
+++ b/libqpdf/QPDFPageDocumentHelper.cc
@@ -1,5 +1,6 @@
#include <qpdf/QPDFPageDocumentHelper.hh>
#include <qpdf/QPDFAcroFormDocumentHelper.hh>
+#include <qpdf/QUtil.hh>
#include <qpdf/QTC.hh>
QPDFPageDocumentHelper::Members::~Members()
@@ -121,6 +122,7 @@ QPDFPageDocumentHelper::flattenAnnotationsForPage(
{
rotate = rotate_obj.getIntValue();
}
+ int next_fx = 1;
for (std::vector<QPDFAnnotationObjectHelper>::iterator iter =
annots.begin();
iter != annots.end(); ++iter)
@@ -140,18 +142,50 @@ QPDFPageDocumentHelper::flattenAnnotationsForPage(
}
if (process)
{
- resources.mergeDictionary(as.getDict().getKey("/Resources"));
if (is_widget)
{
QTC::TC("qpdf", "QPDFPageDocumentHelper merge DR");
QPDFFormFieldObjectHelper ff = afdh.getFieldForAnnotation(aoh);
- resources.mergeDictionary(ff.getInheritableFieldValue("/DR"));
+ QPDFObjectHandle as_resources =
+ as.getDict().getKey("/Resources");
+ if (as_resources.isIndirect())
+ {
+ QTC::TC("qpdf", "QPDFPageDocumentHelper indirect as resources");
+ as.getDict().replaceKey(
+ "/Resources", as_resources.shallowCopy());
+ as_resources = as.getDict().getKey("/Resources");
+ }
+ as_resources.mergeResources(
+ ff.getInheritableFieldValue("/DR"));
}
else
{
QTC::TC("qpdf", "QPDFPageDocumentHelper non-widget annotation");
}
- new_content += aoh.getPageContentForAppearance(rotate);
+ std::set<std::string> names = resources.getResourceNames();
+ std::string name;
+ while (next_fx < 1000000)
+ {
+ std::string candidate = "/Fxo" + QUtil::int_to_string(next_fx);
+ ++next_fx;
+ if (names.count(candidate) == 0)
+ {
+ name = candidate;
+ break;
+ }
+ }
+ if (name.empty())
+ {
+ // There are already more than a million /Fxo names.
+ // Somehow I doubt this is going to actually happen.
+ // Just pick a name and forget conflicts.
+ name = "/FxConflict";
+ }
+ resources.mergeResources(
+ QPDFObjectHandle::parse(
+ "<< /XObject << " + name + " null >> >>"));
+ resources.getKey("/XObject").replaceKey(name, as);
+ new_content += aoh.getPageContentForAppearance(name, rotate);
}
else
{