Inline all the possible type checks in PartialEvaluator.hasBlendModes
to avoid unnecessary function calls
For badly generated PDF documents, with issue 6961 being one example, there's well over one hundred thousand function calls being made in total for just the *two* pages.
This commit is contained in:
parent
dcf49ac753
commit
af71f9b40a
@ -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,32 @@ 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);
|
||||
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 +230,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…
x
Reference in New Issue
Block a user