diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 51c0c511c..ab8fc66dc 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -2115,7 +2115,7 @@ class PartialEvaluator { if ( font.isType3Font && - textState.fontSize <= 1 && + (textState.fontSize <= 1 || font.isCharBBox) && !isArrayEqual(textState.fontMatrix, FONT_IDENTITY_MATRIX) ) { const glyphHeight = font.bbox[3] - font.bbox[1]; @@ -3815,7 +3815,7 @@ class PartialEvaluator { firstChar, lastChar, toUnicode, - bbox: descriptor.getArray("FontBBox"), + bbox: descriptor.getArray("FontBBox") || dict.getArray("FontBBox"), ascent: descriptor.get("Ascent"), descent: descriptor.get("Descent"), xHeight: descriptor.get("XHeight"), @@ -3962,6 +3962,9 @@ class TranslatedFont { const fontResources = this.dict.get("Resources") || resources; const charProcOperatorList = Object.create(null); + const isEmptyBBox = + !translatedFont.bbox || isArrayEqual(translatedFont.bbox, [0, 0, 0, 0]); + for (const key of charProcs.getKeys()) { loadCharProcsPromise = loadCharProcsPromise.then(() => { const glyphStream = charProcs.get(key); @@ -3981,7 +3984,7 @@ class TranslatedFont { // colour-related parameters) in the graphics state; // any use of such operators shall be ignored." if (operatorList.fnArray[0] === OPS.setCharWidthAndBounds) { - this._removeType3ColorOperators(operatorList); + this._removeType3ColorOperators(operatorList, isEmptyBBox); } charProcOperatorList[key] = operatorList.getIR(); @@ -3996,8 +3999,12 @@ class TranslatedFont { }); }); } - this.type3Loaded = loadCharProcsPromise.then(function () { + this.type3Loaded = loadCharProcsPromise.then(() => { translatedFont.charProcOperatorList = charProcOperatorList; + if (this._bbox) { + translatedFont.isCharBBox = true; + translatedFont.bbox = this._bbox; + } }); return this.type3Loaded; } @@ -4005,7 +4012,7 @@ class TranslatedFont { /** * @private */ - _removeType3ColorOperators(operatorList) { + _removeType3ColorOperators(operatorList, isEmptyBBox = false) { if ( typeof PDFJSDev === "undefined" || PDFJSDev.test("!PRODUCTION || TESTING") @@ -4015,6 +4022,17 @@ class TranslatedFont { "Type3 glyph shall start with the d1 operator." ); } + if (isEmptyBBox) { + if (!this._bbox) { + this._bbox = [Infinity, Infinity, -Infinity, -Infinity]; + } + const charBBox = Util.normalizeRect(operatorList.argsArray[0].slice(2)); + + this._bbox[0] = Math.min(this._bbox[0], charBBox[0]); + this._bbox[1] = Math.min(this._bbox[1], charBBox[1]); + this._bbox[2] = Math.max(this._bbox[2], charBBox[2]); + this._bbox[3] = Math.max(this._bbox[3], charBBox[3]); + } let i = 1, ii = operatorList.length; while (i < ii) { diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index d42280b85..30b829844 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -437,6 +437,7 @@ !quadpoints.pdf !transparent.pdf !xobject-image.pdf +!issue6605.pdf !ccitt_EndOfBlock_false.pdf !issue9972-1.pdf !issue9972-2.pdf diff --git a/test/pdfs/issue6605.pdf b/test/pdfs/issue6605.pdf new file mode 100644 index 000000000..529f9ccd6 Binary files /dev/null and b/test/pdfs/issue6605.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index a4afb11b4..f089bfd05 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -4935,6 +4935,12 @@ "type": "eq", "annotations": true }, + { "id": "issue6605", + "file": "pdfs/issue6605.pdf", + "md5": "67158a9c6d0e966ece55f7c433e18cc5", + "rounds": 1, + "type": "text" + }, { "id": "annotation-choice-widget-forms", "file": "pdfs/annotation-choice-widget.pdf", "md5": "7dfb0d743a0da0f4a71b209ab43b0be5",