Iosevka/glyphs/common-shapes.patel

481 lines
18 KiB
Plaintext

###### COMMON SHAPES
define [Ring u d l r transformShiftOnly] : create-glyph : glyph-construction
local my ((u + d) / 2)
local mx ((l + r) / 2)
local s : new Stroke
currentGlyph.gizmo = [if transformShiftOnly [Translate 0 0] globalTransform]
include : spiro-outline
g4 mx d
archv
g4 l my
arcvh
g4 mx u
archv
g4 r my
arcvh
close
if transformShiftOnly : begin
local {.x mx1 .y my1} [tp globalTransform {.x mx .y my}]
apply-transform : Translate (mx1 - mx) (my1 - my)
define [RingAt x y r] : Ring (y + r) (y - r) (x - r) (x + r)
define [DotAt x y r] : Ring (y + r) (y - r) (x - r) (x + r) true
define SERIF_SHIFT_X 0.6
define [LeftwardTopSerif x y length _sw] : glyph-construction
local sw : fallback _sw STROKE
include : dispiro
flat (x + HALFSTROKE * CORRECTION_HX) y [widths.heading sw 0 LEFTWARD]
curl (x - length - globalTransform.yx * (sw * SERIF_SHIFT_X)) y
define [LeftwardBottomSerif x y length _sw] : glyph-construction
local sw : fallback _sw STROKE
include : dispiro
flat (x + HALFSTROKE * CORRECTION_HX) y [widths.heading 0 sw LEFTWARD]
curl (x - length + globalTransform.yx * (sw * SERIF_SHIFT_X)) y
define [RightwardTopSerif x y length _sw] : glyph-construction
local sw : fallback _sw STROKE
include : dispiro
flat (x - HALFSTROKE * CORRECTION_HX) y [widths.heading 0 sw RIGHTWARD]
curl (x + length - globalTransform.yx * (sw * SERIF_SHIFT_X)) y
define [RightwardBottomSerif x y length _sw] : glyph-construction
local sw : fallback _sw STROKE
include : dispiro
flat (x - HALFSTROKE * CORRECTION_HX) y [widths.heading sw 0 RIGHTWARD]
curl (x + length + globalTransform.yx * (sw * SERIF_SHIFT_X)) y
define [CenterTopSerif x y length _sw] : glyph-construction
local sw : fallback _sw STROKE
include : dispiro
flat (x + length - globalTransform.yx * (sw * SERIF_SHIFT_X)) y [widths sw 0]
curl (x - length - globalTransform.yx * (sw * SERIF_SHIFT_X)) y
define [CenterBottomSerif x y length _sw] : glyph-construction
local sw : fallback _sw STROKE
include : dispiro
flat (x + length + globalTransform.yx * (sw * SERIF_SHIFT_X)) y [widths 0 sw]
curl (x - length + globalTransform.yx * (sw * SERIF_SHIFT_X)) y
define [DownwardRightSerif x y length sw] : glyph-construction
include : dispiro
widths.rhs sw
flat x y [heading DOWNWARD]
curl x (y - length) [heading DOWNWARD]
define [UpwardRightSerif x y length sw] : glyph-construction
include : dispiro
widths.lhs sw
flat x y [heading UPWARD]
curl x (y + length) [heading UPWARD]
define [DownwardLeftSerif x y length sw] : glyph-construction
include : dispiro
widths.lhs sw
flat x y [heading DOWNWARD]
curl x (y - length) [heading DOWNWARD]
define [UpwardLeftSerif x y length sw] : glyph-construction
include : dispiro
widths.rhs sw
flat x y [heading UPWARD]
curl x (y + length) [heading UPWARD]
define sideSerifK 0.5
define [AIVSerifs top _left _right] : glyph-construction
local left : fallback _left SB
local right : fallback _right RIGHTSB
if SLAB : begin
include : CenterTopSerif (left + STROKE * sideSerifK * CORRECTION_HX) top JUT
tag-contour 'serifLT'
include : CenterTopSerif (right - STROKE * sideSerifK * CORRECTION_HX) top JUT
tag-contour 'serifRT'
define [AIHSerifs top _left _right] : glyph-construction
local left : fallback _left SB
local right : fallback _right RIGHTSB
if SLAB : begin
include : AIVSerifs top _left _right
include : CenterBottomSerif (left + STROKE * sideSerifK * CORRECTION_HX) 0 JUT
include : CenterBottomSerif (right - STROKE * sideSerifK * CORRECTION_HX) 0 JUT
define [AINSerifs top _left _right sw xn] : glyph-construction
local left : fallback _left SB
local right : fallback _right RIGHTSB
local jut : JUT * [fallback xn 1]
if SLAB : begin
include : LeftwardTopSerif (left + sw * (sideSerifK - 0.5) * CORRECTION_HX) top (jut - sw / 2 * CORRECTION_HX)
include : CenterTopSerif (right - sw * sideSerifK * CORRECTION_HX) top jut
include : CenterBottomSerif (left + sw * sideSerifK * CORRECTION_HX) 0 jut
tag-contour 'serifLB'
#include : CenterdBottomSerif (right - STROKE * (sideSerifK - 0.5) * CORRECTION_HX) 0 (JUT / 2)
define [AICyrISerifs top _left _right] : glyph-construction
local left : fallback _left SB
local right : fallback _right RIGHTSB
if SLAB : begin
include : LeftwardBottomSerif left 0 SIDEJUT
include : RightwardTopSerif right top SIDEJUT
include : CenterTopSerif (left + STROKE * sideSerifK * CORRECTION_HX) top JUT
include : CenterBottomSerif (right - STROKE * sideSerifK * CORRECTION_HX) 0 JUT
tag-contour 'serifRB'
define [AIMSerifs top _left _right] : glyph-construction
local left : fallback _left SB
local right : fallback _right RIGHTSB
if SLAB : begin
include : LeftwardTopSerif (left + STROKE * (sideSerifK - 0.5) * CORRECTION_HX) top SIDEJUT
include : RightwardTopSerif (right - STROKE * (sideSerifK - 0.5) * CORRECTION_HX) top SIDEJUT
include : CenterBottomSerif (left + STROKE * sideSerifK * CORRECTION_HX) 0 JUT
include : CenterBottomSerif (right - STROKE * sideSerifK * CORRECTION_HX) 0 JUT
define [xsStrand _xleft yleft _xright yright _halfstroke0 _halfstroke1 _ess _expansion _roundp] : begin
local expansion : _expansion || 0.25
local halfstroke0 : _halfstroke0 || HALFSTROKE
local halfstroke1 : _halfstroke1 || HALFSTROKE
local ess : _ess || (halfstroke0 + halfstroke1) / 2
local upright : Upright
# calculate italic correction
local outline : [new Stroke
:.set-transform globalTransform
:.start-from _xleft yleft
:.set-width (2 * halfstroke0) 0
:.line-to _xleft (yleft - 1000)
:.max-samples 1
:.to-outline].0.map : [p] -> [tp upright p]
local xItalicCorrection : -(outline.3.x - outline.0.x) / (2 * halfstroke0)
local yItalicCorrection : (outline.3.y - outline.0.y) / (2 * halfstroke0)
local roundsize : (_roundp || SMOOTHA * 0.4) * [if (yleft < yright) (-1) 1]
local roundleft (yleft - roundsize)
local roundright (yright + roundsize)
local xleft : _xleft + halfstroke0 * xItalicCorrection
local xright : _xright - halfstroke1 * xItalicCorrection
local sxleft : mix xleft xright (0.5 - expansion)
local sxright : mix xleft xright (0.5 + expansion)
local syleft : mix roundleft roundright (0.5 - expansion)
local syright : mix roundleft roundright (0.5 + expansion)
return : new Stroke
:.set-transform globalTransform
:.start-from xleft (yleft - halfstroke0 * yItalicCorrection)
:.set-width halfstroke0 halfstroke0
:.curve-to xleft roundleft sxleft syleft
:.set-width ess ess
:.line-to sxright syright
:.curve-to xright roundright xright (yright + halfstroke1 * yItalicCorrection)
:.set-width halfstroke1 halfstroke1
:.to-outline
define [sStrand yleft yright _expansion] : begin
return : xsStrand SB yleft RIGHTSB yright HALFSTROKE HALFSTROKE HALFSTROKE _expansion (SMOOTHA * 0.4)
define [halfXStrand _leftx lefty rightx righty turn straight tension _fine] : glyph-construction
local leftx : _leftx + (HALFSTROKE * CORRECTION_HX * [if (rightx > _leftx) 1 (-1)])
local fine : (_fine || STROKE) * 0.5
local turnyleft : mix lefty righty turn
local cyleft : mix turnyleft righty tension
local straightxleft : mix leftx rightx straight
local straightyleft : mix cyleft righty straight
include : dispiro
widths.center
flat leftx lefty [heading [if (lefty < righty) UPWARD DOWNWARD]]
curl leftx turnyleft [heading [if (lefty < righty) UPWARD DOWNWARD]]
quadcontrols 0 ((cyleft - turnyleft) / (straightyleft - turnyleft)) 4 unimportant
flat straightxleft straightyleft
curl rightx righty
define [xStrand _leftx lefty _rightx righty turn straight tension] : glyph-construction
local middlex : mix _leftx _rightx 0.5
local middley : mix lefty righty 0.5
include : halfXStrand _leftx lefty middlex middley turn straight tension
include : halfXStrand _rightx righty middlex middley turn straight tension
define [nShoulderKnots left right fine _top _bottom _sma _smb _wide] : begin
local top : fallback _top XH
local bottom : fallback _bottom 0
local sma : fallback _sma SMALLSMOOTHA
local smb : fallback _smb SMALLSMOOTHB
local stroke : fallback _wide STROKE
local slope : shoulderMidSlope fine
local middle : [mix (left - stroke * CORRECTION_HX) right 0.5] + (slope - CORRECTION_OMIDX) * stroke
return : list
flat left (top - sma - 2) [widths fine 0]
curl left (top - sma)
arcvh
g4 middle (top - O) [widths.heading 0 stroke {.y (1) .x (slope)}]
archv
flat right (top - smb)
curl right bottom [heading DOWNWARD]
define [nShoulder left right fine _top _bottom _sma _smb _wide] : let [a arguments] : glyph-construction
include : dispiro : nShoulderKnots.apply null a
define [mShoulderSpiro left right top bottom width fine] : glyph-construction
local fix : CORRECTION_VS * CORRECTION_HX * width / STROKE
local sm : SMALLSMOOTH * 0.75
include : spiro-outline
corner (right - width * CORRECTION_HX) bottom
curl (right - width * CORRECTION_HX) (top - sm + fix)
arcvh 8 'no-tiny'
g2 [mix left (right - width * CORRECTION_HX) 0.5] (top - O - width)
archv 8 'no-tiny'
flat left (top - sm - fix)
corner left (top - sm - fix - 1)
corner (left - fine) (top - sm - 1)
curl (left - fine) (top - sm)
arcvh 8 'no-tiny'
g2 [mix (left - fine * CORRECTION_HX) right 0.5] (top - O)
archv 8 'no-tiny'
flat right (top - sm)
corner right bottom
close
define [smallo u d l r _width _sma _smb ai] : glyph-construction
local middle : (l + r) / 2
local width : fallback _width STROKE
local sma : fallback _sma SMALLSMOOTHA
local smb : fallback _smb SMALLSMOOTHB
local mc : CORRECTION_OMIDX * width
if (u - d > sma + smb) : then : begin
include : dispiro
widths width 0
g4 (middle - mc) (u - O)
archv
[if ai flat.ai flat] (l + OX) (u - sma)
[if ai curl.ai curl] (l + OX) (d + smb)
arcvh
g4 (middle + mc) (d + O)
archv
[if ai flat.ai flat] (r - OX) (d + sma)
[if ai curl.ai curl] (r - OX) (u - smb)
arcvh
close
: else : begin
local ymiddlea : mix d u (smb / (sma + smb))
local ymiddleb : mix d u (sma / (sma + smb))
include : dispiro
widths width 0
g4 (middle - mc) (u - O)
archv
g4 (l + OX) ymiddlea
arcvh
g4 (middle + mc) (d + O)
archv
g4 (r - OX) ymiddleb
arcvh
close
define [HBar xleft xright y _fine] : glyph-construction
local fine : [fallback _fine STROKE] / 2
include : dispiro
widths.center (fine * 2)
flat xleft y [heading RIGHTWARD]
curl xright y [heading RIGHTWARD]
define [HBarTop xl xr y _fine] : HBar xl xr (y - [fallback _fine STROKE] * 0.5) _fine
define [HBarBottom xl xr y _fine] : HBar xl xr (y + [fallback _fine STROKE] * 0.5) _fine
define [HOverlayBar xleft xright y] : HBar xleft xright y OVERLAYSTROKE
define [VBar x ydown yup _fine] : glyph-construction
local fine : fallback _fine STROKE
include : dispiro
widths.center fine
flat x ydown [heading [if (ydown < yup) UPWARD DOWNWARD]]
curl x yup [heading [if (ydown < yup) UPWARD DOWNWARD]]
define [VBarLeft x yd yu _fine] : VBar (x + [fallback _fine STROKE] * 0.5 * CORRECTION_HX) yd yu _fine
define [VBarRight x yd yu _fine] : VBar (x - [fallback _fine STROKE] * 0.5 * CORRECTION_HX) yd yu _fine
define [VerticalHook x y extend depth fine] : glyph-construction
include : dispiro
widths.center [fallback fine STROKE]
flat x y [heading [if (depth > 0) DOWNWARD UPWARD]]
curl x (y - [if (depth > 0) 0.01 (-0.01)]) [heading [if (depth > 0) DOWNWARD UPWARD]]
flat (x + extend - [if (extend > 0) 0.01 (-0.01)]) (y - depth)
curl (x + extend) (y - depth)
define [LegShape xt xb xs top bottom _fine] : glyph-construction
local fine : fallback _fine STROKE
include : dispiro
widths.lhs fine
flat xt top [heading DOWNWARD]
curl xb (bottom + LONGJUT)
alsothruthem {{0.5 0.94}}
g4.left.end xs (bottom + fine) [heading LEFTWARD]
define [LeftHook x y xextend] : glyph-construction
local fine : adviceBlackness 4.25
include : dispiro
widths.lhs fine
flat [fallback xextend : x + 1] y
curl x y
archv
g4 (x - fine * 1.5) (y - HOOKX)
# Common transformations
define [FlipAround x y sx sy] : glyph-construction
apply-transform : Upright
apply-transform : Translate (-x) (-y)
apply-transform : Scale [fallback sx (-1)] [fallback sy sx (-1)]
apply-transform : Translate x y
apply-transform : Italify
# Spiro shapes
define [determineMixR w v] : piecewise
(w <= v) 0.5
true : 1 / ([Math.pow (1 - [Math.pow (1 - v / w) SUPERNESS]) (1 / SUPERNESS)] + 1)
define nHookSegments 4
define [HookShape toStraight toFinish isStart y tight s] : begin
local atBottom : toStraight.y > y
local ltr : if isStart (toFinish.x < toStraight.x) (toFinish.x > toStraight.x)
toFinish.x = toFinish.x + OXHOOK * [if ltr (-1) 1] * [if isStart (-1) 1]
if (atBottom && ltr && !isStart) : begin
toFinish.x = toFinish.x + TAILADJX * globalTransform.yx
toFinish.y = toFinish.y - TAILADJY * globalTransform.yx
local w : Math.abs (toStraight.y - y)
local v : Math.abs (toFinish.y - y)
local u : Math.abs (toFinish.x - toStraight.x)
local mixr : determineMixR w v
local mx ([mix toStraight.x toFinish.x mixr] + ([if tight 0 : if atBottom 1 (-1)] * CORRECTION_OMIDX) * [fallback s STROKE])
local keyKnot : g4.[if ltr "right" "left"].mid mx y [if tight [heading [if ltr RIGHTWARD LEFTWARD]] nothing]
local segBefore {}
local segAfter {}
foreach [j : range 1 nHookSegments] : begin
local fraction : j / nHookSegments
local fractionAfter : fraction * (1 - mixr) / mixr
local myfinal : superxy ((1 - mixr) / mixr)
segBefore.push : g4 [mix mx toStraight.x fraction] [mix y toStraight.y (1 - [superxy fraction])] unimportant
segAfter.push : g4 [mix mx toFinish.x fraction] [mix y toFinish.y ((1 - [superxy fractionAfter]) / (1 - myfinal))] unimportant
if (!tight && w < u * mixr) : set segAfter {}
if isStart
: then : return : list
segAfter.reverse
* keyKnot
* segBefore
: else : return : list
segBefore.reverse
* keyKnot
* segAfter
define [hookstart y tight s] : return {.type 'interpolate' .af [lambda [before after] [HookShape after before true y tight s]]}
define [hookend y tight s] : return {.type 'interpolate' .af [lambda [before after] [HookShape before after false y tight s]]}
define [WaveShape l r cy extendy tension sw] : glyph-construction
local cx : mix l r 0.5
local wavex : (r - l) * tension
local endwavey : extendy * 0.97
include : dispiro
widths.center sw
g4 l (cy - endwavey)
bezcontrols.absolute (l + wavex) (cy + extendy) (cx - wavex * 0.8) (cy + extendy) 8 important
g4 cx cy
bezcontrols.absolute (cx + wavex * 0.8) (cy - extendy) (r - wavex) (cy - extendy) 8 important
g4 r (cy + endwavey)
# Derived subfonts
define [Fork gs params] : begin
local p : Object.create params
local shouldBuildList {}
foreach glyphid [items-of gs] : set shouldBuildList : shouldBuildList.concat {glyphid :: dependencyProfile.(glyphid)}
set shouldBuildList : shouldBuildList.filter : [x] -> [not [not x]]
local shouldBuildUnicodes : shouldBuildList.map ([x] -> [if (glyphs.(x) && glyphs.(x).unicode) glyphs.(x).unicode.0 nothing])
:.filter ([x] -> [not [not x]])
try : begin
local forkFont : buildFont.call [TempFont] p shouldBuildList shouldBuildUnicodes
: ex
: begin
if ex.glyfMap : return ex.glyfMap
: else : throw ex
return forkFont.glyfMap
define [Miniature glyphs fold scale] : begin
local forkedPara : Object.create para
forkedPara.stroke = [adviceBlackness fold] / scale
forkedPara.ess = para.ess * forkedPara.stroke / para.stroke
forkedPara.sb = SB / 2
return : Fork glyphs forkedPara
define [Thinner glyphs p] : begin
local forkedPara : Object.create para
forkedPara.width = WIDTH * p
return : Fork glyphs forkedPara
define [Widen glyphs p psb] : begin
local forkedPara : Object.create para
forkedPara.width = WIDTH * p
forkedPara.sb = SB * [fallback psb p]
forkedPara.accentx = ACCENTX * p
forkedPara.jut = JUT * p
forkedPara.longjut = LONGJUT * p
forkedPara.hookx = HOOKX * p
#forkedPara.smoothadjust = para.smoothadjust / p
return : Fork glyphs forkedPara
define [turned newid unicode id x y mark] : create-glyph [fallback newid : 'turn' + id] : glyph-construction
if unicode : assign-unicode unicode
include glyphs.(id) [if mark false AS_BASE]
if mark : include mark
include : FlipAround x y
# Dual derivatives
define [dual newid unicode id spacing] : create-glyph [fallback newid : 'double' + id] : glyph-construction
if unicode : assign-unicode unicode
include glyphs.(id) AS_BASE
apply-transform : Translate (-spacing) 0
include glyphs.(id)
apply-transform : Translate (spacing / 2) 0
define [vdual newid unicode id spacing] : create-glyph [fallback newid : 'double' + id] : glyph-construction
if unicode : assign-unicode unicode
include : create-glyph : glyph-construction
include glyphs.(id)
apply-transform : Upright
apply-transform : Translate 0 (-spacing)
include : create-glyph : glyph-construction
include glyphs.(id)
apply-transform : Upright
apply-transform : Translate 0 (spacing / 2)
apply-transform : Italify
define [composite newid unicode parts] : create-glyph [fallback newid ('glyph' + [set nTemp (nTemp + 1)])] : glyph-construction
if unicode : assign-unicode unicode
include parts.0 AS_BASE
foreach [part : items-of [parts.slice 1]] : include part
# Full-width derivatives
define [fwl newid unicode id] : create-glyph [fallback newid : 'fwl' + id] : glyph-construction
if unicode : assign-unicode unicode
include glyphs.(id)
set-width FULLWIDTH
define [fwr newid unicode id] : create-glyph [fallback newid : 'fwr' + id] : glyph-construction
if unicode : assign-unicode unicode
include glyphs.(id)
set-width FULLWIDTH
apply-transform : Translate (FULLWIDTH - WIDTH) 0
define [dwl newid unicode id] : create-glyph [fallback newid : 'dwl' + id] : glyph-construction
if unicode : assign-unicode unicode
include glyphs.(id)
set-width UPM
define [dwr newid unicode id] : create-glyph [fallback newid : 'dwr' + id] : glyph-construction
if unicode : assign-unicode unicode
include glyphs.(id)
set-width UPM
apply-transform : Translate (UPM - WIDTH) 0
define [dwc newid unicode id] : create-glyph [fallback newid : 'dwc' + id] : glyph-construction
if unicode : assign-unicode unicode
include glyphs.(id)
set-width UPM
apply-transform : Translate ((UPM - WIDTH) / 2) 0