
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import {binarySearch} from '../utils';
export default class KernProcessor {
constructor(font) {
this.kern = font.kern;
}
process(glyphs, positions) {
for (let glyphIndex = 0; glyphIndex < glyphs.length - 1; glyphIndex++) {
let left = glyphs[glyphIndex].id;
let right = glyphs[glyphIndex + 1].id;
positions[glyphIndex].xAdvance += this.getKerning(left, right);
}
}
getKerning(left, right) {
let res = 0;
for (let table of this.kern.tables) {
if (table.coverage.crossStream) {
continue;
}
switch (table.version) {
case 0:
if (!table.coverage.horizontal) {
continue;
}
break;
case 1:
if (table.coverage.vertical || table.coverage.variation) {
continue;
}
break;
default:
throw new Error(`Unsupported kerning table version ${table.version}`);
}
let val = 0;
let s = table.subtable;
switch (table.format) {
case 0:
let pairIdx = binarySearch(s.pairs, function (pair) {
return (left - pair.left) || (right - pair.right);
});
if (pairIdx >= 0) {
val = s.pairs[pairIdx].value;
}
break;
case 2:
let leftOffset = 0, rightOffset = 0;
if (left >= s.leftTable.firstGlyph && left < s.leftTable.firstGlyph + s.leftTable.nGlyphs) {
leftOffset = s.leftTable.offsets[left - s.leftTable.firstGlyph];
} else {
leftOffset = s.array.off;
}
if (right >= s.rightTable.firstGlyph && right < s.rightTable.firstGlyph + s.rightTable.nGlyphs) {
rightOffset = s.rightTable.offsets[right - s.rightTable.firstGlyph];
}
let index = (leftOffset + rightOffset - s.array.off) / 2;
val = s.array.values.get(index);
break;
case 3:
if (left >= s.glyphCount || right >= s.glyphCount) {
return 0;
}
val = s.kernValue[s.kernIndex[s.leftClass[left] * s.rightClassCount + s.rightClass[right]]];
break;
default:
throw new Error(`Unsupported kerning sub-table format ${table.format}`);
}
// Microsoft supports the override flag, which resets the result
// Otherwise, the sum of the results from all subtables is returned
if (table.coverage.override) {
res = val;
} else {
res += val;
}
}
return res;
}
}