Fix broken accent stacking behavior for partially precomposed characters with leaning anchors (#2492). (#2493)
* Fix broken accent stacking behavior for partially precomposed characters with leaning anchors (#2492). * variable name
This commit is contained in:
parent
e896ca6534
commit
f1f39c9b6d
3 changed files with 55 additions and 15 deletions
1
changes/31.6.1.md
Normal file
1
changes/31.6.1.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
- Fix broken accent stacking behavior for partially precomposed characters with leaning anchors (#2492).
|
|
@ -28,15 +28,22 @@ glyph-block AutoBuild-Accents : begin
|
||||||
return amended
|
return amended
|
||||||
|
|
||||||
# Here, we build a simplified substitution builder that does the mark substitutions
|
# Here, we build a simplified substitution builder that does the mark substitutions
|
||||||
define [substParts parts ignore backtrack input loookAhead production] : begin
|
# 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
|
local igl 0
|
||||||
while (igl < parts.length) : begin
|
while (igl < parts.length) : begin
|
||||||
local m : substMatch parts igl ignore backtrack input loookAhead
|
local m : substMatch parts igl ignore backtrack input lookAhead
|
||||||
if [not m]
|
if [not m]
|
||||||
: then : inc igl
|
: then : inc igl
|
||||||
: else : begin
|
: else : begin
|
||||||
local inputGlyphs : ArrayUtil.mapIndexToItems parts m
|
local inputGlyphs : ArrayUtil.mapIndexToItems parts m
|
||||||
local producedGlyphs : production.apply null inputGlyphs
|
local producedGlyphs : replace.apply null inputGlyphs
|
||||||
foreach i [range (m.length - 1) downtill 0] : begin
|
foreach i [range (m.length - 1) downtill 0] : begin
|
||||||
parts.splice m.(i) 1
|
parts.splice m.(i) 1
|
||||||
ArrayUtil.insertSliceAt parts m.0 producedGlyphs
|
ArrayUtil.insertSliceAt parts m.0 producedGlyphs
|
||||||
|
@ -78,24 +85,22 @@ glyph-block AutoBuild-Accents : begin
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
# Match/replace directives
|
||||||
define [dotless g] : begin
|
define [dotless g] : begin
|
||||||
local gDotless : query-glyph : Dotless.get g
|
local gDotless : query-glyph : Dotless.get g
|
||||||
if [not gDotless] : return null
|
if [not gDotless] : return null
|
||||||
return {gDotless}
|
return {gDotless}
|
||||||
|
|
||||||
define [isMark k] : function [g] : begin
|
define [isMark k] : function [g] : begin
|
||||||
return : g && g.markAnchors && g.markAnchors.(k)
|
return : g && g.markAnchors && g.markAnchors.(k)
|
||||||
define [isMarkExcluding k] : function [g] : begin
|
define [isMarkExcluding k] : function [g] : begin
|
||||||
return : g && g.markAnchors && [Object.keys g.markAnchors].length && !g.markAnchors.(k)
|
return : g && g.markAnchors && [Object.keys g.markAnchors].length && !g.markAnchors.(k)
|
||||||
define [hasBaseAnchor k] : function [g] : begin
|
define [hasBaseAnchor k] : function [g] : begin
|
||||||
return : g && g.baseAnchors && g.baseAnchors.(k)
|
return : g && g.baseAnchors && g.baseAnchors.(k)
|
||||||
define [isLeaningMark k] : function [g] : begin
|
define [produceLeaningMark gnSuppressAnchor] : function [g] : begin
|
||||||
return : g && g.markAnchors && g.markAnchors.(k) && [LeaningMark.get g]
|
|
||||||
define [leaningMarkSplit g] : begin
|
|
||||||
local spacer : query-glyph : LeaningMarkSpacer.get g
|
local spacer : query-glyph : LeaningMarkSpacer.get g
|
||||||
local alternative : query-glyph : LeaningMark.get g
|
local alternative : query-glyph : LeaningMark.get g
|
||||||
if (spacer && alternative) : return { spacer alternative }
|
if (spacer && alternative) : return { spacer alternative }
|
||||||
return { g }
|
return { [query-glyph gnSuppressAnchor] g }
|
||||||
|
|
||||||
define [markSubst uk] : begin
|
define [markSubst uk] : begin
|
||||||
local mapping : new Map
|
local mapping : new Map
|
||||||
|
@ -165,23 +170,48 @@ glyph-block AutoBuild-Accents : begin
|
||||||
### Keep the semantics here synchronized with `ccmp` feature
|
### Keep the semantics here synchronized with `ccmp` feature
|
||||||
|
|
||||||
# Handle dotless form
|
# Handle dotless form
|
||||||
substParts parts [isMarkExcluding 'above'] {} {dotless} {[isMark 'above']} dotless
|
substParts parts
|
||||||
|
ignore -- [isMarkExcluding 'above']
|
||||||
|
input -- {dotless}
|
||||||
|
lookAhead -- {[isMark 'above']}
|
||||||
|
replace -- dotless
|
||||||
|
|
||||||
# Handle iota subscript
|
# Handle iota subscript
|
||||||
substParts parts iotaLF.ignore {[hasBaseAnchor 'lf']} {iotaLF.matcher} {} iotaLF.production
|
substParts parts
|
||||||
|
ignore -- iotaLF.ignore
|
||||||
|
backtrack -- {[hasBaseAnchor 'lf']}
|
||||||
|
input -- {iotaLF.matcher}
|
||||||
|
replace -- iotaLF.production
|
||||||
|
|
||||||
# Handle ogonek
|
# Handle ogonek
|
||||||
substParts parts ogonek.ignore {[hasBaseAnchor 'trailing']} {ogonek.matcher} {} ogonek.production
|
substParts parts
|
||||||
|
ignore -- ogonek.ignore
|
||||||
|
backtrack -- {[hasBaseAnchor 'trailing']}
|
||||||
|
input -- {ogonek.matcher}
|
||||||
|
replace -- ogonek.production
|
||||||
|
|
||||||
# Handle mark combinations (Greek)
|
# Handle mark combinations (Greek)
|
||||||
substParts parts MatchUtil.never {} { markComposition.matchFirst markComposition.matchSecond } {} markComposition.production
|
substParts parts
|
||||||
|
input -- { markComposition.matchFirst markComposition.matchSecond }
|
||||||
|
replace -- markComposition.production
|
||||||
|
|
||||||
# Handle upper Greek Tonos marks
|
# Handle upper Greek Tonos marks
|
||||||
substParts parts MatchUtil.never {[hasBaseAnchor 'grekUpperTonos']} {upperTonos.matcher} {} upperTonos.production
|
substParts parts
|
||||||
|
backtrack -- {[hasBaseAnchor 'grekUpperTonos']}
|
||||||
|
input -- {upperTonos.matcher}
|
||||||
|
replace -- upperTonos.production
|
||||||
|
|
||||||
# Handle leaning marks
|
# Handle leaning marks
|
||||||
substParts parts [isMarkExcluding 'above'] {[MatchUtil.either [hasBaseAnchor 'leaningAbove'] [isMark 'leaningAbove']]} {[isLeaningMark 'above']} {} leaningMarkSplit
|
substParts parts
|
||||||
substParts parts [isMarkExcluding 'below'] {[MatchUtil.either [hasBaseAnchor 'leaningBelow'] [isMark 'leaningBelow']]} {[isLeaningMark 'below']} {} leaningMarkSplit
|
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
|
define [pad _s n] : begin
|
||||||
local s _s
|
local s _s
|
||||||
|
|
|
@ -88,3 +88,12 @@ glyph-block Mark-Adjustment : begin
|
||||||
|
|
||||||
export : define Above : Impl 'above' 'leaningAbove'
|
export : define Above : Impl 'above' 'leaningAbove'
|
||||||
export : define Below : Impl 'below' 'leaningBelow'
|
export : define Below : Impl 'below' 'leaningBelow'
|
||||||
|
|
||||||
|
# "Technical" marks, used to suppress leaning anchors.
|
||||||
|
# Used in the build process of precomposed glyphs.
|
||||||
|
create-glyph "mark/suppressLeaningAboveAnchor" : glyph-proc
|
||||||
|
set-width 0
|
||||||
|
set-mark-anchor 'leaningAbove' 0 0
|
||||||
|
create-glyph "mark/suppressLeaningBelowAnchor" : glyph-proc
|
||||||
|
set-width 0
|
||||||
|
set-mark-anchor 'leaningBelow' 0 0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue