Iosevka/font-src/gen/otd-conv/glyphs.js
2020-12-05 19:01:16 -08:00

97 lines
2.4 KiB
JavaScript

const { Ot } = require("ot-builder");
const Point = require("../../support/point");
class NamedGlyphStore {
constructor() {
this.m_mapping = new Map();
}
declare(name) {
const g = new Ot.Glyph();
g.name = name;
this.m_mapping.set(name, g);
}
query(name) {
return this.m_mapping.get(name);
}
decideOrder() {
const gs = Ot.ListGlyphStoreFactory.createStoreFromList([...this.m_mapping.values()]);
return gs.decideOrder();
}
fill(name, data) {
const g = this.query(name);
if (!g) return;
g.horizontal = { start: 0, end: data.advanceWidth };
if (data.references && data.references.length) {
this.fillReferences(g, data);
} else if (data.contours && data.contours.length) {
this.fillContours(g, data);
}
}
fillReferences(g, data) {
const gl = new Ot.Glyph.GeometryList();
for (const ref of data.references) {
const target = this.query(ref.glyph);
if (!target) continue;
const tfm = Ot.Glyph.Transform2X3.Translate(ref.x, ref.y);
gl.items.push(new Ot.Glyph.TtReference(target, tfm));
}
g.geometry = gl;
}
fillContours(g, data) {
const cs = new Ot.Glyph.ContourSet();
for (const c of data.contours) {
const c1 = [];
for (const z of c) {
c1.push(
Ot.Glyph.Point.create(
z.x,
z.y,
z.type === Point.Type.Quadratic
? Ot.Glyph.PointType.Quad
: Ot.Glyph.PointType.Corner
)
);
}
cs.contours.push(c1);
}
g.geometry = cs;
}
}
module.exports = convertGlyphs;
function convertGlyphs(gsOrig) {
const sortedEntries = Array.from(gsOrig.indexedNamedEntries())
.map(([j, gn, g]) => [j, gn, queryOrderingUnicode(gsOrig, g), g])
.sort(byRank);
const gs = new NamedGlyphStore();
const cmap = new Ot.Cmap.Table();
for (const [origIndex, name, uOrd, g] of sortedEntries) {
gs.declare(name);
const us = gsOrig.queryUnicodeOf(g);
if (us) {
for (const u of us) {
if (isFinite(u - 0) && u) {
cmap.unicode.set(u, gs.query(name));
}
}
}
}
for (const [origIndex, name, uOrd, g] of sortedEntries) gs.fill(name, g);
return { glyphs: gs, cmap };
}
function queryOrderingUnicode(gs, g) {
const us = gs.queryUnicodeOf(g);
if (us && us.size) return Array.from(us).sort((a, b) => a - b)[0];
else return 0xffffff;
}
function byRank([ja, gna, ua, a], [jb, gnb, ub, b]) {
return (
(b.glyphRank || 0) - (a.glyphRank || 0) || (ua || 0) - (ub || 0) || (ja || 0) - (jb || 0)
);
}