70 lines
2.3 KiB
Plaintext
70 lines
2.3 KiB
Plaintext
// The `kern` table contains kerning pairs.
|
|
// Note that some fonts use the GPOS OpenType layout table to specify kerning.
|
|
// https://www.microsoft.com/typography/OTSPEC/kern.htm
|
|
|
|
import check from '../check';
|
|
import parse from '../parse';
|
|
|
|
function parseWindowsKernTable(p) {
|
|
const pairs = {};
|
|
// Skip nTables.
|
|
p.skip('uShort');
|
|
const subtableVersion = p.parseUShort();
|
|
check.argument(subtableVersion === 0, 'Unsupported kern sub-table version.');
|
|
// Skip subtableLength, subtableCoverage
|
|
p.skip('uShort', 2);
|
|
const nPairs = p.parseUShort();
|
|
// Skip searchRange, entrySelector, rangeShift.
|
|
p.skip('uShort', 3);
|
|
for (let i = 0; i < nPairs; i += 1) {
|
|
const leftIndex = p.parseUShort();
|
|
const rightIndex = p.parseUShort();
|
|
const value = p.parseShort();
|
|
pairs[leftIndex + ',' + rightIndex] = value;
|
|
}
|
|
return pairs;
|
|
}
|
|
|
|
function parseMacKernTable(p) {
|
|
const pairs = {};
|
|
// The Mac kern table stores the version as a fixed (32 bits) but we only loaded the first 16 bits.
|
|
// Skip the rest.
|
|
p.skip('uShort');
|
|
const nTables = p.parseULong();
|
|
//check.argument(nTables === 1, 'Only 1 subtable is supported (got ' + nTables + ').');
|
|
if (nTables > 1) {
|
|
console.warn('Only the first kern subtable is supported.');
|
|
}
|
|
p.skip('uLong');
|
|
const coverage = p.parseUShort();
|
|
const subtableVersion = coverage & 0xFF;
|
|
p.skip('uShort');
|
|
if (subtableVersion === 0) {
|
|
const nPairs = p.parseUShort();
|
|
// Skip searchRange, entrySelector, rangeShift.
|
|
p.skip('uShort', 3);
|
|
for (let i = 0; i < nPairs; i += 1) {
|
|
const leftIndex = p.parseUShort();
|
|
const rightIndex = p.parseUShort();
|
|
const value = p.parseShort();
|
|
pairs[leftIndex + ',' + rightIndex] = value;
|
|
}
|
|
}
|
|
return pairs;
|
|
}
|
|
|
|
// Parse the `kern` table which contains kerning pairs.
|
|
function parseKernTable(data, start) {
|
|
const p = new parse.Parser(data, start);
|
|
const tableVersion = p.parseUShort();
|
|
if (tableVersion === 0) {
|
|
return parseWindowsKernTable(p);
|
|
} else if (tableVersion === 1) {
|
|
return parseMacKernTable(p);
|
|
} else {
|
|
throw new Error('Unsupported kern table version (' + tableVersion + ').');
|
|
}
|
|
}
|
|
|
|
export default { parse: parseKernTable };
|