Fix an issue with the vhea/vmtx tables
This commit is contained in:
parent
841fabd4e9
commit
5cb2a07b3d
66
fonts.js
66
fonts.js
@ -1032,9 +1032,9 @@ var Font = (function Font() {
|
||||
var end = denseRange[1];
|
||||
var index = firstCode;
|
||||
for (var j = start; j <= end; j++) {
|
||||
var code = j - firstCode - 1;
|
||||
var code = glyphs[j - start];
|
||||
var mapping = encoding[index] || {};
|
||||
mapping.unicode = glyphs[code].unicode;
|
||||
mapping.unicode = code.unicode;
|
||||
encoding[index++] = mapping;
|
||||
}
|
||||
return cmap.data = createCMapTable(glyphs);
|
||||
@ -1043,6 +1043,39 @@ var Font = (function Font() {
|
||||
return cmap.data;
|
||||
};
|
||||
|
||||
function sanitizeMetrics(font, header, metrics, numGlyphs) {
|
||||
if (!header && !metrics)
|
||||
return;
|
||||
|
||||
// The vhea/vmtx tables are not required, so it happens that
|
||||
// some fonts embed a vmtx table without a vhea table. In this
|
||||
// situation the sanitizer assume numOfLongVerMetrics = 1. As
|
||||
// a result it tries to read numGlyphs - 1 SHORT from the vmtx
|
||||
// table, and if it is not possible, the font is rejected.
|
||||
// So remove the vmtx table if there is no vhea table.
|
||||
if (!header && metrics) {
|
||||
metrics.data = null;
|
||||
return;
|
||||
}
|
||||
|
||||
font.pos = (font.start ? font.start : 0) + header.offset;
|
||||
font.pos += header.length - 2;
|
||||
var numOfMetrics = int16(font.getBytes(2));
|
||||
|
||||
var numOfSidebearings = numGlyphs - numOfMetrics;
|
||||
var numMissing = numOfSidebearings -
|
||||
((hmtx.length - numOfMetrics * 4) >> 1);
|
||||
if (numMissing > 0) {
|
||||
font.pos = (font.start ? font.start : 0) + metrics.offset;
|
||||
var entries = '';
|
||||
for (var i = 0; i < hmtx.length; i++)
|
||||
entries += String.fromCharCode(font.getByte());
|
||||
for (var i = 0; i < numMissing; i++)
|
||||
entries += '\x00\x00';
|
||||
metrics.data = stringToArray(entries);
|
||||
}
|
||||
};
|
||||
|
||||
// Check that required tables are present
|
||||
var requiredTables = ['OS/2', 'cmap', 'head', 'hhea',
|
||||
'hmtx', 'maxp', 'name', 'post'];
|
||||
@ -1050,7 +1083,7 @@ var Font = (function Font() {
|
||||
var header = readOpenTypeHeader(font);
|
||||
var numTables = header.numTables;
|
||||
|
||||
var cmap, maxp, hhea, hmtx;
|
||||
var cmap, maxp, hhea, hmtx, vhea, vmtx;
|
||||
var tables = [];
|
||||
for (var i = 0; i < numTables; i++) {
|
||||
var table = readTableEntry(font);
|
||||
@ -1066,6 +1099,11 @@ var Font = (function Font() {
|
||||
hmtx = table;
|
||||
|
||||
requiredTables.splice(index, 1);
|
||||
} else {
|
||||
if (table.tag == 'vmtx')
|
||||
vmtx = table;
|
||||
else if (table.tag == 'vhea')
|
||||
vhea = table;
|
||||
}
|
||||
tables.push(table);
|
||||
}
|
||||
@ -1091,28 +1129,14 @@ var Font = (function Font() {
|
||||
});
|
||||
}
|
||||
|
||||
// Ensure the hmtx tables contains an advance width and a sidebearing
|
||||
// for the number of glyphs declared in the maxp table
|
||||
// Ensure the [h/v]mtx tables contains the advance width and
|
||||
// sidebearings information for numGlyphs in the maxp table
|
||||
font.pos = (font.start ? font.start : 0) + maxp.offset;
|
||||
var version = int16(font.getBytes(4));
|
||||
var numGlyphs = int16(font.getBytes(2));
|
||||
|
||||
font.pos = (font.start ? font.start : 0) + hhea.offset;
|
||||
font.pos += hhea.length - 2;
|
||||
var numOfHMetrics = int16(font.getBytes(2));
|
||||
|
||||
var numOfSidebearings = numGlyphs - numOfHMetrics;
|
||||
var numMissing = numOfSidebearings -
|
||||
((hmtx.length - numOfHMetrics * 4) >> 1);
|
||||
if (numMissing > 0) {
|
||||
font.pos = (font.start ? font.start : 0) + hmtx.offset;
|
||||
var metrics = '';
|
||||
for (var i = 0; i < hmtx.length; i++)
|
||||
metrics += String.fromCharCode(font.getByte());
|
||||
for (var i = 0; i < numMissing; i++)
|
||||
metrics += '\x00\x00';
|
||||
hmtx.data = stringToArray(metrics);
|
||||
}
|
||||
sanitizeMetrics(font, hhea, hmtx, numGlyphs);
|
||||
sanitizeMetrics(font, vhea, vmtx, numGlyphs);
|
||||
|
||||
// Sanitizer reduces the glyph advanceWidth to the maxAdvanceWidth
|
||||
// Sometimes it's 0. That needs to be fixed
|
||||
|
Loading…
Reference in New Issue
Block a user