Skip to content

Commit

Permalink
Add local caching of non-font Graphics State (ExtGState) data in `Par…
Browse files Browse the repository at this point in the history
…tialEvaluator.getTextContent`
  • Loading branch information
Snuffleupagus committed Jul 11, 2020
1 parent 239abc8 commit 6ea824e
Showing 1 changed file with 61 additions and 17 deletions.
78 changes: 61 additions & 17 deletions src/core/evaluator.js
Original file line number Diff line number Diff line change
Expand Up @@ -1866,6 +1866,7 @@ class PartialEvaluator {
// The xobj is parsed iff it's needed, e.g. if there is a `DO` cmd.
var xobjs = null;
const emptyXObjectCache = new LocalImageCache();
const emptyGStateCache = new LocalGStateCache();

var preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager);

Expand Down Expand Up @@ -2442,25 +2443,68 @@ class PartialEvaluator {
);
return;
case OPS.setGState:
flushTextContentItem();
var dictName = args[0];
var extGState = resources.get("ExtGState");

if (!isDict(extGState) || !isName(dictName)) {
break;
}
var gState = extGState.get(dictName.name);
if (!isDict(gState)) {
name = args[0].name;
if (name && emptyGStateCache.getByName(name)) {
break;
}
var gStateFont = gState.get("Font");
if (gStateFont) {
textState.fontName = null;
textState.fontSize = gStateFont[1];
next(handleSetFont(null, gStateFont[0]));
return;
}
break;

next(
new Promise(function (resolveGState, rejectGState) {
if (!name) {
throw new FormatError("GState must be referred to by name.");
}

const extGState = resources.get("ExtGState");
if (!(extGState instanceof Dict)) {
throw new FormatError("ExtGState should be a dictionary.");
}

let gState = extGState.getRaw(name);
if (gState instanceof Ref) {
if (emptyGStateCache.getByRef(gState)) {
resolveGState();
return;
}

gState = xref.fetch(gState);
}

if (!(gState instanceof Dict)) {
throw new FormatError("GState should be a dictionary.");
}

const gStateFont = gState.get("Font");
if (!gStateFont) {
emptyGStateCache.set(name, gState.objId, true);

resolveGState();
return;
}
flushTextContentItem();

textState.fontName = null;
textState.fontSize = gStateFont[1];
handleSetFont(null, gStateFont[0]).then(
resolveGState,
rejectGState
);
}).catch(function (reason) {
if (reason instanceof AbortException) {
return;
}
if (self.options.ignoreErrors) {
// Error(s) in the ExtGState -- sending unsupported feature
// notification and allow parsing/rendering to continue.
self.handler.send("UnsupportedFeature", {
featureId: UNSUPPORTED_FEATURES.errorExtGState,
});
warn(`getTextContent - ignoring ExtGState: "${reason}".`);
return;
}
throw reason;
})
);
return;
} // switch
if (textContent.items.length >= sink.desiredSize) {
// Wait for ready, if we reach highWaterMark.
Expand Down

0 comments on commit 6ea824e

Please sign in to comment.