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';
|
} 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,32 @@ 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);
|
var graphicState = graphicStates.get(key);
|
||||||
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 +230,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…
x
Reference in New Issue
Block a user