From 17aaa125df7f08465008b21d994c16684de83e32 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 23 Mar 2016 13:52:30 +0100 Subject: [PATCH] Keep track of the character to glyph mapping in font_renderer.js, to prevent errors when different characters point to the same glyph (issue 7101) Fixes 7101. --- src/core/font_renderer.js | 39 ++++++++++++++++++++++---------------- test/pdfs/.gitignore | 1 + test/pdfs/issue7101.pdf | Bin 0 -> 6832 bytes test/test_manifest.json | 7 +++++++ 4 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 test/pdfs/issue7101.pdf diff --git a/src/core/font_renderer.js b/src/core/font_renderer.js index 568d30e3e..729282c35 100644 --- a/src/core/font_renderer.js +++ b/src/core/font_renderer.js @@ -137,7 +137,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { } function lookupCmap(ranges, unicode) { - var code = unicode.charCodeAt(0); + var code = unicode.charCodeAt(0), gid = 0; var l = 0, r = ranges.length - 1; while (l < r) { var c = (l + r + 1) >> 1; @@ -148,10 +148,13 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { } } if (ranges[l].start <= code && code <= ranges[l].end) { - return (ranges[l].idDelta + (ranges[l].ids ? - ranges[l].ids[code - ranges[l].start] : code)) & 0xFFFF; + gid = (ranges[l].idDelta + (ranges[l].ids ? + ranges[l].ids[code - ranges[l].start] : code)) & 0xFFFF; } - return 0; + return { + charCode: code, + glyphId: gid, + }; } function compileGlyf(code, cmds, font) { @@ -451,14 +454,14 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { x = stack.pop(); cmds.push({cmd: 'save'}); cmds.push({cmd: 'translate', args: [x, y]}); - var gid = lookupCmap(font.cmap, String.fromCharCode( + var cmap = lookupCmap(font.cmap, String.fromCharCode( font.glyphNameMap[StandardEncoding[achar]])); - compileCharString(font.glyphs[gid], cmds, font); + compileCharString(font.glyphs[cmap.glyphId], cmds, font); cmds.push({cmd: 'restore'}); - gid = lookupCmap(font.cmap, String.fromCharCode( + cmap = lookupCmap(font.cmap, String.fromCharCode( font.glyphNameMap[StandardEncoding[bchar]])); - compileCharString(font.glyphs[gid], cmds, font); + compileCharString(font.glyphs[cmap.glyphId], cmds, font); } return; case 18: // hstemhm @@ -610,14 +613,19 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { function CompiledFont(fontMatrix) { this.compiledGlyphs = Object.create(null); + this.compiledCharCodeToGlyphId = Object.create(null); this.fontMatrix = fontMatrix; } CompiledFont.prototype = { getPathJs: function (unicode) { - var gid = lookupCmap(this.cmap, unicode); - var fn = this.compiledGlyphs[gid]; + var cmap = lookupCmap(this.cmap, unicode); + var fn = this.compiledGlyphs[cmap.glyphId]; if (!fn) { - this.compiledGlyphs[gid] = fn = this.compileGlyph(this.glyphs[gid]); + fn = this.compileGlyph(this.glyphs[cmap.glyphId]); + this.compiledGlyphs[cmap.glyphId] = fn; + } + if (this.compiledCharCodeToGlyphId[cmap.charCode] === undefined) { + this.compiledCharCodeToGlyphId[cmap.charCode] = cmap.glyphId; } return fn; }, @@ -644,8 +652,9 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { }, hasBuiltPath: function (unicode) { - var gid = lookupCmap(this.cmap, unicode); - return gid in this.compiledGlyphs; + var cmap = lookupCmap(this.cmap, unicode); + return (this.compiledGlyphs[cmap.glyphId] !== undefined && + this.compiledCharCodeToGlyphId[cmap.charCode] !== undefined); } }; @@ -655,8 +664,6 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { this.glyphs = glyphs; this.cmap = cmap; - - this.compiledGlyphs = []; } Util.inherit(TrueTypeCompiled, CompiledFont, { @@ -668,13 +675,13 @@ var FontRendererFactory = (function FontRendererFactoryClosure() { function Type2Compiled(cffInfo, cmap, fontMatrix, glyphNameMap) { fontMatrix = fontMatrix || [0.001, 0, 0, 0.001, 0, 0]; CompiledFont.call(this, fontMatrix); + this.glyphs = cffInfo.glyphs; this.gsubrs = cffInfo.gsubrs || []; this.subrs = cffInfo.subrs || []; this.cmap = cmap; this.glyphNameMap = glyphNameMap || getGlyphsUnicode(); - this.compiledGlyphs = []; this.gsubrsBias = (this.gsubrs.length < 1240 ? 107 : (this.gsubrs.length < 33900 ? 1131 : 32768)); this.subrsBias = (this.subrs.length < 1240 ? diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index b675adf06..df3522d6c 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -21,6 +21,7 @@ !issue6782.pdf !issue6961.pdf !issue7020.pdf +!issue7101.pdf !issue7115.pdf !filled-background.pdf !ArabicCIDTrueType.pdf diff --git a/test/pdfs/issue7101.pdf b/test/pdfs/issue7101.pdf new file mode 100644 index 0000000000000000000000000000000000000000..400ebe5e9adf5ca06051a6f06f34785ed2a6bfc3 GIT binary patch literal 6832 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⋙sb}<*nV+j&{SKD<2|U8i{kd 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 literal 0 HcmV?d00001 diff --git a/test/test_manifest.json b/test/test_manifest.json index 6113fcdd9..706a1bb24 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -1263,6 +1263,13 @@ "rounds": 1, "type": "eq" }, + { "id": "issue7101", + "file": "pdfs/issue7101.pdf", + "md5": "cc9cabe12ac9ad49e5372ef33d10aeb4", + "link": false, + "rounds": 1, + "type": "eq" + }, { "id": "pr4606", "file": "pdfs/pr4606.pdf", "md5": "6574fde2314648600056bd0e229df98c",