diff options
author | Jay Berkenbilt <ejb@ql.org> | 2019-01-03 03:44:10 +0100 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2019-01-03 03:49:47 +0100 |
commit | f78ea057ca766e083c53f1c0284944b96a42b1b8 (patch) | |
tree | 226c9ac1a88d1189f134c766160179d2f34245b2 /libqpdf/QPDFPageDocumentHelper.cc | |
parent | 23bcfeb3362c98d598dd8c5db603238ebac66f19 (diff) | |
download | qpdf-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.cc | 40 |
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 { |