summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--include/qpdf/QPDFObjectHandle.hh12
-rw-r--r--libqpdf/QPDFObjectHandle.cc24
-rw-r--r--libqpdf/QPDFPageDocumentHelper.cc26
4 files changed, 43 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index c04b2333..5e327abc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2019-01-25 Jay Berkenbilt <ejb@ql.org>
+ * Add new method QPDFObjectHandle::getUniqueResourceName() to
+ return an unused key available to be used in a resource
+ dictionary.
+
* Add new method QPDFPageObjectHelper::getAttribute() that
properly handles inherited attributes and allows for creation of a
copy of shared attributes. This is very useful if you are getting
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index d6bb1a3b..b181bd79 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -600,6 +600,18 @@ class QPDFObjectHandle
QPDF_DLL
std::set<std::string> getResourceNames();
+ // Find a unique name within a resource dictionary starting with a
+ // given prefix. This method works by appending a number to the
+ // given prefix. It searches starting with min_suffix and sets
+ // min_suffix to selected value upon return. This can be used to
+ // increase efficiency if adding multiple items with the same
+ // prefix. (Why doesn't it set min_suffix to the next number?
+ // Well, maybe you aren't going to actually use the name it
+ // returns.)
+ QPDF_DLL
+ std::string getUniqueResourceName(std::string const& prefix,
+ int& min_suffix);
+
// Return the QPDF object that owns an indirect object. Returns
// null for a direct object.
QPDF_DLL
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index b802a55c..4e77bbaa 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -931,6 +931,30 @@ QPDFObjectHandle::getResourceNames()
return result;
}
+std::string
+QPDFObjectHandle::getUniqueResourceName(std::string const& prefix,
+ int& min_suffix)
+{
+ std::set<std::string> names = getResourceNames();
+ int max_suffix = min_suffix + names.size();
+ while (min_suffix <= max_suffix)
+ {
+ std::string candidate = prefix + QUtil::int_to_string(min_suffix);
+ if (names.count(candidate) == 0)
+ {
+ return candidate;
+ }
+ // Increment after return; min_suffix should be the value
+ // used, not the next value.
+ ++min_suffix;
+ }
+ // This could only happen if there is a coding error.
+ // The number of candidates we test is more than the
+ // number of keys we're checking against.
+ throw std::logic_error("unable to find unconflicting name in"
+ " QPDFObjectHandle::getUniqueResourceName");
+}
+
// Indirect object accessors
QPDF*
QPDFObjectHandle::getOwningQPDF()
diff --git a/libqpdf/QPDFPageDocumentHelper.cc b/libqpdf/QPDFPageDocumentHelper.cc
index 3eec789b..58d6ed22 100644
--- a/libqpdf/QPDFPageDocumentHelper.cc
+++ b/libqpdf/QPDFPageDocumentHelper.cc
@@ -155,35 +155,15 @@ QPDFPageDocumentHelper::flattenAnnotationsForPage(
{
QTC::TC("qpdf", "QPDFPageDocumentHelper non-widget annotation");
}
- std::set<std::string> names = resources.getResourceNames();
- std::string name;
- int max_fx = next_fx + names.size() + 1;
- while (next_fx <= max_fx)
- {
- std::string candidate = "/Fxo" + QUtil::int_to_string(next_fx);
- if (names.count(candidate) == 0)
- {
- name = candidate;
- break;
- }
- ++next_fx;
- }
- if (name.empty())
- {
- // This could only happen if there is a coding error.
- // The number of candidates we test is more than the
- // number of keys we're checking against.
- name = "/FxConflict";
- }
+ std::string name = resources.getUniqueResourceName(
+ "/Fxo", next_fx);
std::string content = aoh.getPageContentForAppearance(
name, rotate, required_flags, forbidden_flags);
if (! content.empty())
{
resources.mergeResources(
- QPDFObjectHandle::parse(
- "<< /XObject << " + name + " null >> >>"));
+ QPDFObjectHandle::parse("<< /XObject << >> >>"));
resources.getKey("/XObject").replaceKey(name, as);
- names.insert(name);
++next_fx;
}
new_content += content;