diff --git a/font-src/glyphs/common/derivatives.ptl b/font-src/glyphs/common/derivatives.ptl index 0085b34fe..d170c4df4 100644 --- a/font-src/glyphs/common/derivatives.ptl +++ b/font-src/glyphs/common/derivatives.ptl @@ -8,17 +8,16 @@ extern Map glyph-module glyph-block Common-Derivatives : begin - glyph-block-export ApplyCv define [ApplyCv g shapeFrom follow para] : begin - foreach { kPrime prime } para.variants.primes : foreach h [prime.variants.values] : begin - local suffix : h.resolveFor para follow - if suffix : begin + foreach { kPrime prime } para.variants.primes : foreach pv [prime.variants.values] : begin + local suffix : pv.resolveFor para follow + if (para.enableCvSs && pv.tag && pv.rank && suffix) : begin local dstName : shapeFrom + '.' + suffix local dst : glyphStore.queryByName dstName if dst : g.dependsOn dst - if (para.enableCvSs && h.tag && h.rank) : begin - [Cv h.tag h.rank h.groupRank h.description].set g dstName - if h.nonDeriving : [Cv h.tag h.rank].setPreventDeriving g + + pv.set g dstName + if pv.nonDeriving : pv.setPreventDeriving g glyph-block-export select-variant define [select-variant] : with-params [name unicode [shapeFrom name] [follow name] [reduction null]] : begin diff --git a/font-src/otl/gsub-cv-ss.ptl b/font-src/otl/gsub-cv-ss.ptl index dae7d997e..d46647473 100644 --- a/font-src/otl/gsub-cv-ss.ptl +++ b/font-src/otl/gsub-cv-ss.ptl @@ -1,6 +1,6 @@ $$include '../meta/macros.ptl' -import [Cv AnyCv CvDecompose RightDependentLink RightDependentTrigger] from"../support/gr.mjs" +import [AnyCv CvDecompose] from"../support/gr.mjs" extern Map extern Set @@ -89,8 +89,8 @@ export : define [buildCVSS gsub para glyphStore] : begin do "cvxx" local cvGrs {} foreach {name prime} para.variants.primes : foreach {vn variant} prime.variants : begin - if (prime.tag && variant.rank) : cvGrs.push : Cv prime.tag variant.rank - cvGrs.sort Cv.compare + if (variant.tag && variant.rank) : cvGrs.push variant + cvGrs.sort AnyCv.compare foreach gr [items-of cvGrs] : begin local cvAlt : [cvs.get gr.tag].createAlternateSubst @@ -106,10 +106,10 @@ export : define [buildCVSS gsub para glyphStore] : begin define decomp : composition.decompose para para.variants.selectorTree local ssGrs {} foreach { prime pv } [items-of decomp] : if (pv.tag && pv.rank) : begin - ssGrs.push : Cv pv.tag pv.rank + ssGrs.push pv local dl [cvs.get pv.tag].decompositionLookup if dl : feature.addLookup dl - ssGrs.sort Cv.compare + ssGrs.sort AnyCv.compare foreach gr [items-of ssGrs] : begin local cvSingle : [cvs.get gr.tag].createSingleSubstFor gr.rank diff --git a/font-src/support/gr.mjs b/font-src/support/gr.mjs index b7801e22e..9be2d2358 100644 --- a/font-src/support/gr.mjs +++ b/font-src/support/gr.mjs @@ -146,57 +146,6 @@ export const HintClass = { /////////////////////////////////////////////////////////////////////////////////////////////////// -const CvTagCache = new Map(); - -export function Cv(tag, rank, groupRank, description) { - const key = tag + "#" + rank; - if (CvTagCache.has(key)) return CvTagCache.get(key); - const rel = { - tag, - rank, - groupRank, - description, - get(glyph) { - if (glyph && glyph.related && glyph.related.cv) return glyph.related.cv[key]; - else return null; - }, - set(glyph, toGid) { - if (typeof toGid !== "string") throw new Error("Must supply a GID instead of a glyph"); - if (!glyph.related) glyph.related = {}; - if (!glyph.related.cv) glyph.related.cv = {}; - glyph.related.cv[key] = toGid; - }, - getPreventDeriving(glyph) { - return ( - glyph.related && - glyph.related.preventCvDeriving && - !!glyph.related.preventCvDeriving[key] - ); - }, - setPreventDeriving(glyph) { - if (!glyph.related) glyph.related = {}; - if (!glyph.related.preventCvDeriving) glyph.related.preventCvDeriving = {}; - glyph.related.preventCvDeriving[key] = true; - }, - amendName(name) { - return name + "." + key; - }, - amendOtName(name) { - return name + "." + tag + "-" + rank; - } - }; - CvTagCache.set(key, rel); - return rel; -} - -Cv.compare = function (a, b) { - if (a.tag < b.tag) return -1; - if (a.tag > b.tag) return 1; - if (a.rank < b.rank) return -1; - if (a.rank > b.rank) return 1; - return 0; -}; - export const DotlessOrNot = { query(glyph) { if (Dotless.get(glyph)) return [Dotless]; @@ -208,14 +157,18 @@ export const AnyCv = { query(glyph) { let ret = []; if (glyph && glyph.related && glyph.related.cv) { - for (const key in glyph.related.cv) { - const [tag, rankStr] = key.split("#"); - const rank = parseInt(rankStr, 10); - const rel = Cv(tag, rank); - if (rel.get(glyph)) ret.push(rel); + for (const [cv, dst] of glyph.related.cv) { + ret.push(cv); } } return ret; + }, + compare(a, b) { + const ua = a.tag.toUpperCase(), + ub = b.tag.toUpperCase(); + if (ua < ub) return -1; + if (ua > ub) return 1; + return a.rank - b.rank; } }; @@ -223,23 +176,17 @@ export const AnyDerivingCv = { query(glyph) { let ret = []; if (glyph && glyph.related && glyph.related.cv) { - for (const key in glyph.related.cv) { - if (glyph.related.preventCvDeriving && glyph.related.preventCvDeriving[key]) + for (const [cv, dst] of glyph.related.cv) { + if (glyph.related.preventCvDeriving && glyph.related.preventCvDeriving.has(cv)) continue; - const [tag, rankStr] = key.split("#"); - const rank = parseInt(rankStr, 10); - const rel = Cv(tag, rank); - if (rel.get(glyph)) ret.push(rel); + ret.push(cv); } } return ret; }, hasNonDerivingVariants(glyph) { - if (glyph && glyph.related && glyph.related.cv) { - for (const key in glyph.related.cv) { - if (glyph.related.preventCvDeriving && glyph.related.preventCvDeriving[key]) - return true; - } + if (glyph && glyph.related && glyph.related.preventCvDeriving) { + return glyph.related.preventCvDeriving.size > 0; } return false; } @@ -278,7 +225,7 @@ export function getGrMesh(gidList, grq, fnGidToGlyph) { for (const g of gidList) { for (const gr of grq.query(fnGidToGlyph(g))) allGrSet.add(gr); } - const allGrList = Array.from(allGrSet).sort(Cv.compare).reverse(); + const allGrList = Array.from(allGrSet).sort(AnyCv.compare).reverse(); let ret = []; for (const gr of allGrList) { @@ -399,15 +346,9 @@ function displayQuerySingleFeature(gs, gid, name, grCis, sink) { ); } } -function byTagPreference(a, b) { - const ua = a.tag.toUpperCase(), - ub = b.tag.toUpperCase(); - if (ua < ub) return -1; - if (ua > ub) return 1; - return a.rank - b.rank; -} + function queryCvFeatureTagsOf(sink, gid, glyph, tagSet) { - const cvs = AnyCv.query(glyph).sort(byTagPreference); + const cvs = AnyCv.query(glyph).sort(AnyCv.compare); let existingFeatures = new Map(); let existingTargets = new Set(); diff --git a/font-src/support/variant-data.mjs b/font-src/support/variant-data.mjs index b357be8e7..a866bd290 100644 --- a/font-src/support/variant-data.mjs +++ b/font-src/support/variant-data.mjs @@ -181,7 +181,7 @@ class Prime { } } -class PrimeVariant { +export class PrimeVariant { constructor(key, tag, cfg) { this.key = key; this.tag = tag; @@ -200,6 +200,36 @@ class PrimeVariant { resolve(para, vs) { Object.assign(vs, this.selector); } + + // Gr methods + get(glyph) { + if (glyph && glyph.related && glyph.related.cv) return glyph.related.cv.get(this); + else return null; + } + set(glyph, toGid) { + if (typeof toGid !== "string") throw new Error("Must supply a GID instead of a glyph"); + if (!glyph.related) glyph.related = {}; + if (!glyph.related.cv) glyph.related.cv = new Map(); + glyph.related.cv.set(this, toGid); + } + getPreventDeriving(glyph) { + return ( + glyph.related && + glyph.related.preventCvDeriving && + !!glyph.related.preventCvDeriving.has(this) + ); + } + setPreventDeriving(glyph) { + if (!glyph.related) glyph.related = {}; + if (!glyph.related.preventCvDeriving) glyph.related.preventCvDeriving = new Set(); + glyph.related.preventCvDeriving.add(this); + } + amendName(name) { + return name + "." + this.tag + "-" + this.rank; + } + amendOtName(name) { + return this.amendName(name); + } } class Composite {