autokerning
Version:
autokerning computes suggested kerning values for glyph pairs from TrueType/OpenType fonts by rendering glyph bitmaps, applying a small Gaussian blur, and measuring pixel overlap across horizontal offsets. It can be used programmatically (as an imported E
56 lines (55 loc) • 2.27 kB
JavaScript
import { Command } from "commander";
import * as opentype from "opentype.js";
import { renderGlyph } from "./glyph.js";
import { kernPair } from "./kernPair.js";
import { generateKerningTable, findS } from "./generateKerningTable.js";
const program = new Command();
program
.name("autokerning")
.description("Auto-compute kerning values for fonts")
.argument("<fontfile>", "Path to font file (.ttf/.otf)")
.argument("[pairs...]")
.option("-s, --size <n>", "Font size (default 100)", "100")
.option("-o, --output <file>", "Generate kerning JSON file like generate-kerning")
.option("--pairs <list>", "Comma-separated list of pairs to analyze for JSON output")
.parse(process.argv);
const fontfile = program.args[0];
let pairs = program.args.slice(1);
const outputFile = program.opts().output;
const pairsString = program.opts().pairs;
// Convert comma-separated pairs string to array
const pairsList = pairsString
? pairsString.split(",").map((p) => p.trim())
: undefined;
import { COMMON_PAIRS } from "./commonPairs.js";
// use findS exported from generateKerningTable (calibrated adaptive kernel)
(async () => {
if (outputFile) {
// Generate kerning JSON file for font, optionally with user pairs
const { outputPath, kerningTable } = await generateKerningTable(fontfile, {
outputfile: outputFile,
pairs: pairsList,
writeFile: true,
});
console.log(`Kerning table saved to: ${outputPath}`);
console.log(`Total pairs: ${Object.keys(kerningTable).length}`);
return;
}
// If no pairs provided, use default common pairs
if (!pairs.length) {
pairs = COMMON_PAIRS;
}
const font = await opentype.load(fontfile);
// Calibrate overlap thresholds (findS returns [minS, maxS, kernelWidth])
const [minS, maxS, kernelWidth] = findS(font);
for (const pair of pairs) {
if (pair.length !== 2)
continue;
const [lch, rch] = pair;
const left = renderGlyph(font, lch);
const right = renderGlyph(font, rch);
const kern = kernPair(left, right, minS, maxS, kernelWidth);
console.log(`${pair}: suggested kerning ${kern.toFixed(2)} (px)`);
}
})();