Fix TTFA control generator to fix broken superscript letters (#1976).

This commit is contained in:
be5invis 2023-09-02 14:21:46 -07:00
parent 130f36a711
commit 82601c5364
4 changed files with 94 additions and 125 deletions

1
changes/26.3.1.md Normal file
View file

@ -0,0 +1 @@
* Fix TTFA control generator to fix broken superscript letters (#1976).

View file

@ -3,31 +3,33 @@ import * as Gr from "../../support/gr.mjs";
import { ArrayUtil } from "../../support/utils.mjs"; import { ArrayUtil } from "../../support/utils.mjs";
export async function generateTtfaControls(gsOrig, gs) { export async function generateTtfaControls(gsOrig, gs) {
let ttfaControls = []; let ttfaControls = [`# Machine generated. Do not modify.`];
for (const alignment of ttfaRanges) { for (const alignment of ttfaRanges) {
ttfaControls.push(generateTTFAAlignments(alignment, gsOrig, gs)); generateTTFAAlignments(ttfaControls, alignment, gsOrig, gs);
} }
return ttfaControls; return ttfaControls;
} }
function generateTTFAAlignments(alignment, gsOrig, gsTtf) { function generateTTFAAlignments(sink, alignment, gsOrig, gsTtf) {
let collectedGlyphs = new Map(); let allGlyphs = new Map();
let defaultGlyphs = new Map();
for (const [lo, hi] of alignment.ranges) { for (const [lo, hi] of alignment.ranges) {
for (let lch = lo; lch <= hi; lch++) { for (let lch = lo; lch <= hi; lch++) {
const go = gsOrig.queryByUnicode(lch); const go = gsOrig.queryByUnicode(lch);
if (!go) continue; if (!go) continue;
const gd = gsTtf.queryBySourceGlyph(go); const gd = gsTtf.queryBySourceGlyph(go);
if (!gd) continue; if (!gd) continue;
collectedGlyphs.set(go, gd); allGlyphs.set(go, gd);
defaultGlyphs.set(go, gd);
} }
} }
for (;;) { for (;;) {
let sizeBefore = collectedGlyphs.size; let sizeBefore = allGlyphs.size;
for (const [go, gd] of collectedGlyphs) { for (const [go, gd] of allGlyphs) {
const cvs = Gr.AnyCv.query(go); const cvs = Gr.AnyCv.query(go);
for (const gr of cvs) { for (const gr of cvs) {
const gnLinked = gr.get(go); const gnLinked = gr.get(go);
@ -36,21 +38,24 @@ function generateTTFAAlignments(alignment, gsOrig, gsTtf) {
if (!goLinked) continue; if (!goLinked) continue;
const gdLinked = gsTtf.queryBySourceGlyph(goLinked); const gdLinked = gsTtf.queryBySourceGlyph(goLinked);
if (!gdLinked) continue; if (!gdLinked) continue;
collectedGlyphs.set(goLinked, gdLinked); allGlyphs.set(goLinked, gdLinked);
} }
} }
let sizeAfter = collectedGlyphs.size; let sizeAfter = allGlyphs.size;
if (sizeAfter <= sizeBefore) break; if (sizeAfter <= sizeBefore) break;
} }
const gOrd = gsTtf.decideOrder(); const gOrd = gsTtf.decideOrder();
const glyphIndices = Array.from(collectedGlyphs.values()).map(gd => gOrd.reverse(gd)); let nonDefaultGlyphIndices = [];
const glyphIndicesRangesStr = ArrayUtil.toRanges(glyphIndices) for (const [go, gd] of allGlyphs) {
if (defaultGlyphs.has(go)) continue;
nonDefaultGlyphIndices.push(gOrd.reverse(gd));
}
const glyphIndicesRangesStr = ArrayUtil.toRanges(nonDefaultGlyphIndices)
.map(([lo, hi]) => (lo === hi ? `${lo}` : `${lo}-${hi}`)) .map(([lo, hi]) => (lo === hi ? `${lo}` : `${lo}-${hi}`))
.join(", "); .join(", ");
const styleAdjustLine = `${alignment.scriptTag} ${alignment.featureTag} @ ${glyphIndicesRangesStr}`; sink.push(`${alignment.scriptTag} ${alignment.featureTag} @ ${glyphIndicesRangesStr}`);
return styleAdjustLine;
} }

View file

@ -7,6 +7,10 @@ export default [
"ranges": [ "ranges": [
[ [
0, 0,
169
],
[
171,
177 177
], ],
[ [
@ -14,7 +18,7 @@ export default [
184 184
], ],
[ [
186, 187,
442 442
], ],
[ [
@ -168,47 +172,21 @@ export default [
] ]
}, },
{ {
"scriptTag": "latb", "scriptTag": "latp",
"featureTag": "dflt", "featureTag": "dflt",
"ranges": [ "ranges": [
[
170,
170
],
[ [
178, 178,
179 179
], ],
[ [
185, 185,
185 186
], ],
[
7522,
7525
],
[
8304,
8304
],
[
8308,
8318
],
[
8320,
8334
],
[
8336,
8348
],
[
11388,
11388
]
]
},
{
"scriptTag": "latp",
"featureTag": "dflt",
"ranges": [
[ [
688, 688,
696 696
@ -217,26 +195,42 @@ export default [
736, 736,
740 740
], ],
[
890,
890
],
[ [
7468, 7468,
7516 7521
],
[
7544,
7544
], ],
[ [
7579, 7579,
7614 7615
], ],
[ [
8305, 8304,
8305 8305
], ],
[ [
8319, 8308,
8319 8319
], ],
[ [
11389, 11389,
11389 11389
], ],
[
42623,
42623
],
[
42652,
42653
],
[ [
42864, 42864,
42864 42864
@ -268,6 +262,14 @@ export default [
[ [
67506, 67506,
67514 67514
],
[
122928,
122960
],
[
122987,
122989
] ]
] ]
}, },
@ -417,24 +419,6 @@ export default [
] ]
] ]
}, },
{
"scriptTag": "grek",
"featureTag": "sups",
"ranges": [
[
890,
890
],
[
7517,
7521
],
[
7615,
7615
]
]
},
{ {
"scriptTag": "cyrl", "scriptTag": "cyrl",
"featureTag": "dflt", "featureTag": "dflt",
@ -466,45 +450,25 @@ export default [
] ]
}, },
{ {
"scriptTag": "grek", "scriptTag": "latb",
"featureTag": "subs", "featureTag": "dflt",
"ranges": [ "ranges": [
[ [
7526, 7522,
7530 7530
]
]
},
{
"scriptTag": "cyrl",
"featureTag": "sups",
"ranges": [
[
7544,
7544
], ],
[ [
42623, 8320,
42623 8334
], ],
[ [
42652, 8336,
42653 8348
], ],
[ [
122928, 11388,
122960 11388
], ],
[
122987,
122989
]
]
},
{
"scriptTag": "cyrl",
"featureTag": "subs",
"ranges": [
[ [
122961, 122961,
122986 122986

View file

@ -187,6 +187,11 @@ const GreekBase = {
Either(GeneralCategory("Uppercase_Letter"), GeneralCategory("Lowercase_Letter")) Either(GeneralCategory("Uppercase_Letter"), GeneralCategory("Lowercase_Letter"))
) )
}; };
const DigitBase = {
scriptTag: "latn",
featureTag: "dflt",
filter: Either(In("0123456789"))
};
const LatinSubscript = { const LatinSubscript = {
scriptTag: "latb", scriptTag: "latb",
@ -194,44 +199,38 @@ const LatinSubscript = {
filter: Either(In("ₐₑₔₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓ")) filter: Either(In("ₐₑₔₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓ"))
}; };
const GreekSubscript = { const GreekSubscript = {
scriptTag: "grek", scriptTag: "latb",
featureTag: "subs", featureTag: "dflt",
filter: Either(In("ᵦᵧᵨᵩᵪ")) filter: Either(In("ᵦᵧᵨᵩᵪ"))
}; };
const CyrillicSubscript = { const CyrillicSubscript = {
scriptTag: "cyrl", scriptTag: "latb",
featureTag: "subs", featureTag: "dflt",
filter: Either(In("𞁑𞁒𞁓𞁔𞁧𞁕𞁖𞁗𞁘𞁩𞁙𞁨𞁚𞁛𞁜𞁝𞁞𞁟𞁠𞁡𞁢𞁣𞁪𞁤𞁥𞁦")) filter: Either(In("𞁑𞁒𞁓𞁔𞁧𞁕𞁖𞁗𞁘𞁩𞁙𞁨𞁚𞁛𞁜𞁝𞁞𞁟𞁠𞁡𞁢𞁣𞁪𞁤𞁥𞁦"))
}; };
const LatinSuperscript = {
scriptTag: "latp",
featureTag: "dflt",
filter: Either(All(Script("Latin"), Either(GeneralCategory("Modifier_Letter"))))
};
const GreekSuperscript = {
scriptTag: "grek",
featureTag: "sups",
filter: All(Script("Greek"), Either(GeneralCategory("Modifier_Letter")))
};
const CyrillicSuperscript = {
scriptTag: "cyrl",
featureTag: "sups",
filter: All(Script("Cyrillic"), Either(GeneralCategory("Modifier_Letter")))
};
const DigitBase = {
scriptTag: "latn",
featureTag: "dflt",
filter: Either(In("0123456789"))
};
const DigitSubscript = { const DigitSubscript = {
scriptTag: "latb", scriptTag: "latb",
featureTag: "dflt", featureTag: "dflt",
filter: Either(In("₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎")) filter: Either(In("₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎"))
}; };
const LatinSuperscript = {
scriptTag: "latp",
featureTag: "dflt",
filter: Either(In("ªº"), All(Script("Latin"), Either(GeneralCategory("Modifier_Letter"))))
};
const GreekSuperscript = {
scriptTag: "latp",
featureTag: "dflt",
filter: All(Script("Greek"), Either(GeneralCategory("Modifier_Letter")))
};
const CyrillicSuperscript = {
scriptTag: "latp",
featureTag: "dflt",
filter: All(Script("Cyrillic"), Either(GeneralCategory("Modifier_Letter")))
};
const DigitSuperscript = { const DigitSuperscript = {
scriptTag: "latb", scriptTag: "latp",
featureTag: "dflt", featureTag: "dflt",
filter: Either(In("⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾")) filter: Either(In("⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾"))
}; };