diff --git a/changes/28.0.0-alpha.1.md b/changes/28.0.0-alpha.1.md new file mode 100644 index 000000000..b81d3bac0 --- /dev/null +++ b/changes/28.0.0-alpha.1.md @@ -0,0 +1 @@ + * Add hook-inward-serifed variants for `a` (#2085). diff --git a/font-src/glyphs/letter/cyrillic/iotified-a.ptl b/font-src/glyphs/letter/cyrillic/iotified-a.ptl index 7590a0c06..b49268f84 100644 --- a/font-src/glyphs/letter/cyrillic/iotified-a.ptl +++ b/font-src/glyphs/letter/cyrillic/iotified-a.ptl @@ -126,13 +126,13 @@ glyph-block Letter-Cyrillic-Iotified-A : begin do "iotified a" glyph-block-import Letter-Latin-Lower-A : DoubleStorey DoubleStoreyConfig SingleStorey SingleStoreyConfig - foreach { suffix { body xTrailing } } [Object.entries DoubleStoreyConfig] : do + foreach { suffix { body xTrailing hookStyle } } [Object.entries DoubleStoreyConfig] : do create-glyph "cyrl/aIotified.\(suffix)" : glyph-proc define df : include : DivFrame para.diversityM 3 include : df.markSet.e local { subDf shift } : SubDfAndShift 1 df - include : with-transform [ApparentTranslate shift 0] [body subDf df.mvs] + include : with-transform [ApparentTranslate shift 0] [body subDf hookStyle df.mvs] include : difference Iotified.full df XH [mix df.leftSB df.rightSB (3 / 4)] (XH / 2) diff --git a/font-src/glyphs/letter/latin-ext/lower-ae-oe.ptl b/font-src/glyphs/letter/latin-ext/lower-ae-oe.ptl index 242f8611a..e8bdadebf 100644 --- a/font-src/glyphs/letter/latin-ext/lower-ae-oe.ptl +++ b/font-src/glyphs/letter/latin-ext/lower-ae-oe.ptl @@ -18,32 +18,37 @@ glyph-block Letter-Latin-Lower-AE-OE : begin return { subDf shift } do "a subglyphs" - define [AAShape pShift df body o] : begin + define [AAShape body hookStyle pShift df o] : begin local { subDf shift } : SubDfAndShift pShift df o - return : with-transform [ApparentTranslate shift 0] [body subDf df.mvs] + return : with-transform [ApparentTranslate shift 0] [body subDf hookStyle df.mvs] glyph-block-import Letter-Latin-Lower-A : DoubleStorey define DoubleStoreyConfig : object - doubleStoreySerifless { DoubleStorey.Serifless } - doubleStoreySerifed { DoubleStorey.Serifed } - doubleStoreyTailed { DoubleStorey.Tailed } - doubleStoreyToothlessCorner { DoubleStorey.ToothlessCorner } - doubleStoreyToothlessRounded { DoubleStorey.ToothlessRounded } + doubleStoreySerifless { DoubleStorey.Serifless 1 } + doubleStoreySerifed { DoubleStorey.Serifed 1 } + doubleStoreyTailed { DoubleStorey.Tailed 1 } + doubleStoreyToothlessCorner { DoubleStorey.ToothlessCorner 1 } + doubleStoreyToothlessRounded { DoubleStorey.ToothlessRounded 1 } + doubleStoreyHookInwardSerifedSerifless { DoubleStorey.Serifless 2 } + doubleStoreyHookInwardSerifedSerifed { DoubleStorey.Serifed 2 } + doubleStoreyHookInwardSerifedTailed { DoubleStorey.Tailed 2 } + doubleStoreyHookInwardSerifedToothlessCorner { DoubleStorey.ToothlessCorner 2 } + doubleStoreyHookInwardSerifedToothlessRounded { DoubleStorey.ToothlessRounded 2 } - create-glyph "ae/a" : glyph-proc - local df : include : DivFrame para.diversityM 3 - include : df.markSet.e - set-base-anchor 'cvDecompose' 0 0 - include : AAShape 0 df DoubleStorey.ToothlessRounded 0 + foreach { suffix { bodyR hookStyle } } [Object.entries DoubleStoreyConfig] : do - foreach { suffix { bodyR } } [Object.entries DoubleStoreyConfig] : do + create-glyph "ae/a.\(suffix)" : glyph-proc + local df : include : DivFrame para.diversityM 3 + include : df.markSet.e + set-base-anchor 'cvDecompose' 0 0 + include : AAShape DoubleStorey.ToothlessRounded hookStyle 0 df 0 create-glyph "aa.\(suffix)" : glyph-proc local df : include : DivFrame para.diversityM 3 include : df.markSet.e - local [left] : AAShape 0 df DoubleStorey.ToothlessRounded - local [right] : AAShape 1 df bodyR + local [left] : AAShape DoubleStorey.ToothlessRounded hookStyle 0 df + local [right] : AAShape bodyR hookStyle 1 df include : difference [right] : intersection MaskAbove (XH * OverlayPos * 1.02) union @@ -51,6 +56,7 @@ glyph-block Letter-Latin-Lower-AE-OE : begin with-transform [ApparentTranslate (-0.50 * df.mvs) 0] [left] with-transform [ApparentTranslate (-0.75 * df.mvs) 0] [left] with-transform [ApparentTranslate (-1.00 * df.mvs) 0] [left] + include : difference [left] : intersection MaskBelow (XH * OverlayPos * 1.02) union @@ -251,6 +257,7 @@ glyph-block Letter-Latin-Lower-AE-OE : begin select-variant "aa" 0xA733 (follow -- 'a/turnABase') + select-variant "ae/a" select-variant "ae/e" (follow -- 'e') select-variant "aeInvE/right" (follow -- 'e') select-variant "ue/u" diff --git a/font-src/glyphs/letter/latin/lower-a.ptl b/font-src/glyphs/letter/latin/lower-a.ptl index ec4956763..8fc1d1037 100644 --- a/font-src/glyphs/letter/latin/lower-a.ptl +++ b/font-src/glyphs/letter/latin/lower-a.ptl @@ -10,7 +10,7 @@ glyph-block Letter-Latin-Lower-A : begin glyph-block-import Common-Derivatives glyph-block-import Mark-Shared-Metrics : markHalfStroke glyph-block-import Letter-Shared : CreateAccentedComposition CreateOgonekComposition - glyph-block-import Letter-Shared-Shapes : SerifFrame OBarLeft OBarRight + glyph-block-import Letter-Shared-Shapes : SerifFrame OBarLeft OBarRight ArcStartSerif glyph-block-import Letter-Shared-Shapes : RightwardTailedBar InvRightwardTailedBar glyph-block-import Letter-Shared-Shapes : DToothlessRise DMBlend RetroflexHook @@ -24,20 +24,30 @@ glyph-block Letter-Latin-Lower-A : begin local sw : ADoubleStoreyStroke df return : df.archDepthB (ArchDepth * [StrokeWidthBlend 0.9 0.81 sw]) sw - define [ADoubleStoreyHookAndBarT df sink y0 stroke] : begin + define [ADoubleStoreyHookAndBarT sink df hookStyle y0 stroke] : begin local isMask : sink == spiro-outline return : sink widths.rhs stroke - g4 df.leftSB (XH - AHook) - hookstart (XH - O) (sw -- stroke) + match hookStyle + 1 : list + g4 df.leftSB (XH - AHook) + hookstart (XH - O) (sw -- stroke) + 2 : list + g4 df.leftSB (XH - DToothlessRise) + g4 (df.middle - CorrectionOMidX * stroke) (XH - O) flat df.rightSB (XH - [ADoubleStoreySmoothB df]) [if isMask corner curl] df.rightSB y0 [heading Downward] if [not isMask] {} {[corner df.leftSB y0]} - export : define [HookAndBar df y0 _stroke] : ADoubleStoreyHookAndBarT df dispiro y0 - fallback _stroke [ADoubleStoreyStroke df] - export : define [HookAndBarMask df y0 _stroke] : ADoubleStoreyHookAndBarT df spiro-outline y0 - fallback _stroke [ADoubleStoreyStroke df] + export : define [HookAndBar df hookStyle y0 _stroke] : glyph-proc + if ((hookStyle != 1) && (hookStyle != 2)) : throw : new Error "Invalid hookStyle" + local sw : fallback _stroke [ADoubleStoreyStroke df] + include : ADoubleStoreyHookAndBarT dispiro df hookStyle y0 sw + if (hookStyle == 2) : include : ArcStartSerif.L df.leftSB (XH - DToothlessRise) sw AHook + + export : define [HookAndBarMask df hookStyle y0 _stroke] : begin + local sw : fallback _stroke [ADoubleStoreyStroke df] + return : ADoubleStoreyHookAndBarT spiro-outline df hookStyle y0 sw define [ADoubleStoreyArcT df sink kind rise stroke] : glyph-proc local isMask : sink == spiro-outline @@ -76,21 +86,21 @@ glyph-block Letter-Latin-Lower-A : begin export : define [ArcMask df kind rise _sw] : ADoubleStoreyArcT df spiro-outline kind rise fallback _sw [ADoubleStoreyStroke df] - export : define [Serifless df sw] : union - HookAndBar df 0 sw + export : define [Serifless df hookStyle sw] : union + HookAndBar df hookStyle 0 sw Arc df 0 nothing nothing sw - export : define [Serifed df sw] : union - Serifless df sw + export : define [Serifed df hookStyle sw] : union + Serifless df hookStyle sw begin [SerifFrame.fromDf df XH 0].rb.outer - export : define [Tailed df sw] : union - HookAndBar df (XH - [ADoubleStoreySmoothB df] + O) sw + export : define [Tailed df hookStyle sw] : union + HookAndBar df hookStyle (XH - [ADoubleStoreySmoothB df] + O) sw Arc df 0 nothing nothing sw RightwardTailedBar df.rightSB 0 (XH - [ADoubleStoreySmoothB df]) (sw -- [fallback sw : ADoubleStoreyStroke df]) - export : define [ToothlessCorner df sw] : union - HookAndBar df DToothlessRise sw + export : define [ToothlessCorner df hookStyle sw] : union + HookAndBar df hookStyle DToothlessRise sw Arc df 1 DToothlessRise sw - export : define [ToothlessRounded df sw] : union - HookAndBar df [ADoubleStoreySmoothA df] sw + export : define [ToothlessRounded df hookStyle sw] : union + HookAndBar df hookStyle [ADoubleStoreySmoothA df] sw Arc df 2 [ADoubleStoreySmoothA df] sw export : define [GetMask shapeFn df sw] : match shapeFn @@ -99,27 +109,32 @@ glyph-block Letter-Latin-Lower-A : begin __ : ArcMask df 0 nothing nothing sw define DoubleStoreyConfig : object - doubleStoreySerifless { DoubleStorey.Serifless (RightSB ) } - doubleStoreySerifed { DoubleStorey.Serifed (RightSB + SideJut) } - doubleStoreyTailed { DoubleStorey.Tailed (RightSB + SideJut) } - doubleStoreyToothlessCorner { DoubleStorey.ToothlessCorner nothing } - doubleStoreyToothlessRounded { DoubleStorey.ToothlessRounded nothing } + doubleStoreySerifless { DoubleStorey.Serifless (RightSB ) 1 } + doubleStoreySerifed { DoubleStorey.Serifed (RightSB + SideJut) 1 } + doubleStoreyTailed { DoubleStorey.Tailed (RightSB + SideJut) 1 } + doubleStoreyToothlessCorner { DoubleStorey.ToothlessCorner nothing 1 } + doubleStoreyToothlessRounded { DoubleStorey.ToothlessRounded nothing 1 } + doubleStoreyHookInwardSerifedSerifless { DoubleStorey.Serifless (RightSB ) 2 } + doubleStoreyHookInwardSerifedSerifed { DoubleStorey.Serifed (RightSB + SideJut) 2 } + doubleStoreyHookInwardSerifedTailed { DoubleStorey.Tailed (RightSB + SideJut) 2 } + doubleStoreyHookInwardSerifedToothlessCorner { DoubleStorey.ToothlessCorner nothing 2 } + doubleStoreyHookInwardSerifedToothlessRounded { DoubleStorey.ToothlessRounded nothing 2 } - foreach { suffix { body xTrailing } } [Object.entries DoubleStoreyConfig] : do + foreach { suffix { body xTrailing hookStyle } } [Object.entries DoubleStoreyConfig] : do create-glyph "a.\(suffix)" : glyph-proc local df : include : DivFrame 1 include : df.markSet.e if xTrailing : set-base-anchor 'trailing' xTrailing 0 - include : body df + include : body df hookStyle glyph-block-import Letter-Blackboard : BBS BBD create-glyph 'mathbb/a' 0x1D552 : glyph-proc local df : include : DivFrame 1 include : df.markSet.e - include : DoubleStorey.HookAndBar df 0 BBS + include : DoubleStorey.HookAndBar df 1 0 BBS include : intersection - DoubleStorey.HookAndBarMask df 0 + DoubleStorey.HookAndBarMask df 1 0 VBar.r (RightSB - BBD) 0 XH BBS include : difference union diff --git a/font-src/support/geometry/spiro-control.mjs b/font-src/support/geometry/spiro-control.mjs index ca5ca3081..55e3f79f8 100644 --- a/font-src/support/geometry/spiro-control.mjs +++ b/font-src/support/geometry/spiro-control.mjs @@ -32,7 +32,7 @@ export class BiKnotCollector { this.controls.push(c); this.needsUnwrap = true; } else { - throw new Error("Invalid spiro control type"); + throw new Error("Invalid spiro control type " + String(c)); } } unwrap() { diff --git a/params/variants.toml b/params/variants.toml index 5a13c0584..cfe723f37 100644 --- a/params/variants.toml +++ b/params/variants.toml @@ -1505,9 +1505,10 @@ descriptionLeader = "`a`" [prime.a.variants-buildup.stages.storey.double-storey] rank = 1 -next = "terminal" +next = "double-storey-hook" descriptionAffix = "double-storey body" selectorAffix.a = "doubleStorey" +selectorAffix."ae/a" = "doubleStorey" selectorAffix."a/sansSerif" = "doubleStorey" selectorAffix."a/rtailBase" = "doubleStorey" selectorAffix."a/turnABase" = "doubleStorey" @@ -1519,12 +1520,41 @@ rank = 2 next = "ear" descriptionAffix = "single-storey body" selectorAffix.a = "singleStorey" +selectorAffix."ae/a" = "doubleStorey" selectorAffix."a/sansSerif" = "singleStorey" selectorAffix."a/rtailBase" = "singleStorey" selectorAffix."a/turnABase" = "doubleStorey" selectorAffix."a/single" = "singleStorey" selectorAffix.scripta = "singleStorey" +[prime.a.variants-buildup.stages.double-storey-hook."*"] +next = "terminal" + +[prime.a.variants-buildup.stages.double-storey-hook.hook-serifless] +rank = 1 +keyAffix = "" +descriptionAffix = "serifless hook" +selectorAffix.a = "" +selectorAffix."ae/a" = "" +selectorAffix."a/sansSerif" = "" +selectorAffix."a/rtailBase" = "" +selectorAffix."a/turnABase" = "" +selectorAffix."a/single" = "" +selectorAffix.scripta = "" + +[prime.a.variants-buildup.stages.double-storey-hook.hook-serifed] +rank = 2 +nonBreakingVariantAdditionPriority = 100 +keyAffix = "hook-inward-serifed" +descriptionAffix = "serifed hook" +selectorAffix.a = "hookInwardSerifed" +selectorAffix."ae/a" = "hookInwardSerifed" +selectorAffix."a/sansSerif" = "hookInwardSerifed" +selectorAffix."a/rtailBase" = "hookInwardSerifed" +selectorAffix."a/turnABase" = "hookInwardSerifed" +selectorAffix."a/single" = "" +selectorAffix.scripta = "" + [prime.a.variants-buildup.stages.ear."*"] next = "terminal" @@ -1532,6 +1562,7 @@ next = "terminal" rank = 1 keyAffix = "" selectorAffix.a = "" +selectorAffix."ae/a" = "" selectorAffix."a/sansSerif" = "" selectorAffix."a/rtailBase" = "" selectorAffix."a/turnABase" = "" @@ -1542,6 +1573,7 @@ selectorAffix.scripta = "" rank = 2 descriptionAffix = "earless (cornered top-right)" selectorAffix.a = "earlessCorner" +selectorAffix."ae/a" = "" selectorAffix."a/sansSerif" = "earlessCorner" selectorAffix."a/rtailBase" = "earlessCorner" selectorAffix."a/turnABase" = "" @@ -1552,6 +1584,7 @@ selectorAffix.scripta = "" rank = 3 descriptionAffix = "earless (rounded top-right)" selectorAffix.a = "earlessRounded" +selectorAffix."ae/a" = "" selectorAffix."a/sansSerif" = "earlessRounded" selectorAffix."a/rtailBase" = "earlessRounded" selectorAffix."a/turnABase" = "" @@ -1563,6 +1596,7 @@ rank = 1 descriptionAffix = "serif at terminal" descriptionJoiner = "without" selectorAffix.a = "serifless" +selectorAffix."ae/a" = "serifless" selectorAffix."a/sansSerif" = "serifless" selectorAffix."a/rtailBase" = "serifless" selectorAffix."a/turnABase" = "serifless" @@ -1573,6 +1607,7 @@ selectorAffix.scripta = "serifless" rank = 2 descriptionAffix = "curly tail" selectorAffix.a = "tailed" +selectorAffix."ae/a" = "serifless" selectorAffix."a/sansSerif" = "tailed" selectorAffix."a/rtailBase" = "serifless" selectorAffix."a/turnABase" = "tailed" @@ -1584,6 +1619,7 @@ rank = 3 disableIf = [{ storey = "single-storey" }] descriptionAffix = "toothless (cornered bottom-right)" selectorAffix.a = "toothlessCorner" +selectorAffix."ae/a" = "serifless" selectorAffix."a/sansSerif" = "toothlessCorner" selectorAffix."a/rtailBase" = "serifless" selectorAffix."a/turnABase" = "toothlessCorner" @@ -1595,6 +1631,7 @@ rank = 4 disableIf = [{ storey = "single-storey" }] descriptionAffix = "toothless (rounded bottom-right)" selectorAffix.a = "toothlessRounded" +selectorAffix."ae/a" = "serifless" selectorAffix."a/sansSerif" = "toothlessRounded" selectorAffix."a/rtailBase" = "serifless" selectorAffix."a/turnABase" = "toothlessRounded" @@ -1605,6 +1642,7 @@ selectorAffix.scripta = "serifless" rank = 5 descriptionAffix = "serif at terminal" selectorAffix.a = "serifed" +selectorAffix."ae/a" = "serifless" selectorAffix."a/sansSerif" = "serifless" selectorAffix."a/rtailBase" = "serifless" selectorAffix."a/turnABase" = "serifed"