Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Macedonian Cyrillic Gje under italics (#2493). #2495

Merged
merged 2 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/31.6.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Fix Macedonian Cyrillic Gje under italics (#2493).
200 changes: 5 additions & 195 deletions packages/font-glyphs/src/auto-build/accents.ptl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ glyph-module

glyph-block AutoBuild-Accents : begin
glyph-block-import Common-Derivatives : query-glyph refer-glyph
glyph-block-import CommonShapes : NameUni
glyph-block-import Letter-Accent-Builder : TransformGlyphCompositionSequence

define [suggestName _name] : begin
local name _name
Expand All @@ -27,197 +29,6 @@ glyph-block AutoBuild-Accents : begin
set map.(key) amended
return amended

# Here, we build a simplified substitution builder that does the mark substitutions
# This is similar to GSUB lookup type 6 but with more flexibility
define flex-params [substParts] : begin
local-parameter : parts
local-parameter : ignore -- MatchUtil.never
local-parameter : backtrack -- {}
local-parameter : input
local-parameter : lookAhead -- {}
local-parameter : replace
local igl 0
while (igl < parts.length) : begin
local m : substMatch parts igl ignore backtrack input lookAhead
if [not m]
: then : inc igl
: else : begin
local inputGlyphs : ArrayUtil.mapIndexToItems parts m
local producedGlyphs : replace.apply null inputGlyphs
foreach i [range (m.length - 1) downtill 0] : begin
parts.splice m.(i) 1
ArrayUtil.insertSliceAt parts m.0 producedGlyphs
set igl : m.(m.length - 1) + 1 + producedGlyphs.length - m.length

return parts

define [substMatch parts igl ignore backtrack input lookAhead] : begin
if (igl >= parts.length) : return null
if [ignore parts.(igl)] : return null
if [not : input.0 parts.(igl)] : return null

local m { igl }

# Check input
local iglInput : igl + 1
foreach iInput [range 1 input.length] : begin
while (iglInput < parts.length && [ignore parts.(iglInput)]) : inc iglInput
if (iglInput >= parts.length) : return null
if [not : input.(iInput) parts.(iglInput)] : return null
m.push iglInput
inc iglInput

# Check lookahead
local iglLookAhead iglInput
foreach iLookAhead [range 0 lookAhead.length] : begin
while (iglLookAhead < parts.length && [ignore parts.(iglLookAhead)]) : inc iglLookAhead
if (iglLookAhead >= parts.length) : return null
if [not : lookAhead.(iLookAhead) parts.(iglLookAhead)] : return null
inc iglLookAhead

# Check backtrack
local iglBacktrack : igl - 1
foreach iBacktrack [range (backtrack.length - 1) downtill 0] : begin
while (iglBacktrack >= 0 && [ignore parts.(iglBacktrack)]) : dec iglBacktrack
if (iglBacktrack < 0) : return null
if [not : backtrack.(iBacktrack) parts.(iglBacktrack)] : return null
dec iglBacktrack

return m

# Match/replace directives
define [dotless g] : begin
local gDotless : query-glyph : Dotless.get g
if [not gDotless] : return null
return {gDotless}
define [isMark k] : function [g] : begin
return : g && g.markAnchors && g.markAnchors.(k)
define [isMarkExcluding k] : function [g] : begin
return : g && g.markAnchors && [Object.keys g.markAnchors].length && !g.markAnchors.(k)
define [hasBaseAnchor k] : function [g] : begin
return : g && g.baseAnchors && g.baseAnchors.(k)
define [produceLeaningMark gnSuppressAnchor] : function [g] : begin
local spacer : query-glyph : LeaningMarkSpacer.get g
local alternative : query-glyph : LeaningMark.get g
if (spacer && alternative) : return { spacer alternative }
return { [query-glyph gnSuppressAnchor] g }

define [markSubst uk] : begin
local mapping : new Map
foreach { k v } [Object.entries uk] : begin
local gFrom : query-glyph k
local gTo : query-glyph v
mapping.set gFrom gTo

define [matcher g] : mapping.has g
define [ignore g] : g && g.markAnchors && [Object.keys g.markAnchors].length && ![matcher g]
define [production g] : list ([mapping.get g] || g)

return : object matcher ignore production

define [markSplit uk] : begin
local mapping : new Map
foreach { k v } [Object.entries uk] : begin
local gFrom : query-glyph k
local gsTo : v.map query-glyph
mapping.set gFrom gsTo

define [matcher g] : mapping.has g
define [ignore g] : g && g.markAnchors && [Object.keys g.markAnchors].length && ![matcher g]
define [production g] : begin
console.log g [mapping.get g]
return : [mapping.get g] || { g }

return : object matcher ignore production

define [markCombine uk] : begin
local first : new Set
local second : new Set
local mapping : new Map

foreach { { k1 k2 } v } [items-of uk] : begin
local g1 : query-glyph k1
local g2 : query-glyph k2
local g3 : query-glyph v
if (g1 && g2 && g3) : begin
first.add g1
second.add g2

local mm : mapping.get g1
if [not mm] : begin
set mm : new Map
mapping.set g1 mm
mm.set g2 g3

define [matchFirst g] : first.has g
define [matchSecond g] : second.has g
define [production g1 g2] : begin
local mm : mapping.get g1
if [not mm] : return { g1 g2 }
local g3 : mm.get g2
if [not g3] : return { g1 g2 }
return { g3 }

return : object matchFirst matchSecond production

define iotaLF : markSubst UnicodeKnowledge.iotaBelowToLfTf
define ogonek : markSplit UnicodeKnowledge.ogonekBelowToTRTf
define upperTonos : markSubst UnicodeKnowledge.upperGrekMarkToTonosTf

define markComposition : markCombine UnicodeKnowledge.markCompositionTf

define [subParts parts] : begin
### Keep the semantics here synchronized with `ccmp` feature

# Handle dotless form
substParts parts
ignore -- [isMarkExcluding 'above']
input -- {dotless}
lookAhead -- {[isMark 'above']}
replace -- dotless

# Handle iota subscript
substParts parts
ignore -- iotaLF.ignore
backtrack -- {[hasBaseAnchor 'lf']}
input -- {iotaLF.matcher}
replace -- iotaLF.production

# Handle ogonek
substParts parts
ignore -- ogonek.ignore
backtrack -- {[hasBaseAnchor 'trailing']}
input -- {ogonek.matcher}
replace -- ogonek.production

# Handle mark combinations (Greek)
substParts parts
input -- { markComposition.matchFirst markComposition.matchSecond }
replace -- markComposition.production

# Handle upper Greek Tonos marks
substParts parts
backtrack -- {[hasBaseAnchor 'grekUpperTonos']}
input -- {upperTonos.matcher}
replace -- upperTonos.production

# Handle leaning marks
substParts parts
ignore -- [isMarkExcluding 'above']
backtrack -- {[MatchUtil.either [hasBaseAnchor 'leaningAbove'] [isMark 'leaningAbove']]}
input -- {[isMark 'above']}
replace -- [produceLeaningMark 'mark/suppressLeaningAboveAnchor']
substParts parts
ignore -- [isMarkExcluding 'below']
backtrack -- {[MatchUtil.either [hasBaseAnchor 'leaningBelow'] [isMark 'leaningBelow']]}
input -- {[isMark 'below']}
replace -- [produceLeaningMark 'mark/suppressLeaningBelowAnchor']

define [pad _s n] : begin
local s _s
while (s.length < n) : s = '0' + s
return s

local foundDecompositions {.}

local goalCodes : range 0x0000 0x1FFFF
Expand All @@ -228,7 +39,7 @@ glyph-block AutoBuild-Accents : begin
local customDecomp UnicodeKnowledge.decompOverrides.(code)

local str : String.fromCodePoint code
local nfd : str.normalize 'NFD'
local nfd : str.normalize 'NFD'

if customDecomp
: then : begin
Expand All @@ -247,8 +58,8 @@ glyph-block AutoBuild-Accents : begin
: else : parts.push part

if (allFound && parts.length) : begin
local glyphName : 'u' + [code.toString 16 :.padStart 4 '0']
subParts parts
local glyphName : NameUni code
TransformGlyphCompositionSequence parts
set foundDecompositions.(glyphName) { glyphName code parts }

local s_goalName nothing
Expand All @@ -266,7 +77,6 @@ glyph-block AutoBuild-Accents : begin
define construction : glyph-proc
include s_parts.0 AS_BASE ALSO_METRICS
local nonTrivial : AnyDerivingCv.hasNonDerivingVariants s_parts.0
if nonTrivial : console.log s_parts.0
foreach part [items-of : s_parts.slice 1] : if part : begin
include part
if (part.markAnchors && part.markAnchors.bottomRight) : begin
Expand Down
70 changes: 0 additions & 70 deletions packages/font-glyphs/src/auto-build/mark-doppelganger.ptl

This file was deleted.

5 changes: 2 additions & 3 deletions packages/font-glyphs/src/common/derivatives.ptl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ glyph-block Common-Derivatives : begin
if suffix : begin
local dstName : shapeFrom + '.' + suffix
local dstGlyph : query-glyph dstName
if dstGlyph : g.dependsOn dstGlyph
if dstGlyph : g.addVariantForRecursiveBuild dstGlyph

if (follow === primaryFollow && para.enableCvSs && pv.tag && pv.rank) : begin
pv.set g dstName
Expand All @@ -35,7 +35,6 @@ glyph-block Common-Derivatives : begin
if [not fromGlyph] : throw : new Error "Cannot find glyph '\(fromGlyphName)'"

include fromGlyph AS_BASE ALSO_METRICS
currentGlyph.dependsOn fromGlyph
currentGlyph.cloneRankFromGlyph fromGlyph

ApplyCv currentGlyph shapeFrom [resolveMainFollow follow] [resolveAllFollow follow] para
Expand Down Expand Up @@ -106,7 +105,7 @@ glyph-block Common-Derivatives : begin
linksGnMap.set key gnDerivedTo

local gDerivedTo : query-glyph gnDerivedTo
if (gSource && gDerivedTo) : gSource.dependsOn gDerivedTo
if (gSource && gDerivedTo) : gSource.addVariantForRecursiveBuild gDerivedTo

# Link related derivatives
foreach { gr from to } [items-of mesh] : begin
Expand Down
2 changes: 1 addition & 1 deletion packages/font-glyphs/src/index.ptl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export : define [buildGlyphs para recursive] : begin
run-glyph-module "./marks/index.mjs"

# Unified letters
run-glyph-module "./letter/accent-builder.mjs"
run-glyph-module "./letter/shared.mjs"
run-glyph-module "./letter/latin.mjs"
run-glyph-module "./letter/greek.mjs"
Expand Down Expand Up @@ -102,7 +103,6 @@ export : define [buildGlyphs para recursive] : begin
# Auto-builds
if [not recursive] : begin
run-glyph-module "./auto-build/recursive-build.mjs"
run-glyph-module "./auto-build/mark-doppelganger.mjs"
run-glyph-module "./auto-build/accents.mjs"
run-glyph-module "./auto-build/transformed.mjs"
run-glyph-module "./auto-build/composite.mjs"
Expand Down
1 change: 0 additions & 1 deletion packages/font-glyphs/src/letter-like/fraktur/lower-mnu.ptl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ glyph-module
glyph-block LetterLike-Fraktur-Lower-MNU : begin
glyph-block-import Common-Derivatives
glyph-block-import CommonShapes
glyph-block-import Letter-Shared : CreateAccentedComposition
glyph-block-import Mark-Shared-Metrics : markMiddle markDotsRadius
glyph-block-import Mark-Above : StdAnchors aboveMarkTop aboveMarkBot aboveMarkMid aboveMarkStack
glyph-block-import LetterLike-Fraktur-Common : LowerDf S M fraktur-stroke change-pen
Expand Down
Loading
Loading