diff --git a/src/core/evaluator.js b/src/core/evaluator.js index b0d79e88b..1fff07543 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -795,6 +795,26 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { return glyphs; }, + ensureStateFont(state) { + if (state.font) { + return; + } + const reason = new FormatError( + "Missing setFont (Tf) operator before text rendering operator." + ); + + if (this.options.ignoreErrors) { + // Missing setFont operator before text rendering operator -- sending + // unsupported feature notification and allow rendering to continue. + this.handler.send("UnsupportedFeature", { + featureId: UNSUPPORTED_FEATURES.font, + }); + warn(`ensureStateFont: "${reason}".`); + return; + } + throw reason; + }, + setGState: function PartialEvaluator_setGState( resources, gState, @@ -1364,9 +1384,17 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { ); return; case OPS.showText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } args[0] = self.handleText(args[0], stateManager.state); break; case OPS.showSpacedText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } var arr = args[0]; var combinedGlyphs = []; var arrLength = arr.length; @@ -1386,11 +1414,19 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { fn = OPS.showText; break; case OPS.nextLineShowText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } operatorList.addOp(OPS.nextLine); args[0] = self.handleText(args[0], stateManager.state); fn = OPS.showText; break; case OPS.nextLineSetSpacingShowText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } operatorList.addOp(OPS.nextLine); operatorList.addOp(OPS.setWordSpacing, [args.shift()]); operatorList.addOp(OPS.setCharSpacing, [args.shift()]); @@ -2056,6 +2092,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { textState.textLineMatrix = IDENTITY_MATRIX.slice(); break; case OPS.showSpacedText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } var items = args[0]; var offset; for (var j = 0, jj = items.length; j < jj; j++) { @@ -2105,14 +2145,26 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } break; case OPS.showText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } buildTextContentItem(args[0]); break; case OPS.nextLineShowText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } flushTextContentItem(); textState.carriageReturn(); buildTextContentItem(args[0]); break; case OPS.nextLineSetSpacingShowText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } flushTextContentItem(); textState.wordSpacing = args[0]; textState.charSpacing = args[1]; diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index d2db531b2..6635f1eb2 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -89,6 +89,7 @@ !issue11279.pdf !issue11362.pdf !issue11578_reduced.pdf +!issue11651.pdf !bad-PageLabels.pdf !decodeACSuccessive.pdf !filled-background.pdf diff --git a/test/pdfs/issue11651.pdf b/test/pdfs/issue11651.pdf new file mode 100644 index 000000000..7c4928527 Binary files /dev/null and b/test/pdfs/issue11651.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index 71c4bafe3..4a8be1a46 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -67,6 +67,20 @@ "link": false, "type": "eq" }, + { "id": "issue11651-eq", + "file": "pdfs/issue11651.pdf", + "md5": "375233ad8dc4181a06148f8412f35b91", + "rounds": 1, + "link": false, + "type": "eq" + }, + { "id": "issue11651-text", + "file": "pdfs/issue11651.pdf", + "md5": "375233ad8dc4181a06148f8412f35b91", + "rounds": 1, + "link": false, + "type": "text" + }, { "id": "issue1293", "file": "pdfs/issue1293r.pdf", "md5": "4a098f5051f34fab036f5bbe88f8deef",