From db591769a4bfe2c5f7ad2c18d81e3e36f3a45e41 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Thu, 22 Aug 2013 10:12:16 -0700 Subject: [PATCH] Fix handling of multiply-encoded glyphs. --- src/core/fonts.js | 54 +++++++++++++++++++++++++++------------- test/pdfs/issue3566.pdf | Bin 0 -> 9805 bytes test/test_manifest.json | 8 ++++++ 3 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 test/pdfs/issue3566.pdf diff --git a/src/core/fonts.js b/src/core/fonts.js index b621e55b2..d59fcbdae 100644 --- a/src/core/fonts.js +++ b/src/core/fonts.js @@ -4128,7 +4128,7 @@ var Font = (function FontClosure() { properties.seacMap = seacMap; } - if (!properties.hasEncoding && (properties.subtype == 'Type1C' || + if (properties.overridableEncoding && (properties.subtype == 'Type1C' || properties.subtype == 'CIDFontType0C')) { var encoding = []; for (var i = 0; i < charstrings.length; ++i) { @@ -5534,8 +5534,20 @@ var CFFFont = (function CFFFontClosure() { } } } else { - for (var charcode in encoding) - inverseEncoding[encoding[charcode]] = charcode | 0; + for (var charcode in encoding) { + var gid = encoding[charcode]; + if (gid in inverseEncoding) { + // Glyphs can be multiply-encoded if there was an encoding + // supplement. Convert to an array and append the charcode. + var previousCharcode = inverseEncoding[gid]; + if (!isArray(previousCharcode)) { + inverseEncoding[gid] = [previousCharcode]; + } + inverseEncoding[gid].push(charcode | 0); + } else { + inverseEncoding[gid] = charcode | 0; + } + } if (charsets[0] === '.notdef') { gidStart = 1; } @@ -5544,22 +5556,30 @@ var CFFFont = (function CFFFontClosure() { for (var i = gidStart, ii = charsets.length; i < ii; i++) { var glyph = charsets[i]; - var code = inverseEncoding[i]; - if (!code || isSpecialUnicode(code)) { - unassignedUnicodeItems.push(i); - continue; + var codes = inverseEncoding[i]; + if (!isArray(codes)) { + codes = [codes]; + } + + for (var j = 0; j < codes.length; j++) { + var code = codes[j]; + + if (!code || isSpecialUnicode(code)) { + unassignedUnicodeItems.push(i, code); + continue; + } + charstrings.push({ + unicode: code, + code: code, + gid: i, + glyph: glyph + }); + unicodeUsed[code] = true; } - charstrings.push({ - unicode: code, - code: code, - gid: i, - glyph: glyph - }); - unicodeUsed[code] = true; } var nextUnusedUnicode = CMAP_GLYPH_OFFSET; - for (var j = 0, jj = unassignedUnicodeItems.length; j < jj; ++j) { + for (var j = 0, jj = unassignedUnicodeItems.length; j < jj; j += 2) { var i = unassignedUnicodeItems[j]; // giving unicode value anyway while (nextUnusedUnicode in unicodeUsed) @@ -5567,7 +5587,7 @@ var CFFFont = (function CFFFontClosure() { var unicode = nextUnusedUnicode++; charstrings.push({ unicode: unicode, - code: inverseEncoding[i] || 0, + code: unassignedUnicodeItems[j + 1] || 0, gid: i, glyph: charsets[i] }); @@ -6136,7 +6156,7 @@ var CFFParser = (function CFFParserClosure() { for (var i = 0; i < supplementsCount; i++) { var code = bytes[pos++]; var sid = (bytes[pos++] << 8) + (bytes[pos++] & 0xff); - encoding[code] = properties.differences.indexOf(strings.get(sid)); + encoding[code] = charset.indexOf(strings.get(sid)); } } diff --git a/test/pdfs/issue3566.pdf b/test/pdfs/issue3566.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4bc606263ec40d50911a820cae124c2c3af07c72 GIT binary patch literal 9805 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 ZpJQ