Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Fraktur B M N P V W #2452

Merged
merged 1 commit into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions changes/31.1.0.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
* Add separate variant selectors for Cyrillic Capital En/Er (`VXAA`, `VXAB`).
* Add variant selectors for Greek lower Beta/Gamma/Nu/Upsilon (`VXAC`, `VXAD`, `VXAE`, `VXAF`).
* Optimize glyph for VERTICAL LINE WITH MIDDLE DOT (`U+2327`).
* Improve `k` (`cv46`) and `x` (`cv58`) variants used by `ss03`, `ss08`, `ss09`, `ss10`, `ss12`, `ss14`, and `ss18` under slab italic.
* Add characters:
- BLACK-LETTER CAPITAL H (`U+210C`) (#714).
- BLACK-LETTER CAPITAL I (`U+2111`) (#714).
Expand All @@ -12,9 +8,19 @@
- LATIN SMALL LETTER BLACKLETTER O (`U+AB3D`) (#2443).
- LATIN SMALL LETTER BLACKLETTER O WITH STROKE (`U+AB3E`) (#2443).
- MATHEMATICAL FRAKTUR CAPITAL A (`U+1D504`) (#444).
- MATHEMATICAL FRAKTUR CAPITAL B (`U+1D505`) (#444).
- MATHEMATICAL FRAKTUR CAPITAL E (`U+1D508`) (#444).
- MATHEMATICAL FRAKTUR CAPITAL G (`U+1D50A`) (#444).
- MATHEMATICAL FRAKTUR CAPITAL J (`U+1D50D`) (#444).
- MATHEMATICAL FRAKTUR CAPITAL K (`U+1D50E`) (#444).
- MATHEMATICAL FRAKTUR CAPITAL M (`U+1D510`) (#444).
- MATHEMATICAL FRAKTUR CAPITAL N (`U+1D511`) (#444).
- MATHEMATICAL FRAKTUR CAPITAL P (`U+1D513`) (#444).
- MATHEMATICAL FRAKTUR CAPITAL V (`U+1D519`) (#444).
- MATHEMATICAL FRAKTUR CAPITAL W (`U+1D51A`) (#444).
- MATHEMATICAL FRAKTUR SMALL E (`U+1D522`) (#444).
- MATHEMATICAL FRAKTUR SMALL O (`U+1D52C`) (#444).
* Add separate variant selectors for Cyrillic Capital En/Er (`VXAA`, `VXAB`).
* Add variant selectors for Greek lower Beta/Gamma/Nu/Upsilon (`VXAC`, `VXAD`, `VXAE`, `VXAF`).
* Optimize glyph for VERTICAL LINE WITH MIDDLE DOT (`U+2327`).
* Improve `k` (`cv46`) and `x` (`cv58`) variants used by `ss03`, `ss08`, `ss09`, `ss10`, `ss12`, `ss14`, and `ss18` under slab italic.
2 changes: 2 additions & 0 deletions packages/font-glyphs/src/letter-like/fraktur.ptl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ export : define [apply] : begin
run-glyph-module "./fraktur/common.mjs"

run-glyph-module "./fraktur/upper-a.mjs"
run-glyph-module "./fraktur/upper-bvw.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-mnp.mjs"
run-glyph-module "./fraktur/upper-z.mjs"

run-glyph-module "./fraktur/lower-e.mjs"
Expand Down
44 changes: 36 additions & 8 deletions packages/font-glyphs/src/letter-like/fraktur/common.ptl
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,9 @@ glyph-block LetterLike-Fraktur-Common : begin
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 collector : new PenKnotCollector glyph.gizmo defaultProfile this.profile.fixed
local c : spiro-collect collector this.knots

local proxy : new FrakturProxy glyph.gizmo defaultProfile collector
Expand All @@ -56,6 +55,7 @@ glyph-block LetterLike-Fraktur-Common : begin
# simplify the math.
class FrakturProfile
public [new thick thin] : begin
this.fixed = false
# .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
Expand Down Expand Up @@ -92,15 +92,30 @@ glyph-block LetterLike-Fraktur-Common : begin
define frakThick : 1.0 * Stroke
define frakFine : 1.0 * [AdviceStroke 4] # For decoration

class MaskingProfile
public [new dx dy] : begin
this.fixed = true
this.dx = dx
this.dy = dy
public [getPenShape gizmo] : begin
local tf : gizmo.applyOffsetXY this.dx this.dy
list [new Vec2 0 0] [new Vec2 tf.x tf.y]

glyph-block-export S
define S : new FrakturProfile frakThick (0.875 * frakThin)

glyph-block-export M
define M : new FrakturProfile [AdviceStroke 3 para.diversityM] (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)

glyph-block-export CutMaskLeft
define CutMaskLeft : new MaskingProfile (-VERY-FAR) 0

# Key metrics
glyph-block-export DecoSizeX DecoSizeY FHook Wave.DepthY Wave.DepthX LbFootRise
define DecoSizeX : 0.15 * (RightSB - SB)
Expand All @@ -117,19 +132,32 @@ glyph-block LetterLike-Fraktur-Common : begin
define Wave : namespace
export : define DepthY : 0.4 * SHook - 0.25 * S.thick
export : define DepthX : 1 * DecoSizeX
export : define LTDecoSize : 0.75 * DecoSizeX

export : define [vc waveDepth] : Interpolator vcWaveBlender [object waveDepth]
define [vcWaveBlender before after args] : begin
export : define [h] : Interpolator hBlender
define [hBlender 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

export : define [vc waveDepth] : Interpolator vcBlender [object waveDepth]
define [vcBlender 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
export : define [v] : Interpolator vBlender
define [vBlender 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
g2 after.x [mix before.y after.y 0.375]
g2 before.x [mix before.y after.y 0.625]

export : define [vDistAfter d] : Interpolator vDistAfterBlender [object d]
define [vDistAfterBlender before after args] : begin
return : list
g2 after.x [mix before.y after.y 0.375]
g2 (after.x - args.d) [mix before.y after.y 0.625]

glyph-block-export PHexTop
define PHexTop : 0.5 + 0.5 * ([Math.max DecoSizeX frakThin] / (RightSB - SB))
Expand Down
135 changes: 135 additions & 0 deletions packages/font-glyphs/src/letter-like/fraktur/upper-bvw.ptl
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
$$include '../../meta/macros.ptl'

import [mix fallback] from "@iosevka/util"

glyph-module

glyph-block LetterLike-Fraktur-Upper-BVW : begin
glyph-block-import Common-Derivatives
glyph-block-import CommonShapes
glyph-block-import LetterLike-Fraktur-Common : FrakDf S M F 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
glyph-block-import LetterLike-Fraktur-Common : CutMaskLeft

define [deriveBoxes box] : begin
local body : box.padLeft (+1.50 * DecoSizeX)
local deco : box.padLeft (-0.25 * DecoSizeX)
return { body deco }

define [StartStroke mode box profile pRight] : glyph-proc
local { body deco } : deriveBoxes box

local [knots] : list
g2.ru.start (post@) ([deco.yp 0.625] - 2 * F.thick) [change-profile F]
~~~ [Wave.vc Wave.LTDecoSize]
g2.ru.mid deco.left (post@ <-> DecoSizeY) [change-profile M]
arch.rhs (sw -- S.thick) (blendPre -- null) deco.top 0.4
match mode
[Just "P"] : list
flat body.left [mix@ 0.375]
virt pre@ body.bot
curl body.left Descender
_ : list
straight.down.mid body.left [mix@ 0.375]
corner deco.left [post@slope SlopeB]
virt [body.xp : pRight * PHexBot] body.bot

local s : include : fraktur-stroke profile [knots]
return : object
lbKnot : s.last
maskLeft : function [] : fraktur-stroke CutMaskLeft [knots]

create-glyph 'frak/B' 0x1D505 : glyph-proc
local df : include : FrakDf 1
include : df.markSet.capital

local box : S.box CAP 0 df.leftSB df.rightSB
local { body deco } : deriveBoxes box

local leftStroke : include : StartStroke 'B' box S 1
local rightStroke : include : difference
union
fraktur-stroke S
corner leftStroke.lbKnot.x leftStroke.lbKnot.y
corner [body.xp PHexBot] body.bot
decor@ : g2.up.mid body.right [mix@ 0.5]
corner [body.xp 0.625] [body.yp 0.55]
fraktur-stroke S
corner deco.left [post@slope SlopeA]
corner [body.xp PHexTop] body.top
decor@ : g2.down.mid body.right [mix@ 0.5]
corner [body.xp 0.625] [body.yp 0.55]
corner deco.left [pre@slope : 0.5 * SlopeA]
leftStroke.maskLeft

create-glyph 'frak/P' 0x1D513 : glyph-proc
local df : include : FrakDf 1
include : df.markSet.capDesc

local box : S.box CAP 0 df.leftSB df.rightSB
local { body deco } : deriveBoxes box

local leftStroke : include : StartStroke "P" box S 1

local rightStroke : include : difference
fraktur-stroke S
g2 deco.left (post@ <+> Wave.DepthY)
~~~ [g2 [deco.xp 0.21] (pre@ <+> Wave.DepthY)]
g2 [deco.xp 0.625] body.bottom
~~~ [Wave.vDistAfter : 1.5 * Wave.DepthX]
[g2c.sr SlopeA].end (body.right + 0.25 * DecoSizeX) ([body.yp 0.75] + S.thick)
~~~ [curl [pre@tang-in 1] [pre@tang-in SlopeB]]
g2 (pre@ <-> Wave.DepthX) [mix@ 0.5]
arch.rhs (sw -- S.thick) (blendPre -- {}) body.top
corner (body.left - S.thick) (pre@ <-> ArchDepthA)
intersection [leftStroke.maskLeft] [MaskAbove body.yMid]

create-glyph 'frak/V' 0x1D519 : glyph-proc
local df : include : FrakDf 1
include : df.markSet.capital

local box : S.box CAP 0 df.leftSB df.rightSB
local { body deco } : deriveBoxes box

local leftStroke : include : StartStroke 'V' box S 1
local rightStroke : include : difference
fraktur-stroke S
corner leftStroke.lbKnot.x leftStroke.lbKnot.y
[cg2.sr SlopeA].start [body.xp PHexBot] body.bottom
~~~ [Wave.vDistAfter : 1.5 * Wave.DepthX]
[g2c.sr SlopeA].end (body.right + 0.25 * DecoSizeX) ([body.yp 0.75] + S.thick)
~~~ [curl [pre@tang-in 1] [pre@tang-in SlopeB]]
g2 (pre@ <-> Wave.DepthX) [mix@ 0.5]
arch.rhs (sw -- S.thick) (blendPre -- {}) body.top
corner (body.left - S.thick) (pre@ <-> ArchDepthA)
leftStroke.maskLeft

create-glyph 'frak/W' 0x1D51A : glyph-proc
local df : include : FrakDf para.diversityM 3
include : df.markSet.capital

local box : M.box CAP 0 df.leftSB df.rightSB
local { body deco } : deriveBoxes box

local leftStroke : include : StartStroke 'W' box M 0.5 1

local rightStroke : include : fraktur-stroke M
corner leftStroke.lbKnot.x leftStroke.lbKnot.y
corner [deco.xp : 0.5 * PHexBot] box.bottom
corner deco.xMid [post@slope SlopeB]
[cg2.sr SlopeA].start [deco.xp : mix 0.5 1 PHexBot] body.bot
~~~ [Wave.vDistAfter : 0.75 * Wave.DepthX]
[g2c.sr SlopeA].end (body.right + 0.5 * DecoSizeX) ([body.yp 0.75] + S.thick)
~~~ [curl [pre@tang-in 1] [pre@tang-in SlopeB]]
g2 (pre@ <-> 0.75 * Wave.DepthX) [mix@ 0.5]
arch.rhs (sw -- M.thick) (blendPre -- {}) body.top
corner body.xMid (body.top - 0.5 * Wave.DepthY)
~~~ [arch.rhs (sw -- M.thick) (blendPre -- {}) (blendPost -- {}) body.top]
corner body.left pre@

local middleStroke : include : fraktur-stroke M
virt [deco.xp : mix 0.5 1 PHexBot] body.bot
corner deco.xMid [pre@slope SlopeB]
~~~ [Wave.vDistAfter : 0.375 * Wave.DepthX]
corner body.xMid (body.top - 0.5 * Wave.DepthY)
2 changes: 1 addition & 1 deletion packages/font-glyphs/src/letter-like/fraktur/upper-hkr.ptl
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ glyph-block LetterLike-Fraktur-Upper-HKR : begin
# Left stroke
include : fraktur-stroke F
g2.ru.start post@ ([rDeco.yp 0.625] - 2 * F.thick)
~~~ [Wave.vc Wave.DepthX]
~~~ [Wave.vc Wave.LTDecoSize]
g2.ru.mid rDeco.left (post@ <-> DecoSizeY) [change-profile S]
arch.rhs (blendPre -- {}) rBody.top 0.625
flat rBody.left (pre@ <-> 0.6 * ArchDepthA)
Expand Down
86 changes: 86 additions & 0 deletions packages/font-glyphs/src/letter-like/fraktur/upper-mnp.ptl
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
$$include '../../meta/macros.ptl'

import [mix fallback] from "@iosevka/util"

glyph-module

glyph-block LetterLike-Fraktur-Upper-MNP : begin
glyph-block-import Common-Derivatives
glyph-block-import CommonShapes
glyph-block-import LetterLike-Fraktur-Common : FrakDf S M F T fraktur-stroke change-profile
glyph-block-import LetterLike-Fraktur-Common : DecoSizeX DecoSizeY SlopeA SlopeB CutMaskLeft
glyph-block-import LetterLike-Fraktur-Common : Wave LbFootRise FHook PHexTop PHexBot

define [deriveBoxes box] : begin
local body : box.padLeft (+1.50 * DecoSizeX)
local deco : box.padLeft (-0.25 * DecoSizeX)
return { body deco }

define [LeftStroke box profile] : glyph-proc
local { body deco } : deriveBoxes box

local [knots] : list
g2.ru.start (post@) ([deco.yp 0.625] - 2 * F.thick) [change-profile F]
~~~ [Wave.vc Wave.LTDecoSize]
g2.ru.mid deco.left (post@ <-> DecoSizeY) [change-profile profile]
arch.rhs (sw -- profile.thick) (blendPre -- null) deco.top 0.4
flat body.left (pre@ <-> ArchDepthA)
curl pre@ (post@ <+> ArchDepthB)
corner (deco.left + 0.5 * DecoSizeX) deco.bot
corner (pre@ <-> DecoSizeX) (pre@ <+> DecoSizeY)

local s : include : fraktur-stroke profile [knots]

return : object
maskLeft : function [] : fraktur-stroke CutMaskLeft [knots]


create-glyph 'frak/M' 0x1D510 : glyph-proc
local df : include : FrakDf para.diversityM 3
include : df.markSet.capital

local box : M.box CAP 0 df.leftSB df.rightSB
local { body deco } : deriveBoxes box

local leftStroke : include : LeftStroke box M

local rightStroke : include : fraktur-stroke M
corner (post@ <+> DecoSizeX) (post@ <+> DecoSizeY)
corner (body.right + 0.25 * DecoSizeX) body.bottom
~~~ [straight.up.mid (pre@ <-> Wave.DepthX) [mix@ 0.5]]
corner (pre@ <+> 0.25 * DecoSizeX) ([body.yp 0.75] + S.thick)
~~~ [curl [pre@tang-in 1] [pre@tang-in SlopeB]]
g2 (pre@ <-> 0.75 * Wave.DepthX) [mix@ 0.5]
arch.rhs (sw -- M.thick) (blendPre -- {}) body.top
corner (body.xMid - 0.25 * Wave.DepthX) (body.top - 0.5 * Wave.DepthY)
~~~ [arch.rhs (sw -- M.thick) (blendPre -- {}) (blendPost -- {}) body.top]
corner body.left pre@

local middleStroke : include : fraktur-stroke M
corner (post@ <-> DecoSizeX) (post@ <+> DecoSizeY)
corner deco.xMid deco.bot
flat post@ [mix@ 0.5]
# flat post@ (pre@ <+> ArchDepthB)
flat post@ ([body.yp 0.75] + S.thick)
curl (body.xMid - 0.25 * Wave.DepthX) (body.top - 0.5 * Wave.DepthY)

create-glyph 'frak/N' 0x1D511 : glyph-proc
local df : include : FrakDf 1
include : df.markSet.capital

local box : S.box CAP 0 df.leftSB df.rightSB
local { body deco } : deriveBoxes box

local leftStroke : include : LeftStroke box S

local rightStroke : include : difference
fraktur-stroke S
corner (post@ <+> DecoSizeX) (post@ <+> DecoSizeY)
corner (body.right + 0.25 * DecoSizeX) body.bottom
~~~ [straight.up.mid (pre@ <-> Wave.DepthX) [mix@ 0.5]]
corner pre@ ([body.yp 0.75] + S.thick)
~~~ [curl [pre@tang-in 1] [pre@tang-in SlopeB]]
g2 (pre@ <-> Wave.DepthX) [mix@ 0.5]
arch.rhs (sw -- S.thick) (blendPre -- {}) body.top
corner (body.left - S.thick) (pre@ <-> ArchDepthA)
leftStroke.maskLeft
4 changes: 3 additions & 1 deletion packages/geometry/src/spiro-pen-expand.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { Point } from "./point.mjs";
import { MonoKnot } from "./spiro-to-outline.mjs";

export class PenKnotCollector {
constructor(gizmo, defaultProfile) {
constructor(gizmo, defaultProfile, fProfileFixed) {
this.gizmo = gizmo;
this.m_profile = defaultProfile;
this.m_lastKnot = null;
this.m_finished = false;
this.m_profileFixed = fProfileFixed;

this.knots = [];
this.closed = false;
Expand All @@ -35,6 +36,7 @@ export class PenKnotCollector {
setContrast() {}

setProfile(profile) {
if (this.m_profileFixed) return;
if (profile.length !== this.m_profile.length)
throw new Error("Pen profile length mismatch");
if (this.m_lastKnot) this.m_lastKnot.profile = profile;
Expand Down
Loading