summaryrefslogtreecommitdiff
path: root/Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc')
-rw-r--r--Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc136
1 files changed, 78 insertions, 58 deletions
diff --git a/Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc b/Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc
index 5f56111581e..9a53d9c9e97 100644
--- a/Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc
+++ b/Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc
@@ -7,8 +7,8 @@
// Copyright 2013, 2014 Igalia S.L.
// Copyright 2014 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright 2017 Jan-Erik S <janerik234678@gmail.com>
-// Copyright 2017 Albert Astals Cid <aacid@kde.org>
-// Copyright 2017 Adrian Johnson <ajohnson@redneon.com>
+// Copyright 2017, 2018 Albert Astals Cid <aacid@kde.org>
+// Copyright 2017, 2018 Adrian Johnson <ajohnson@redneon.com>
//
//========================================================================
@@ -53,52 +53,9 @@ void StructTreeRoot::parse(Dict *root)
// corresponsing structure element. Here only the references are
// loaded into the array, the pointers to the StructElements will
// be filled-in later when parsing them.
- Object obj = root->lookup("ParentTree");
- if (obj.isDict()) {
- Object nums = obj.dictLookup("Nums");
- if (nums.isArray()) {
- if (nums.arrayGetLength() % 2 == 0) {
- parentTree.resize(nums.arrayGetLength() / 2);
- // Index numbers in even positions, references in odd ones
- for (int i = 0; i < nums.arrayGetLength(); i += 2) {
- Object index = nums.arrayGet(i);
-
- if (!index.isInt()) {
- error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i, index.getTypeName());
- continue;
- }
- const int idx = index.getInt();
- if (idx < 0 || idx >= (int)parentTree.size()) {
- error(errSyntaxError, -1, "Nums item at position {0:d} is invalid value ({1:d}): [0..{2:d}]", i, idx, parentTree.size() - 1);
- continue;
- }
-
- Object value = nums.arrayGetNF(i + 1);
- if (value.isRef()) {
- parentTree[idx].resize(1);
- parentTree[idx][0].ref = value.getRef();
- } else {
- value = nums.arrayGet(i + 1);
- if (value.isArray()) {
- parentTree[idx].resize(value.arrayGetLength());
- for (int j = 0; j < value.arrayGetLength(); j++) {
- Object itemvalue = value.arrayGetNF(j);
- if (itemvalue.isRef())
- parentTree[idx][j].ref = itemvalue.getRef();
- else
- error(errSyntaxError, -1, "Nums array item at position {0:d}/{1:d} is invalid type ({2:s})", i, j, itemvalue.getTypeName());
- }
- } else {
- error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i + 1, value.getTypeName());
- }
- }
- }
- } else {
- error(errSyntaxError, -1, "Nums array length is not a even ({0:d})", nums.arrayGetLength());
- }
- } else {
- error(errSyntaxError, -1, "Nums object is wrong type ({0:s})", nums.getTypeName());
- }
+ const Object parentTreeObj = root->lookup("ParentTree");
+ if (parentTreeObj.isDict()) {
+ parseNumberTreeNode(parentTreeObj.getDict());
}
std::set<int> seenElements;
@@ -117,7 +74,7 @@ void StructTreeRoot::parse(Dict *root)
}
Object obj = kids.arrayGet(i);
if (obj.isDict()) {
- StructElement *child = new StructElement(obj.getDict(), this, NULL, seenElements);
+ StructElement *child = new StructElement(obj.getDict(), this, nullptr, seenElements);
if (child->isOk()) {
if (marked && !(child->getType() == StructElement::Document ||
child->getType() == StructElement::Part ||
@@ -138,10 +95,7 @@ void StructTreeRoot::parse(Dict *root)
}
}
} else if (kids.isDict()) {
- if (marked) {
- error(errSyntaxWarning, -1, "K has a child of wrong type for a tagged PDF ({0:s})", kids.getTypeName());
- }
- StructElement *child = new StructElement(kids.getDict(), this, NULL, seenElements);
+ StructElement *child = new StructElement(kids.getDict(), this, nullptr, seenElements);
if (child->isOk()) {
appendChild(child);
Object ref = root->lookupNF("K");
@@ -154,14 +108,80 @@ void StructTreeRoot::parse(Dict *root)
} else if (!kids.isNull()) {
error(errSyntaxWarning, -1, "K in StructTreeRoot is wrong type ({0:s})", kids.getTypeName());
}
+
+ // refToParentMap is only used during parsing. Ensure all memory used by it is freed.
+ std::multimap<Ref, Parent*, RefCompare>().swap(refToParentMap);
}
-void StructTreeRoot::parentTreeAdd(const Ref &objectRef, StructElement *element)
+void StructTreeRoot::parseNumberTreeNode(Dict *node)
{
- for (std::vector< std::vector<Parent> >::iterator i = parentTree.begin(); i != parentTree.end(); ++i) {
- for (std::vector<Parent>::iterator j = i->begin(); j != i->end(); ++j) {
- if (j->ref.num == objectRef.num && j->ref.gen == objectRef.gen)
- j->element = element;
+ Object kids = node->lookup("Kids");
+ if (kids.isArray()) {
+ for (int i = 0; i < kids.arrayGetLength(); i++) {
+ Object obj = kids.arrayGet(i);
+ if (obj.isDict()) {
+ parseNumberTreeNode(obj.getDict());
+ } else {
+ error(errSyntaxError, -1, "Kids item at position {0:d} is wrong type ({1:s})", i, obj.getTypeName());
+ }
}
+ return;
+ } else if (!kids.isNull()) {
+ error(errSyntaxError, -1, "Kids object is wrong type ({0:s})", kids.getTypeName());
}
+
+ Object nums = node->lookup("Nums");
+ if (nums.isArray()) {
+ if (nums.arrayGetLength() % 2 == 0) {
+ // keys in even positions, references in odd ones
+ for (int i = 0; i < nums.arrayGetLength(); i += 2) {
+ Object key = nums.arrayGet(i);
+
+ if (!key.isInt()) {
+ error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i, key.getTypeName());
+ continue;
+ }
+ int keyVal = key.getInt();
+ std::vector<Parent>& vec = parentTree[keyVal];
+
+ Object value = nums.arrayGet(i + 1);
+ if (value.isArray()) {
+ vec.resize(value.arrayGetLength());
+ memset(vec.data(), 0, vec.size()*sizeof(Parent*));
+ for (int j = 0; j < value.arrayGetLength(); j++) {
+ Object itemvalue = value.arrayGetNF(j);
+ if (itemvalue.isRef()) {
+ Ref ref = itemvalue.getRef();
+ vec[j].ref = ref;
+ refToParentMap.insert(std::pair<Ref, Parent*>(ref, &vec[j]));
+ } else if (!itemvalue.isNull()) {
+ error(errSyntaxError, -1, "Nums array item at position {0:d}/{1:d} is invalid type ({2:s})", i, j, itemvalue.getTypeName());
+ }
+ }
+ } else {
+ value = nums.arrayGetNF(i + 1);
+ if (value.isRef()) {
+ Ref ref = value.getRef();
+ vec.resize(1);
+ vec[0].ref = ref;
+ refToParentMap.insert(std::pair<Ref, Parent*>(ref, &vec[0]));
+ } else {
+ error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i + 1, value.getTypeName());
+ }
+ }
+ }
+ } else {
+ error(errSyntaxError, -1, "Nums array length is not a even ({0:d})", nums.arrayGetLength());
+ }
+ } else {
+ error(errSyntaxError, -1, "Nums object is wrong type ({0:s})", nums.getTypeName());
+ }
+}
+
+
+void StructTreeRoot::parentTreeAdd(const Ref &objectRef, StructElement *element)
+{
+ auto range = refToParentMap.equal_range(objectRef);
+ for (auto it = range.first; it !=range.second; ++it)
+ it->second->element = element;
}