mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-25 17:48:07 +02:00
Doesn't traverse cyclic references in Dict.getAll; reduces empty-Dict garbage
This commit is contained in:
parent
9a36184dfa
commit
31f081ae17
7 changed files with 93 additions and 18 deletions
|
@ -62,11 +62,30 @@ var Dict = (function DictClosure() {
|
|||
return nonSerializable; // creating closure on some variable
|
||||
};
|
||||
|
||||
var GETALL_DICTIONARY_TYPES_WHITELIST = {
|
||||
'Background': true,
|
||||
'ExtGState': true,
|
||||
'Halftone': true,
|
||||
'Layout': true,
|
||||
'Mask': true,
|
||||
'Pagination': true,
|
||||
'Printing': true
|
||||
};
|
||||
|
||||
function isRecursionAllowedFor(dict) {
|
||||
if (!isName(dict.Type)) {
|
||||
return true;
|
||||
}
|
||||
var dictType = dict.Type.name;
|
||||
return GETALL_DICTIONARY_TYPES_WHITELIST[dictType] === true;
|
||||
}
|
||||
|
||||
// xref is optional
|
||||
function Dict(xref) {
|
||||
// Map should only be used internally, use functions below to access.
|
||||
this.map = Object.create(null);
|
||||
this.xref = xref;
|
||||
this.objId = null;
|
||||
this.__nonSerializable__ = nonSerializable; // disable cloning of the Dict
|
||||
}
|
||||
|
||||
|
@ -130,10 +149,51 @@ var Dict = (function DictClosure() {
|
|||
|
||||
// creates new map and dereferences all Refs
|
||||
getAll: function Dict_getAll() {
|
||||
var all = {};
|
||||
var all = Object.create(null);
|
||||
var queue = null;
|
||||
for (var key in this.map) {
|
||||
var obj = this.get(key);
|
||||
all[key] = (obj instanceof Dict ? obj.getAll() : obj);
|
||||
if (obj instanceof Dict) {
|
||||
if (isRecursionAllowedFor(obj)) {
|
||||
(queue || (queue = [])).push({target: all, key: key, obj: obj});
|
||||
} else {
|
||||
all[key] = this.getRaw(key);
|
||||
}
|
||||
} else {
|
||||
all[key] = obj;
|
||||
}
|
||||
}
|
||||
if (!queue) {
|
||||
return all;
|
||||
}
|
||||
|
||||
// trying to take cyclic references into the account
|
||||
var processed = Object.create(null);
|
||||
while (queue.length > 0) {
|
||||
var item = queue.shift();
|
||||
var itemObj = item.obj;
|
||||
var objId = itemObj.objId;
|
||||
if (objId && objId in processed) {
|
||||
item.target[item.key] = processed[objId];
|
||||
continue;
|
||||
}
|
||||
var dereferenced = Object.create(null);
|
||||
for (var key in itemObj.map) {
|
||||
var obj = itemObj.get(key);
|
||||
if (obj instanceof Dict) {
|
||||
if (isRecursionAllowedFor(obj)) {
|
||||
queue.push({target: dereferenced, key: key, obj: obj});
|
||||
} else {
|
||||
dereferenced[key] = itemObj.getRaw(key);
|
||||
}
|
||||
} else {
|
||||
dereferenced[key] = obj;
|
||||
}
|
||||
}
|
||||
if (objId) {
|
||||
processed[objId] = dereferenced;
|
||||
}
|
||||
item.target[item.key] = dereferenced;
|
||||
}
|
||||
return all;
|
||||
},
|
||||
|
@ -153,6 +213,8 @@ var Dict = (function DictClosure() {
|
|||
}
|
||||
};
|
||||
|
||||
Dict.empty = new Dict(null);
|
||||
|
||||
return Dict;
|
||||
})();
|
||||
|
||||
|
@ -1061,10 +1123,15 @@ var XRef = (function XRefClosure() {
|
|||
}
|
||||
|
||||
if (xrefEntry.uncompressed) {
|
||||
return this.fetchUncompressed(ref, xrefEntry, suppressEncryption);
|
||||
xrefEntry = this.fetchUncompressed(ref, xrefEntry, suppressEncryption);
|
||||
} else {
|
||||
return this.fetchCompressed(xrefEntry, suppressEncryption);
|
||||
xrefEntry = this.fetchCompressed(xrefEntry, suppressEncryption);
|
||||
}
|
||||
|
||||
if (isDict(xrefEntry)) {
|
||||
xrefEntry.objId = 'R' + ref.num + '.' + ref.gen;
|
||||
}
|
||||
return xrefEntry;
|
||||
},
|
||||
|
||||
fetchUncompressed: function XRef_fetchUncompressed(ref, xrefEntry,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue