Produce more meaningful glyph names
This commit is contained in:
parent
7f35523506
commit
dcc2de59f4
3 changed files with 82 additions and 28 deletions
|
@ -1,4 +1,4 @@
|
||||||
import { Joining, AnyCv, TieMark, Nwid, Wwid, VS01 } from "../../support/gr.mjs";
|
import { Joining, AnyCv, TieMark, Nwid, Wwid, VS01, CvDecompose } from "../../support/gr.mjs";
|
||||||
|
|
||||||
const ApplePostNames = new Map([
|
const ApplePostNames = new Map([
|
||||||
/* spell-checker: disable */
|
/* spell-checker: disable */
|
||||||
|
@ -267,7 +267,7 @@ export function byCode(gSrc, primaryUnicode, conflictSet) {
|
||||||
let preferredName = null;
|
let preferredName = null;
|
||||||
if (primaryUnicode) {
|
if (primaryUnicode) {
|
||||||
preferredName =
|
preferredName =
|
||||||
ApplePostNames.get(primaryUnicode) || `u${formatCodePointHex(primaryUnicode)}`;
|
ApplePostNames.get(primaryUnicode) || `uni${formatCodePointHex(primaryUnicode)}`;
|
||||||
}
|
}
|
||||||
if (preferredName && !conflictSet.has(preferredName)) {
|
if (preferredName && !conflictSet.has(preferredName)) {
|
||||||
conflictSet.add(preferredName);
|
conflictSet.add(preferredName);
|
||||||
|
@ -278,30 +278,16 @@ function formatCodePointHex(u) {
|
||||||
return u.toString(16).padStart(4, "0").toUpperCase();
|
return u.toString(16).padStart(4, "0").toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
export function bySpacing(gSrcBase, gOtBase, internalNameMap, conflictSet) {
|
export function bySpacing(gSrcBase, gOtBase, internalNameMap, conflictSet) {
|
||||||
if (!gOtBase.name) return 0;
|
if (!gOtBase.name) return 0;
|
||||||
let n = 0;
|
let n = 0;
|
||||||
n += nameByPairGr(Nwid, Wwid, "NWID", "WWID", gSrcBase, gOtBase, internalNameMap, conflictSet);
|
n += byPairGrImpl(Nwid, "NWID", "WWID", gSrcBase, gOtBase, internalNameMap, conflictSet);
|
||||||
n += nameByPairGr(Wwid, Nwid, "WWID", "NWID", gSrcBase, gOtBase, internalNameMap, conflictSet);
|
n += byPairGrImpl(Wwid, "WWID", "NWID", gSrcBase, gOtBase, internalNameMap, conflictSet);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
function byPairGrImpl(grCis, tagCis, tagTrans, gSrcBase, gOtBase, nm, conflictSet) {
|
||||||
const NamingGr = [TieMark, VS01];
|
|
||||||
|
|
||||||
export function byGr(gSrcBase, gOtBase, internalNameMap, conflictSet) {
|
|
||||||
if (!gOtBase.name) return 0;
|
|
||||||
let n = 0;
|
|
||||||
for (const cv of AnyCv.query(gSrcBase)) {
|
|
||||||
n += nameByGr(cv, gSrcBase, gOtBase, internalNameMap, conflictSet);
|
|
||||||
}
|
|
||||||
for (const gr of NamingGr) {
|
|
||||||
if (gr.get(gSrcBase)) {
|
|
||||||
n += nameByGr(gr, gSrcBase, gOtBase, internalNameMap, conflictSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
function nameByPairGr(grCis, grTrans, tagCis, tagTrans, gSrcBase, gOtBase, nm, conflictSet) {
|
|
||||||
const gnDst = grCis.get(gSrcBase);
|
const gnDst = grCis.get(gSrcBase);
|
||||||
if (!gnDst) return 0;
|
if (!gnDst) return 0;
|
||||||
const gOtDst = nm.get(gnDst);
|
const gOtDst = nm.get(gnDst);
|
||||||
|
@ -317,7 +303,48 @@ function nameByPairGr(grCis, grTrans, tagCis, tagTrans, gSrcBase, gOtBase, nm, c
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
function nameByGr(gr, gSrcBase, gOtBase, internalNameMap, conflictSet) {
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
export function byDecompose(gSrcBase, gOtBase, internalNameMap, conflictSet) {
|
||||||
|
const parts = CvDecompose.get(gSrcBase);
|
||||||
|
|
||||||
|
if (!parts || !parts.length) return 0;
|
||||||
|
|
||||||
|
let newNamesCount = 0;
|
||||||
|
for (const [index, gnPart] of parts.entries()) {
|
||||||
|
const gComponent = internalNameMap.get(gnPart);
|
||||||
|
|
||||||
|
if (!gComponent || gComponent.name) continue;
|
||||||
|
|
||||||
|
const nameT = CvDecompose.amendOtName(gOtBase.name, index);
|
||||||
|
if (!conflictSet.has(nameT)) {
|
||||||
|
conflictSet.add(nameT);
|
||||||
|
gComponent.name = nameT;
|
||||||
|
newNamesCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newNamesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const NamingGr = [TieMark, VS01];
|
||||||
|
export function byGr(gSrcBase, gOtBase, internalNameMap, conflictSet) {
|
||||||
|
if (!gOtBase.name) return 0;
|
||||||
|
let n = 0;
|
||||||
|
for (const cv of AnyCv.query(gSrcBase)) {
|
||||||
|
n += nameByGrImpl(cv, gSrcBase, gOtBase, internalNameMap, conflictSet);
|
||||||
|
}
|
||||||
|
for (const gr of NamingGr) {
|
||||||
|
if (gr.get(gSrcBase)) {
|
||||||
|
n += nameByGrImpl(gr, gSrcBase, gOtBase, internalNameMap, conflictSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
function nameByGrImpl(gr, gSrcBase, gOtBase, internalNameMap, conflictSet) {
|
||||||
const gnDst = gr.get(gSrcBase);
|
const gnDst = gr.get(gSrcBase);
|
||||||
if (!gnDst) return 0;
|
if (!gnDst) return 0;
|
||||||
const gOtDst = internalNameMap.get(gnDst);
|
const gOtDst = internalNameMap.get(gnDst);
|
||||||
|
@ -331,6 +358,8 @@ function nameByGr(gr, gSrcBase, gOtBase, internalNameMap, conflictSet) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
export function byBuildOrder(rank, gSrc, gnOrig) {
|
export function byBuildOrder(rank, gSrc, gnOrig) {
|
||||||
if (!gnOrig) gnOrig = `.g${rank}`;
|
if (!gnOrig) gnOrig = `.g${rank}`;
|
||||||
gnOrig = Joining.amendOtName(gnOrig, Joining.get(gSrc));
|
gnOrig = Joining.amendOtName(gnOrig, Joining.get(gSrc));
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Ot } from "ot-builder";
|
||||||
import { Point } from "../../support/geometry/point.mjs";
|
import { Point } from "../../support/geometry/point.mjs";
|
||||||
import * as Gr from "../../support/gr.mjs";
|
import * as Gr from "../../support/gr.mjs";
|
||||||
|
|
||||||
import { byBuildOrder, byCode, byGr, bySpacing } from "./glyph-name.mjs";
|
import * as GlyphName from "./glyph-name.mjs";
|
||||||
|
|
||||||
function byRank([gna, a], [gnb, b]) {
|
function byRank([gna, a], [gnb, b]) {
|
||||||
return (
|
return (
|
||||||
|
@ -54,7 +54,6 @@ class MappedGlyphStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fillOtGlyphNames() {
|
fillOtGlyphNames() {
|
||||||
let gid = 0;
|
|
||||||
let conflictSet = new Set();
|
let conflictSet = new Set();
|
||||||
let rev = new Map();
|
let rev = new Map();
|
||||||
for (const [u, g] of this.m_primaryUnicodeMapping) rev.set(g, u);
|
for (const [u, g] of this.m_primaryUnicodeMapping) rev.set(g, u);
|
||||||
|
@ -62,29 +61,52 @@ class MappedGlyphStore {
|
||||||
([a], [b]) => a.subRank - b.subRank
|
([a], [b]) => a.subRank - b.subRank
|
||||||
);
|
);
|
||||||
for (const [gSrc, gOt] of glyphsInBuildOrder) gOt.name = undefined;
|
for (const [gSrc, gOt] of glyphsInBuildOrder) gOt.name = undefined;
|
||||||
|
|
||||||
// Name by Unicode
|
// Name by Unicode
|
||||||
for (const [gSrc, gOt] of glyphsInBuildOrder) {
|
for (const [gSrc, gOt] of glyphsInBuildOrder) {
|
||||||
gOt.name = byCode(gSrc, rev.get(gSrc), conflictSet);
|
gOt.name = GlyphName.byCode(gSrc, rev.get(gSrc), conflictSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name by NWID/WWID
|
// Name by NWID/WWID
|
||||||
let nNewNames = 0;
|
let nNewNames = 0;
|
||||||
do {
|
do {
|
||||||
nNewNames = 0;
|
nNewNames = 0;
|
||||||
for (const [gSrcBase, gOtBase] of glyphsInBuildOrder) {
|
for (const [gSrcBase, gOtBase] of glyphsInBuildOrder) {
|
||||||
nNewNames += bySpacing(gSrcBase, gOtBase, this.m_nameMapping, conflictSet);
|
nNewNames += GlyphName.bySpacing(
|
||||||
|
gSrcBase,
|
||||||
|
gOtBase,
|
||||||
|
this.m_nameMapping,
|
||||||
|
conflictSet
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} while (nNewNames > 0);
|
} while (nNewNames > 0);
|
||||||
|
|
||||||
|
// Name by decompose
|
||||||
|
do {
|
||||||
|
nNewNames = 0;
|
||||||
|
for (const [gSrcBase, gOtBase] of glyphsInBuildOrder) {
|
||||||
|
nNewNames += GlyphName.byDecompose(
|
||||||
|
gSrcBase,
|
||||||
|
gOtBase,
|
||||||
|
this.m_nameMapping,
|
||||||
|
conflictSet
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} while (nNewNames > 0);
|
||||||
|
|
||||||
// Name by Gr
|
// Name by Gr
|
||||||
do {
|
do {
|
||||||
nNewNames = 0;
|
nNewNames = 0;
|
||||||
for (const [gSrcBase, gOtBase] of glyphsInBuildOrder) {
|
for (const [gSrcBase, gOtBase] of glyphsInBuildOrder) {
|
||||||
nNewNames += byGr(gSrcBase, gOtBase, this.m_nameMapping, conflictSet);
|
nNewNames += GlyphName.byGr(gSrcBase, gOtBase, this.m_nameMapping, conflictSet);
|
||||||
}
|
}
|
||||||
} while (nNewNames > 0);
|
} while (nNewNames > 0);
|
||||||
|
|
||||||
// Name rest
|
// Name rest
|
||||||
for (const [gSrc, gOt] of glyphsInBuildOrder) {
|
for (const [gSrc, gOt] of glyphsInBuildOrder) {
|
||||||
gOt.name = byBuildOrder(gSrc.subRank, gSrc, gOt.name);
|
gOt.name = GlyphName.byBuildOrder(gSrc.subRank, gSrc, gOt.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
{
|
{
|
||||||
let gnSet = new Set();
|
let gnSet = new Set();
|
||||||
|
|
|
@ -78,6 +78,9 @@ function DecompositionProp(key) {
|
||||||
if (!Array.isArray(composition)) throw new Error("Must supply a GID array");
|
if (!Array.isArray(composition)) throw new Error("Must supply a GID array");
|
||||||
if (!glyph.related) glyph.related = {};
|
if (!glyph.related) glyph.related = {};
|
||||||
glyph.related[key] = composition;
|
glyph.related[key] = composition;
|
||||||
|
},
|
||||||
|
amendOtName(baseName, index) {
|
||||||
|
return `${baseName}.d${index}`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue