diff --git a/changes/5.0.0.md b/changes/5.0.0.md index 3793892e2..03b4d63ad 100644 --- a/changes/5.0.0.md +++ b/changes/5.0.0.md @@ -1,3 +1,4 @@ * Add Hooky variant for `j` (#864). * Fix width of flat-hook-serifless `j` (#860). * Add Circled Zero With Slash (`U+1F10D`, #861). + * Add bar-interrupted variants for Dollar and Cent sign (#863). \ No newline at end of file diff --git a/font-src/glyphs/common/derivatives.ptl b/font-src/glyphs/common/derivatives.ptl index 2cb3090ba..0e94dce75 100644 --- a/font-src/glyphs/common/derivatives.ptl +++ b/font-src/glyphs/common/derivatives.ptl @@ -3,7 +3,7 @@ $$include '../../meta/macros.ptl' import '../../support/transform' as Transform import [mix linreg clamp fallback] from '../../support/utils' -import [Cv AnyCv AnyDerivingCv Dotless] from '../../support/gr' +import [Cv AnyCv AnyDerivingCv Dotless SvInheritableRelations] from '../../support/gr' import [DesignParameters] from '../../meta/aesthetics' extern Map @@ -32,7 +32,10 @@ glyph-block Common-Derivatives : begin create-glyph name unicode : glyph-proc include [refer-glyph (shapeFrom + '.' + variant)] AS_BASE ALSO_METRICS ApplyCv currentGlyph shapeFrom follow para - set this.autoRefPriority [query-glyph (shapeFrom + '.' + variant)].autoRefPriority + currentGlyph.cloneRankFromGlyph [query-glyph (shapeFrom + '.' + variant)] + foreach gr [items-of SvInheritableRelations] : begin + local v : gr.get [query-glyph (shapeFrom + '.' + variant)] + if v : gr.set this v define [orthographic-italic name unicode] : if para.isItalic alias name unicode (name + '.italic') diff --git a/font-src/glyphs/letter/latin/c.ptl b/font-src/glyphs/letter/latin/c.ptl index 8660ed18c..8cc1f2e99 100644 --- a/font-src/glyphs/letter/latin/c.ptl +++ b/font-src/glyphs/letter/latin/c.ptl @@ -248,6 +248,17 @@ glyph-block Letter-Latin-C : begin include [refer-glyph 'currency/centSignBar.open'] AS_BASE ALSO_METRICS include : VBar (Middle - Width) (XH - HalfStroke) (0 + HalfStroke) fine + create-glyph 'currency/centSignBar.barInterrupted' : glyph-proc + set-width 0 + define fine : AdviceStroke 4 + define gap : Math.max (XH / 8) [AdviceStroke2 6 6 XH] + include : dispiro + flat (Middle - Width) (XH - Descender / 2) [widths.center.heading Stroke Downward] + curl (Middle - Width) (XH / 2 + gap / 2) [widths.center.heading fine Downward] + include : dispiro + flat (Middle - Width) (Descender / 2) [widths.center.heading Stroke Upward] + curl (Middle - Width) (XH / 2 - gap / 2) [widths.center.heading fine Upward] + select-variant 'currency/centSignBar' (follow -- 'cent') create-glyph 'currency/centSign' 0xA2 : glyph-proc diff --git a/font-src/glyphs/letter/latin/s.ptl b/font-src/glyphs/letter/latin/s.ptl index e8bdafc0b..cac9b3905 100644 --- a/font-src/glyphs/letter/latin/s.ptl +++ b/font-src/glyphs/letter/latin/s.ptl @@ -2,7 +2,7 @@ $$include '../../../meta/macros.ptl' import [mix linreg clamp fallback] from '../../../support/utils' import [DesignParameters] from '../../../meta/aesthetics' -import [Dotless CvDecompose] from "../../../support/gr" +import [DollarShrinkKernel DollarShorterBar CvDecompose] from "../../../support/gr" glyph-module @@ -29,34 +29,43 @@ glyph-block Letter-Latin-S : begin define tension : tensionCoeff * (0.5 - 0.4 * dist - 0.005 * strokeCoeff + slantCoeff * TanSlope) return : alsoThruThem {{(0.5 - dist) tension} {(0.5 + dist) (1 - tension)}} [widths.center stroke] - define [SStrokeImpl st sb stroke refSwEss] : begin + define [SStrokeDollarInterruptGap deltaX top bot gap stroke refSwEss] : begin + local ess : refSwEss * gap / Stroke + define smooth : adviceSSmooth (top - bot) (-1) stroke + + return : dispiro + g4.down.mid (deltaX + SB - Width) (top - smooth) [widths.lhs gap] + alsoThru.g2 0.5 0.5 [widths.center ess] + g4.down.mid (deltaX + RightSB - Width - SOBot) (bot + smooth) [widths.rhs gap] + + define [SStrokeImpl top bot st sb stroke refSwEss] : begin local ess : refSwEss * stroke / Stroke - define smooth : adviceSSmooth CAP (-1) stroke + define smooth : adviceSSmooth (top - bot) (-1) stroke return : dispiro match st - [Just SLAB-CLASSICAL] : SerifedArcStart_RtlLhs RightSB Middle CAP stroke Hook + [Just SLAB-CLASSICAL] : SerifedArcStart_RtlLhs RightSB Middle top stroke Hook [Just SLAB-INWARD] : list - g4 RightSB (CAP - DToothlessRise) [widths.lhs stroke] - g4 (Middle - CorrectionOMidX * stroke) (CAP - O) + g4 RightSB (top - DToothlessRise) [widths.lhs stroke] + g4 (Middle - CorrectionOMidX * stroke) (top - O) archv __ : list - g4 RightSB (CAP - Hook) [widths.lhs stroke] - hookstart (CAP - O) (sw -- stroke) (swItalicAdj -- Stroke) + g4 RightSB (top - Hook) [widths.lhs stroke] + hookstart (top - O) (sw -- stroke) (swItalicAdj -- Stroke) - g4 SB (CAP - smooth) + g4 SB (top - smooth) alsoThru.g2 0.5 0.5 [widths.center ess] - g4 (RightSB - SOBot) smooth [widths 0 stroke] + g4 (RightSB - SOBot) (bot + smooth) [widths 0 stroke] match sb - [Just SLAB-CLASSICAL] : SerifedArcEnd_RtlRhs SB Middle 0 stroke Hook + [Just SLAB-CLASSICAL] : SerifedArcEnd_RtlRhs SB Middle bot stroke Hook [Just SLAB-INWARD] : list arcvh - g4 (Middle + CorrectionOMidX * stroke) O - g4 SB DToothlessRise + g4 (Middle + CorrectionOMidX * stroke) (bot + O) + g4 SB (bot + DToothlessRise) __ : list - hookend O (sw -- stroke) (swItalicAdj -- Stroke) - g4 (SB + SOBot) Hook + hookend (bot + O) (sw -- stroke) (swItalicAdj -- Stroke) + g4 (SB + SOBot) (bot + Hook) define [RevSStroke] : begin local stroke : AdviceStroke2 2 3 CAP @@ -173,10 +182,27 @@ glyph-block Letter-Latin-S : begin foreach { suffix { doTS doBS } } [Object.entries SConfig] : do create-glyph "S.\(suffix)" : glyph-proc include : MarkSet.capital - include : SStrokeImpl doTS doBS [AdviceStroke2 2 3 CAP] Ess + include : SStrokeImpl CAP 0 doTS doBS [AdviceStroke2 2 3 CAP] Ess include : SAutoSlabStart doTS CAP Stroke Hook include : SAutoSlabEnd doBS 0 Stroke Hook + create-glyph "DollarKernelStd.\(suffix)" : glyph-proc + define top : CAP * 0.95 + define bot : CAP * 0.05 + include : MarkSet.capital + include : SStrokeImpl top bot doTS doBS [AdviceStroke2 3 3 (top - bot)] Ess + include : SAutoSlabStart doTS top Stroke Hook + include : SAutoSlabEnd doBS bot Stroke Hook + DollarShrinkKernel.set currentGlyph "DollarKernelCap.\(suffix)" + + create-glyph "DollarKernelCap.\(suffix)" : glyph-proc + define top : CAP * 0.88 + define bot : CAP * 0.12 + include : MarkSet.capital + include : SStrokeImpl top bot doTS doBS [AdviceStroke2 3 3 (top - bot)] Ess + include : SAutoSlabStart doTS top Stroke Hook + include : SAutoSlabEnd doBS bot Stroke Hook + create-glyph "s.\(suffix)" : glyph-proc include : MarkSet.e include : SmallSStrokeImpl doTS doBS [AdviceStroke2 2 3 XH] Ess @@ -187,7 +213,7 @@ glyph-block Letter-Latin-S : begin include : MarkSet.if include : SAutoSlabStart doTS CAP Stroke Hook - local stroke : include : SStrokeImpl doTS doBS [AdviceStroke2 2 3 CAP] Ess + local stroke : include : SStrokeImpl CAP 0 doTS doBS [AdviceStroke2 2 3 CAP] Ess local start : currentGlyph.gizmo.unapply stroke.lhsKnots.(stroke.lhsKnots.length - 1) local sw : AdviceStroke2 2 3 CAP @@ -232,6 +258,12 @@ glyph-block Letter-Latin-S : begin select-variant 'S' 'S' select-variant 's' 's' + + select-variant 'DollarKernelStd' (follow -- 'S') + select-variant 'DollarKernelCap' (follow -- 'S') + if [query-glyph 'DollarKernelStd'] : begin + DollarShrinkKernel.set [query-glyph 'DollarKernelStd'] 'DollarKernelCap' + select-variant 'SSwash' 0x2C7E select-variant 'sSwash' 0x23F select-variant 'sRTail' 0x282 (follow -- 'sSwash') @@ -317,58 +349,57 @@ glyph-block Letter-Latin-S : begin local start : currentGlyph.gizmo.unapply stroke.rhsKnots.(0) include : VBarRight start.x (-Accent) start.y - create-glyph 'dollar.open' : glyph-proc - include : MarkSet.capital - define top : CAP * 0.95 - define bot : CAP * 0.05 - define w : AdviceStroke 3 - define fine : AdviceStroke 3.5 - define smooth : adviceSSmooth (top - bot) (-1) w - include : dispiro - widths.lhs w - g4 RightSB (top - Hook) - hookstart (top - O) - g4 SB (top - smooth) - SNeck w - g4 RightSB (bot + smooth) [widths 0 w] - hookend (bot + O) - g4 SB (bot + Hook) - include : dispiro - widths.center w - flat Middle (top - HalfStroke) - curl Middle (CAP - Descender / 2) [heading Upward] - include : dispiro - widths.center w - flat Middle (Descender / 2) [heading Upward] - curl Middle (bot + HalfStroke) - create-derived 'dollar.through' : VBar Middle (bot + HalfStroke) (top - HalfStroke) fine + define DollarConfig : object + open { 0.95 0.05 (Descender / 2) 0 0 } + through { 0.95 0.05 (Descender / 2) 1 0 } + interrupted { 0.95 0.05 (Descender / 2) 2 0 } + openCap { 0.88 0.12 0 0 1 } + throughCap { 0.88 0.12 0 1 1 } + interruptedCap { 0.88 0.12 0 2 1 } - create-glyph 'dollar.opencap' : glyph-proc - include : MarkSet.capital - define top : CAP * 0.88 - define bot : CAP * 0.12 - define w : AdviceStroke 3 - define fine : AdviceStroke 3.5 - define smooth : adviceSSmooth (top - bot) (-1) w - include : dispiro - widths.lhs w - g4 RightSB (top - Hook) - hookstart (top - O) - g4 SB (top - smooth) - SNeck w - g4 RightSB (bot + smooth) [widths 0 w] - hookend (bot + O) - g4 SB (bot + Hook) - include : dispiro - widths.center w - flat Middle (top - HalfStroke) - curl Middle (CAP) [heading Upward] - include : dispiro - widths.center w - flat Middle (0) [heading Upward] - curl Middle (bot + HalfStroke) + foreach { suffix { kTop kBot overflow fillType fShort } } [Object.entries DollarConfig] : do + create-glyph "dollar/bar.\(suffix)" : glyph-proc + set-width 0 + define top : CAP * kTop + define bot : CAP * kBot + define w : AdviceStroke 3 + define fine : AdviceStroke 4 + define barMid : Middle - Width - create-derived 'dollar.throughcap' : VBar Middle (bot + HalfStroke) (top - HalfStroke) fine + if (fillType === 1) : include : VBar barMid (bot + HalfStroke) (top - HalfStroke) fine + if (fillType === 0 || fillType === 1) : begin + include : dispiro + widths.center w + flat barMid (top - HalfStroke) + curl barMid (CAP - overflow) [heading Upward] + include : dispiro + widths.center w + flat barMid overflow [heading Upward] + curl barMid (bot + HalfStroke) + if (fillType === 2) : begin + local gap : Math.max ((top - bot) / 6) (w / Stroke * Ess * 1.5) + local maskOffset : gap / 2 - w / 2 + SStrokeDollarInterruptGap top bot gap w Ess + include : difference + union + dispiro + flat barMid (CAP - overflow) [widths.center.heading w Downward] + curl barMid [mix bot top 0.5] [widths.center.heading fine Downward] + dispiro + flat barMid overflow [widths.center.heading w Upward] + curl barMid [mix bot top 0.5] [widths.center.heading fine Upward] - select-variant 'dollar' '$' + SStrokeDollarInterruptGap (+maskOffset / 2) (top + maskOffset) (bot + maskOffset ) w w Ess + SStrokeDollarInterruptGap 0 top bot (gap - w) w Ess + SStrokeDollarInterruptGap (-maskOffset / 2) (top - maskOffset) (bot - maskOffset ) w w Ess + + if fShort : DollarShorterBar.set currentGlyph 'trigger' + + select-variant 'dollar/bar' (follow -- 'dollar') + + create-glyph 'dollar' '$' : glyph-proc + include : WithTransform [Translate Width 0] [refer-glyph 'dollar/bar'] + local kernel : if [DollarShorterBar.get : query-glyph 'dollar/bar'] 'DollarKernelCap' 'DollarKernelStd' + include [refer-glyph kernel] AS_BASE ALSO_METRICS + CvDecompose.set currentGlyph { 'DollarKernelStd' 'dollar/bar' } diff --git a/font-src/otl/gsub-cv-ss.ptl b/font-src/otl/gsub-cv-ss.ptl index da20577da..e9b8a77e1 100644 --- a/font-src/otl/gsub-cv-ss.ptl +++ b/font-src/otl/gsub-cv-ss.ptl @@ -1,13 +1,19 @@ -import [add-lookup add-common-feature pick-feature add-feature-lookup pick-lookup BeginLookupBlock EndLookupBlock] from "./table-util" -import [Cv AnyCv CvDecompose] from "../support/gr" +import [add-lookup add-common-feature pick-feature add-feature-lookup pick-lookup BeginLookupBlock EndLookupBlock ChainRuleBuilder] from "./table-util" +import [Cv AnyCv CvDecompose DollarShrinkKernel DollarShorterBar] from "../support/gr" + extern Set +define look-around null +define-operator "~>" 880 'right' : syntax-rules + `(@l ~> @r) `{.left @l .right @r} + define [FeatureName tag] : tag + '_cvss' define [CvLookupName tag] : 'lookup_cv_' + tag define [SsLookupName tag] : 'lookup_ss_' + tag export : define [buildCVSS sink para glyphStore] : begin if [not para.enableCvSs] : return nothing + define {chain-rule} : ChainRuleBuilder sink local rec : BeginLookupBlock sink local cvLookupNameSet : new Set @@ -23,14 +29,32 @@ export : define [buildCVSS sink para glyphStore] : begin .type 'gsub_multiple' .substitutions decompositions + # '$' : Kernel Shrinking + define dsFrom { } + define dsTo { } + define sbSet : new Set + foreach { gid g } [glyphStore.namedEntries] : begin + if ([DollarShorterBar.get g] === 'trigger') : begin + sbSet.add : glyphStore.ensureExists gid + if [DollarShrinkKernel.get g] : begin + dsFrom.push : glyphStore.ensureExists gid + dsTo.push : glyphStore.ensureExists : DollarShrinkKernel.get g + + define lookupNameDollarShrink : add-lookup sink : object + .type 'gsub_chaining' + .rules : list : chain-rule (dsFrom ~> dsTo) ([Array.from sbSet] ~> look-around) + + define [addFeatureAndLookup tag lookupName init] : begin define feature : pick-feature sink [FeatureName tag] add-common-feature sink feature define lookup : pick-lookup sink lookupName init add-feature-lookup feature lookupNameCvDecompose + add-feature-lookup feature lookupNameDollarShrink add-feature-lookup feature lookupName sink.lookupDep.push { lookupNameCvDecompose lookupName } + sink.lookupDep.push { lookupName lookupNameDollarShrink } cvLookupNameSet.add lookupName diff --git a/font-src/support/gr.js b/font-src/support/gr.js index 409308fde..6f68990bf 100644 --- a/font-src/support/gr.js +++ b/font-src/support/gr.js @@ -16,17 +16,23 @@ const Dotless = { } }; -const ZReduced = { - get(glyph) { - if (glyph && glyph.related) return glyph.related.zReduced; - else return null; - }, - set(glyph, toGid) { - if (typeof toGid !== "string") throw new Error("Must supply a GID instead of a glyph"); - if (!glyph.related) glyph.related = {}; - glyph.related.zReduced = toGid; - } -}; +function SimpleProp(key) { + return { + get(glyph) { + if (glyph && glyph.related) return glyph.related[key]; + else return null; + }, + set(glyph, toGid) { + if (typeof toGid !== "string") throw new Error("Must supply a GID instead of a glyph"); + if (!glyph.related) glyph.related = {}; + glyph.related[key] = toGid; + } + }; +} + +const ZReduced = SimpleProp("ZReduced"); +const DollarShrinkKernel = SimpleProp("DollarShrinkKernel"); +const DollarShorterBar = SimpleProp("DollarShorterBar"); const CvDecompose = { get(glyph) { @@ -344,3 +350,6 @@ exports.AnyDerivingCv = AnyDerivingCv; exports.CcmpDecompose = CcmpDecompose; exports.CvDecompose = CvDecompose; exports.createGrDisplaySheet = createGrDisplaySheet; +exports.DollarShrinkKernel = DollarShrinkKernel; +exports.DollarShorterBar = DollarShorterBar; +exports.SvInheritableRelations = [DollarShrinkKernel, DollarShorterBar]; diff --git a/params/variants.toml b/params/variants.toml index 34c7474ac..0ea615efe 100644 --- a/params/variants.toml +++ b/params/variants.toml @@ -3188,37 +3188,52 @@ rank = 2 description = "Dollar symbol with strike-through vertical bar" selector.dollar = "through" -[prime.dollar.variants.opencap] +[prime.dollar.variants.interrupted] rank = 3 -description = "Dollar symbol with open contour, not exceeding baseline and ascender" -selector.dollar = "opencap" +description = "Dollar symbol with strike-through vertical bar" +selector.dollar = "interrupted" -[prime.dollar.variants.throughcap] +[prime.dollar.variants.open-cap] rank = 4 +description = "Dollar symbol with open contour, not exceeding baseline and ascender" +selector.dollar = "openCap" + +[prime.dollar.variants.through-cap] +rank = 5 description = "Dollar symbol with strike-through vertical bar, not exceeding baseline and ascender" -selector.dollar = "throughcap" +selector.dollar = "throughCap" + +[prime.dollar.variants.interrupted-cap] +rank = 6 +description = "Dollar symbol with strike-through vertical bar, not exceeding baseline and ascender" +selector.dollar = "interruptedCap" [prime.cent] sampler = "¢" -tag = "cv85" +tag = "cv79" [prime.cent.variants.open] rank = 1 -description = "Cent sign with open contour" +description = "Cent sign (`¢`) with open contour" selector.cent = "open" [prime.cent.variants.through] rank = 2 -description = "Cent sign with open contour" +description = "Cent sign (`¢`) with vertical bar all through the `c` part" selector.cent = "through" +[prime.cent.variants.bar-interrupted] +rank = 3 +description = "Cent sign (`¢`) with vertical bar breaks at center" +selector.cent = "barInterrupted" + [prime.percent] sampler = "%" -tag = "cv79" +tag = "cv80" [prime.percent.variants.dots] rank = 1 @@ -3248,7 +3263,7 @@ selector.permille = "ringsContinuousSlash" [prime.bar] sampler = "|" -tag = "cv80" +tag = "cv81" slopeDependent = true [prime.bar.variants.natural-slope] @@ -3265,7 +3280,7 @@ selector."bar.italic" = "forceUpright" [prime.lig-ltgteq] sampler = "<= >=" -tag = "cv81" +tag = "cv82" [prime.lig-ltgteq.variants.flat] rank = 1 @@ -3283,7 +3298,7 @@ selector."eq.at-gteq.lig2" = "slanted" [prime.ascii-single-quote] sampler = "'" -tag = "cv82" +tag = "cv83" [prime.ascii-single-quote.variants.straight] rank = 1 @@ -3299,7 +3314,7 @@ selector.asciiSingleQuote = "raisedComma" [prime.ascii-grave] sampler = "`" -tag = "cv83" +tag = "cv84" [prime.ascii-grave.variants.straight] rank = 1 @@ -3320,7 +3335,7 @@ selector.asciiGrave = "raisedTurnComma" [prime.question] sampler = "?" -tag = "cv84" +tag = "cv85" [prime.question.variants.smooth] rank = 1