From d35b849f68a93f95d7f208b3b77b42c0c74a3229 Mon Sep 17 00:00:00 2001 From: be5invis Date: Wed, 16 Aug 2023 20:43:02 -0700 Subject: [PATCH] Make below marks to avoid bottom-right Ogoneks (#1789). --- changes/26.2.0.md | 1 + font-src/glyphs/auto-build/accents.ptl | 24 ++++++++++++++++++------ font-src/glyphs/letter/latin/k.ptl | 2 +- font-src/glyphs/letter/latin/lower-e.ptl | 1 + font-src/glyphs/letter/shared.ptl | 8 +++++--- font-src/glyphs/marks/horn-and-angle.ptl | 7 ++++++- font-src/meta/unicode-knowledge.ptl | 2 +- font-src/otl/gsub-ccmp.ptl | 21 ++++++++++++++++----- 8 files changed, 49 insertions(+), 17 deletions(-) diff --git a/changes/26.2.0.md b/changes/26.2.0.md index 30b813c85..d5c8f82bb 100644 --- a/changes/26.2.0.md +++ b/changes/26.2.0.md @@ -2,6 +2,7 @@ - DIAMETER SIGN (`U+2300`) (#1923). - CIRCLE WITH SUPERIMPOSED X (`U+29BB`). - CLOCK FACE ONE OCLOCK (`U+1F550`) ... CLOCK FACE TWELVE-THIRTY (`U+1F567`) (#1850). +* Make below marks to avoid bottom-right Ogoneks (#1789). * Use oval shape for Empty Set symbols to distinguish with O-Slash (#1822). * Implement leaning mark mechanism for `F`, `L`, `P`, `b`, `d`, `h`, `k`, `p`, `q`, `r` to get better mark placement. Now, "narrow" marks will align to these letters' extension parts (#1851). * Fix detached cedilla in Hookless asymmetric LATIN SMALL LETTER T WITH CEDILLA (`U+0163`) (#1914). diff --git a/font-src/glyphs/auto-build/accents.ptl b/font-src/glyphs/auto-build/accents.ptl index 4e88b0898..9158a705a 100644 --- a/font-src/glyphs/auto-build/accents.ptl +++ b/font-src/glyphs/auto-build/accents.ptl @@ -98,21 +98,33 @@ glyph-block AutoBuild-Accents : begin return { g } define [markSubst uk] : begin - local fromGlyphs : new Set local mapping : new Map foreach { k v } [Object.entries uk] : begin local gFrom : query-glyph k local gTo : query-glyph v - if (gFrom && gTo) : begin - fromGlyphs.add gFrom - mapping.set gFrom gTo + mapping.set gFrom gTo - define [matcher g] : fromGlyphs.has g + 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 @@ -145,7 +157,7 @@ glyph-block AutoBuild-Accents : begin return : object matchFirst matchSecond production define iotaLF : markSubst UnicodeKnowledge.iotaBelowToLfTf - define ogonek : markSubst UnicodeKnowledge.ogonekBelowToTRTf + define ogonek : markSplit UnicodeKnowledge.ogonekBelowToTRTf define upperTonos : markSubst UnicodeKnowledge.upperGrekMarkToTonosTf define markComposition : markCombine UnicodeKnowledge.markCompositionTf diff --git a/font-src/glyphs/letter/latin/k.ptl b/font-src/glyphs/letter/latin/k.ptl index 7cf854d63..7c7b794da 100644 --- a/font-src/glyphs/letter/latin/k.ptl +++ b/font-src/glyphs/letter/latin/k.ptl @@ -426,7 +426,7 @@ glyph-block Letter-Latin-K : begin create-glyph "grek/KaiSymbol.\(suffix)" : glyph-proc include [refer-glyph "K.\(suffix)"] AS_BASE ALSO_METRICS - include : MarkSet.capDesc + include : ExtendBelowBaseAnchors Descender include : refer-glyph : match slabKS 0 'UpperKaiSymbolAttachment/sans' 1 'UpperKaiSymbolAttachment/serifed' diff --git a/font-src/glyphs/letter/latin/lower-e.ptl b/font-src/glyphs/letter/latin/lower-e.ptl index d3fb9109a..9b63b5081 100644 --- a/font-src/glyphs/letter/latin/lower-e.ptl +++ b/font-src/glyphs/letter/latin/lower-e.ptl @@ -164,6 +164,7 @@ glyph-block Letter-Latin-Lower-E : begin create-glyph "eOgonek.\(suffix)" : glyph-proc include : MarkSet.e local lastKnot : include : Body [DivFrame 1] XH [AdviceStroke2 2 3 XH] + include : refer-glyph 'ogonekTR/spacer' # Connected Ogonek shape local fine : AdviceStroke 8 diff --git a/font-src/glyphs/letter/shared.ptl b/font-src/glyphs/letter/shared.ptl index 8ab497c9e..373a1c407 100644 --- a/font-src/glyphs/letter/shared.ptl +++ b/font-src/glyphs/letter/shared.ptl @@ -20,11 +20,13 @@ glyph-block Letter-Shared : begin glyph-block-export CreateOgonekComposition define [CreateOgonekComposition dst u srcGid] - derive-multi-part-glyphs dst u { srcGid 'ogonekBelow' 'ogonekTR' } : function [gns gr] : glyph-proc - local { base markBelow markTR } gns + derive-multi-part-glyphs dst u { srcGid 'ogonekBelow' 'ogonekTR/spacer' 'ogonekTR' } : function [gns gr] : glyph-proc + local { base markBelow spacer markTR } gns include [refer-glyph base] AS_BASE ALSO_METRICS if currentGlyph.baseAnchors.trailing - then : include [refer-glyph markTR] + then : begin + include [refer-glyph spacer] + include [refer-glyph markTR] else : include [refer-glyph markBelow] glyph-block-export CreateCommaCaronComposition diff --git a/font-src/glyphs/marks/horn-and-angle.ptl b/font-src/glyphs/marks/horn-and-angle.ptl index 816e213b6..f77d37f30 100644 --- a/font-src/glyphs/marks/horn-and-angle.ptl +++ b/font-src/glyphs/marks/horn-and-angle.ptl @@ -181,11 +181,12 @@ glyph-block Mark-Horn-And-Angle : begin 'ogonekTR_Y' { (3/16) 1 6 0.5 } foreach { glyphName { pExtL pExtR cwMidStrokeWidth paren } } [Object.entries ogonekTrConfig] : do + local depth : 0 - Descender - markStroke + create-glyph glyphName : glyph-proc set-width 0 local fine : AdviceStroke 8 - local depth : 0 - Descender - markStroke local extL : pExtL * depth + 0.125 * markStress local extR : Math.max (pExtR * markExtend) (1.5 * TanSlope * markStroke) @@ -207,3 +208,7 @@ glyph-block Mark-Horn-And-Angle : begin set-mark-anchor 'trailing' markMiddle 0 (markMiddle + extR) (-depth - 0.5 * O - markStroke) set-base-anchor 'belowBraceL' (markMiddle - extL - paren * markExtend - [HSwToV : 0.25 * swMid]) (-0.75 * depth) set-base-anchor 'belowBraceR' (markMiddle - 0.75 * extL + paren * markExtend) (-0.75 * depth) + + create-glyph "\(glyphName)/spacer" : glyph-proc + set-width 0 + set-mark-anchor 'below' 0 0 0 (-depth - 0.5 * O - markStroke) diff --git a/font-src/meta/unicode-knowledge.ptl b/font-src/meta/unicode-knowledge.ptl index 77ba60c85..f1dd51801 100644 --- a/font-src/meta/unicode-knowledge.ptl +++ b/font-src/meta/unicode-knowledge.ptl @@ -2,7 +2,7 @@ export : define iotaBelowToLfTf : object 'iotaBelow' 'iotaLF' export : define ogonekBelowToTRTf : object - 'ogonekBelow' 'ogonekTR' + 'ogonekBelow' { 'ogonekTR/spacer' 'ogonekTR' } export : define ogonekBelowToTRTf_Y : object 'ogonekBelow' 'ogonekTR_Y' diff --git a/font-src/otl/gsub-ccmp.ptl b/font-src/otl/gsub-ccmp.ptl index 02ccb1080..7c4ca10c7 100644 --- a/font-src/otl/gsub-ccmp.ptl +++ b/font-src/otl/gsub-ccmp.ptl @@ -278,7 +278,6 @@ export : define [buildCCMPPostCvSs sink ccmpFeature glyphStore markGlyphs] : beg local rec : BeginLookupBlock sink define ccmp : AddFeature sink 'ccmp' - define {chain-rule} : ChainRuleBuilder sink define triggerGlyphs_Normal { } define triggerGlyphs_Y { } @@ -287,15 +286,27 @@ export : define [buildCCMPPostCvSs sink ccmpFeature glyphStore markGlyphs] : beg [OgonekTrY.get g] : triggerGlyphs_Y.push gid true : triggerGlyphs_Normal.push gid - define [markTransform_Normal] : UkMapToLookup UnicodeKnowledge.ogonekBelowToTRTf - define [markTransform_Y] : UkMapToLookup UnicodeKnowledge.ogonekBelowToTRTf_Y + define ogonekSpacerNormal : AddLookup sink : object + .type 'gsub_multiple' + .substitutions UnicodeKnowledge.ogonekBelowToTRTf + define ogonekSpacerY : AddLookup sink : object + .type 'gsub_single' + .substitutions UnicodeKnowledge.ogonekBelowToTRTf_Y define lookupMarks1 : AddLookup sink : object .type 'gsub_chaining' .ignoreGlyphs [filterMarkByClassNegated markGlyphs 'below'] .rules : list - chain-rule triggerGlyphs_Normal [markTransform_Normal] - chain-rule triggerGlyphs_Y [markTransform_Y] + object + .match { triggerGlyphs_Y [Object.keys UnicodeKnowledge.ogonekBelowToTRTf_Y] } + .inputBegins 1 + .inputEnds 2 + .apply {{.at 1 .lookup ogonekSpacerY}} + object + .match { triggerGlyphs_Normal [Object.keys UnicodeKnowledge.ogonekBelowToTRTf] } + .inputBegins 1 + .inputEnds 2 + .apply {{.at 1 .lookup ogonekSpacerNormal}} ccmpFeature.lookups.push lookupMarks1 EndLookupBlock rec sink