From 34177b01a4068efccaeb93a7b6ba28c9ed274353 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Mon, 29 Jul 2013 15:24:32 -0500 Subject: [PATCH] Fixes glyph 0 in CIDTypeFont2 --- src/fonts.js | 44 ++++++++++++++++++++++++++++++++---- test/pdfs/issue3427.pdf.link | 1 + test/test_manifest.json | 8 +++++++ 3 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 test/pdfs/issue3427.pdf.link diff --git a/src/fonts.js b/src/fonts.js index 9800967eb..de7b3adfb 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -3457,7 +3457,8 @@ var Font = (function FontClosure() { } function sanitizeGlyphLocations(loca, glyf, numGlyphs, - isGlyphLocationsLong, hintsValid) { + isGlyphLocationsLong, hintsValid, + dupFirstEntry) { var itemSize, itemDecode, itemEncode; if (isGlyphLocationsLong) { itemSize = 4; @@ -3516,7 +3517,22 @@ var Font = (function FontClosure() { return; } - glyf.data = newGlyfData.subarray(0, writeOffset); + if (dupFirstEntry) { + var firstEntryLength = itemDecode(locaData, itemSize); + if (newGlyfData.length > firstEntryLength + writeOffset) { + glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset); + } else { + glyf.data = new Uint8Array(firstEntryLength + writeOffset); + glyf.data.set(newGlyfData.subarray(0, writeOffset)); + } + glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset); + loca.data = new Uint8Array(locaData.length + itemSize); + loca.data.set(locaData); + itemEncode(loca.data, locaData.length, + writeOffset + firstEntryLength); + } else { + glyf.data = newGlyfData.subarray(0, writeOffset); + } } function readPostScriptTable(post, properties, maxpNumGlyphs) { @@ -3905,6 +3921,16 @@ var Font = (function FontClosure() { maxFunctionDefs = int16(font.getBytes(2)); } + var dupFirstEntry = false; + if (properties.type == 'CIDFontType2' && properties.toUnicode && + properties.toUnicode[0] > 0) { + // oracle's defect (see 3427), duplicating first entry + dupFirstEntry = true; + numGlyphs++; + tables.maxp.data[4] = numGlyphs >> 8; + tables.maxp.data[5] = numGlyphs & 255; + } + var hintsValid = sanitizeTTPrograms(tables.fpgm, tables.prep, maxFunctionDefs); if (!hintsValid) { @@ -3945,7 +3971,7 @@ var Font = (function FontClosure() { tables.head.data[51]]); sanitizeGlyphLocations(tables.loca, tables.glyf, numGlyphs, - isGlyphLocationsLong, hintsValid); + isGlyphLocationsLong, hintsValid, dupFirstEntry); } if (!tables.hhea) { @@ -3998,6 +4024,13 @@ var Font = (function FontClosure() { if (!gidToCidMap[i]) gidToCidMap[i] = nextCid++; } + } else { + for (var i = 1; i < numGlyphs; i++) { + gidToCidMap[i] = i; + } + if (dupFirstEntry) { + gidToCidMap[numGlyphs - 1] = 0; + } } glyphs = []; @@ -4007,7 +4040,7 @@ var Font = (function FontClosure() { var unassignedUnicodeItems = []; var toFontChar = this.cidToFontChar || this.toFontChar; for (var i = 1; i < numGlyphs; i++) { - var cid = gidToCidMap[i] || i; + var cid = gidToCidMap[i]; var unicode = toFontChar[cid]; if (!unicode || typeof unicode !== 'number' || isSpecialUnicode(unicode) || unicode in usedUnicodes) { @@ -4018,6 +4051,7 @@ var Font = (function FontClosure() { glyphs.push({ unicode: unicode, code: cid }); ids.push(i); } + // unassigned codepoints will never be used for non-Identity CMap // because the input will be Unicode if (!this.cidToFontChar) { @@ -4026,7 +4060,7 @@ var Font = (function FontClosure() { var unusedUnicode = CMAP_GLYPH_OFFSET; for (var j = 0, jj = unassignedUnicodeItems.length; j < jj; j++) { var i = unassignedUnicodeItems[j]; - var cid = gidToCidMap[i] || i; + var cid = gidToCidMap[i]; while (unusedUnicode in usedUnicodes) unusedUnicode++; if (unusedUnicode >= CMAP_GLYPH_OFFSET + GLYPH_AREA_SIZE) diff --git a/test/pdfs/issue3427.pdf.link b/test/pdfs/issue3427.pdf.link new file mode 100644 index 000000000..838ae6d8b --- /dev/null +++ b/test/pdfs/issue3427.pdf.link @@ -0,0 +1 @@ +https://bugzilla.mozilla.org/attachment.cgi?id=718943 \ No newline at end of file diff --git a/test/test_manifest.json b/test/test_manifest.json index 66bf4630f..4ad7c34b7 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -439,6 +439,14 @@ "rounds": 1, "type": "eq" }, + { "id": "issue3427", + "file": "pdfs/issue3427.pdf", + "md5": "61979ede77f4557c65d4eb3c1a6dceeb", + "link": true, + "lastPage": 1, + "rounds": 1, + "type": "eq" + }, { "id": "piperine", "file": "pdfs/piperine.pdf", "md5": "603ca43dc5732dbba1579f122958c0c2",