Merge pull request #11232 from Snuffleupagus/hasBlendModes-improvements
Cache processed 'ExtGState's in `PartialEvaluator.hasBlendModes` to avoid unnecessary parsing/lookups
This commit is contained in:
commit
c701ae3f4c
@ -21,7 +21,7 @@ import {
|
|||||||
} from '../shared/util';
|
} from '../shared/util';
|
||||||
import { CMapFactory, IdentityCMap } from './cmap';
|
import { CMapFactory, IdentityCMap } from './cmap';
|
||||||
import {
|
import {
|
||||||
Cmd, Dict, EOF, isDict, isName, isRef, isStream, Name
|
Cmd, Dict, EOF, isDict, isName, isRef, isStream, Name, Ref
|
||||||
} from './primitives';
|
} from './primitives';
|
||||||
import {
|
import {
|
||||||
ErrorFont, Font, FontFlags, getFontType, IdentityToUnicodeMap, ToUnicodeMap
|
ErrorFont, Font, FontFlags, getFontType, IdentityToUnicodeMap, ToUnicodeMap
|
||||||
@ -180,7 +180,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
hasBlendModes: function PartialEvaluator_hasBlendModes(resources) {
|
hasBlendModes: function PartialEvaluator_hasBlendModes(resources) {
|
||||||
if (!isDict(resources)) {
|
if (!(resources instanceof Dict)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,33 +191,44 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
|
|
||||||
var nodes = [resources], xref = this.xref;
|
var nodes = [resources], xref = this.xref;
|
||||||
while (nodes.length) {
|
while (nodes.length) {
|
||||||
var key, i, ii;
|
|
||||||
var node = nodes.shift();
|
var node = nodes.shift();
|
||||||
// First check the current resources for blend modes.
|
// First check the current resources for blend modes.
|
||||||
var graphicStates = node.get('ExtGState');
|
var graphicStates = node.get('ExtGState');
|
||||||
if (isDict(graphicStates)) {
|
if (graphicStates instanceof Dict) {
|
||||||
var graphicStatesKeys = graphicStates.getKeys();
|
var graphicStatesKeys = graphicStates.getKeys();
|
||||||
for (i = 0, ii = graphicStatesKeys.length; i < ii; i++) {
|
for (let i = 0, ii = graphicStatesKeys.length; i < ii; i++) {
|
||||||
key = graphicStatesKeys[i];
|
const key = graphicStatesKeys[i];
|
||||||
|
|
||||||
var graphicState = graphicStates.get(key);
|
let graphicState = graphicStates.getRaw(key);
|
||||||
|
if (graphicState instanceof Ref) {
|
||||||
|
if (processed[graphicState.toString()]) {
|
||||||
|
continue; // The ExtGState has already been processed.
|
||||||
|
}
|
||||||
|
graphicState = xref.fetch(graphicState);
|
||||||
|
}
|
||||||
|
if (!(graphicState instanceof Dict)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (graphicState.objId) {
|
||||||
|
processed[graphicState.objId] = true;
|
||||||
|
}
|
||||||
var bm = graphicState.get('BM');
|
var bm = graphicState.get('BM');
|
||||||
if (isName(bm) && bm.name !== 'Normal') {
|
if ((bm instanceof Name) && bm.name !== 'Normal') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Descend into the XObjects to look for more resources and blend modes.
|
// Descend into the XObjects to look for more resources and blend modes.
|
||||||
var xObjects = node.get('XObject');
|
var xObjects = node.get('XObject');
|
||||||
if (!isDict(xObjects)) {
|
if (!(xObjects instanceof Dict)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var xObjectsKeys = xObjects.getKeys();
|
var xObjectsKeys = xObjects.getKeys();
|
||||||
for (i = 0, ii = xObjectsKeys.length; i < ii; i++) {
|
for (let i = 0, ii = xObjectsKeys.length; i < ii; i++) {
|
||||||
key = xObjectsKeys[i];
|
const key = xObjectsKeys[i];
|
||||||
|
|
||||||
var xObject = xObjects.getRaw(key);
|
var xObject = xObjects.getRaw(key);
|
||||||
if (isRef(xObject)) {
|
if (xObject instanceof Ref) {
|
||||||
if (processed[xObject.toString()]) {
|
if (processed[xObject.toString()]) {
|
||||||
// The XObject has already been processed, and by avoiding a
|
// The XObject has already been processed, and by avoiding a
|
||||||
// redundant `xref.fetch` we can *significantly* reduce the load
|
// redundant `xref.fetch` we can *significantly* reduce the load
|
||||||
@ -231,14 +242,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
}
|
}
|
||||||
if (xObject.dict.objId) {
|
if (xObject.dict.objId) {
|
||||||
if (processed[xObject.dict.objId]) {
|
if (processed[xObject.dict.objId]) {
|
||||||
// stream has objId and is processed already
|
continue; // Stream has objId and was processed already.
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
processed[xObject.dict.objId] = true;
|
processed[xObject.dict.objId] = true;
|
||||||
}
|
}
|
||||||
var xResources = xObject.dict.get('Resources');
|
var xResources = xObject.dict.get('Resources');
|
||||||
// Checking objId to detect an infinite loop.
|
// Checking objId to detect an infinite loop.
|
||||||
if (isDict(xResources) &&
|
if ((xResources instanceof Dict) &&
|
||||||
(!xResources.objId || !processed[xResources.objId])) {
|
(!xResources.objId || !processed[xResources.objId])) {
|
||||||
nodes.push(xResources);
|
nodes.push(xResources);
|
||||||
if (xResources.objId) {
|
if (xResources.objId) {
|
||||||
|
Loading…
Reference in New Issue
Block a user