diff --git a/packages/font-glyphs/src/auto-build/composite.ptl b/packages/font-glyphs/src/auto-build/composite.ptl index c5dc3bfe2..0b4a47c0c 100644 --- a/packages/font-glyphs/src/auto-build/composite.ptl +++ b/packages/font-glyphs/src/auto-build/composite.ptl @@ -76,19 +76,18 @@ glyph-block Autobuild-Enclosure-Shared : begin local jobsOrig : if demandDecomposable decomposableJobs nonDecomposable jobsOrig.push { origJobGlyphGn unicode parts :: restInfo } - if para.enableCvSs : begin - if demandDecomposable - : then : foreach part [items-of parts] : begin - local mesh : getGrMesh { part } AnyCvOrCherryPicking query-glyph - foreach {gr fromParts toParts} [items-of mesh] : foreach gn [items-of toParts] - decomposableRelGlyphs.add gn - : else : begin - local mesh : getGrMesh parts AnyCvOrCherryPicking query-glyph - foreach {gr fromParts toParts} [items-of mesh] : do - local fromGn : CircNameNoCheck unicode prefix fromParts suffix - local toGn : CircName unicode prefix toParts suffix - nonDecomposable.push { toGn null toParts :: restInfo } - relApplications.push { gr fromGn toGn } + if demandDecomposable + : then : foreach part [items-of parts] : begin + local mesh : getGrMesh { part } AnyCvOrCherryPicking query-glyph + foreach {gr fromParts toParts} [items-of mesh] : foreach gn [items-of toParts] + decomposableRelGlyphs.add gn + : else : begin + local mesh : getGrMesh parts AnyCvOrCherryPicking query-glyph + foreach {gr fromParts toParts} [items-of mesh] : do + local fromGn : CircNameNoCheck unicode prefix fromParts suffix + local toGn : CircName unicode prefix toParts suffix + nonDecomposable.push { toGn null toParts :: restInfo } + relApplications.push { gr fromGn toGn } return : object nonDecomposable decomposableJobs decomposableRelGlyphs relApplications diff --git a/packages/font-otl/src/gsub-cv-ss.ptl b/packages/font-otl/src/gsub-cv-ss.ptl index 7e6da2ee3..2ed6f5666 100644 --- a/packages/font-otl/src/gsub-cv-ss.ptl +++ b/packages/font-otl/src/gsub-cv-ss.ptl @@ -58,19 +58,23 @@ class CvLookupManager return lookup public [linkDeps] : begin - if this.decompositionLookup : begin + if (this.decompositionLookup && this.altrenatesLookup) : begin this.table.setDependency this.decompositionLookup this.altrenatesLookup - foreach lookupSS [items-of this.singleSubstLookups] : if lookupSS : begin - this.table.setDependency this.altrenatesLookup lookupSS - foreach lookupCP [items-of this.cherryPickingLookups] : if lookupCP : begin - this.table.setDependency lookupCP this.altrenatesLookup + if this.altrenatesLookup : begin foreach lookupSS [items-of this.singleSubstLookups] : if lookupSS : begin - this.table.setDependency lookupCP lookupSS + this.table.setDependency this.altrenatesLookup lookupSS + foreach lookupCP [items-of this.cherryPickingLookups] : if lookupCP : begin + this.table.setDependency lookupCP this.altrenatesLookup + foreach lookupSS [items-of this.singleSubstLookups] : if lookupSS : begin + this.table.setDependency lookupCP lookupSS public [linkCrossDeps other] : begin - this.table.setDependency this.altrenatesLookup other.altrenatesLookup - foreach lookupSS [items-of this.singleSubstLookups] : if lookupSS : begin - this.table.setDependency lookupSS other.altrenatesLookup + if (this.altrenatesLookup && other.altrenatesLookup) : begin + this.table.setDependency this.altrenatesLookup other.altrenatesLookup + + if other.altrenatesLookup : begin + foreach lookupSS [items-of this.singleSubstLookups] : if lookupSS : begin + this.table.setDependency lookupSS other.altrenatesLookup static [compare a b] : begin if (a.tag < b.tag) : return (-1) @@ -154,9 +158,10 @@ export : define [buildCVSS gsub para glyphStore] : begin sortedCvs.sort CvLookupManager.compare foreach cv [items-of sortedCvs] : begin - local st cv.altrenatesLookup.substitutions - foreach { k v } [pairs-of st] : foreach idx [range 0 v.length] : if [not v.(idx)] - set v.(idx) k + if cv.altrenatesLookup : begin + local st cv.altrenatesLookup.substitutions + foreach { k v } [pairs-of st] : foreach idx [range 0 v.length] : if [not v.(idx)] + set v.(idx) k cv.linkDeps for [local i 1] (i < sortedCvs.length) [inc i] diff --git a/packages/font-otl/src/index.ptl b/packages/font-otl/src/index.ptl index 097dd51a7..130440669 100644 --- a/packages/font-otl/src/index.ptl +++ b/packages/font-otl/src/index.ptl @@ -36,8 +36,7 @@ define [buildGSUB para glyphStore markGlyphs] : begin # As it is a cv/ss "cherry picking". # APLF - if para.enableCvSs : begin - buildGrFeature gsub glyphStore Gr.AplForm + buildGrFeature gsub glyphStore Gr.AplForm # numr / dnom buildGrFeature gsub glyphStore Gr.NumeratorForm @@ -61,8 +60,7 @@ define [buildGSUB para glyphStore markGlyphs] : begin # cv##, ss## local cvs nothing - if para.enableCvSs : begin - set cvs : buildCVSS gsub para glyphStore + set cvs : buildCVSS gsub para glyphStore # ccmp post cv/ss (for Ogonek shape transform) buildCCMPPostCvSs gsub ccmp glyphStore markGlyphs diff --git a/packages/glyph/src/block.mjs b/packages/glyph/src/block.mjs index 1ca0f9217..53212c6c4 100644 --- a/packages/glyph/src/block.mjs +++ b/packages/glyph/src/block.mjs @@ -61,6 +61,26 @@ export class DependencyManager { } s.add(dependency); } + hasGlyphToGlyphDependency(dependent, dependency) { + return this.hasGlyphToGlyphDependencyImpl(new Set(), dependent, dependency); + } + + hasGlyphToGlyphDependencyImpl(alreadyScanned, dependent, dependency) { + // Prevent infinite recursion + if (alreadyScanned.has(dependent)) return true; + alreadyScanned.add(dependent); + + // Check for direct dependency + if (!this.glyphToGlyph.has(dependent)) return false; + const ds = this.glyphToGlyph.get(dependent); + if (ds.has(dependency)) return true; + + // Check for indirect dependency + for (const d of ds) { + if (this.hasGlyphToGlyphDependencyImpl(alreadyScanned, d, dependency)) return true; + } + return false; + } traverseGlyphDependenciesImpl(glyphs, fBlockwiseExpand) { let state = new Map(); diff --git a/packages/glyph/src/glyph.mjs b/packages/glyph/src/glyph.mjs index 72e472855..c2d2b6e84 100644 --- a/packages/glyph/src/glyph.mjs +++ b/packages/glyph/src/glyph.mjs @@ -2,7 +2,7 @@ import * as util from "util"; import * as Geom from "@iosevka/geometry"; import { Anchor } from "@iosevka/geometry/anchor"; -import { Point, Vec2 } from "@iosevka/geometry/point"; +import { Vec2 } from "@iosevka/geometry/point"; import { Transform } from "@iosevka/geometry/transform"; export class Glyph { @@ -66,6 +66,10 @@ export class Glyph { if (!this._m_dependencyManager) return; this._m_dependencyManager.addDependency(this, glyph); } + hasDependency(other) { + if (!this._m_dependencyManager) return false; + return this._m_dependencyManager.hasGlyphToGlyphDependency(this, other); + } // Copying cloneFromGlyph(g) { @@ -138,6 +142,7 @@ export class Glyph { } tryBecomeMirrorOf(dst, rankSet) { if (rankSet.has(this) || rankSet.has(dst)) return; + if (dst.hasDependency(this)) return; const csThis = this.geometry.unlinkReferences().toShapeStringOrNull(); const csDst = dst.geometry.unlinkReferences().toShapeStringOrNull(); if (csThis && csDst && csThis === csDst) {