Merge pull request #5651 from Snuffleupagus/missing-glyphs
Try to skip mapping of missing TrueType and CIDFontType2 glyphs
This commit is contained in:
commit
394b38b22f
@ -2203,6 +2203,10 @@ var ToUnicodeMap = (function ToUnicodeMapClosure() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
has: function(i) {
|
||||||
|
return this._map[i] !== undefined;
|
||||||
|
},
|
||||||
|
|
||||||
get: function(i) {
|
get: function(i) {
|
||||||
return this._map[i];
|
return this._map[i];
|
||||||
},
|
},
|
||||||
@ -2232,6 +2236,10 @@ var IdentityToUnicodeMap = (function IdentityToUnicodeMapClosure() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
has: function (i) {
|
||||||
|
return this.firstChar <= i && i <= this.lastChar;
|
||||||
|
},
|
||||||
|
|
||||||
get: function (i) {
|
get: function (i) {
|
||||||
if (this.firstChar <= i && i <= this.lastChar) {
|
if (this.firstChar <= i && i <= this.lastChar) {
|
||||||
return String.fromCharCode(i);
|
return String.fromCharCode(i);
|
||||||
@ -2664,7 +2672,6 @@ var Font = (function FontClosure() {
|
|||||||
var isSymbolic = !!(properties.flags & FontFlags.Symbolic);
|
var isSymbolic = !!(properties.flags & FontFlags.Symbolic);
|
||||||
var isIdentityUnicode =
|
var isIdentityUnicode =
|
||||||
properties.toUnicode instanceof IdentityToUnicodeMap;
|
properties.toUnicode instanceof IdentityToUnicodeMap;
|
||||||
var isCidFontType2 = (properties.type === 'CIDFontType2');
|
|
||||||
var newMap = Object.create(null);
|
var newMap = Object.create(null);
|
||||||
var toFontChar = [];
|
var toFontChar = [];
|
||||||
var usedFontCharCodes = [];
|
var usedFontCharCodes = [];
|
||||||
@ -2675,17 +2682,11 @@ var Font = (function FontClosure() {
|
|||||||
var fontCharCode = originalCharCode;
|
var fontCharCode = originalCharCode;
|
||||||
// First try to map the value to a unicode position if a non identity map
|
// First try to map the value to a unicode position if a non identity map
|
||||||
// was created.
|
// was created.
|
||||||
if (!isIdentityUnicode) {
|
if (!isIdentityUnicode && toUnicode.has(originalCharCode)) {
|
||||||
if (toUnicode.get(originalCharCode) !== undefined) {
|
var unicode = toUnicode.get(fontCharCode);
|
||||||
var unicode = toUnicode.get(fontCharCode);
|
// TODO: Try to map ligatures to the correct spot.
|
||||||
// TODO: Try to map ligatures to the correct spot.
|
if (unicode.length === 1) {
|
||||||
if (unicode.length === 1) {
|
fontCharCode = unicode.charCodeAt(0);
|
||||||
fontCharCode = unicode.charCodeAt(0);
|
|
||||||
}
|
|
||||||
} else if (isCidFontType2) {
|
|
||||||
// For CIDFontType2, move characters not present in toUnicode
|
|
||||||
// to the private use area (fixes bug 1028735 and issue 4881).
|
|
||||||
fontCharCode = nextAvailableFontCharCode;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Try to move control characters, special characters and already mapped
|
// Try to move control characters, special characters and already mapped
|
||||||
@ -3530,6 +3531,7 @@ var Font = (function FontClosure() {
|
|||||||
var newGlyfData = new Uint8Array(oldGlyfDataLength);
|
var newGlyfData = new Uint8Array(oldGlyfDataLength);
|
||||||
var startOffset = itemDecode(locaData, 0);
|
var startOffset = itemDecode(locaData, 0);
|
||||||
var writeOffset = 0;
|
var writeOffset = 0;
|
||||||
|
var missingGlyphData = {};
|
||||||
itemEncode(locaData, 0, writeOffset);
|
itemEncode(locaData, 0, writeOffset);
|
||||||
var i, j;
|
var i, j;
|
||||||
for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {
|
for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {
|
||||||
@ -3547,6 +3549,10 @@ var Font = (function FontClosure() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (startOffset === endOffset) {
|
||||||
|
missingGlyphData[i] = true;
|
||||||
|
}
|
||||||
|
|
||||||
var newLength = sanitizeGlyph(oldGlyfData, startOffset, endOffset,
|
var newLength = sanitizeGlyph(oldGlyfData, startOffset, endOffset,
|
||||||
newGlyfData, writeOffset, hintsValid);
|
newGlyfData, writeOffset, hintsValid);
|
||||||
writeOffset += newLength;
|
writeOffset += newLength;
|
||||||
@ -3563,7 +3569,7 @@ var Font = (function FontClosure() {
|
|||||||
itemEncode(locaData, j, simpleGlyph.length);
|
itemEncode(locaData, j, simpleGlyph.length);
|
||||||
}
|
}
|
||||||
glyf.data = simpleGlyph;
|
glyf.data = simpleGlyph;
|
||||||
return;
|
return missingGlyphData;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dupFirstEntry) {
|
if (dupFirstEntry) {
|
||||||
@ -3580,6 +3586,7 @@ var Font = (function FontClosure() {
|
|||||||
} else {
|
} else {
|
||||||
glyf.data = newGlyfData.subarray(0, writeOffset);
|
glyf.data = newGlyfData.subarray(0, writeOffset);
|
||||||
}
|
}
|
||||||
|
return missingGlyphData;
|
||||||
}
|
}
|
||||||
|
|
||||||
function readPostScriptTable(post, properties, maxpNumGlyphs) {
|
function readPostScriptTable(post, properties, maxpNumGlyphs) {
|
||||||
@ -4039,11 +4046,13 @@ var Font = (function FontClosure() {
|
|||||||
|
|
||||||
sanitizeHead(tables.head, numGlyphs, isTrueType ? tables.loca.length : 0);
|
sanitizeHead(tables.head, numGlyphs, isTrueType ? tables.loca.length : 0);
|
||||||
|
|
||||||
|
var missingGlyphs = {};
|
||||||
if (isTrueType) {
|
if (isTrueType) {
|
||||||
var isGlyphLocationsLong = int16(tables.head.data[50],
|
var isGlyphLocationsLong = int16(tables.head.data[50],
|
||||||
tables.head.data[51]);
|
tables.head.data[51]);
|
||||||
sanitizeGlyphLocations(tables.loca, tables.glyf, numGlyphs,
|
missingGlyphs = sanitizeGlyphLocations(tables.loca, tables.glyf,
|
||||||
isGlyphLocationsLong, hintsValid, dupFirstEntry);
|
numGlyphs, isGlyphLocationsLong,
|
||||||
|
hintsValid, dupFirstEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tables.hhea) {
|
if (!tables.hhea) {
|
||||||
@ -4065,19 +4074,33 @@ var Font = (function FontClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var charCodeToGlyphId = [], charCode;
|
var charCodeToGlyphId = [], charCode, toUnicode = properties.toUnicode;
|
||||||
|
|
||||||
|
function hasGlyph(glyphId, charCode) {
|
||||||
|
if (!missingGlyphs[glyphId]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (charCode >= 0 && toUnicode.has(charCode)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (properties.type === 'CIDFontType2') {
|
if (properties.type === 'CIDFontType2') {
|
||||||
var cidToGidMap = properties.cidToGidMap || [];
|
var cidToGidMap = properties.cidToGidMap || [];
|
||||||
var cidToGidMapLength = cidToGidMap.length;
|
var isCidToGidMapEmpty = cidToGidMap.length === 0;
|
||||||
|
|
||||||
properties.cMap.forEach(function(charCode, cid) {
|
properties.cMap.forEach(function(charCode, cid) {
|
||||||
assert(cid <= 0xffff, 'Max size of CID is 65,535');
|
assert(cid <= 0xffff, 'Max size of CID is 65,535');
|
||||||
var glyphId = -1;
|
var glyphId = -1;
|
||||||
if (cidToGidMapLength === 0) {
|
if (isCidToGidMapEmpty) {
|
||||||
glyphId = charCode;
|
glyphId = charCode;
|
||||||
} else if (cidToGidMap[cid] !== undefined) {
|
} else if (cidToGidMap[cid] !== undefined) {
|
||||||
glyphId = cidToGidMap[cid];
|
glyphId = cidToGidMap[cid];
|
||||||
}
|
}
|
||||||
if (glyphId >= 0 && glyphId < numGlyphs) {
|
|
||||||
|
if (glyphId >= 0 && glyphId < numGlyphs &&
|
||||||
|
hasGlyph(glyphId, charCode)) {
|
||||||
charCodeToGlyphId[charCode] = glyphId;
|
charCodeToGlyphId[charCode] = glyphId;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -4137,7 +4160,8 @@ var Font = (function FontClosure() {
|
|||||||
|
|
||||||
var found = false;
|
var found = false;
|
||||||
for (i = 0; i < cmapMappingsLength; ++i) {
|
for (i = 0; i < cmapMappingsLength; ++i) {
|
||||||
if (cmapMappings[i].charCode === unicodeOrCharCode) {
|
if (cmapMappings[i].charCode === unicodeOrCharCode &&
|
||||||
|
hasGlyph(cmapMappings[i].glyphId, unicodeOrCharCode)) {
|
||||||
charCodeToGlyphId[charCode] = cmapMappings[i].glyphId;
|
charCodeToGlyphId[charCode] = cmapMappings[i].glyphId;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@ -4147,7 +4171,7 @@ var Font = (function FontClosure() {
|
|||||||
// Try to map using the post table. There are currently no known
|
// Try to map using the post table. There are currently no known
|
||||||
// pdfs that this fixes.
|
// pdfs that this fixes.
|
||||||
var glyphId = properties.glyphNames.indexOf(glyphName);
|
var glyphId = properties.glyphNames.indexOf(glyphName);
|
||||||
if (glyphId > 0) {
|
if (glyphId > 0 && hasGlyph(glyphId, -1)) {
|
||||||
charCodeToGlyphId[charCode] = glyphId;
|
charCodeToGlyphId[charCode] = glyphId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
test/pdfs/.gitignore
vendored
4
test/pdfs/.gitignore
vendored
@ -18,6 +18,7 @@
|
|||||||
!sizes.pdf
|
!sizes.pdf
|
||||||
!close-path-bug.pdf
|
!close-path-bug.pdf
|
||||||
!issue4630.pdf
|
!issue4630.pdf
|
||||||
|
!issue5202.pdf
|
||||||
!issue5280.pdf
|
!issue5280.pdf
|
||||||
!alphatrans.pdf
|
!alphatrans.pdf
|
||||||
!devicen.pdf
|
!devicen.pdf
|
||||||
@ -58,10 +59,13 @@
|
|||||||
!zerowidthline.pdf
|
!zerowidthline.pdf
|
||||||
!bug868745.pdf
|
!bug868745.pdf
|
||||||
!mmtype1.pdf
|
!mmtype1.pdf
|
||||||
|
!issue5704.pdf
|
||||||
|
!bug893730.pdf
|
||||||
!bug864847.pdf
|
!bug864847.pdf
|
||||||
!issue1002.pdf
|
!issue1002.pdf
|
||||||
!issue925.pdf
|
!issue925.pdf
|
||||||
!issue2840.pdf
|
!issue2840.pdf
|
||||||
|
!issue4061.pdf
|
||||||
!issue4668.pdf
|
!issue4668.pdf
|
||||||
!issue5039.pdf
|
!issue5039.pdf
|
||||||
!issue5070.pdf
|
!issue5070.pdf
|
||||||
|
BIN
test/pdfs/bug893730.pdf
Normal file
BIN
test/pdfs/bug893730.pdf
Normal file
Binary file not shown.
BIN
test/pdfs/issue4061.pdf
Normal file
BIN
test/pdfs/issue4061.pdf
Normal file
Binary file not shown.
BIN
test/pdfs/issue5202.pdf
Normal file
BIN
test/pdfs/issue5202.pdf
Normal file
Binary file not shown.
BIN
test/pdfs/issue5704.pdf
Normal file
BIN
test/pdfs/issue5704.pdf
Normal file
Binary file not shown.
@ -485,6 +485,20 @@
|
|||||||
"lastPage": 1,
|
"lastPage": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue4061",
|
||||||
|
"file": "pdfs/issue4061.pdf",
|
||||||
|
"md5": "236aaa8840a47c3c061f8e3034549764",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": false,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
|
{ "id": "issue5202",
|
||||||
|
"file": "pdfs/issue5202.pdf",
|
||||||
|
"md5": "bb9cc69211112e66aab40828086a4e5a",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": false,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "issue5238",
|
{ "id": "issue5238",
|
||||||
"file": "pdfs/issue5238.pdf",
|
"file": "pdfs/issue5238.pdf",
|
||||||
"md5": "6ddecda00893be1793de20a70c83a3c2",
|
"md5": "6ddecda00893be1793de20a70c83a3c2",
|
||||||
@ -1015,6 +1029,20 @@
|
|||||||
"link": true,
|
"link": true,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue5704",
|
||||||
|
"file": "pdfs/issue5704.pdf",
|
||||||
|
"md5": "6e0b62585feef24dff2d7e7687cd8128",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": false,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
|
{ "id": "bug893730",
|
||||||
|
"file": "pdfs/bug893730.pdf",
|
||||||
|
"md5": "2587379fb1b3bbff89c14f0863e78383",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": false,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "pdfkit_compressed",
|
{ "id": "pdfkit_compressed",
|
||||||
"file": "pdfs/pdfkit_compressed.pdf",
|
"file": "pdfs/pdfkit_compressed.pdf",
|
||||||
"md5": "ffe9c571d0a1572e234253e6c7cdee6c",
|
"md5": "ffe9c571d0a1572e234253e6c7cdee6c",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user