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