diff --git a/src/core/fonts.js b/src/core/fonts.js index 5092aa022..6cc4badd6 100644 --- a/src/core/fonts.js +++ b/src/core/fonts.js @@ -4132,7 +4132,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) { @@ -5538,8 +5538,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; } @@ -5548,22 +5560,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) @@ -5571,7 +5591,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] }); @@ -6140,7 +6160,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 000000000..4bc606263 Binary files /dev/null and b/test/pdfs/issue3566.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index 7181ef33e..9b5146877 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -996,6 +996,14 @@ "type": "eq", "about": "CFF CID font with font matrices in main top dict and sub top dict." }, + { "id": "issue3566", + "file": "pdfs/issue3566.pdf", + "md5": "e9ab02aa769f4c040a6fa52f00d6e3f0", + "rounds": 1, + "type": "eq", + "lastPage": 1, + "about": "CFF font with multiply-encoded glyph and no pdf encoding dict." + }, { "id": "issue1878", "file": "pdfs/issue1878.pdf", "md5": "b4fb0ce7c19368e7104dce3d0d34bcb3",