Merge pull request #1361 from notmasteryet/truetype-enc-1

Fixes TrueType cmap re-encoding
This commit is contained in:
Brendan Dahl 2012-03-22 11:49:16 -07:00
commit 25c0bfaa79
4 changed files with 80 additions and 13 deletions

View File

@ -174,7 +174,6 @@ var Encodings = {
'', '', 'Lslash', 'Oslash', 'OE', 'ordmasculine', '', '', '', '', '', 'ae',
'', '', '', 'dotlessi', '', '', 'lslash', 'oslash', 'oe', 'germandbls'],
WinAnsiEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent',
'ampersand', 'quotesingle', 'parenleft', 'parenright', 'asterisk', 'plus',
@ -1658,6 +1657,30 @@ var Font = (function FontClosure() {
glyf.data = newGlyfData.subarray(0, writeOffset);
}
function findEmptyGlyphs(locaTable, isGlyphLocationsLong, emptyGlyphIds) {
var itemSize, itemDecode;
if (isGlyphLocationsLong) {
itemSize = 4;
itemDecode = function fontItemDecodeLong(data, offset) {
return (data[offset] << 24) | (data[offset + 1] << 16) |
(data[offset + 2] << 8) | data[offset + 3];
};
} else {
itemSize = 2;
itemDecode = function fontItemDecode(data, offset) {
return (data[offset] << 9) | (data[offset + 1] << 1);
};
}
var data = locaTable.data, length = data.length;
var lastOffset = itemDecode(data, 0);
for (var i = itemSize, j = 0; i < length; i += itemSize, j++) {
var offset = itemDecode(data, i);
if (offset == lastOffset)
emptyGlyphIds[j] = true;
lastOffset = offset;
}
}
function readGlyphNameMap(post, properties) {
var start = (font.start ? font.start : 0) + post.offset;
font.pos = start;
@ -1784,11 +1807,15 @@ var Font = (function FontClosure() {
sanitizeMetrics(font, hhea, hmtx, numGlyphs);
sanitizeMetrics(font, vhea, vmtx, numGlyphs);
if (head && loca && glyf) {
var isGlyphLocationsLong = int16([head.data[50], head.data[51]]);
if (head && loca && glyf) {
sanitizeGlyphLocations(loca, glyf, numGlyphs, isGlyphLocationsLong);
}
var emptyGlyphIds = [];
if (glyf)
findEmptyGlyphs(loca, isGlyphLocationsLong, emptyGlyphIds);
// Sanitizer reduces the glyph advanceWidth to the maxAdvanceWidth
// Sometimes it's 0. That needs to be fixed
if (hhea.data[10] == 0 && hhea.data[11] == 0) {
@ -1920,6 +1947,25 @@ var Font = (function FontClosure() {
}
}
// remove glyph references outside range of avaialable glyphs or empty
var glyphsRemoved = 0;
for (var i = ids.length - 1; i >= 0; i--) {
if (ids[i] < numGlyphs &&
(!emptyGlyphIds[ids[i]] || this.isSymbolicFont))
continue;
ids.splice(i, 1);
glyphs.splice(i, 1);
glyphsRemoved++;
}
// heuristics: if removed more than 2 glyphs encoding WinAnsiEncoding
// does not set properly
if (glyphsRemoved > 2) {
warn('Switching TrueType encoding to MacRomanEncoding for ' +
this.name + ' font');
encoding = Encodings.MacRomanEncoding;
}
if (hasShortCmap && this.hasEncoding && !this.isSymbolicFont) {
// Re-encode short map encoding to unicode -- that simplifies the
// resolution of MacRoman encoded glyphs logic for TrueType fonts:
@ -1956,6 +2002,7 @@ var Font = (function FontClosure() {
for (var i = 0, ii = glyphs.length; i < ii; i++)
reverseMap[glyphs[i].unicode] = i;
var newGlyphUnicodes = [];
for (var i = 0, ii = glyphs.length; i < ii; i++) {
var code = glyphs[i].unicode;
var changeCode = false;
@ -1968,17 +2015,27 @@ var Font = (function FontClosure() {
}
if (glyphName in GlyphsUnicode) {
var unicode = GlyphsUnicode[glyphName];
if (!unicode || (unicode in reverseMap))
continue; // unknown glyph name or its place is taken
if (!unicode || reverseMap[unicode] === i)
continue; // unknown glyph name or in its own place
glyphs[i].unicode = unicode;
reverseMap[unicode] = i;
newGlyphUnicodes[i] = unicode;
if (changeCode)
toFontChar[code] = unicode;
delete reverseMap[code];
}
}
for (var index in newGlyphUnicodes) {
var unicode = newGlyphUnicodes[index];
if (reverseMap[unicode]) {
// avoiding assigning to the same unicode
glyphs[index].unicode = unusedUnicode++;
continue;
}
glyphs[index].unicode = unicode;
reverseMap[unicode] = index;
}
this.useToFontChar = true;
}
}
// Moving all symbolic font glyphs into 0xF000 - 0xF0FF range.
if (this.isSymbolicFont) {
@ -1990,12 +2047,6 @@ var Font = (function FontClosure() {
this.useToFontChar = true;
}
// remove glyph references outside range of avaialable glyphs
for (var i = 0, ii = ids.length; i < ii; i++) {
if (ids[i] >= numGlyphs)
ids[i] = 0;
}
createGlyphNameMap(glyphs, ids, properties);
this.glyphNameMap = properties.glyphNameMap;

View File

@ -0,0 +1 @@
http://www.lufthansa.com/mediapool/pdf/31/media_907231.pdf

View File

@ -0,0 +1 @@
http://iliad.fr/presse/2012/CP_080312_Free_mobile.pdf

View File

@ -530,5 +530,19 @@
"pageLimit": 2,
"link": true,
"type": "eq"
},
{ "id": "issue1309",
"file": "pdfs/issue1309.pdf",
"md5": "e835fb7f3dab3073ad37d0bd3c6399fa",
"rounds": 1,
"link": true,
"type": "eq"
},
{ "id": "issue1317",
"file": "pdfs/issue1317.pdf",
"md5": "6fb46275b30c48c8985617d4f86199e3",
"rounds": 1,
"link": true,
"type": "eq"
}
]