poppler/Annot.cc | 2 +- poppler/Array.cc | 11 +++++++++++ poppler/Array.h | 2 ++ poppler/Dict.cc | 12 ++++++++++++ poppler/Dict.h | 2 ++ poppler/Object.cc | 32 ++++++++++++++++++++++++++++++++ poppler/Object.h | 7 ++++++- 7 files changed, 66 insertions(+), 2 deletions(-)
New commits: commit d6a34e2ca8b74cfdf9a1d58edb072e0aee26b233 Author: Albert Astals Cid <[email protected]> Date: Thu Nov 18 23:27:24 2021 +0100 AnnotWidget::generateFieldAppearance: Do not modify the Form DR dict diff --git a/poppler/Annot.cc b/poppler/Annot.cc index 0dfbd731..9f2289b5 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -5089,7 +5089,7 @@ void AnnotWidget::generateFieldAppearance() if (!resourcesDictObj.isDict()) { // No luck with a field's resource dictionary. Let's use an AcroForm's resource dictionary. if (form && form->getDefaultResourcesObj()->isDict()) { - resourcesDictObj = form->getDefaultResourcesObj()->copy(); + resourcesDictObj = form->getDefaultResourcesObj()->deepCopy(); resources = form->getDefaultResources(); } } diff --git a/poppler/Array.cc b/poppler/Array.cc index a8df2d72..2f9de6cd 100644 --- a/poppler/Array.cc +++ b/poppler/Array.cc @@ -57,6 +57,17 @@ Array *Array::copy(XRef *xrefA) const return a; } +Array *Array::deepCopy() const +{ + arrayLocker(); + Array *a = new Array(xref); + a->elems.reserve(elems.size()); + for (const auto &elem : elems) { + a->elems.push_back(elem.deepCopy()); + } + return a; +} + void Array::add(Object &&elem) { arrayLocker(); diff --git a/poppler/Array.h b/poppler/Array.h index 638a1f94..50bc9d0a 100644 --- a/poppler/Array.h +++ b/poppler/Array.h @@ -60,6 +60,8 @@ public: // Copy array with new xref Array *copy(XRef *xrefA) const; + Array *deepCopy() const; + // Add an element // elem becomes a dead object after this call void add(Object &&elem); diff --git a/poppler/Dict.cc b/poppler/Dict.cc index 222257d3..6fc70bc4 100644 --- a/poppler/Dict.cc +++ b/poppler/Dict.cc @@ -85,6 +85,18 @@ Dict *Dict::copy(XRef *xrefA) const return dictA; } +Dict *Dict::deepCopy() const +{ + dictLocker(); + Dict *dictA = new Dict(xref); + + dictA->entries.reserve(entries.size()); + for (auto &entry : entries) { + dictA->entries.emplace_back(entry.first, entry.second.deepCopy()); + } + return dictA; +} + void Dict::add(const char *key, Object &&val) { dictLocker(); diff --git a/poppler/Dict.h b/poppler/Dict.h index 6a4d456b..1639ab44 100644 --- a/poppler/Dict.h +++ b/poppler/Dict.h @@ -52,6 +52,8 @@ public: explicit Dict(const Dict *dictA); Dict *copy(XRef *xrefA) const; + Dict *deepCopy() const; + Dict(const Dict &) = delete; Dict &operator=(const Dict &) = delete; diff --git a/poppler/Object.cc b/poppler/Object.cc index 49ddfbf5..06016aad 100644 --- a/poppler/Object.cc +++ b/poppler/Object.cc @@ -71,6 +71,38 @@ Object Object::copy() const return obj; } +Object Object::deepCopy() const +{ + CHECK_NOT_DEAD; + + Object obj; + std::memcpy(reinterpret_cast<void *>(&obj), this, sizeof(Object)); + + switch (type) { + case objString: + case objHexString: + obj.string = string->copy(); + break; + case objName: + case objCmd: + obj.cString = copyString(cString); + break; + case objArray: + obj.array = array->deepCopy(); + break; + case objDict: + obj.dict = dict->deepCopy(); + break; + case objStream: + stream->incRef(); + break; + default: + break; + } + + return obj; +} + Object Object::fetch(XRef *xref, int recursion) const { CHECK_NOT_DEAD; diff --git a/poppler/Object.h b/poppler/Object.h index 1ce75211..d5ca59d0 100644 --- a/poppler/Object.h +++ b/poppler/Object.h @@ -263,9 +263,14 @@ public: type = objNull; } - // Copy this to obj + // Copies all object types except + // objArray, objDict, objStream whose refcount is increased by 1 Object copy() const; + // Deep copies all object types (recursively) + // except objStream whose refcount is increased by 1 + Object deepCopy() const; + // If object is a Ref, fetch and return the referenced object. // Otherwise, return a copy of the object. Object fetch(XRef *xref, int recursion = 0) const;
