OTL codegen cleanup
This commit is contained in:
parent
d471e9d948
commit
c6dc8c370c
11 changed files with 120 additions and 123 deletions
|
@ -26,9 +26,9 @@ function markLookups(table, sink) {
|
|||
let sizeBefore = sink.size;
|
||||
for (const l of Array.from(sink)) {
|
||||
const lookup = table.lookups[l];
|
||||
if (!lookup || !lookup.subtables) continue;
|
||||
if (!lookup) continue;
|
||||
if (lookup.type === "gsub_chaining" || lookup.type === "gpos_chaining") {
|
||||
for (let st of lookup.subtables) {
|
||||
for (let st of lookup.rules) {
|
||||
if (!st || !st.apply) continue;
|
||||
for (const app of st.apply) sink.add(app.lookup);
|
||||
}
|
||||
|
@ -91,56 +91,60 @@ function markGlyphsStep(glyphStore, sink, restFont, cfg) {
|
|||
if (restFont.GSUB) {
|
||||
for (const l in restFont.GSUB.lookups) {
|
||||
const lookup = restFont.GSUB.lookups[l];
|
||||
if (!lookup || !lookup.subtables) continue;
|
||||
for (let st of lookup.subtables) {
|
||||
markGlyphsSubtable(sink, lookup.type, st, cfg);
|
||||
}
|
||||
if (!lookup) continue;
|
||||
markGlyphsLookupImpl(sink, lookup, cfg);
|
||||
}
|
||||
}
|
||||
const glyphCount1 = sink.size;
|
||||
return glyphCount1 > glyphCount;
|
||||
}
|
||||
|
||||
function markGlyphsSubtable(sink, type, st, cfg) {
|
||||
switch (type) {
|
||||
function markGlyphsLookupImpl(sink, lookup, cfg) {
|
||||
switch (lookup.type) {
|
||||
case "gsub_single":
|
||||
return markGlyphsGsubSingle(sink, st, cfg);
|
||||
return markGlyphsGsubSingle(sink, lookup, cfg);
|
||||
case "gsub_multiple":
|
||||
return markGlyphsGsubMultiple(sink, st, cfg);
|
||||
return markGlyphsGsubMultiple(sink, lookup, cfg);
|
||||
case "gsub_alternate":
|
||||
return markGlyphsGsubAlternate(sink, st, cfg);
|
||||
return markGlyphsGsubAlternate(sink, lookup, cfg);
|
||||
case "gsub_ligature":
|
||||
return markGlyphsGsubLigature(sink, st, cfg);
|
||||
return markGlyphsGsubLigature(sink, lookup, cfg);
|
||||
case "gsub_chaining":
|
||||
break;
|
||||
case "gsub_reverse":
|
||||
return markGlyphsGsubReverse(sink, st, cfg);
|
||||
return markGlyphsGsubReverse(sink, lookup, cfg);
|
||||
}
|
||||
}
|
||||
|
||||
function markGlyphsGsubSingle(sink, st, cfg) {
|
||||
function markGlyphsGsubSingle(sink, lookup, cfg) {
|
||||
const st = lookup.substitutions;
|
||||
for (const k in st) if (sink.has(k) && st[k]) sink.add(st[k]);
|
||||
}
|
||||
function markGlyphsGsubMultiple(sink, st, cfg) {
|
||||
function markGlyphsGsubMultiple(sink, lookup, cfg) {
|
||||
const st = lookup.substitutions;
|
||||
for (const k in st) if (sink.has(k) && st[k]) for (const g of st[k]) sink.add(g);
|
||||
}
|
||||
function markGlyphsGsubAlternate(sink, st, cfg) {
|
||||
function markGlyphsGsubAlternate(sink, lookup, cfg) {
|
||||
const st = lookup.substitutions;
|
||||
if (!cfg || !cfg.ignoreAltSub) {
|
||||
for (const k in st) if (sink.has(k) && st[k]) for (const g of st[k]) sink.add(g);
|
||||
}
|
||||
}
|
||||
function markGlyphsGsubLigature(sink, st, cfg) {
|
||||
for (const sub of st.substitutions) {
|
||||
function markGlyphsGsubLigature(sink, lookup, cfg) {
|
||||
const st = lookup.substitutions;
|
||||
for (const sub of st) {
|
||||
let check = true;
|
||||
for (const g of sub.from) if (!sink.has(g)) check = false;
|
||||
if (check && sub.to) sink.add(sub.to);
|
||||
}
|
||||
}
|
||||
function markGlyphsGsubReverse(sink, st, cfg) {
|
||||
if (st.match && st.to) {
|
||||
const matchCoverage = st.match[st.inputIndex];
|
||||
function markGlyphsGsubReverse(sink, lookup, cfg) {
|
||||
for (const rule of lookup.rules) {
|
||||
if (rule.match && rule.to) {
|
||||
const matchCoverage = rule.match[rule.inputIndex];
|
||||
for (let j = 0; j < matchCoverage.length; j++) {
|
||||
if (sink.has(matchCoverage[j]) && st.to[j]) sink.add(st.to[j]);
|
||||
if (sink.has(matchCoverage[j]) && rule.to[j]) sink.add(rule.to[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ class LookupStore {
|
|||
const dst = this.query(id);
|
||||
const handler = this.m_handlers[otdLookup.type];
|
||||
if (!dst || !handler) return;
|
||||
|
||||
if (otdLookup.subtables) throw new Error("Unreachable.");
|
||||
handler.fill(dst, otdLookup, this);
|
||||
}
|
||||
}
|
||||
|
@ -33,29 +33,27 @@ const GsubSingleHandler = {
|
|||
return new Ot.Gsub.Single();
|
||||
},
|
||||
fill(dst, src, store) {
|
||||
for (const st of src.subtables) {
|
||||
const st = src.substitutions;
|
||||
for (const k in st) {
|
||||
const from = store.glyphs.query(k);
|
||||
const to = store.glyphs.query(st[k]);
|
||||
if (from && to) dst.mapping.set(from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const GsubMultipleHandler = {
|
||||
init() {
|
||||
return new Ot.Gsub.Multiple();
|
||||
},
|
||||
fill(dst, src, store) {
|
||||
for (const st of src.subtables) {
|
||||
out: for (const k in st) {
|
||||
const st = src.substitutions;
|
||||
for (const k in st) {
|
||||
const from = store.glyphs.query(k);
|
||||
const to = mapGlyphListAll(st[k], store);
|
||||
if (!from || !to) continue out;
|
||||
if (!from || !to) continue;
|
||||
dst.mapping.set(from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const GsubAlternateHandler = {
|
||||
init() {
|
||||
|
@ -68,15 +66,14 @@ const GsubLigatureHandler = {
|
|||
return new Ot.Gsub.Ligature();
|
||||
},
|
||||
fill(dst, src, store) {
|
||||
for (const st of src.subtables) {
|
||||
for (const { from: _from, to: _to } of st.substitutions) {
|
||||
const st = src.substitutions;
|
||||
for (const { from: _from, to: _to } of st) {
|
||||
const to = store.glyphs.query(_to);
|
||||
const from = mapGlyphListAll(_from, store);
|
||||
if (!from || !to) continue;
|
||||
dst.mapping.push({ from, to });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const GsubChainingHandler = {
|
||||
|
@ -84,7 +81,7 @@ const GsubChainingHandler = {
|
|||
return new Ot.Gsub.Chaining();
|
||||
},
|
||||
fill(dst, src, store) {
|
||||
out: for (const st of src.subtables) {
|
||||
out: for (const st of src.rules) {
|
||||
const match = [];
|
||||
for (const m of st.match) {
|
||||
const m1 = mapGlyphListSome(m, store);
|
||||
|
@ -109,7 +106,7 @@ const GsubReverseHandler = {
|
|||
return new Ot.Gsub.ReverseSub();
|
||||
},
|
||||
fill(dst, src, store) {
|
||||
out: for (const st of src.subtables) {
|
||||
out: for (const st of src.rules) {
|
||||
const match = [];
|
||||
const doSubAt = st.inputIndex;
|
||||
const replacement = new Map();
|
||||
|
@ -176,10 +173,9 @@ const GposMarkToBaseHandler = {
|
|||
return new Ot.Gpos.MarkToBase();
|
||||
},
|
||||
fill(dst, src, store) {
|
||||
const st = src.subtables[0];
|
||||
const mm = collectClassMap(st.marks);
|
||||
dst.marks = convertMarkRecords(st.marks, mm, store);
|
||||
dst.bases = convertBaseRecords(st.bases, mm, store);
|
||||
const mm = collectClassMap(src.marks);
|
||||
dst.marks = convertMarkRecords(src.marks, mm, store);
|
||||
dst.bases = convertBaseRecords(src.bases, mm, store);
|
||||
}
|
||||
};
|
||||
const GposMarkToMarkHandler = {
|
||||
|
@ -187,10 +183,9 @@ const GposMarkToMarkHandler = {
|
|||
return new Ot.Gpos.MarkToMark();
|
||||
},
|
||||
fill(dst, src, store) {
|
||||
const st = src.subtables[0];
|
||||
const mm = collectClassMap(st.marks);
|
||||
dst.marks = convertMarkRecords(st.marks, mm, store);
|
||||
dst.baseMarks = convertBaseRecords(st.bases, mm, store);
|
||||
const mm = collectClassMap(src.marks);
|
||||
dst.marks = convertMarkRecords(src.marks, mm, store);
|
||||
dst.baseMarks = convertBaseRecords(src.bases, mm, store);
|
||||
}
|
||||
};
|
||||
function collectClassMap(marks) {
|
||||
|
|
|
@ -16,44 +16,42 @@ define [interpretLookup gs lut lookups] : match lut.type
|
|||
local j 0
|
||||
while (j < gs.length) : begin
|
||||
local incN 1
|
||||
do : foreach [subtable : items-of lut.subtables] : begin
|
||||
local matchT subtable.match
|
||||
local ib subtable.inputBegins
|
||||
do : foreach [rule : items-of lut.rules] : begin
|
||||
local matchT rule.match
|
||||
local ib rule.inputBegins
|
||||
local foundMatch true
|
||||
for [local k 0] (foundMatch && k < matchT.length) [inc k] : begin
|
||||
if [not gs.(j + k - ib)]
|
||||
: then : set foundMatch false
|
||||
: else : if ([matchT.(k).indexOf gs.(j + k - ib)] < 0) : set foundMatch false
|
||||
if foundMatch : begin
|
||||
foreach [app : items-of subtable.apply] : do
|
||||
foreach [app : items-of rule.apply] : do
|
||||
local aj : j - ib + app.at
|
||||
local alut lookups.(app.lookup)
|
||||
interpretLookupAt gs aj alut
|
||||
set incN : incN + subtable.inputEnds - subtable.inputBegins
|
||||
set incN : incN + rule.inputEnds - rule.inputBegins
|
||||
break nothing
|
||||
set j : j + incN
|
||||
"gsub_reverse" : begin
|
||||
local j (gs.length - 1)
|
||||
while (j >= 0) : begin
|
||||
do : foreach [subtable : items-of lut.subtables] : begin
|
||||
local matchT subtable.match
|
||||
local ib subtable.inputIndex
|
||||
do : foreach [rule : items-of lut.rules] : begin
|
||||
local matchT rule.match
|
||||
local ib rule.inputIndex
|
||||
local foundMatch true
|
||||
for [local k 0] (foundMatch && k < matchT.length) [inc k] : begin
|
||||
if [not gs.(j + k - ib)]
|
||||
: then : set foundMatch false
|
||||
: else : if ([matchT.(k).indexOf gs.(j + k - ib)] < 0) : set foundMatch false
|
||||
if foundMatch : begin
|
||||
set gs.(j) : subtable.to.[matchT.(ib).indexOf gs.(j)] || gs.(j)
|
||||
set gs.(j) : rule.to.[matchT.(ib).indexOf gs.(j)] || gs.(j)
|
||||
set j : j - 1
|
||||
"gsub_single" : begin
|
||||
for [local j 0] (j < gs.length) [inc j] : begin
|
||||
interpretLookupAt gs j lut
|
||||
|
||||
define [interpretLookupAt gs j lut] : match lut.type
|
||||
"gsub_single" : foreach [subtable : items-of lut.subtables] : begin
|
||||
if subtable.(gs.(j)) : begin
|
||||
set gs.(j) subtable.(gs.(j))
|
||||
"gsub_single" : if lut.substitutions.(gs.(j)) : set gs.(j) lut.substitutions.(gs.(j))
|
||||
|
||||
export : define [BuildCompatLigatures glyphStore GSUB GDEF config] : begin
|
||||
foreach [cldef : items-of config] : do
|
||||
|
|
|
@ -16,32 +16,32 @@ export : define [buildMarkMkmk sink glyphStore] : begin
|
|||
local mkmkLookupNames {}
|
||||
|
||||
foreach markCls [items-of MarkClasses] : begin
|
||||
local [object markSubtable mkmkSubtable] : createMTSubtables glyphStore { markCls }
|
||||
if ([objectIsNotEmpty markSubtable.marks] && [objectIsNotEmpty markSubtable.bases]) : begin
|
||||
local lidMark : add-lookup sink {.type 'gpos_mark_to_base' .subtables { markSubtable }}
|
||||
local [object markLookup mkmkLookup] : createMTLookups glyphStore { markCls }
|
||||
if ([objectIsNotEmpty markLookup.marks] && [objectIsNotEmpty markLookup.bases]) : begin
|
||||
local lidMark : add-lookup sink markLookup
|
||||
mark.lookups.push lidMark
|
||||
markLookupNames.push lidMark
|
||||
|
||||
if ([objectIsNotEmpty mkmkSubtable.marks] && [objectIsNotEmpty mkmkSubtable.bases]) : begin
|
||||
local lidMkmk : add-lookup sink {.type 'gpos_mark_to_mark' .subtables { mkmkSubtable }}
|
||||
if ([objectIsNotEmpty mkmkLookup.marks] && [objectIsNotEmpty mkmkLookup.bases]) : begin
|
||||
local lidMkmk : add-lookup sink mkmkLookup
|
||||
mkmk.lookups.push lidMkmk
|
||||
mkmkLookupNames.push lidMkmk
|
||||
|
||||
foreach lidMark [items-of markLookupNames] : foreach lidMkmk [items-of mkmkLookupNames]
|
||||
sink.lookupDep.push { lidMark lidMkmk }
|
||||
|
||||
define [createMTSubtables glyphStore markClasses] : begin
|
||||
local markSubtable {.marks {.} .bases {.}}
|
||||
local mkmkSubtable {.marks {.} .bases {.}}
|
||||
define [createMTLookups glyphStore markClasses] : begin
|
||||
local markLookup {.type 'gpos_mark_to_base' .marks {.} .bases {.}}
|
||||
local mkmkLookup {.type 'gpos_mark_to_mark' .marks {.} .bases {.}}
|
||||
local allowMarkClsSet : new Set markClasses
|
||||
foreach { gn glyph } [glyphStore.namedEntries] : begin
|
||||
createMarkInfo markSubtable.marks gn glyph allowMarkClsSet
|
||||
createMarkInfo mkmkSubtable.marks gn glyph allowMarkClsSet
|
||||
createMarkInfo markLookup.marks gn glyph allowMarkClsSet
|
||||
createMarkInfo mkmkLookup.marks gn glyph allowMarkClsSet
|
||||
local isMark : objectIsNotEmpty glyph.markAnchors
|
||||
if isMark
|
||||
createBaseInfo mkmkSubtable.bases gn glyph allowMarkClsSet
|
||||
createBaseInfo markSubtable.bases gn glyph allowMarkClsSet
|
||||
return : object markSubtable mkmkSubtable
|
||||
createBaseInfo mkmkLookup.bases gn glyph allowMarkClsSet
|
||||
createBaseInfo markLookup.bases gn glyph allowMarkClsSet
|
||||
return : object markLookup mkmkLookup
|
||||
|
||||
define [createBaseInfo sink gn glyph allowMarkClsSet] : begin
|
||||
local res {.}
|
||||
|
|
|
@ -99,7 +99,7 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
|||
|
||||
define lookupCcmp1 : add-lookup sink : object
|
||||
.type 'gsub_chaining'
|
||||
.subtables : list
|
||||
.rules : list
|
||||
# Dot removal (max 6 middle marks are supported)
|
||||
chain-rule (dotlessFrom ~> dotlessTo) (markGlyphs.above ~> null)
|
||||
chain-rule (dotlessFrom ~> dotlessTo) markGlyphs.all (markGlyphs.above ~> null)
|
||||
|
@ -128,7 +128,7 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
|||
|
||||
define lookupCcmp2 : add-lookup sink : object
|
||||
.type 'gsub_ligature'
|
||||
.subtables : list : object : substitutions : list
|
||||
.substitutions : list
|
||||
object [from {'commaAbove' 'graveAbove'}] [to 'psilivaria']
|
||||
object [from {'commaAbove' 'acuteAbove'}] [to 'psilioxia']
|
||||
object [from {'commaAbove' 'perispomeniAbove'}] [to 'psiliperispomeni']
|
||||
|
@ -141,15 +141,15 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
|||
|
||||
define lookupCcmp-TieMarkLigature : add-lookup sink : object
|
||||
.type 'gsub_ligature'
|
||||
.subtables : list
|
||||
object : substitutions : TieMarkFrom.map : lambda [gnFrom idx]
|
||||
.substitutions : {}.concat
|
||||
TieMarkFrom.map : lambda [gnFrom idx]
|
||||
object [from {gnCgjNwid gnFrom}] [to TieMarkTo.(idx)]
|
||||
object : substitutions : TieMarkFrom.map : lambda [gnFrom idx]
|
||||
TieMarkFrom.map : lambda [gnFrom idx]
|
||||
object [from {gnCgjWwid gnFrom}] [to TieMarkTo.(idx)]
|
||||
|
||||
define lookupCcmp-TieMarkContextual : add-lookup sink : object
|
||||
.type 'gsub_chaining'
|
||||
.subtables : list : object
|
||||
.rules : list : object
|
||||
match {[TieGlyphs.concat TieMarkTo] {gnCgjNwid gnCgjWwid} TieMarkFrom}
|
||||
inputBegins 1
|
||||
inputEnds 3
|
||||
|
@ -157,7 +157,7 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
|||
|
||||
define lookupCcmp-ToneStart : add-lookup sink : object
|
||||
.type 'gsub_chaining'
|
||||
.subtables : list
|
||||
.rules : list
|
||||
chain-rule [ToneToToneStart 0] {'tone0'}
|
||||
chain-rule [ToneToToneStart 1] {'tone1'}
|
||||
chain-rule [ToneToToneStart 2] {'tone2'}
|
||||
|
@ -166,7 +166,7 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
|||
|
||||
define lookupCcmp-ToneMid : add-lookup sink : object
|
||||
.type 'gsub_chaining'
|
||||
.subtables : list
|
||||
.rules : list
|
||||
chain-rule [ToneStartOrMidAt 0] [ToneStartToToneMid 0]
|
||||
chain-rule [ToneStartOrMidAt 1] [ToneStartToToneMid 1]
|
||||
chain-rule [ToneStartOrMidAt 2] [ToneStartToToneMid 2]
|
||||
|
@ -175,7 +175,7 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
|||
|
||||
define lookupCcmp-ToneEnd : add-lookup sink : object
|
||||
.type 'gsub_chaining'
|
||||
.subtables : list
|
||||
.rules : list
|
||||
chain-rule [ToneStartOrMidAt 0] [ToneToToneEnd 0]
|
||||
chain-rule [ToneStartOrMidAt 1] [ToneToToneEnd 1]
|
||||
chain-rule [ToneStartOrMidAt 2] [ToneToToneEnd 2]
|
||||
|
@ -184,7 +184,7 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
|||
|
||||
define lookupCcmp-ToneSandhiStart : add-lookup sink : object
|
||||
.type 'gsub_chaining'
|
||||
.subtables : list
|
||||
.rules : list
|
||||
chain-rule [ToneSandhiToToneStart 0] {'toneSandhi0'}
|
||||
chain-rule [ToneSandhiToToneStart 1] {'toneSandhi1'}
|
||||
chain-rule [ToneSandhiToToneStart 2] {'toneSandhi2'}
|
||||
|
@ -193,7 +193,7 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
|||
|
||||
define lookupCcmp-ToneSandhiMid : add-lookup sink : object
|
||||
.type 'gsub_chaining'
|
||||
.subtables : list
|
||||
.rules : list
|
||||
chain-rule [ToneSandhiStartOrMidAt 0] [ToneSandhiStartToToneMid 0]
|
||||
chain-rule [ToneSandhiStartOrMidAt 1] [ToneSandhiStartToToneMid 1]
|
||||
chain-rule [ToneSandhiStartOrMidAt 2] [ToneSandhiStartToToneMid 2]
|
||||
|
@ -202,7 +202,7 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
|||
|
||||
define lookupCcmp-ToneSandhiEnd : add-lookup sink : object
|
||||
.type 'gsub_chaining'
|
||||
.subtables : list
|
||||
.rules : list
|
||||
chain-rule [ToneSandhiStartOrMidAt 0] [ToneSandhiToToneEnd 0]
|
||||
chain-rule [ToneSandhiStartOrMidAt 1] [ToneSandhiToToneEnd 1]
|
||||
chain-rule [ToneSandhiStartOrMidAt 2] [ToneSandhiToToneEnd 2]
|
||||
|
@ -228,7 +228,7 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
|||
ccmp.lookups.push lookupCcmp-Decompose
|
||||
define lookupCcmp-Decompose : add-lookup sink : object
|
||||
.type 'gsub_multiple'
|
||||
.subtables : list decompositions
|
||||
.substitutions decompositions
|
||||
|
||||
add-common-feature sink ccmp
|
||||
EndLookupBlock rec sink
|
||||
|
|
|
@ -20,7 +20,7 @@ export : define [buildCVSS sink para glyphStore] : begin
|
|||
|
||||
define lookupNameCvDecompose : add-lookup sink : object
|
||||
.type 'gsub_multiple'
|
||||
.subtables : list decompositions
|
||||
.substitutions decompositions
|
||||
|
||||
# cvxx
|
||||
foreach {gn glyph} [glyphStore.namedEntries] : if [not : CvDecompose.get glyph] : do
|
||||
|
@ -31,13 +31,13 @@ export : define [buildCVSS sink para glyphStore] : begin
|
|||
add-common-feature sink feature
|
||||
|
||||
local lookup : pick-lookup sink lookupName
|
||||
begin {.type 'gsub_alternate' .subtables {{.}}}
|
||||
begin {.type 'gsub_alternate' .substitutions {.}}
|
||||
add-feature-lookup feature lookupNameCvDecompose
|
||||
add-feature-lookup feature lookupName
|
||||
sink.lookupDep.push { lookupNameCvDecompose lookupName }
|
||||
cvLookupNameSet.add lookupName
|
||||
|
||||
local st [pick-lookup sink lookupName].subtables.0
|
||||
local st [pick-lookup sink lookupName].substitutions
|
||||
if [not st.(gn)] : set st.(gn) { }
|
||||
set st.(gn).(gr.rank - 1) : glyphStore.ensureExists : gr.get glyph
|
||||
|
||||
|
@ -46,11 +46,11 @@ export : define [buildCVSS sink para glyphStore] : begin
|
|||
local feature : pick-feature sink [FeatureName composition.tag]
|
||||
add-common-feature sink feature
|
||||
add-feature-lookup feature lookupNameCvDecompose
|
||||
local lookupNameSub : add-lookup sink {.type 'gsub_single' .subtables {{.}}}
|
||||
local lookupNameSub : add-lookup sink {.type 'gsub_single' .substitutions {.}}
|
||||
sink.lookupDep.push { lookupNameCvDecompose lookupNameSub }
|
||||
add-feature-lookup feature lookupNameSub
|
||||
|
||||
define st [pick-lookup sink lookupNameSub].subtables.0
|
||||
define st [pick-lookup sink lookupNameSub].substitutions
|
||||
local decomp : composition.decompose para para.variants.selectorTree
|
||||
foreach { prime pv } [items-of decomp] : if (pv.tag && pv.rank) : begin
|
||||
local gr : Cv pv.tag pv.rank
|
||||
|
@ -60,7 +60,7 @@ export : define [buildCVSS sink para glyphStore] : begin
|
|||
|
||||
# If there are holes in the alternates list, fill them
|
||||
foreach lutn cvLookupNameSet : begin
|
||||
local st [pick-lookup sink lutn].subtables.0
|
||||
local st [pick-lookup sink lutn].substitutions
|
||||
foreach { k v } [pairs-of st] : foreach idx [range 0 v.length] : if [not v.(idx)]
|
||||
set v.(idx) k
|
||||
|
||||
|
|
|
@ -139,14 +139,14 @@ define [buildLigationsImpl sink para featureName mappedFeature rankedLookups] :
|
|||
define rules : filterNulls _rules
|
||||
if (rules && rules.length) : AddRankedLookup
|
||||
.type 'gsub_chaining'
|
||||
.subtables rules
|
||||
.rules rules
|
||||
set lookupRank : lookupRank + 1
|
||||
|
||||
define [CreateReverseLigationLookup _rules] : begin
|
||||
define rules : filterNulls _rules
|
||||
if (rules && rules.length) : AddRankedLookup
|
||||
.type 'gsub_reverse'
|
||||
.subtables rules
|
||||
.rules rules
|
||||
set lookupRank : lookupRank + 1
|
||||
|
||||
do "Operator centering"
|
||||
|
|
|
@ -13,7 +13,7 @@ export : define [buildLOCL sink para glyphStore] : begin
|
|||
cyrlMKD.features.unshift loclSRB.name
|
||||
loclSRB.lookups.push : add-lookup sink : object
|
||||
type 'gsub_single'
|
||||
subtables : list : if para.isItalic
|
||||
substitutions : if para.isItalic
|
||||
object
|
||||
'cyrl/be' : glyphStore.ensureExists 'cyrl/be.SRB'
|
||||
'cyrl/ghe' : glyphStore.ensureExists 'cyrl/ghe.SRB'
|
||||
|
@ -28,7 +28,7 @@ export : define [buildLOCL sink para glyphStore] : begin
|
|||
cyrlBGR.features.unshift loclBGR.name
|
||||
loclBGR.lookups.push : add-lookup sink : object
|
||||
type 'gsub_single'
|
||||
subtables : list : object
|
||||
substitutions : object
|
||||
'cyrl/ve' : glyphStore.ensureExists 'cyrl/ve.BGR'
|
||||
'cyrl/ghe' : glyphStore.ensureExists 'cyrl/ghe.italic'
|
||||
'cyrl/de' : glyphStore.ensureExists 'cyrl/de.BGR'
|
||||
|
|
|
@ -19,13 +19,13 @@ export : define [buildPairFeature sink tag1 tag2 glyphStore codedOnly] : begin
|
|||
set mapTag1.(gnTag2) glyphName
|
||||
|
||||
if [objectIsNotEmpty mapTag1] : begin
|
||||
define lookup1 : add-lookup sink {.type 'gsub_single' .subtables {mapTag1}}
|
||||
define lookup1 : add-lookup sink {.type 'gsub_single' .substitutions mapTag1}
|
||||
define feature1 : add-feature sink tag1
|
||||
feature1.lookups.push lookup1
|
||||
add-common-feature sink feature1
|
||||
|
||||
if [objectIsNotEmpty mapTag2] : begin
|
||||
define lookup2 : add-lookup sink {.type 'gsub_single' .subtables {mapTag2}}
|
||||
define lookup2 : add-lookup sink {.type 'gsub_single' .substitutions mapTag2}
|
||||
define feature2 : add-feature sink tag2
|
||||
feature2.lookups.push lookup2
|
||||
add-common-feature sink feature2
|
||||
|
|
|
@ -17,7 +17,7 @@ export : define [buildGsubThousands sink para] : begin
|
|||
|
||||
define lookupThousand1 : add-lookup sink : object
|
||||
.type 'gsub_chaining'
|
||||
.subtables : list
|
||||
.rules : list
|
||||
chain-rule ({'period'} ~> null) (numberGlyphIDs ~> [nd 2]) (numberGlyphIDs ~> null) (numberGlyphIDs ~> null)
|
||||
chain-rule ([nd 2] ~> null) (numberGlyphIDs ~> [nd 1])
|
||||
chain-rule ([nd 1] ~> null) (numberGlyphIDs ~> [nd 6])
|
||||
|
@ -28,13 +28,13 @@ export : define [buildGsubThousands sink para] : begin
|
|||
|
||||
define lookupThousand2 : add-lookup sink : object
|
||||
.type 'gsub_chaining'
|
||||
.subtables : list
|
||||
.rules : list
|
||||
chain-rule (numberGlyphIDs ~> [nd 0]) (numberGlyphIDs ~> null) (numberGlyphIDs ~> null) (numberGlyphIDs ~> null)
|
||||
chain-rule ([nd 0] ~> null) (numberGlyphIDs ~> [nd 0])
|
||||
|
||||
define lookupThousand3 : add-lookup sink : object
|
||||
.type 'gsub_reverse'
|
||||
.subtables : list
|
||||
.rules : list
|
||||
reverse-rule ([nd 0] ~> [nd 1]) ([nd 0] ~> null)
|
||||
reverse-rule ([nd 0] ~> [nd 2]) ([nd 1] ~> null)
|
||||
reverse-rule ([nd 0] ~> [nd 3]) ([nd 2] ~> null)
|
||||
|
|
|
@ -95,9 +95,9 @@ export : define [MoveBackUtilityLookups sink] : begin
|
|||
|
||||
export : define [ChainRuleBuilder sink] : begin
|
||||
define [createNewLookup f t] : begin
|
||||
local subtable {.}
|
||||
foreach [j : range 0 f.length] : set subtable.(f.(j)) t.(j)
|
||||
return : add-lookup sink {.type 'gsub_single' .subtables {subtable}} UtilityLookupPrefix
|
||||
local subst {.}
|
||||
foreach [j : range 0 f.length] : set subst.(f.(j)) t.(j)
|
||||
return : add-lookup sink {.type 'gsub_single' .substitutions subst} UtilityLookupPrefix
|
||||
|
||||
define [getSubLookup left right] : piecewise
|
||||
[not right] null
|
||||
|
@ -108,7 +108,7 @@ export : define [ChainRuleBuilder sink] : begin
|
|||
local maxMatch 0
|
||||
local lookupKeys : [Object.keys sink.lookups].reverse
|
||||
foreach [name : items-of lookupKeys] : begin
|
||||
local st sink.lookups.(name).subtables.0
|
||||
local st sink.lookups.(name).substitutions
|
||||
if [IsUtilityLookupId name] : begin
|
||||
local compatible true
|
||||
local matchCount 0
|
||||
|
@ -120,7 +120,7 @@ export : define [ChainRuleBuilder sink] : begin
|
|||
set maxMatch matchCount
|
||||
|
||||
if found : begin
|
||||
local st sink.lookups.(found).subtables.0
|
||||
local st sink.lookups.(found).substitutions
|
||||
foreach [j : range 0 left.length] : set st.(left.(j)) right.(j)
|
||||
return found
|
||||
|
||||
|
@ -128,25 +128,25 @@ export : define [ChainRuleBuilder sink] : begin
|
|||
|
||||
define [chain-rule] : begin
|
||||
local terms : [{}.slice.call arguments 0].map (x -> [if x.left x {.left x .right null}])
|
||||
local subtable {.match {} .apply {} .inputBegins 0 .inputEnds 0}
|
||||
local rule {.match {} .apply {} .inputBegins 0 .inputEnds 0}
|
||||
local foundi false
|
||||
local founde false
|
||||
foreach [j : range 0 terms.length] : if (!foundi && terms.(j).right) : begin
|
||||
set subtable.inputBegins j
|
||||
set rule.inputBegins j
|
||||
set foundi true
|
||||
foreach [j : range (terms.length - 1) downtill 0] : if (!founde && terms.(j).right) : begin
|
||||
set subtable.inputEnds (j + 1)
|
||||
set rule.inputEnds (j + 1)
|
||||
set founde true
|
||||
foreach [j : range 0 terms.length] : begin
|
||||
local term terms.(j)
|
||||
subtable.match.push : Array.from : new Set term.left
|
||||
rule.match.push : Array.from : new Set term.left
|
||||
local lutn : getSubLookup term.left term.right
|
||||
if lutn : subtable.apply.push {.at j .lookup lutn}
|
||||
return subtable
|
||||
if lutn : rule.apply.push {.at j .lookup lutn}
|
||||
return rule
|
||||
|
||||
define [reverse-rule] : begin
|
||||
local terms : [{}.slice.call arguments 0].map (x -> [if x.left x {.left x .right null}])
|
||||
local subtable {.match {} .to {} .inputIndex 0}
|
||||
local rule {.match {} .to {} .inputIndex 0}
|
||||
local foundi false
|
||||
|
||||
foreach [j : range 0 terms.length] : begin
|
||||
|
@ -157,18 +157,18 @@ export : define [ChainRuleBuilder sink] : begin
|
|||
if term.right : begin
|
||||
if foundi : throw : new Error "Duplicate substitutions in one reverse rule"
|
||||
set foundi true
|
||||
set subtable.inputIndex j
|
||||
set rule.inputIndex j
|
||||
local toGlyphs : piecewise
|
||||
(term.right <@ Function) [term.right term.left]
|
||||
true term.right
|
||||
foreach [k : range 0 term.left.length]
|
||||
subst.set term.left.(k) (toGlyphs.(k) || term.left.(k))
|
||||
|
||||
set subtable.to : Array.from [subst.values]
|
||||
set rule.to : Array.from [subst.values]
|
||||
|
||||
set subtable.match.(j) : Array.from [subst.keys]
|
||||
set rule.match.(j) : Array.from [subst.keys]
|
||||
|
||||
return subtable
|
||||
return rule
|
||||
|
||||
return {chain-rule reverse-rule}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue