Fix shape of y-ogonek (used by Elfdalian) (#1437).

This commit is contained in:
be5invis 2022-10-29 14:57:01 -07:00
parent 0c9b46ac9b
commit b3b7646f5b
7 changed files with 70 additions and 125 deletions

1
changes/16.3.6.md Normal file
View file

@ -0,0 +1 @@
* Fix shape of y-ogonek (used by Elfdalian) (#1437).

View file

@ -1,7 +1,7 @@
$$include '../../../meta/macros.ptl'
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
import [LowerYDotAtBelow Dotless CvDecompose MathSansSerif] from"../../../support/gr.mjs"
import [LowerYDotAtBelow Dotless CvDecompose MathSansSerif OgonekTrY] from"../../../support/gr.mjs"
glyph-module
@ -64,7 +64,18 @@ glyph-block Letter-Latin-Lower-Y : begin
curl x (top - ds) [widths.heading hl hr Downward]
quadControls 0 dpy1 16
define [yBaseKnots top bottom shrink hooktop ogonek] : begin
define [yOgonekAttach top bottom shrink hooktop] : glyph-proc
define {ds ds2} : CalcDS top bottom
define coJoinX : if (straightBar && (! hooktop)) yrstroker [mix yrstrokel yrstroker px1]
define coJoinY : if (straightBar && (! hooktop)) top [mix (bottom + ds2) (top - ds) py1]
define joinX : mix yrstrokel yrstroker (1 - px2)
define joinY : mix (bottom + ds2) (top - ds) (1 - py2)
define anchorX : mix coJoinX joinX ((0 - coJoinY) / (joinY - coJoinY))
set-base-anchor 'trailing' anchorX 0
OgonekTrY.set currentGlyph
define [yBaseKnots top bottom shrink hooktop] : begin
define {ds ds2} : CalcDS top bottom
define coJoinX : mix yrstrokel yrstroker px1
define coJoinY : mix (bottom + ds2) (top - ds) py1
@ -72,30 +83,12 @@ glyph-block Letter-Latin-Lower-Y : begin
define joinY : mix (bottom + ds2) (top - ds) (1 - py2)
define [ConnectZ shrink] : curl joinX joinY [widths.rhs : Stroke * shrink]
define [ogonekKnots] : begin
local stopX : mix joinX coJoinX ((0 - joinY) / (coJoinY - joinY))
local stopY 0
local depth : 0 - Descender - markStroke
local extL : (0.5 * 0.75 * depth / coJoinY) * depth + 0.25 * markStress
local extR : Math.max (0.5 * markExtend) (1.5 * TanSlope * markStroke)
local turnSlope : 0.5 * ((markStroke - Stroke) / markStroke - (ArchDepthB - ArchDepth) / ArchDepth)
list
curl stopX stopY [widths.rhs : Stroke * [if useStraightBottom shrink 1]]
g4.down.mid (stopX - extL) (stopY - 0.75 * depth) [widths.rhs.heading [mix Stroke markStroke 0.25] {.x HVContrast .y (-turnSlope)}]
arcvh [widths.rhs markStroke]
g4 (stopX + [mix (-extL) extR (11/16)]) (stopY - depth + O) [heading Rightward]
g4 (stopX + extR) (stopY - depth + 0.5 * O) [heading Rightward]
return : list
if (straightBar && (! hooktop))
then : list
else : list [flat coJoinX coJoinY]
piecewise
ogonek : ogonekKnots
useStraightBottom : list
ConnectZ shrink
curl [mix yrstroker joinX ((top - bottom) / (top - joinY))] bottom [widths.heading 0 (Stroke * [yDiagCor (top - bottom)]) Downward]
@ -159,6 +152,8 @@ glyph-block Letter-Latin-Lower-Y : begin
define [SmallYShape top bottom] : glyph-proc
local {ds ds2} : CalcDS top bottom
include : yOgonekAttach top bottom yshrink
include : intersection
SmallYStrokeSplitMask top bottom false 1
dispiro
@ -183,39 +178,12 @@ glyph-block Letter-Latin-Lower-Y : begin
if doSlabBottom : include : yBaseSerif top bottom
if doSlabMotion : include : LeftwardTopSerif SB top SideJut
define [SmallYOgonekShape top bottom] : glyph-proc
local {ds ds2} : CalcDS top bottom
include : intersection
union
SmallYStrokeSplitMask top bottom false 1
MaskBelow 0
dispiro
yTopKnots yrstroker top bottom ds 1
yBaseKnots top bottom 1 false true
include : difference
dispiro
yTopKnots yrstroker top bottom ds 1
yBaseKnots top bottom yshrink false true
SmallYStrokeSplitMask top bottom false 1 1
MaskBelow 0
include : difference
dispiro
yTopKnots (Width - yrstroker) top bottom ds (-1)
yJoinKnots ds ds2 top bottom
SmallYStrokeSplitMask top bottom false (-1)
Rect (bottom + HalfStroke) (bottom - top) 0 Width
if doSlabTop : include : let [sf : SerifFrame top bottom SB RightSB]
composite-proc sf.lt.full sf.rt.full
if doSlabMotion : include : LeftwardTopSerif SB top SideJut
define [SmallYHookTopShape top bottom] : glyph-proc
local {ds ds2} : CalcDS top bottom
local joinHeight : yJoinHeight ds ds2 top bottom true
include : yOgonekAttach top bottom yshrink true
include : intersection
SmallYStrokeSplitMask top bottom true 1
dispiro
@ -248,7 +216,7 @@ glyph-block Letter-Latin-Lower-Y : begin
include : Scale 1 (-1)
include : Translate 0 (+[mix bottom top 0.5])
return : object SmallYShape SmallYOgonekShape SmallYHookTopShape SmallLambdaShape
return : object SmallYShape SmallYHookTopShape SmallLambdaShape
create-glyph : glyph-proc
include : MarkSet.p
@ -271,19 +239,6 @@ glyph-block Letter-Latin-Lower-Y : begin
create-forked-glyph 'y.curlyTurnMotionSerifed' : glyph-proc
include : [GenSmallYShape false true SLAB-MOTION].SmallYShape XH Descender
create-glyph : glyph-proc
include : MarkSet.p
set-base-anchor 'overlay' Middle (XH / 2)
set-base-anchor 'yBelowDot' (RightSB - 0.5 * DotRadius) (Descender + AccentStackOffset + DotRadius)
create-forked-glyph 'yOgonek.straight' : glyph-proc
include : [GenSmallYShape true false SLAB-AUTO].SmallYOgonekShape XH Descender
create-forked-glyph 'yOgonek.curly' : glyph-proc
include : [GenSmallYShape false false SLAB-AUTO].SmallYOgonekShape XH Descender
create-forked-glyph 'yOgonek.straightMotionSerifed' : glyph-proc
include : [GenSmallYShape true false SLAB-MOTION].SmallYOgonekShape XH Descender
create-forked-glyph 'yOgonek.curlyMotionSerifed' : glyph-proc
include : [GenSmallYShape false false SLAB-MOTION].SmallYOgonekShape XH Descender
define [SmallYCursiveArc top bottom] : new-glyph : glyph-proc
include : nShoulder
top -- top
@ -343,25 +298,8 @@ glyph-block Letter-Latin-Lower-Y : begin
include : LeftwardTopSerif SB XH SideJut
set-base-anchor 'overlay' Middle (XH / 2)
create-glyph 'yOgonek.cursive' : glyph-proc
include [refer-glyph 'y.cursive'] AS_BASE ALSO_METRICS
include [refer-glyph 'ogonekBelow']
create-glyph 'yOgonek.cursiveFlatHook' : glyph-proc
include [refer-glyph 'y.cursiveFlatHook'] AS_BASE ALSO_METRICS
include [refer-glyph 'ogonekBelow']
create-glyph 'yOgonek.cursiveMotionSerifed' : glyph-proc
include [refer-glyph 'y.cursiveMotionSerifed'] AS_BASE ALSO_METRICS
include [refer-glyph 'ogonekBelow']
create-glyph 'yOgonek.cursiveFlatHookMotionSerifed' : glyph-proc
include [refer-glyph 'y.cursiveFlatHookMotionSerifed'] AS_BASE ALSO_METRICS
include [refer-glyph 'ogonekBelow']
select-variant 'y' 'y'
link-reduced-variant 'y/sansSerif' 'y' MathSansSerif
select-variant 'yOgonek' 0xE011
alias 'cyrl/u' 0x443 'y'
foreach { suffix { DrawAt kdr } } [Object.entries DotVariants] : do

View file

@ -150,26 +150,32 @@ glyph-block Mark-Horn-And-Angle : begin
include : refer-glyph "leftHalfCircleBelow"
include : FlipAround markMiddle (XH / 2)
create-glyph 'ogonekTR' : glyph-proc
set-width 0
define ogonekTrConfig : object
'ogonekTR' { (7/16) (1/8) 1 }
'ogonekTR_Y' { (3/16) 1 6 }
local fine : AdviceStroke 8
local depth : 0 - Descender - markStroke
local extL : (7 / 16) * depth + 0.125 * markStress
local extR : Math.max (0.125 * markExtend) (1.5 * TanSlope * markStroke)
foreach { glyphName { pExtL pExtR cwMidStrokeWidth } } [Object.entries ogonekTrConfig] : do
create-glyph glyphName : glyph-proc
set-width 0
local turnSlope : 0.5 * ((markStroke - fine) / markStroke - (ArchDepthB - ArchDepth) / ArchDepth)
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)
include : difference
dispiro
g4 markMiddle 0 [widths.rhs.heading fine Leftward]
alsoThru 0.5 (0.375 - 0.2 * markStroke / depth) [widths.rhs : mix fine markStroke 0.25]
g4.down.mid (markMiddle - extL) (-0.75 * depth) [widths.rhs.heading markStroke {.x HVContrast .y turnSlope}]
arcvh [widths.rhs markStroke]
g4 (markMiddle + [mix (-extL) extR (11/16)]) (-depth + O) [heading Rightward]
g4 (markMiddle + extR) (-depth + 0.5 * O) [heading Rightward]
intersection
MaskAbove 0
MaskRight markMiddle
local turnSlope : 0.5 * ((markStroke - fine) / markStroke - (ArchDepthB - ArchDepth) / ArchDepth)
local swMid : Math.min markStroke [AdviceStroke cwMidStrokeWidth]
set-mark-anchor 'trailing' markMiddle 0 (markMiddle + extR) (-depth - 0.5 * O - markStroke)
include : difference
dispiro
g4 markMiddle 0 [widths.rhs.heading fine Leftward]
alsoThru 0.5 (0.375 - 0.2 * markStroke / depth) [widths.rhs : mix fine swMid 0.25]
g4.down.mid (markMiddle - extL) (-0.75 * depth) [widths.rhs.heading swMid {.x HVContrast .y turnSlope}]
arcvh
g4 (markMiddle + [mix (-extL) extR (11/16)]) (-depth + O) [widths.rhs.heading markStroke Rightward]
g4 (markMiddle + extR) (-depth + 0.5 * O) [heading Rightward]
intersection
MaskAbove 0
MaskRight markMiddle
set-mark-anchor 'trailing' markMiddle 0 (markMiddle + extR) (-depth - 0.5 * O - markStroke)

View file

@ -4,6 +4,9 @@ export : define iotaBelowToLfTf : object
export : define ogonekBelowToTRTf : object
'ogonekBelow' 'ogonekTR'
export : define ogonekBelowToTRTf_Y : object
'ogonekBelow' 'ogonekTR_Y'
export : define upperGrekMarkToTonosTf : object
'variaAbove' 'variaGrekUpperTonos'
'oxiaAbove' 'oxiaGrekUpperTonos'
@ -30,8 +33,6 @@ export : define markCompositionTf : object
'perispomeniAbove' 'dasiaPerispomeni'
'cyrlPsiliAbove' : object
'cyrlPokrytieAbove' 'cyrlPsiliPokrytieAbove'
'y' : object
'ogonekBelow' 'yOgonek'
export : define decompositionOverrides : object
# Latvians use comma instead of cedillas in several letters.

View file

@ -1,5 +1,5 @@
import [AddCommonFeature AddFeature AddLookup AddFeatureLookup ChainRuleBuilder BeginLookupBlock EndLookupBlock UkMapToLookup UkMap2ToLookup] from"./table-util.mjs"
import [AnyCv Dotless TieMark TieGlyph CcmpDecompose] from"../support/gr.mjs"
import [AnyCv Dotless TieMark TieGlyph CcmpDecompose OgonekTrY] from"../support/gr.mjs"
import as UnicodeKnowledge from"../meta/unicode-knowledge.mjs"
extern Set
@ -234,22 +234,32 @@ export : define [buildCCMPPostCvSs sink ccmpFeature glyphStore markGlyphs] : beg
define ccmp : AddFeature sink 'ccmp'
define {chain-rule} : ChainRuleBuilder sink
define groupTR {}
define triggerGlyphs_Normal { }
define triggerGlyphs_Y { }
foreach { gid g } [glyphStore.namedEntries] : if (gid.(0) !== "."): begin
if g.baseAnchors.trailing : groupTR.push gid
if g.baseAnchors.trailing : piecewise
[OgonekTrY.get g] : triggerGlyphs_Y.push gid
true : triggerGlyphs_Normal.push gid
define [OgonekTrailing] : UkMapToLookup UnicodeKnowledge.ogonekBelowToTRTf
define [markTransform_Normal] : UkMapToLookup UnicodeKnowledge.ogonekBelowToTRTf
define [markTransform_Y] : UkMapToLookup UnicodeKnowledge.ogonekBelowToTRTf_Y
define [pushTransforms sink triggers tf] : begin
sink.push : chain-rule triggers [tf]
sink.push : chain-rule triggers markGlyphs.all [tf]
sink.push : chain-rule triggers markGlyphs.all markGlyphs.all [tf]
sink.push : chain-rule triggers markGlyphs.all markGlyphs.all markGlyphs.all [tf]
sink.push : chain-rule triggers markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all [tf]
sink.push : chain-rule triggers markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all [tf]
sink.push : chain-rule triggers markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all [tf]
define ogonekTransforms {}
pushTransforms ogonekTransforms triggerGlyphs_Normal markTransform_Normal
pushTransforms ogonekTransforms triggerGlyphs_Y markTransform_Y
define lookupMarks1 : AddLookup sink : object
.type 'gsub_chaining'
.rules : list
# Ogonek transform (max 6 middle marks are supported)
chain-rule groupTR [OgonekTrailing]
chain-rule groupTR markGlyphs.all [OgonekTrailing]
chain-rule groupTR markGlyphs.all markGlyphs.all [OgonekTrailing]
chain-rule groupTR markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all [OgonekTrailing]
chain-rule groupTR markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all [OgonekTrailing]
chain-rule groupTR markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all markGlyphs.all [OgonekTrailing]
.rules ogonekTransforms
ccmpFeature.lookups.push lookupMarks1
EndLookupBlock rec sink

View file

@ -107,6 +107,7 @@ function BoolProp(id) {
export const Radical = BoolProp("Radical");
export const RequireCcmpDecompose = BoolProp("RequireCcmpDecompose");
export const NeqLigationSlashDotted = BoolProp("NeqLigationSlashDotted");
export const OgonekTrY = BoolProp("OgonekTrY");
export const Joining = {
get(glyph) {

View file

@ -4270,7 +4270,6 @@ rank = 1
description = "Letter `y` that is fully straight"
selector.y = "straight"
selector."y/sansSerif" = "straight"
selector.yOgonek = "straight"
selector.yHookTop = "straight"
[prime.y.variants.straight-turn]
@ -4278,7 +4277,6 @@ rank = 2
description = "Letter `y` with straight upper and a tail turns leftward"
selector.y = "straightTurn"
selector."y/sansSerif" = "straightTurn"
selector.yOgonek = "straight"
selector.yHookTop = "straightTurn"
[prime.y.variants.curly]
@ -4286,7 +4284,6 @@ rank = 3
description = "More curly letter `y`, like Iosevka 2.x"
selector.y = "curly"
selector."y/sansSerif" = "curly"
selector.yOgonek = "curly"
selector.yHookTop = "curly"
[prime.y.variants.curly-turn]
@ -4294,7 +4291,6 @@ rank = 4
description = "More curly letter `y`, like Iosevka 2.x, with a tail turns leftward"
selector.y = "curlyTurn"
selector."y/sansSerif" = "curlyTurn"
selector.yOgonek = "curly"
selector.yHookTop = "curlyTurn"
[prime.y.variants.cursive]
@ -4302,7 +4298,6 @@ rank = 5
description = "Cursive-like `y`"
selector.y = "cursive"
selector."y/sansSerif" = "cursive"
selector.yOgonek = "cursive"
selector.yHookTop = "cursive"
[prime.y.variants.cursive-flat-hook]
@ -4310,7 +4305,6 @@ rank = 6
description = "Cursive-like `y` with flat terminal hook"
selector.y = "cursiveFlatHook"
selector."y/sansSerif" = "cursiveFlatHook"
selector.yOgonek = "cursiveFlatHook"
selector.yHookTop = "cursiveFlatHook"
[prime.y.variants.straight-motion-serifed]
@ -4318,7 +4312,6 @@ rank = 7
description = "Letter `y` that is fully straight, with motion serifs"
selector.y = "straightMotionSerifed"
selector."y/sansSerif" = "straight"
selector.yOgonek = "straightMotionSerifed"
selector.yHookTop = "straight"
[prime.y.variants.straight-turn-motion-serifed]
@ -4326,7 +4319,6 @@ rank = 8
description = "Letter `y` with straight upper and a tail turns leftward, and motion serifs"
selector.y = "straightTurnMotionSerifed"
selector."y/sansSerif" = "straightTurn"
selector.yOgonek = "straightMotionSerifed"
selector.yHookTop = "straightTurn"
[prime.y.variants.curly-motion-serifed]
@ -4334,7 +4326,6 @@ rank = 9
description = "More curly letter `y`, like Iosevka 2.x, with motion serifs"
selector.y = "curlyMotionSerifed"
selector."y/sansSerif" = "curly"
selector.yOgonek = "curlyMotionSerifed"
selector.yHookTop = "curly"
[prime.y.variants.curly-turn-motion-serifed]
@ -4342,7 +4333,6 @@ rank = 10
description = "More curly letter `y`, like Iosevka 2.x, with a tail turns leftward and motion serifs"
selector.y = "curlyTurnMotionSerifed"
selector."y/sansSerif" = "curlyTurn"
selector.yOgonek = "curlyMotionSerifed"
selector.yHookTop = "curlyTurn"
[prime.y.variants.cursive-motion-serifed]
@ -4350,7 +4340,6 @@ rank = 11
description = "Cursive-like `y`, with motion serifs"
selector.y = "cursiveMotionSerifed"
selector."y/sansSerif" = "cursive"
selector.yOgonek = "cursiveMotionSerifed"
selector.yHookTop = "cursive"
[prime.y.variants.cursive-flat-hook-motion-serifed]
@ -4358,7 +4347,6 @@ rank = 12
description = "Cursive-like `y` with flat terminal hook, and motion serifs"
selector.y = "cursiveFlatHookMotionSerifed"
selector."y/sansSerif" = "cursiveFlatHook"
selector.yOgonek = "cursiveFlatHookMotionSerifed"
selector.yHookTop = "cursiveFlatHook"