diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 46c45fd58..91d7b610d 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -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) {