Feature Request: expose getKerning(left, right) to users
Typogram opened this issue · 3 comments
My use case need a function like getKerningValue
from OpenType.js
Font.getKerningValue(leftGlyph, rightGlyph)
I found that in KernProcessor.js, there is already an function called getKerning
I wish it can get exposed to users to get kerning value directly like what OpenType.js does with getKerningValue
With the existing code already there, it should be a low hanging fruit to imcrease developer experience! What do you think?
Why can't you use the existing public API for layout? This is much better because it works across multiple font formats including legacy kerning and opentype positioning.
I agree the font.layout()
API is pretty solid. I needed the kerning because I am migrating Typogram from opentype.js to fontkit, and I already wrote my own layout logic dependent on getKerningValue
of OpenType.js
So having this API would make my developer experience much better, and require less code rewrite to migrate from OpenType.js to fontkit.
I also find the requested API helpful for debugging font. eg. to see if it has correct kerning values. One of the reasons I migrate is because of this bug of OpenType.js, where it doesn't read kerning data correctly for certain fonts. I tested with fontkit and it can read kerning data correctly, but the only way I found out is by looking at the rendition, I couldn't just output the kerning data reading directly with fontkit.
Codepen: https://codepen.io/wendyz/pen/YzOKWwY?editors=1011
@devongovett Would this be an advisable way to use layout for getting the kerning?
export interface KerningCache {
[key: string]: number;
}
const kerningCache: KerningCache = {};
function getKerning(
fontData: fontkit.Font,
prevChar: string,
char: string,
fontSize: number
): number {
if (!prevChar || !char) {
return 0;
}
const cacheKey = `${prevChar}_${char}_${fontSize}`;
if (cacheKey in kerningCache) {
return kerningCache[cacheKey];
}
const scaleFactor = fontSize / fontData.unitsPerEm;
const glyphRun = fontData.layout(prevChar + char);
if (!glyphRun.positions[1] || !glyphRun.positions[0]) {
return 0;
}
const kerning =
(glyphRun.positions[1].xAdvance - glyphRun.positions[0].xAdvance) *
scaleFactor;
// console.info("kerning", char, kerning);
kerningCache[cacheKey] = kerning;
return kerning;
}