Merge pull request #12296 from Snuffleupagus/mergeSubDicts

Add support, in `Dict.merge`, for merging of "sub"-dictionaries
This commit is contained in:
Tim van der Meij 2020-08-31 23:29:44 +02:00 committed by GitHub
commit 60ffac0480
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 115 additions and 18 deletions

View File

@ -114,7 +114,7 @@ class Page {
if (value.length === 1 || !isDict(value[0])) {
return value[0];
}
return Dict.merge(this.xref, value);
return Dict.merge({ xref: this.xref, dictArray: value });
}
get content() {

View File

@ -726,8 +726,10 @@ class PartialEvaluator {
const tilingOpList = new OperatorList();
// Merge the available resources, to prevent issues when the patternDict
// is missing some /Resources entries (fixes issue6541.pdf).
const resourcesArray = [patternDict.get("Resources"), resources];
const patternResources = Dict.merge(this.xref, resourcesArray);
const patternResources = Dict.merge({
xref: this.xref,
dictArray: [patternDict.get("Resources"), resources],
});
return this.getOperatorList({
stream: pattern,

View File

@ -173,22 +173,61 @@ var Dict = (function DictClosure() {
Dict.empty = new Dict(null);
Dict.merge = function (xref, dictArray) {
Dict.merge = function ({ xref, dictArray, mergeSubDicts = false }) {
const mergedDict = new Dict(xref);
for (let i = 0, ii = dictArray.length; i < ii; i++) {
const dict = dictArray[i];
if (!isDict(dict)) {
continue;
}
for (const keyName in dict._map) {
if (mergedDict._map[keyName] !== undefined) {
if (!mergeSubDicts) {
for (const dict of dictArray) {
if (!(dict instanceof Dict)) {
continue;
}
mergedDict._map[keyName] = dict._map[keyName];
for (const [key, value] of Object.entries(dict._map)) {
if (mergedDict._map[key] === undefined) {
mergedDict._map[key] = value;
}
}
}
return mergedDict.size > 0 ? mergedDict : Dict.empty;
}
const properties = new Map();
for (const dict of dictArray) {
if (!(dict instanceof Dict)) {
continue;
}
for (const [key, value] of Object.entries(dict._map)) {
let property = properties.get(key);
if (property === undefined) {
property = [];
properties.set(key, property);
}
property.push(value);
}
}
return mergedDict;
for (const [name, values] of properties) {
if (values.length === 1 || !(values[0] instanceof Dict)) {
mergedDict._map[name] = values[0];
continue;
}
const subDict = new Dict(xref);
for (const dict of values) {
if (!(dict instanceof Dict)) {
continue;
}
for (const [key, value] of Object.entries(dict._map)) {
if (subDict._map[key] === undefined) {
subDict._map[key] = value;
}
}
}
if (subDict.size > 0) {
mergedDict._map[name] = subDict;
}
}
properties.clear();
return mergedDict.size > 0 ? mergedDict : Dict.empty;
};
return Dict;

View File

@ -390,4 +390,13 @@ if (
}
Object.values = require("core-js/es/object/values.js");
})();
// Provides support for Object.entries in legacy browsers.
// Support: IE, Chrome<54
(function checkObjectEntries() {
if (Object.entries) {
return;
}
Object.entries = require("core-js/es/object/entries.js");
})();
}

View File

@ -317,16 +317,63 @@ describe("primitives", function () {
const fontFileDict = new Dict();
fontFileDict.set("FontFile", "Type1 font file");
const mergedDict = Dict.merge(null, [
dictWithManyKeys,
dictWithSizeKey,
fontFileDict,
]);
const mergedDict = Dict.merge({
xref: null,
dictArray: [dictWithManyKeys, dictWithSizeKey, fontFileDict],
});
const mergedKeys = mergedDict.getKeys();
expect(mergedKeys.sort()).toEqual(expectedKeys);
expect(mergedDict.get("FontFile")).toEqual(testFontFile);
});
it("should correctly merge sub-dictionaries", function () {
const localFontDict = new Dict();
localFontDict.set("F1", "Local font one");
const globalFontDict = new Dict();
globalFontDict.set("F1", "Global font one");
globalFontDict.set("F2", "Global font two");
globalFontDict.set("F3", "Global font three");
const localDict = new Dict();
localDict.set("Font", localFontDict);
const globalDict = new Dict();
globalDict.set("Font", globalFontDict);
const mergedDict = Dict.merge({
xref: null,
dictArray: [localDict, globalDict],
});
const mergedSubDict = Dict.merge({
xref: null,
dictArray: [localDict, globalDict],
mergeSubDicts: true,
});
const mergedFontDict = mergedDict.get("Font");
const mergedSubFontDict = mergedSubDict.get("Font");
expect(mergedFontDict instanceof Dict).toEqual(true);
expect(mergedSubFontDict instanceof Dict).toEqual(true);
const mergedFontDictKeys = mergedFontDict.getKeys();
const mergedSubFontDictKeys = mergedSubFontDict.getKeys();
expect(mergedFontDictKeys).toEqual(["F1"]);
expect(mergedSubFontDictKeys).toEqual(["F1", "F2", "F3"]);
const mergedFontDictValues = mergedFontDict.getRawValues();
const mergedSubFontDictValues = mergedSubFontDict.getRawValues();
expect(mergedFontDictValues).toEqual(["Local font one"]);
expect(mergedSubFontDictValues).toEqual([
"Local font one",
"Global font two",
"Global font three",
]);
});
});
describe("Ref", function () {