Add fraktur A and K (#2450)
This commit is contained in:
parent
d3767217af
commit
dc9d7f3ac2
13 changed files with 584 additions and 395 deletions
|
@ -1,395 +1,14 @@
|
|||
###### Fraktur letterforms
|
||||
###
|
||||
### This file is used to define the letterforms of the Fraktur style.
|
||||
### For simplicity, the letters here will *NOT* support any variants.
|
||||
###
|
||||
|
||||
$$include '../meta/macros.ptl'
|
||||
|
||||
import [mix fallback] from "@iosevka/util"
|
||||
import [SpiroPenGeometry] from "@iosevka/geometry"
|
||||
import [Vec2] from "@iosevka/geometry/point"
|
||||
import [Box] from "@iosevka/geometry/box"
|
||||
import [Interpolator] from "@iosevka/geometry/spiro-control"
|
||||
import [PenKnotCollector] from "@iosevka/geometry/spiro-pen-expand"
|
||||
|
||||
glyph-module
|
||||
|
||||
glyph-block LetterLike-Fraktur-Shared : begin
|
||||
|
||||
# [fraktur-stroke profile ...] will construct a Fraktur stroke from a pen profile and a list
|
||||
# of control knots. The knots will form a (usually open) spiro path, then the result will be
|
||||
# the area that the pen tip covers when moving along the path.
|
||||
glyph-block-export fraktur-stroke
|
||||
define [fraktur-stroke profile __knots] : begin
|
||||
local knots : {}.slice.call arguments 1
|
||||
return : new FrakturImpl profile knots
|
||||
|
||||
class FrakturImpl
|
||||
public [new profile knots] : begin
|
||||
this.profile = profile
|
||||
this.knots = knots
|
||||
|
||||
public [applyToGlyph glyph] : begin
|
||||
local defaultProfile : this.profile.getPenShape glyph.gizmo
|
||||
local collector : new PenKnotCollector glyph.gizmo defaultProfile
|
||||
local c : spiro-collect collector this.knots
|
||||
|
||||
local geom : new SpiroPenGeometry
|
||||
begin glyph.gizmo
|
||||
begin defaultProfile
|
||||
begin collector.closed
|
||||
begin collector.knots
|
||||
|
||||
glyph.includeGeometry geom
|
||||
return collector.knots
|
||||
|
||||
# Directive to change the profile
|
||||
glyph-block-export change-profile
|
||||
define [change-profile newProfile] : function : begin
|
||||
this.setProfile : newProfile.getPenShape this.gizmo
|
||||
|
||||
# A pen profile describes a virtual flat-tip pen. We use a 45-degree arrangement to
|
||||
# simplify the math.
|
||||
class FrakturProfile
|
||||
public [new thick thin] : begin
|
||||
# .thick is the half length of the flat tip, projected to the X/Y axis
|
||||
this.thick = 0.25 * [Math.sqrt 2] * thick
|
||||
# .thin is the half width of the thin tip, projected to the X/Y axis
|
||||
this.thin = 0.25 * [Math.sqrt 2] * thin
|
||||
|
||||
public [getPenShape gizmo] : begin
|
||||
local thickTf : gizmo.applyOffsetXY this.thick this.thick
|
||||
list
|
||||
new Vec2 (thickTf.x - this.thin) (thickTf.y + this.thin)
|
||||
new Vec2 (thickTf.x + this.thin) (thickTf.y + this.thin)
|
||||
new Vec2 (thickTf.x + this.thin) (thickTf.y - this.thin)
|
||||
new Vec2 (-thickTf.x + this.thin) (-thickTf.y - this.thin)
|
||||
new Vec2 (-thickTf.x - this.thin) (-thickTf.y - this.thin)
|
||||
new Vec2 (-thickTf.x - this.thin) (-thickTf.y + this.thin)
|
||||
|
||||
public [box u d l r] : new Box [this.yt u] [this.yb d] [this.xl l] [this.xr r]
|
||||
|
||||
public [xl x] : x + this.thick
|
||||
public [xr x] : x - this.thick
|
||||
public [xp l r p] : mix [this.xl l] [this.xr r] p
|
||||
|
||||
public [yb y] : y + this.thick
|
||||
public [yt y] : y - this.thick
|
||||
public [yp b t p] : mix [this.yb b] [this.yt t] p
|
||||
|
||||
# Connection to another profile's pen tip position
|
||||
public [connL otherProfile x] : x - otherProfile.thick + this.thick
|
||||
public [connR otherProfile x] : x + otherProfile.thick - this.thick
|
||||
public [connB otherProfile y] : y - otherProfile.thick + this.thick
|
||||
public [connT otherProfile y] : y + otherProfile.thick - this.thick
|
||||
|
||||
# Stroke widths
|
||||
define frakThin : 1.0 * [AdviceStroke 12]
|
||||
define frakThick : 1.0 * Stroke
|
||||
define frakFine : 1.0 * [AdviceStroke 4] # For decoration
|
||||
|
||||
glyph-block-export S
|
||||
define S : new FrakturProfile frakThick (0.875 * frakThin)
|
||||
|
||||
glyph-block-export F
|
||||
define F : new FrakturProfile frakFine (0.875 * frakThin)
|
||||
|
||||
glyph-block-export T
|
||||
define T : new FrakturProfile frakThin (0.875 * frakThin)
|
||||
|
||||
# Key metrics
|
||||
glyph-block-export DecoSizeX DecoSizeY FHook Wave.DepthY Wave.DepthX LbFootRise
|
||||
define DecoSizeX : 0.15 * (RightSB - SB)
|
||||
define DecoSizeY : 0.08 * (RightSB - SB)
|
||||
define FHook : 0.4 * SHook - 0.25 * S.thick
|
||||
define LbFootRise : 0.375 * SHook + 0.375 * S.thick
|
||||
|
||||
glyph-block-export SlopeA SlopeB
|
||||
define SlopeA : 0.875 * DecoSizeY / DecoSizeX
|
||||
define SlopeB : 0.875 * -[mix SlopeA 1.0 0.5]
|
||||
|
||||
# Wave blenders
|
||||
glyph-block-export Wave
|
||||
define Wave : namespace
|
||||
export : define DepthY : 0.4 * SHook - 0.25 * S.thick
|
||||
export : define DepthX : 0.375 * SHook + 0.125 * S.thick
|
||||
|
||||
export : define [vc waveDepth] : Interpolator vcWaveBlender [object waveDepth]
|
||||
define [vcWaveBlender before after args] : begin
|
||||
local [object waveDepth] args
|
||||
return : list
|
||||
g2 (before.x + 0.5 * waveDepth) [mix before.y after.y 0.375]
|
||||
g2 (after.x - 0.5 * waveDepth) [mix before.y after.y 0.625]
|
||||
|
||||
export : define [h] : Interpolator hWaveBlender [object h]
|
||||
define [hWaveBlender before after] : begin
|
||||
return : list
|
||||
g2 [mix before.x after.x 0.375] after.y
|
||||
g2 [mix before.x after.x 0.625] before.y
|
||||
|
||||
glyph-block-export PHexTop
|
||||
define PHexTop : 0.5 + 0.5 * ([Math.max DecoSizeX frakThin] / (RightSB - SB))
|
||||
glyph-block-export PHexBot
|
||||
define PHexBot : 1 - PHexTop
|
||||
|
||||
glyph-block LetterLike-Fraktur : begin
|
||||
glyph-block-import Common-Derivatives
|
||||
glyph-block-import CommonShapes
|
||||
glyph-block-import LetterLike-Fraktur-Shared : S F T fraktur-stroke change-profile
|
||||
glyph-block-import LetterLike-Fraktur-Shared : DecoSizeX DecoSizeY SlopeA SlopeB
|
||||
glyph-block-import LetterLike-Fraktur-Shared : Wave LbFootRise FHook PHexTop PHexBot
|
||||
|
||||
|
||||
define [LtDecorativeWave sx sy ey] : fraktur-stroke F
|
||||
g2.ld.start sx sy
|
||||
~~~ [Wave.vc (-Wave.DepthX)]
|
||||
g2.ld.end pre@ (ey - 2 * S.thick)
|
||||
|
||||
do "C, E, and G"
|
||||
define flex-params [FrakCTopAndCenterStroke] : glyph-proc
|
||||
local-parameter : top -- [S.yt CAP]
|
||||
local-parameter : bot -- [S.yp 0 CAP 0.375]
|
||||
local-parameter : left -- [S.xl SB]
|
||||
local-parameter : right -- [S.xr RightSB]
|
||||
|
||||
local xCenter : [mix left right 0.5] + 0.25 * F.thick
|
||||
local deco : Math.max DecoSizeX (0.5 * ArchDepthA - 2 * S.thick)
|
||||
local waveTop : top - deco
|
||||
|
||||
# Top-right stroke
|
||||
include : fraktur-stroke S
|
||||
g2 right top
|
||||
g2.left.mid [mix@ 0.5] (top - 0.5 * FHook)
|
||||
corner (post@ <+> deco) top
|
||||
corner xCenter (top - deco)
|
||||
|
||||
# Inner decoration
|
||||
include : fraktur-stroke F
|
||||
g2.ld.start [F.connL S xCenter] [F.connB S : top - deco]
|
||||
~~~ [Wave.vc (-Wave.DepthX)]
|
||||
g2.ld.end pre@ bot
|
||||
|
||||
return : object xCenter [waveTop : top - deco] [waveBot bot]
|
||||
|
||||
define flex-params [FrakCOutlineShape] : glyph-proc
|
||||
local-parameter : mode -- 'C'
|
||||
local-parameter : top -- [S.yt CAP]
|
||||
local-parameter : bot -- [S.yb 0]
|
||||
local-parameter : left -- [S.xl SB]
|
||||
local-parameter : right -- [S.xr RightSB]
|
||||
|
||||
local [object xCenter waveTop waveBot] : include : FrakCTopAndCenterStroke
|
||||
bot -- ([mix bot top 0.1] + 2 * Wave.DepthY + 0.5 * S.thick)
|
||||
|
||||
# Left and bottom stroke
|
||||
local mainStroke : include : fraktur-stroke S
|
||||
g4.ru.start [T.connL S xCenter] [T.connB S waveTop] [change-profile T]
|
||||
arch.rhs [T.connT S top] (sw -- T.thick) (anglePre -- (-45)) (anglePost -- 0)
|
||||
flat left (pre@ <-> 0.6 * ArchDepthA) [change-profile S]
|
||||
curl pre@ (post@ <+> ArchDepthB)
|
||||
match mode
|
||||
: [Just 'C'] : list # C and E
|
||||
hookend (sw -- S.thick) bot
|
||||
g2 [T.connR S right] (pre@ <+> [T.connT S SHook]) [change-profile T]
|
||||
: [Just 'G'] : list # G
|
||||
arch.lhs (sw -- S.thick) bot
|
||||
flat right (pre@ <+> ArchDepthA)
|
||||
decor@ : curl pre@ (post@ <-> 0.5 * ArchDepthB)
|
||||
decor@@ : g2 [post@tang-out 1] [post@tang-out SlopeB]
|
||||
decor@ : corner [mix@rev PHexTop] [post@slope SlopeA]
|
||||
decor@ : corner xCenter [mix waveTop waveBot 0.5]
|
||||
|
||||
return : object xCenter waveTop waveBot
|
||||
|
||||
create-glyph "frak/C" 0x212D : glyph-proc
|
||||
include : MarkSet.capital
|
||||
include : FrakCOutlineShape (mode -- 'C')
|
||||
|
||||
create-glyph "frak/E" 0x1D508 : glyph-proc
|
||||
include [refer-glyph "frak/C"] AS_BASE ALSO_METRICS
|
||||
local [object xCenter waveTop waveBot] : include : FrakCOutlineShape (mode -- 'C')
|
||||
|
||||
include : fraktur-stroke F
|
||||
corner [F.connL S xCenter] [F.connB S : mix waveTop waveBot 0.5]
|
||||
corner (post@ <-> 0.5 * DecoSizeX) [pre@slope SlopeA]
|
||||
corner [F.xr RightSB] (pre@ <-> 0.5 * DecoSizeY)
|
||||
|
||||
create-glyph "frak/G" 0x1D50A : glyph-proc
|
||||
include : MarkSet.capital
|
||||
include : FrakCOutlineShape (mode -- 'G')
|
||||
|
||||
create-glyph "frak/H" 0x210C : glyph-proc
|
||||
include : MarkSet.capDesc
|
||||
|
||||
local xExt : mix 0 SB 0.25
|
||||
local xLeftStem : Math.max (xExt + 1.5 * DecoSizeX) [mix SB RightSB 0]
|
||||
local ada : 0.6 * ArchDepthA
|
||||
local adb : 0.6 * ArchDepthB
|
||||
|
||||
local xMidStrokeTop : S.xp xLeftStem RightSB 0.625
|
||||
local yMidStrokeTop : S.yt (XH - FHook)
|
||||
local xMidStrokeStart : S.xl xLeftStem
|
||||
local yMidStrokeStart : yMidStrokeTop - SlopeA * (xMidStrokeTop - xMidStrokeStart)
|
||||
|
||||
# Top and left stroke
|
||||
include : fraktur-stroke S
|
||||
g2 [S.xr RightSB] ([S.yt CAP] - FHook)
|
||||
~~~ [arch.rhs [S.yt CAP] (sw -- S.thick) (blendPre -- null) (blendPost -- null)]
|
||||
corner [S.xl xLeftStem] ([S.yt CAP] - adb)
|
||||
curl [S.xl xLeftStem] [Math.min [S.yt (XH - FHook)] [S.yp 0 CAP 0.5]]
|
||||
corner [S.xl xExt] [Math.min yMidStrokeStart ([S.yb 0] + LbFootRise)]
|
||||
g2c.right.end (Middle - DecoSizeX) [S.yb 0]
|
||||
corner Middle ([S.yb 0] + DecoSizeY)
|
||||
|
||||
# Middle and right stroke
|
||||
include : fraktur-stroke S
|
||||
g2 xMidStrokeStart yMidStrokeStart
|
||||
corner xMidStrokeTop yMidStrokeTop
|
||||
g2.down.mid [S.xr RightSB] [S.yp Descender(XH - FHook) 0.75]
|
||||
~~~ [alsoThru.g2 0.5 0.5]
|
||||
g2.down.mid [S.xp xLeftStem RightSB 0.75] [S.yp Descender(XH - FHook) 0.25]
|
||||
g2 [S.xr RightSB] [S.yb Descender]
|
||||
|
||||
do "I, J"
|
||||
define [IJTopStroke] : glyph-proc
|
||||
include : fraktur-stroke S
|
||||
g2.ld.start [S.xr RightSB] [S.yt CAP]
|
||||
~~~ [Wave.h]
|
||||
g2.ld.end [S.xl SB] (pre@ <-> Wave.DepthY) [change-profile F]
|
||||
~~~ [Wave.vc (-Wave.DepthX)]
|
||||
g2.ld.end pre@ (CAP * 0.625 - 2 * F.thick)
|
||||
|
||||
create-glyph "frak/I" 0x2111 : glyph-proc
|
||||
include : MarkSet.capital
|
||||
include : IJTopStroke
|
||||
|
||||
local iBox : S.box CAP 0 SB RightSB
|
||||
include : fraktur-stroke S
|
||||
g2.ld.start iBox.right iBox.top
|
||||
g4 [iBox.xp 0.7] [mix@ 0.375]
|
||||
g4 iBox.right (post@ <+> ArchDepthA)
|
||||
hookend (sw -- S.thick) iBox.bot
|
||||
g2 iBox.left (pre@ <+> SHook)
|
||||
|
||||
create-glyph "frak/J" 0x1D50D : glyph-proc
|
||||
include : MarkSet.capDesc
|
||||
include : IJTopStroke
|
||||
|
||||
local jBox : S.box [S.yt (CAP - 1.5 * Wave.DepthY - 2 * S.thick)] Descender SB RightSB
|
||||
include : fraktur-stroke S
|
||||
g4 [T.connR S jBox.right] (post@ <-> FHook) [change-profile T]
|
||||
hookstart (sw -- S.thick) [T.connT S jBox.top]
|
||||
g4 ([jBox.xp 0.6] - S.thick) (pre@ <-> 0.6 * ArchDepthA) [change-profile S]
|
||||
g4 jBox.right (post@ <+> ArchDepthA)
|
||||
hookend (sw -- S.thick) jBox.bot
|
||||
g2 jBox.left (pre@ <+> SHook)
|
||||
|
||||
create-glyph "frak/R" 0x211C : glyph-proc
|
||||
include : MarkSet.capital
|
||||
|
||||
local xExt : mix 0 SB 0.25
|
||||
local xLeftStem : Math.max (xExt + 1.5 * DecoSizeX) [mix SB RightSB 0.166]
|
||||
local ltHook : 0.25 * Hook
|
||||
local ada : 0.6 * ArchDepthA
|
||||
local adb : 0.6 * ArchDepthB
|
||||
|
||||
# Deocration at top-left
|
||||
# include : LtDecorativeWave [S.xl xExt] [S.yt (CAP - Wave.DepthY)] (CAP * 0.625)
|
||||
|
||||
local xMidStrokeL : S.xl xLeftStem
|
||||
local xMidStrokeR : S.xp xLeftStem RightSB 0.625
|
||||
local yMidStrokeR : S.yp 0 CAP 0.55
|
||||
local yMidStrokeL : yMidStrokeR - SlopeA * (xMidStrokeR - xMidStrokeL)
|
||||
|
||||
local xArchStart xMidStrokeL
|
||||
local xArchTop xMidStrokeR
|
||||
local yArchTop : S.yt CAP
|
||||
local yArchStart : yArchTop - SlopeA * (xArchTop - xArchStart)
|
||||
|
||||
# Left stroke
|
||||
include : fraktur-stroke F
|
||||
g2.ru.start post@ (CAP * 0.625 - 2 * F.thick)
|
||||
~~~ [Wave.vc Wave.DepthX]
|
||||
g2.ru.start [S.xl xExt] (post@ <-> ltHook) [change-profile S]
|
||||
arch.rhs (blendPre -- null) [S.yt CAP] 0.625
|
||||
flat [S.xl xLeftStem] [Math.max ([S.yb CAP] - ada) yArchStart]
|
||||
curl (pre@ <+> 0) yMidStrokeL
|
||||
corner [S.xl xExt] (post@ <+> LbFootRise)
|
||||
g2c.right.end (post@ <-> DecoSizeX) [S.yb 0]
|
||||
corner Middle (pre@ <+> DecoSizeY)
|
||||
|
||||
# Top-right arch
|
||||
include : fraktur-stroke S
|
||||
flat xArchStart yArchStart
|
||||
corner xArchTop yArchTop
|
||||
g2.down.mid [S.xr RightSB] [mix@ 0.5]
|
||||
flat xMidStrokeR yMidStrokeR
|
||||
curl xMidStrokeL yMidStrokeL
|
||||
|
||||
local xLegStart : mix xMidStrokeL xMidStrokeR 0.75
|
||||
local yLegStart : mix yMidStrokeL yMidStrokeR 0.75
|
||||
local xLegEnd RightSB
|
||||
local yLegEnd : S.yb 0
|
||||
|
||||
# Leg
|
||||
include : fraktur-stroke S
|
||||
[g2.sr SlopeA].start xLegStart yLegStart
|
||||
flat [mix@ 0.75] (pre@ <-> adb)
|
||||
decor@ : curl pre@ (post@ <+> ada)
|
||||
corner xLegEnd yLegEnd
|
||||
corner (pre@ <+> DecoSizeX) (pre@ <+> DecoSizeY)
|
||||
|
||||
create-glyph "frak/Z" 0x2128 : glyph-proc
|
||||
include : MarkSet.capital
|
||||
|
||||
local zBox : S.box CAP 0 SB RightSB
|
||||
|
||||
# Top Stroke
|
||||
include : fraktur-stroke S
|
||||
g2.ld.start zBox.right zBox.top
|
||||
~~~ [Wave.h]
|
||||
g2.ld.mid zBox.left (pre@ <-> Wave.DepthY)
|
||||
|
||||
# Bottom Stroke
|
||||
local diag : list
|
||||
corner zBox.right zBox.top
|
||||
corner [zBox.xp 0.166] [zBox.yp 0.5]
|
||||
include : fraktur-stroke S diag
|
||||
include : difference
|
||||
fraktur-stroke S
|
||||
g2.ru.start diag.1.x diag.1.y
|
||||
~~~ [arch.rhs [zBox.yp 0.55] 0.375 (sw -- S.thick)]
|
||||
g2.down.mid zBox.right (post@ <+> ArchDepthA)
|
||||
hookend zBox.bot (sw -- S.thick)
|
||||
g2 zBox.left (pre@ <+> SHook)
|
||||
MaskAboveLine diag.0.x diag.0.y diag.1.x diag.1.y 4
|
||||
|
||||
|
||||
create-glyph "frak/e" 0xAB32 : glyph-proc
|
||||
include : MarkSet.e
|
||||
local eBox : S.box XH 0 SB RightSB
|
||||
include : fraktur-stroke S
|
||||
corner (eBox.left + S.thick) [post@slope SlopeA]
|
||||
g2 eBox.xMid [eBox.yp DesignParameters.eBarPos]
|
||||
corner eBox.right [pre@slope SlopeA]
|
||||
corner [eBox.xp PHexTop] eBox.top
|
||||
corner eBox.left [pre@slope SlopeA]
|
||||
curl pre@ (post@ <+> ArchDepthB)
|
||||
[g2c.sr (-SlopeA)].end [eBox.xp PHexTop] eBox.bot
|
||||
corner eBox.right [pre@slope SlopeA]
|
||||
|
||||
alias 'mathFrak/e' 0x1D522 'frak/e'
|
||||
|
||||
create-glyph "frak/o" 0xAB3D : glyph-proc
|
||||
include : MarkSet.e
|
||||
local oBox : S.box XH 0 SB RightSB
|
||||
include : fraktur-stroke S
|
||||
[cg2.sr SlopeB].start [oBox.xp PHexTop] oBox.top
|
||||
g2.down.mid oBox.right [mix@ 0.5]
|
||||
[g2c.sl SlopeA].start [oBox.xp PHexBot] oBox.bot
|
||||
corner oBox.left [pre@slope SlopeB]
|
||||
corner pre@ [post@slope SlopeA]
|
||||
close
|
||||
|
||||
alias 'mathFrak/o' 0x1D52C 'frak/o'
|
||||
export : define [apply] : begin
|
||||
define $$Capture$$ this
|
||||
run-glyph-module "./fraktur/common.mjs"
|
||||
|
||||
run-glyph-module "./fraktur/upper-a.mjs"
|
||||
run-glyph-module "./fraktur/upper-ceg.mjs"
|
||||
run-glyph-module "./fraktur/upper-hkr.mjs"
|
||||
run-glyph-module "./fraktur/upper-ij.mjs"
|
||||
run-glyph-module "./fraktur/upper-z.mjs"
|
||||
|
||||
run-glyph-module "./fraktur/lower-e.mjs"
|
||||
run-glyph-module "./fraktur/lower-o.mjs"
|
||||
|
|
140
packages/font-glyphs/src/letter-like/fraktur/common.ptl
Normal file
140
packages/font-glyphs/src/letter-like/fraktur/common.ptl
Normal file
|
@ -0,0 +1,140 @@
|
|||
$$include '../../meta/macros.ptl'
|
||||
|
||||
import [mix fallback] from "@iosevka/util"
|
||||
import [SpiroPenGeometry] from "@iosevka/geometry"
|
||||
import [Vec2] from "@iosevka/geometry/point"
|
||||
import [Box] from "@iosevka/geometry/box"
|
||||
import [Interpolator] from "@iosevka/geometry/spiro-control"
|
||||
import [PenKnotCollector] from "@iosevka/geometry/spiro-pen-expand"
|
||||
|
||||
glyph-module
|
||||
|
||||
glyph-block LetterLike-Fraktur-Common : begin
|
||||
|
||||
# [fraktur-stroke profile ...] will construct a Fraktur stroke from a pen profile and a list
|
||||
# of control knots. The knots will form a (usually open) spiro path, then the result will be
|
||||
# the area that the pen tip covers when moving along the path.
|
||||
glyph-block-export fraktur-stroke
|
||||
define [fraktur-stroke profile __knots] : begin
|
||||
local knots : {}.slice.call arguments 1
|
||||
return : new FrakturImpl profile knots
|
||||
|
||||
class FrakturProxy
|
||||
public [new gizmo profile collector] : begin
|
||||
set this.gizmo gizmo
|
||||
set this.knots collector.knots
|
||||
|
||||
set this.geometry : new SpiroPenGeometry
|
||||
begin gizmo
|
||||
begin profile
|
||||
begin collector.closed
|
||||
begin collector.knots
|
||||
|
||||
public [first i] this.knots.[fallback i 0]
|
||||
public [last i] this.knots.(this.knots.length - [fallback i 1])
|
||||
|
||||
class FrakturImpl
|
||||
public [new profile knots] : begin
|
||||
this.profile = profile
|
||||
this.knots = knots
|
||||
|
||||
public [applyToGlyph glyph] : begin
|
||||
local defaultProfile : this.profile.getPenShape glyph.gizmo
|
||||
local collector : new PenKnotCollector glyph.gizmo defaultProfile
|
||||
local c : spiro-collect collector this.knots
|
||||
|
||||
local proxy : new FrakturProxy glyph.gizmo defaultProfile collector
|
||||
glyph.includeGeometry proxy.geometry
|
||||
return proxy
|
||||
|
||||
# Directive to change the profile
|
||||
glyph-block-export change-profile
|
||||
define [change-profile newProfile] : function : begin
|
||||
this.setProfile : newProfile.getPenShape this.gizmo
|
||||
|
||||
# A pen profile describes a virtual flat-tip pen. We use a 45-degree arrangement to
|
||||
# simplify the math.
|
||||
class FrakturProfile
|
||||
public [new thick thin] : begin
|
||||
# .thick is the half length of the flat tip, projected to the X/Y axis
|
||||
this.thick = 0.25 * [Math.sqrt 2] * thick
|
||||
# .thin is the half width of the thin tip, projected to the X/Y axis
|
||||
this.thin = 0.25 * [Math.sqrt 2] * thin
|
||||
|
||||
public [getPenShape gizmo] : begin
|
||||
local thickTf : gizmo.applyOffsetXY this.thick this.thick
|
||||
list
|
||||
new Vec2 (thickTf.x - this.thin) (thickTf.y + this.thin)
|
||||
new Vec2 (thickTf.x + this.thin) (thickTf.y + this.thin)
|
||||
new Vec2 (thickTf.x + this.thin) (thickTf.y - this.thin)
|
||||
new Vec2 (-thickTf.x + this.thin) (-thickTf.y - this.thin)
|
||||
new Vec2 (-thickTf.x - this.thin) (-thickTf.y - this.thin)
|
||||
new Vec2 (-thickTf.x - this.thin) (-thickTf.y + this.thin)
|
||||
|
||||
public [box u d l r] : new Box [this.yt u] [this.yb d] [this.xl l] [this.xr r]
|
||||
|
||||
public [xl x] : x + this.thick
|
||||
public [xr x] : x - this.thick
|
||||
public [xp l r p] : mix [this.xl l] [this.xr r] p
|
||||
|
||||
public [yb y] : y + this.thick
|
||||
public [yt y] : y - this.thick
|
||||
public [yp b t p] : mix [this.yb b] [this.yt t] p
|
||||
|
||||
# Connection to another profile's pen tip position
|
||||
public [connL otherProfile x] : x - otherProfile.thick + this.thick
|
||||
public [connR otherProfile x] : x + otherProfile.thick - this.thick
|
||||
public [connB otherProfile y] : y - otherProfile.thick + this.thick
|
||||
public [connT otherProfile y] : y + otherProfile.thick - this.thick
|
||||
|
||||
# Stroke widths
|
||||
define frakThin : 1.0 * [AdviceStroke 12]
|
||||
define frakThick : 1.0 * Stroke
|
||||
define frakFine : 1.0 * [AdviceStroke 4] # For decoration
|
||||
|
||||
glyph-block-export S
|
||||
define S : new FrakturProfile frakThick (0.875 * frakThin)
|
||||
|
||||
glyph-block-export F
|
||||
define F : new FrakturProfile frakFine (0.875 * frakThin)
|
||||
|
||||
glyph-block-export T
|
||||
define T : new FrakturProfile frakThin (0.875 * frakThin)
|
||||
|
||||
# Key metrics
|
||||
glyph-block-export DecoSizeX DecoSizeY FHook Wave.DepthY Wave.DepthX LbFootRise
|
||||
define DecoSizeX : 0.15 * (RightSB - SB)
|
||||
define DecoSizeY : 0.08 * (RightSB - SB)
|
||||
define FHook : 0.4 * SHook - 0.25 * S.thick
|
||||
define LbFootRise : 0.375 * SHook + 0.375 * S.thick
|
||||
|
||||
glyph-block-export SlopeA SlopeB
|
||||
define SlopeA : 0.875 * DecoSizeY / DecoSizeX
|
||||
define SlopeB : 0.875 * -[mix SlopeA 1.0 0.5]
|
||||
|
||||
# Wave blenders
|
||||
glyph-block-export Wave
|
||||
define Wave : namespace
|
||||
export : define DepthY : 0.4 * SHook - 0.25 * S.thick
|
||||
export : define DepthX : 1 * DecoSizeX
|
||||
|
||||
export : define [vc waveDepth] : Interpolator vcWaveBlender [object waveDepth]
|
||||
define [vcWaveBlender before after args] : begin
|
||||
local [object waveDepth] args
|
||||
return : list
|
||||
g2 (before.x + 0.5 * waveDepth) [mix before.y after.y 0.375]
|
||||
g2 (after.x - 0.5 * waveDepth) [mix before.y after.y 0.625]
|
||||
|
||||
export : define [h] : Interpolator hWaveBlender [object h]
|
||||
define [hWaveBlender before after] : begin
|
||||
return : list
|
||||
g2 [mix before.x after.x 0.375] after.y
|
||||
g2 [mix before.x after.x 0.625] before.y
|
||||
|
||||
glyph-block-export PHexTop
|
||||
define PHexTop : 0.5 + 0.5 * ([Math.max DecoSizeX frakThin] / (RightSB - SB))
|
||||
glyph-block-export PHexBot
|
||||
define PHexBot : 1 - PHexTop
|
||||
|
||||
glyph-block-export FrakDf
|
||||
define [FrakDf div m] : DivFrame [fallback div 1] [fallback m 2] [Math.max 1 : DecoSizeX / SB]
|
27
packages/font-glyphs/src/letter-like/fraktur/lower-e.ptl
Normal file
27
packages/font-glyphs/src/letter-like/fraktur/lower-e.ptl
Normal file
|
@ -0,0 +1,27 @@
|
|||
$$include '../../meta/macros.ptl'
|
||||
|
||||
glyph-module
|
||||
|
||||
glyph-block LetterLike-Fraktur-Lower-E : begin
|
||||
glyph-block-import Common-Derivatives
|
||||
glyph-block-import CommonShapes
|
||||
glyph-block-import LetterLike-Fraktur-Common : FrakDf S F T fraktur-stroke change-profile
|
||||
glyph-block-import LetterLike-Fraktur-Common : DecoSizeX DecoSizeY SlopeA SlopeB
|
||||
glyph-block-import LetterLike-Fraktur-Common : Wave LbFootRise FHook PHexTop PHexBot
|
||||
|
||||
create-glyph "frak/e" 0xAB32 : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.e
|
||||
|
||||
local eBox : S.box XH 0 df.leftSB df.rightSB
|
||||
include : fraktur-stroke S
|
||||
corner (eBox.left + S.thick) [post@slope SlopeA]
|
||||
g2 eBox.xMid [eBox.yp DesignParameters.eBarPos]
|
||||
corner eBox.right [pre@slope SlopeA]
|
||||
corner [eBox.xp PHexTop] eBox.top
|
||||
corner eBox.left [pre@slope SlopeA]
|
||||
curl pre@ (post@ <+> ArchDepthB)
|
||||
[g2c.sr (-SlopeA)].end [eBox.xp PHexTop] eBox.bot
|
||||
corner eBox.right [pre@slope SlopeA]
|
||||
|
||||
alias 'mathFrak/e' 0x1D522 'frak/e'
|
25
packages/font-glyphs/src/letter-like/fraktur/lower-o.ptl
Normal file
25
packages/font-glyphs/src/letter-like/fraktur/lower-o.ptl
Normal file
|
@ -0,0 +1,25 @@
|
|||
$$include '../../meta/macros.ptl'
|
||||
|
||||
glyph-module
|
||||
|
||||
glyph-block LetterLike-Fraktur-Lower-O : begin
|
||||
glyph-block-import Common-Derivatives
|
||||
glyph-block-import CommonShapes
|
||||
glyph-block-import LetterLike-Fraktur-Common : FrakDf S F T fraktur-stroke change-profile
|
||||
glyph-block-import LetterLike-Fraktur-Common : DecoSizeX DecoSizeY SlopeA SlopeB
|
||||
glyph-block-import LetterLike-Fraktur-Common : Wave LbFootRise FHook PHexTop PHexBot
|
||||
|
||||
create-glyph "frak/o" 0xAB3D : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.e
|
||||
|
||||
local oBox : S.box XH 0 df.leftSB df.rightSB
|
||||
include : fraktur-stroke S
|
||||
[cg2.sr SlopeB].start [oBox.xp PHexTop] oBox.top
|
||||
g2.down.mid oBox.right [mix@ 0.5]
|
||||
[g2c.sl SlopeA].start [oBox.xp PHexBot] oBox.bot
|
||||
corner oBox.left [pre@slope SlopeB]
|
||||
corner pre@ [post@slope SlopeA]
|
||||
close
|
||||
|
||||
alias 'mathFrak/o' 0x1D52C 'frak/o'
|
35
packages/font-glyphs/src/letter-like/fraktur/upper-a.ptl
Normal file
35
packages/font-glyphs/src/letter-like/fraktur/upper-a.ptl
Normal file
|
@ -0,0 +1,35 @@
|
|||
$$include '../../meta/macros.ptl'
|
||||
|
||||
import [mix fallback] from "@iosevka/util"
|
||||
|
||||
glyph-module
|
||||
|
||||
glyph-block LetterLike-Fraktur-Upper-A : begin
|
||||
glyph-block-import Common-Derivatives
|
||||
glyph-block-import CommonShapes
|
||||
glyph-block-import LetterLike-Fraktur-Common : FrakDf S F T fraktur-stroke change-profile
|
||||
glyph-block-import LetterLike-Fraktur-Common : DecoSizeX DecoSizeY SlopeA SlopeB
|
||||
glyph-block-import LetterLike-Fraktur-Common : Wave LbFootRise FHook PHexTop PHexBot
|
||||
|
||||
create-glyph 'frak/A' 0x1D504 : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.capital
|
||||
|
||||
local aBox : S.box CAP 0 df.leftSB df.rightSB
|
||||
|
||||
include : fraktur-stroke S
|
||||
g2.ru.start (post@) ([aBox.yp 0.625] - 2 * F.thick) [change-profile F]
|
||||
~~~ [Wave.vc Wave.DepthX]
|
||||
g2.ru.mid aBox.left (post@ <-> DecoSizeY) [change-profile S]
|
||||
arch.rhs (sw -- S.thick) (blendPre -- null) aBox.top 0.4
|
||||
straight.down.mid [aBox.xp 0.5] [mix@ 0.375]
|
||||
[flatc.sl SlopeA].end (aBox.left - 0.25 * DecoSizeX) [post@slope SlopeB]
|
||||
corner [aBox.xp PHexBot] aBox.bot
|
||||
corner aBox.right [pre@slope SlopeA]
|
||||
|
||||
include : fraktur-stroke S
|
||||
flat aBox.right aBox.top
|
||||
curl pre@ [post@slope : 2 * SlopeB]
|
||||
[flatc.sr SlopeB].end (pre@ <+> 0.5 * DecoSizeX) aBox.bot
|
||||
corner (pre@ <+> DecoSizeX) (pre@ <+> DecoSizeY)
|
||||
# g2.ld.mid aBox.left (pre@ <-> Wave.DepthY)
|
92
packages/font-glyphs/src/letter-like/fraktur/upper-ceg.ptl
Normal file
92
packages/font-glyphs/src/letter-like/fraktur/upper-ceg.ptl
Normal file
|
@ -0,0 +1,92 @@
|
|||
$$include '../../meta/macros.ptl'
|
||||
|
||||
import [mix fallback] from "@iosevka/util"
|
||||
|
||||
glyph-module
|
||||
|
||||
glyph-block LetterLike-Fraktur-Upper-CEG : begin
|
||||
glyph-block-import Common-Derivatives
|
||||
glyph-block-import CommonShapes
|
||||
glyph-block-import LetterLike-Fraktur-Common : FrakDf S F T fraktur-stroke change-profile
|
||||
glyph-block-import LetterLike-Fraktur-Common : DecoSizeX DecoSizeY SlopeA SlopeB
|
||||
glyph-block-import LetterLike-Fraktur-Common : Wave LbFootRise FHook PHexTop PHexBot
|
||||
|
||||
|
||||
define flex-params [FrakCTopAndCenterStroke] : glyph-proc
|
||||
local-parameter df
|
||||
local-parameter : top -- [S.yt CAP]
|
||||
local-parameter : bot -- [S.yp 0 CAP 0.375]
|
||||
local-parameter : left -- [S.xl df.leftSB]
|
||||
local-parameter : right -- [S.xr df.rightSB]
|
||||
|
||||
local xCenter : [mix left right 0.5] + 0.25 * F.thick
|
||||
local deco : Math.max DecoSizeX (0.5 * ArchDepthA - 2 * S.thick)
|
||||
local waveTop : top - deco
|
||||
|
||||
# Top-right stroke
|
||||
include : fraktur-stroke S
|
||||
g2 right top
|
||||
g2.left.mid [mix@ 0.5] (top - 0.5 * FHook)
|
||||
corner (post@ <+> deco) top
|
||||
corner xCenter (top - deco)
|
||||
|
||||
# Inner decoration
|
||||
include : fraktur-stroke F
|
||||
g2.ld.start [F.connL S xCenter] [F.connB S : top - deco]
|
||||
~~~ [Wave.vc (-Wave.DepthX)]
|
||||
g2.ld.end pre@ bot
|
||||
|
||||
return : object xCenter [waveTop : top - deco] [waveBot bot]
|
||||
|
||||
define flex-params [FrakCOutlineShape] : glyph-proc
|
||||
local-parameter df
|
||||
local-parameter : mode -- 'C'
|
||||
local-parameter : top -- [S.yt CAP]
|
||||
local-parameter : bot -- [S.yb 0]
|
||||
local-parameter : left -- [S.xl df.leftSB]
|
||||
local-parameter : right -- [S.xr df.rightSB]
|
||||
|
||||
local [object xCenter waveTop waveBot] : include : FrakCTopAndCenterStroke df
|
||||
bot -- ([mix bot top 0.1] + 2 * Wave.DepthY + 0.5 * S.thick)
|
||||
|
||||
# Left and bottom stroke
|
||||
include : fraktur-stroke S
|
||||
g4.ru.start [T.connL S xCenter] [T.connB S waveTop] [change-profile T]
|
||||
arch.rhs [T.connT S top] (sw -- T.thick) (anglePre -- (-45)) (anglePost -- 0)
|
||||
flat left (pre@ <-> 0.6 * ArchDepthA) [change-profile S]
|
||||
curl pre@ (post@ <+> ArchDepthB)
|
||||
match mode
|
||||
: [Just 'C'] : list # C and E
|
||||
hookend (sw -- S.thick) bot
|
||||
g2 [T.connR S right] (pre@ <+> [T.connT S SHook]) [change-profile T]
|
||||
: [Just 'G'] : list # G
|
||||
arch.lhs (sw -- S.thick) bot
|
||||
flat right (pre@ <+> ArchDepthA)
|
||||
decor@ : curl pre@ (post@ <-> 0.5 * ArchDepthB)
|
||||
decor@@ : g2 [post@tang-out 1] [post@tang-out SlopeB]
|
||||
decor@ : corner [mix@rev PHexTop] [post@slope SlopeA]
|
||||
decor@ : corner xCenter [mix waveTop waveBot 0.5]
|
||||
|
||||
return : object xCenter waveTop waveBot
|
||||
|
||||
create-glyph "frak/C" 0x212D : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.capital
|
||||
|
||||
include : FrakCOutlineShape df (mode -- 'C')
|
||||
|
||||
create-glyph "frak/E" 0x1D508 : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.capital
|
||||
|
||||
local [object xCenter waveTop waveBot] : include : FrakCOutlineShape df (mode -- 'C')
|
||||
|
||||
include : fraktur-stroke F
|
||||
corner [F.connL S xCenter] [F.connB S : mix waveTop waveBot 0.5]
|
||||
corner (post@ <-> 0.5 * DecoSizeX) [pre@slope SlopeA]
|
||||
corner [F.xr df.rightSB] (pre@ <-> 0.5 * DecoSizeY)
|
||||
|
||||
create-glyph "frak/G" 0x1D50A : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.capital
|
||||
include : FrakCOutlineShape df (mode -- 'G')
|
102
packages/font-glyphs/src/letter-like/fraktur/upper-hkr.ptl
Normal file
102
packages/font-glyphs/src/letter-like/fraktur/upper-hkr.ptl
Normal file
|
@ -0,0 +1,102 @@
|
|||
$$include '../../meta/macros.ptl'
|
||||
|
||||
import [mix fallback] from "@iosevka/util"
|
||||
|
||||
glyph-module
|
||||
|
||||
glyph-block LetterLike-Fraktur-Upper-HKR : begin
|
||||
glyph-block-import Common-Derivatives
|
||||
glyph-block-import CommonShapes
|
||||
glyph-block-import LetterLike-Fraktur-Common : FrakDf S F T fraktur-stroke change-profile
|
||||
glyph-block-import LetterLike-Fraktur-Common : DecoSizeX DecoSizeY SlopeA SlopeB
|
||||
glyph-block-import LetterLike-Fraktur-Common : Wave LbFootRise FHook PHexTop PHexBot
|
||||
|
||||
define [HOuterShape bBody bDeco yConnT yConnB] : fraktur-stroke S
|
||||
g2 bBody.right (post@ <-> FHook)
|
||||
arch.lhs bBody.top (sw -- S.thick) (blendPre -- {})
|
||||
~~~ [corner (post@ <-> 0.5 * DecoSizeX) [post@slope SlopeB]]
|
||||
corner bBody.left [max@ yConnT (pre@ <-> 0.75 * ArchDepthA)]
|
||||
curl pre@ [min@ yConnB (post@ <+> ArchDepthA)]
|
||||
corner bDeco.left (post@ <+> 2 * DecoSizeY)
|
||||
g2c.r.end (post@ <-> DecoSizeX) bBody.bot
|
||||
corner bBody.xMid (pre@ <+> DecoSizeY)
|
||||
|
||||
define [KRLegs box] : glyph-proc
|
||||
# Top-right arch
|
||||
local c : include : fraktur-stroke S
|
||||
flat box.left [post@slope SlopeA]
|
||||
corner [box.xp PHexTop] box.top
|
||||
g2.down.mid box.right [mix@ 0.5]
|
||||
flat [box.xp 0.625] [box.yp 0.55]
|
||||
curl box.left [pre@slope SlopeA]
|
||||
|
||||
|
||||
local xLegStart : mix [c.last 1].x [c.last 2].x 0.75
|
||||
local yLegStart : mix [c.last 1].y [c.last 2].y 0.75
|
||||
|
||||
# Leg
|
||||
include : fraktur-stroke S
|
||||
[g2.sr SlopeA].start xLegStart yLegStart
|
||||
flat [mix@ 0.75] (pre@ <-> 0.6 * ArchDepthB)
|
||||
decor@ : curl pre@ (post@ <+> 2 * DecoSizeY)
|
||||
corner (box.right + 0.5 * DecoSizeX) box.bot
|
||||
corner (pre@ <+> DecoSizeX) (pre@ <+> DecoSizeY)
|
||||
|
||||
return : object [yConnT [c.first].y] [yConnB [c.last].y]
|
||||
|
||||
create-glyph "frak/H" 0x210C : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.capDesc
|
||||
|
||||
local hBox : S.box CAP 0 df.leftSB df.rightSB
|
||||
local hDeco : hBox.padLeft (-0.25 * DecoSizeX) # top-left decoration ref box
|
||||
local hBody : hBox.padLeft (+0.75 * DecoSizeX) # body ref box
|
||||
local hInner : [hBody.withTop : hBody.yp 0.6].withBottom Descender
|
||||
|
||||
# Inner stroke
|
||||
local c : include : fraktur-stroke S
|
||||
corner hInner.left [post@slope SlopeA]
|
||||
corner [hInner.xp PHexTop] hInner.top
|
||||
g2.down.mid hInner.right [hInner.yp 0.75]
|
||||
~~~ [alsoThru.g2 0.5 0.5]
|
||||
g2.down.mid [hInner.xp 0.75] [hInner.yp 0.25]
|
||||
g2 hInner.right hInner.bot
|
||||
|
||||
# Top and left stroke
|
||||
include : HOuterShape hBody hDeco (-VERY-FAR) [c.first].y
|
||||
|
||||
create-glyph "frak/K" 0x1D50E : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.capital
|
||||
|
||||
local kBox : S.box CAP 0 df.leftSB df.rightSB
|
||||
local kDeco : kBox.padLeft (-0.25 * DecoSizeX) # top-left decoration ref box
|
||||
local kBody : kBox.padLeft (+0.75 * DecoSizeX) # body ref box
|
||||
local kInner : kBody.withTop : Math.min [kBody.yp 0.75] (kBody.top - FHook - Wave.DepthY - S.thick)
|
||||
|
||||
local leg : include : KRLegs kInner
|
||||
|
||||
include : HOuterShape kBody kDeco leg.yConnT leg.yConnB
|
||||
|
||||
create-glyph "frak/R" 0x211C : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.capital
|
||||
|
||||
local rBox : S.box CAP 0 df.leftSB df.rightSB
|
||||
local rDeco : rBox.padLeft (-0.25 * DecoSizeX) # top-left decoration ref box
|
||||
local rBody : rBox.padLeft (+1.50 * DecoSizeX) # body ref box
|
||||
|
||||
# Legs
|
||||
local leg : include : KRLegs rBody
|
||||
|
||||
# Left stroke
|
||||
include : fraktur-stroke F
|
||||
g2.ru.start post@ ([rDeco.yp 0.625] - 2 * F.thick)
|
||||
~~~ [Wave.vc Wave.DepthX]
|
||||
g2.ru.mid rDeco.left (post@ <-> DecoSizeY) [change-profile S]
|
||||
arch.rhs (blendPre -- {}) rBody.top 0.625
|
||||
flat rBody.left (pre@ <-> 0.6 * ArchDepthA)
|
||||
curl (pre@ <+> 0) leg.yConnB
|
||||
corner rDeco.left (post@ <+> 2 * DecoSizeY)
|
||||
g2c.right.end (post@ <-> DecoSizeX) [S.yb 0]
|
||||
corner [rBody.xp 0.5] (pre@ <+> DecoSizeY)
|
46
packages/font-glyphs/src/letter-like/fraktur/upper-ij.ptl
Normal file
46
packages/font-glyphs/src/letter-like/fraktur/upper-ij.ptl
Normal file
|
@ -0,0 +1,46 @@
|
|||
$$include '../../meta/macros.ptl'
|
||||
|
||||
glyph-module
|
||||
|
||||
glyph-block LetterLike-Fraktur-Upper-IJ : begin
|
||||
glyph-block-import Common-Derivatives
|
||||
glyph-block-import CommonShapes
|
||||
glyph-block-import LetterLike-Fraktur-Common : FrakDf S F T fraktur-stroke change-profile
|
||||
glyph-block-import LetterLike-Fraktur-Common : DecoSizeX DecoSizeY SlopeA SlopeB
|
||||
glyph-block-import LetterLike-Fraktur-Common : Wave LbFootRise FHook PHexTop PHexBot
|
||||
|
||||
define [TopStroke df] : glyph-proc
|
||||
local iBox : S.box CAP 0 df.leftSB df.rightSB
|
||||
include : fraktur-stroke S
|
||||
g2.ld.start iBox.right iBox.top
|
||||
~~~ [Wave.h]
|
||||
g2.ld.end iBox.left (pre@ <-> Wave.DepthY) [change-profile F]
|
||||
~~~ [Wave.vc (-Wave.DepthX)]
|
||||
g2.ld.end pre@ ([iBox.yp 0.625] - 2 * F.thick)
|
||||
|
||||
define [BottomStroke df bot archScalar] : glyph-proc
|
||||
local gap : 2.5 * Wave.DepthY + 1 * S.thick
|
||||
local jBox : S.box [S.yt (CAP - gap)] bot df.leftSB df.rightSB
|
||||
local ada1 : 0.6 * archScalar * ArchDepthA
|
||||
local ada2 : archScalar * ArchDepthA
|
||||
include : fraktur-stroke S
|
||||
g4 [T.connR S jBox.right] (post@ <-> FHook) [change-profile T]
|
||||
hookstart (sw -- S.thick) [T.connT S jBox.top]
|
||||
g4 ([jBox.xp 0.6] - S.thick) (jBox.top - ada1) [change-profile S]
|
||||
g4 jBox.right (jBox.bot + ada2)
|
||||
hookend (sw -- S.thick) jBox.bot
|
||||
g2 jBox.left (pre@ <+> SHook)
|
||||
|
||||
create-glyph "frak/I" 0x2111 : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.capital
|
||||
|
||||
include : TopStroke df
|
||||
include : BottomStroke df 0 0.75
|
||||
|
||||
create-glyph "frak/J" 0x1D50D : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.capDesc
|
||||
|
||||
include : TopStroke df
|
||||
include : BottomStroke df Descender 1
|
36
packages/font-glyphs/src/letter-like/fraktur/upper-z.ptl
Normal file
36
packages/font-glyphs/src/letter-like/fraktur/upper-z.ptl
Normal file
|
@ -0,0 +1,36 @@
|
|||
$$include '../../meta/macros.ptl'
|
||||
|
||||
glyph-module
|
||||
|
||||
glyph-block LetterLike-Fraktur-Upper-Z : begin
|
||||
glyph-block-import Common-Derivatives
|
||||
glyph-block-import CommonShapes
|
||||
glyph-block-import LetterLike-Fraktur-Common : FrakDf S F T fraktur-stroke change-profile
|
||||
glyph-block-import LetterLike-Fraktur-Common : DecoSizeX DecoSizeY SlopeA SlopeB
|
||||
glyph-block-import LetterLike-Fraktur-Common : Wave LbFootRise FHook PHexTop PHexBot
|
||||
|
||||
create-glyph "frak/Z" 0x2128 : glyph-proc
|
||||
local df : include : FrakDf 1
|
||||
include : df.markSet.capital
|
||||
|
||||
local zBox : S.box CAP 0 df.leftSB df.rightSB
|
||||
|
||||
# Top Stroke
|
||||
include : fraktur-stroke S
|
||||
g2.ld.start zBox.right zBox.top
|
||||
~~~ [Wave.h]
|
||||
g2.ld.mid zBox.left (pre@ <-> Wave.DepthY)
|
||||
|
||||
# Bottom Stroke
|
||||
local diag : include : fraktur-stroke S
|
||||
corner zBox.right zBox.top
|
||||
corner [zBox.xp 0.166] [zBox.yp 0.5]
|
||||
|
||||
include : difference
|
||||
fraktur-stroke S
|
||||
g2.ru.start [diag.last].x [diag.last].y
|
||||
~~~ [arch.rhs [zBox.yp 0.55] 0.375 (sw -- S.thick)]
|
||||
g2.down.mid zBox.right (post@ <+> ArchDepthA)
|
||||
hookend zBox.bot (sw -- S.thick)
|
||||
g2 zBox.left (pre@ <+> SHook)
|
||||
MaskAboveLine [diag.first].x [diag.first].y [diag.last].x [diag.last].y 4
|
|
@ -294,7 +294,7 @@ define-macro glyph-block : syntax-rules
|
|||
|
||||
define booleFnImports `[union intersection difference]
|
||||
|
||||
define drvCoordImports `[pre@ post@ mix@ mix@rev pre@slope post@slope
|
||||
define drvCoordImports `[pre@ post@ mix@ mix@rev pre@slope post@slope min@ max@
|
||||
decor@ decor@@ decor@@@ pre@tang-in post@tang-in pre@tang-out post@tang-out]
|
||||
|
||||
dirty `[$GlyphBlocks$.push : lambda [$Capture_Ext$] : begin \\
|
||||
|
|
|
@ -36,8 +36,11 @@ export function SetupBuilders(_bindings) {
|
|||
"pre@slope": (s, delta) => new CAtSlopePre(s, delta),
|
||||
"post@slope": (s, delta) => new CAtSlopePost(s, delta),
|
||||
|
||||
// Interpolators
|
||||
// Min and max derived coordinates
|
||||
"min@": (...args) => new CMathFold(Math.min, args),
|
||||
"max@": (...args) => new CMathFold(Math.max, args),
|
||||
|
||||
// Interpolators
|
||||
// decor@, decor@@, decor@@@: Add a "delay" to the thing inside when resolving the spiro
|
||||
// controls. This is a very useful utility for coordinate propagation, which allow us to
|
||||
// "skip" the current point and go to the next or previous point. The number of @'s
|
||||
|
@ -98,6 +101,54 @@ class CDeltaPost extends DerivedCoordinateBase {
|
|||
}
|
||||
}
|
||||
|
||||
class CMathFold extends DerivedCoordinateBase {
|
||||
constructor(operator, args) {
|
||||
super();
|
||||
this.operator = operator;
|
||||
this.args = args;
|
||||
}
|
||||
getDependencyForX() {
|
||||
let flag = 0;
|
||||
for (const item of this.args) {
|
||||
if (typeof item === "number") continue;
|
||||
flag |= item.getDependencyForX();
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
getDependencyForY() {
|
||||
let flag = 0;
|
||||
for (const item of this.args) {
|
||||
if (typeof item === "number") continue;
|
||||
flag |= item.getDependencyForY();
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
resolveX(pre, curr, post) {
|
||||
let result =
|
||||
typeof this.args[0] === "number"
|
||||
? this.args[0]
|
||||
: this.args[0].resolveX(pre, curr, post);
|
||||
for (let i = 1; i < this.args.length; i++) {
|
||||
const item = this.args[i];
|
||||
const value = typeof item === "number" ? item : item.resolveX(pre, curr, post);
|
||||
result = this.operator(result, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
resolveY(pre, curr, post) {
|
||||
let result =
|
||||
typeof this.args[0] === "number"
|
||||
? this.args[0]
|
||||
: this.args[0].resolveY(pre, curr, post);
|
||||
for (let i = 1; i < this.args.length; i++) {
|
||||
const item = this.args[i];
|
||||
const value = typeof item === "number" ? item : item.resolveY(pre, curr, post);
|
||||
result = this.operator(result, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export class CMixCoord extends DerivedCoordinateBase {
|
||||
constructor(proportion, delta, mockPre, mockPost) {
|
||||
super();
|
||||
|
|
|
@ -27,6 +27,20 @@ export class Box {
|
|||
withYPadding(d) {
|
||||
return new Box(this.top - d, this.bottom + d, this.left, this.right);
|
||||
}
|
||||
|
||||
padLeft(d) {
|
||||
return new Box(this.top, this.bottom, this.left + d, this.right);
|
||||
}
|
||||
padRight(d) {
|
||||
return new Box(this.top, this.bottom, this.left, this.right - d);
|
||||
}
|
||||
padTop(d) {
|
||||
return new Box(this.top - d, this.bottom, this.left, this.right);
|
||||
}
|
||||
padBottom(d) {
|
||||
return new Box(this.top, this.bottom + d, this.left, this.right);
|
||||
}
|
||||
|
||||
withXMix(pL, pR) {
|
||||
return new Box(
|
||||
this.top,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue