aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDFObjectHandle.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/QPDFObjectHandle.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/QPDFObjectHandle.cc')
-rw-r--r--libqpdf/QPDFObjectHandle.cc80
1 files changed, 41 insertions, 39 deletions
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index 300027b9..a0d45c86 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -826,23 +826,8 @@ QPDFObjectHandle::isOrHasName(std::string const& value)
}
void
-QPDFObjectHandle::mergeDictionary(QPDFObjectHandle other)
+QPDFObjectHandle::mergeResources(QPDFObjectHandle other)
{
- std::set<QPDFObjGen> visiting;
- mergeDictionaryInternal(other, visiting, 0);
-}
-
-void
-QPDFObjectHandle::mergeDictionaryInternal(
- QPDFObjectHandle other,
- std::set<QPDFObjGen>& visiting,
- int depth)
-{
- if (depth > 100)
- {
- // Arbitrarily limit depth to avoid stack overflow
- return;
- }
if (! (isDictionary() && other.isDictionary()))
{
QTC::TC("qpdf", "QPDFObjectHandle merge top type mismatch");
@@ -859,33 +844,22 @@ QPDFObjectHandle::mergeDictionaryInternal(
QPDFObjectHandle this_val = getKey(key);
if (this_val.isDictionary() && other_val.isDictionary())
{
- if (this_val.isIndirect() && other_val.isIndirect() &&
- (this_val.getObjGen() == other_val.getObjGen()))
+ if (this_val.isIndirect())
{
- QTC::TC("qpdf", "QPDFObjectHandle merge equal indirect");
+ QTC::TC("qpdf", "QPDFObjectHandle replace with copy");
+ this_val = this_val.shallowCopy();
+ replaceKey(key, this_val);
}
- else if (this_val.isIndirect() &&
- (visiting.count(this_val.getObjGen())))
+ std::set<std::string> other_val_keys = other_val.getKeys();
+ for (std::set<std::string>::iterator i2 =
+ other_val_keys.begin();
+ i2 != other_val_keys.end(); ++i2)
{
- QTC::TC("qpdf", "QPDFObjectHandle merge loop");
- }
- else
- {
- QPDFObjGen loop;
- if (this_val.isIndirect())
+ if (! this_val.hasKey(*i2))
{
- loop = this_val.getObjGen();
- visiting.insert(loop);
QTC::TC("qpdf", "QPDFObjectHandle merge shallow copy");
- this_val = this_val.shallowCopy();
- replaceKey(key, this_val);
- }
- QTC::TC("qpdf", "QPDFObjectHandle nested merge");
- this_val.mergeDictionaryInternal(
- other_val, visiting, 1 + depth);
- if (loop.getObj())
- {
- visiting.erase(loop);
+ this_val.replaceKey(
+ *i2, other_val.getKey(*i2).shallowCopy());
}
}
}
@@ -923,9 +897,37 @@ QPDFObjectHandle::mergeDictionaryInternal(
else
{
QTC::TC("qpdf", "QPDFObjectHandle merge copy from other");
- replaceKey(key, other_val);
+ replaceKey(key, other_val.shallowCopy());
+ }
+ }
+}
+
+std::set<std::string>
+QPDFObjectHandle::getResourceNames()
+{
+ // Return second-level dictionary keys
+ std::set<std::string> result;
+ if (! isDictionary())
+ {
+ return result;
+ }
+ std::set<std::string> keys = getKeys();
+ for (std::set<std::string>::iterator iter = keys.begin();
+ iter != keys.end(); ++iter)
+ {
+ std::string const& key = *iter;
+ QPDFObjectHandle val = getKey(key);
+ if (val.isDictionary())
+ {
+ std::set<std::string> val_keys = val.getKeys();
+ for (std::set<std::string>::iterator i2 = val_keys.begin();
+ i2 != val_keys.end(); ++i2)
+ {
+ result.insert(*i2);
+ }
}
}
+ return result;
}
// Indirect object accessors