Iosevka/font-src/gen/finalize/index.mjs

42 lines
1.6 KiB
JavaScript

import { Nwid, Wwid } from "../../support/gr.mjs";
import { gcFont } from "./gc.mjs";
import { finalizeGlyphs } from "./glyphs.mjs";
function assignGrAndCodeRank(glyphStore, ...flatteners) {
for (const g of glyphStore.glyphs()) {
g.codeRank = 0xffffffff;
for (const c of glyphStore.flattenCodes(g, flatteners)) if (c < g.codeRank) g.codeRank = c;
g.grRank = 0;
for (let i = 0; i < flatteners.length; i++) if (flatteners[i].get(g)) g.grRank |= 1 << i;
}
}
function assignSubRank(glyphStore) {
let sr = 0;
for (const g of glyphStore.glyphs()) g.subRank = sr++;
}
// In FontConfig, a font is considered "monospace" if and only if all encoded non-combining
// characters (AW > 0) have the same width. We use this method to validate whether our
// "Fixed" subfamilies are properly built.
function validateMonospace(para, glyphStore) {
let awSet = new Set();
for (const [u, n, g] of glyphStore.encodedEntries()) {
const aw = Math.round(g.advanceWidth || 0);
if (aw > 0) awSet.add(aw);
}
if (para.forceMonospace && awSet.size > 1) {
throw new Error("Unreachable! Fixed variant has wide characters");
}
if (!para.isQuasiProportional && !para.compLig && awSet.size > 2) {
throw new Error("Unreachable! Building monospace with more than 2 character widths");
}
}
export function finalizeFont(cache, para, glyphStore, excludedCodePoints, restFont) {
assignGrAndCodeRank(glyphStore, Nwid, Wwid);
assignSubRank(glyphStore);
glyphStore = gcFont(glyphStore, excludedCodePoints, restFont);
glyphStore = finalizeGlyphs(cache, para, glyphStore);
validateMonospace(para, glyphStore);
return glyphStore;
}