623 lines
21 KiB
Text
623 lines
21 KiB
Text
$$include '../../meta/macros.ptl'
|
|
|
|
import [Transform] from"../../support/geometry/transform.mjs"
|
|
|
|
import [mix linreg clamp fallback] from"../../support/utils.mjs"
|
|
import [Radical] from"../../support/gr.mjs"
|
|
import [Interpolator] from"../../support/geometry/spiro-control.mjs"
|
|
|
|
glyph-module
|
|
|
|
glyph-block CommonShapes : begin
|
|
glyph-block-import Common-Derivatives
|
|
|
|
glyph-block-export no-shape
|
|
define [no-shape] { .__isNoShape true }
|
|
|
|
glyph-block-export KnotAdj
|
|
define KnotAdj : namespace
|
|
define [BowlYAdjImpl sign y w] : y + sign * TanSlope * SmoothAdjust * w / Width
|
|
|
|
export : define [BowlLeft] : with-params [ty x y af [width Width]]
|
|
ty x [BowlYAdjImpl (+1) y width] af
|
|
set BowlLeft.yOf : function : with-params [y [width Width]] : BowlYAdjImpl (+1) y width
|
|
set BowlLeft.o : function : with-params [ty x y af [width Width]]
|
|
ty (x + OX) [BowlYAdjImpl (+1) y width] af
|
|
|
|
export : define [BowlRight] : with-params [ty x y af [width Width]]
|
|
ty x [BowlYAdjImpl (-1) y width] af
|
|
set BowlRight.yOf : function : with-params [y [width Width]] : BowlYAdjImpl (-1) y width
|
|
set BowlRight.o : function : with-params [ty x y af [width Width]]
|
|
ty (x - OX) [BowlYAdjImpl (-1) y width] af
|
|
|
|
export : define [ArchTop] : with-params [x y af [ty g4] [sw Stroke]]
|
|
ty (x - CorrectionOMidX * sw) y af
|
|
set ArchTop.o : function : with-params [x y af [ty g4] [sw Stroke]]
|
|
ty (x - CorrectionOMidX * sw) (y - O) af
|
|
|
|
export : define [ArchBot] : with-params [x y af [ty g4] [sw Stroke]]
|
|
ty (x + CorrectionOMidX * sw) y af
|
|
set ArchBot.o : function : with-params [x y af [ty g4] [sw Stroke]]
|
|
ty (x + CorrectionOMidX * sw) (y + O) af
|
|
|
|
glyph-block-export Rect
|
|
define [Rect u d l r transformShiftOnly] : glyph-proc
|
|
local giz currentGlyph.gizmo
|
|
include : new-glyph : glyph-proc
|
|
local my ((u + d) / 2)
|
|
local mx ((l + r) / 2)
|
|
currentGlyph.gizmo = [if transformShiftOnly [Transform.Id] giz]
|
|
include : spiro-outline
|
|
corner l d
|
|
corner l u
|
|
corner r u
|
|
corner r d
|
|
if transformShiftOnly : begin
|
|
local {.x mx1 .y my1} : giz.apply {.x mx .y my}
|
|
include : Translate (mx1 - mx) (my1 - my)
|
|
|
|
glyph-block-export SquareAt
|
|
define [SquareAt x y r] : Rect (y + r) (y - r) (x - r) (x + r)
|
|
|
|
glyph-block-export VERY-FAR
|
|
define VERY-FAR : UPM * 16
|
|
glyph-block-export MaskAbove
|
|
define [MaskAbove y] : Rect (VERY-FAR) y (-VERY-FAR) (VERY-FAR)
|
|
glyph-block-export MaskBelow
|
|
define [MaskBelow y] : Rect y (-VERY-FAR) (-VERY-FAR) (VERY-FAR)
|
|
glyph-block-export MaskLeft
|
|
define [MaskLeft x] : Rect VERY-FAR (-VERY-FAR) (-VERY-FAR) x
|
|
glyph-block-export MaskRight
|
|
define [MaskRight x] : Rect VERY-FAR (-VERY-FAR) x VERY-FAR
|
|
glyph-block-export MaskAboveLine
|
|
define [MaskAboveLine x1 y1 x2 y2] : spiro-outline
|
|
corner x1 (+VERY-FAR)
|
|
corner x1 y1
|
|
corner x2 y2
|
|
corner x2 (+VERY-FAR)
|
|
glyph-block-export MaskBelowLine
|
|
define [MaskBelowLine x1 y1 x2 y2] : spiro-outline
|
|
corner x1 (-VERY-FAR)
|
|
corner x1 y1
|
|
corner x2 y2
|
|
corner x2 (-VERY-FAR)
|
|
glyph-block-export MaskLeftLine
|
|
define [MaskLeftLine x1 y1 x2 y2] : spiro-outline
|
|
corner (-VERY-FAR) y1
|
|
corner x1 y1
|
|
corner x2 y2
|
|
corner (-VERY-FAR) y2
|
|
glyph-block-export MaskRightLine
|
|
define [MaskRightLine x1 y1 x2 y2] : spiro-outline
|
|
corner (+VERY-FAR) y1
|
|
corner x1 y1
|
|
corner x2 y2
|
|
corner (+VERY-FAR) y2
|
|
|
|
glyph-block-export HalfRectTriangle
|
|
define [HalfRectTriangle x1 y1 x2 y2] : spiro-outline
|
|
corner x1 y1
|
|
corner x2 y2
|
|
corner x2 y1
|
|
|
|
|
|
glyph-block-export Ring
|
|
define [Ring u d l r transformShiftOnly] : glyph-proc
|
|
local giz currentGlyph.gizmo
|
|
include : new-glyph : glyph-proc
|
|
local my ((u + d) / 2)
|
|
local mx ((l + r) / 2)
|
|
currentGlyph.gizmo = [if transformShiftOnly [Transform.Id] giz]
|
|
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} : giz.apply {.x mx .y my}
|
|
include : Translate (mx1 - mx) (my1 - my)
|
|
glyph-block-export RingAt
|
|
define [RingAt x y r] : Ring (y + r) (y - r) (x - r) (x + r)
|
|
glyph-block-export DotAt
|
|
define [DotAt x y r] : Ring (y + r) (y - r) (x - r) (x + r) true
|
|
|
|
glyph-block-export RingStroke
|
|
define [RingStroke u d l r s transformShiftOnly] : glyph-proc
|
|
local giz currentGlyph.gizmo
|
|
include : new-glyph : glyph-proc
|
|
local my ((u + d) / 2)
|
|
local mx ((l + r) / 2)
|
|
currentGlyph.gizmo = [if transformShiftOnly [Transform.Id] giz]
|
|
include : dispiro
|
|
begin [lambda : set this.gizmo currentGlyph.gizmo]
|
|
widths.rhs [fallback s Stroke]
|
|
g4 mx d [heading Leftward]
|
|
archv
|
|
g4 l my
|
|
arcvh
|
|
g4 mx u [heading Rightward]
|
|
archv
|
|
g4 r my
|
|
arcvh
|
|
close
|
|
if transformShiftOnly : begin
|
|
local {.x mx1 .y my1} : giz.apply {.x mx .y my}
|
|
include : Translate (mx1 - mx) (my1 - my)
|
|
glyph-block-export RingStrokeAt
|
|
define [RingStrokeAt x y r s] : RingStroke (y + r) (y - r) (x - r) (x + r) s
|
|
glyph-block-export DotStrokeAt
|
|
define [DotStrokeAt x y r s] : RingStroke (y + r) (y - r) (x - r) (x + r) s true
|
|
|
|
glyph-block-export CircleRing
|
|
define [CircleRing u d l r transformShiftOnly] : glyph-proc
|
|
local giz currentGlyph.gizmo
|
|
include : new-glyph : glyph-proc
|
|
local my ((u + d) / 2)
|
|
local mx ((l + r) / 2)
|
|
currentGlyph.gizmo = [if transformShiftOnly [Transform.Id] giz]
|
|
include : spiro-outline
|
|
begin [lambda : set this.gizmo currentGlyph.gizmo]
|
|
g4 mx d
|
|
archv 32 2.0
|
|
g4 l my
|
|
arcvh 32 2.0
|
|
g4 mx u
|
|
archv 32 2.0
|
|
g4 r my
|
|
arcvh 32 2.0
|
|
close
|
|
if transformShiftOnly : begin
|
|
local {.x mx1 .y my1} : giz.apply {.x mx .y my}
|
|
include : Translate (mx1 - mx) (my1 - my)
|
|
glyph-block-export CircleRingAt
|
|
define [CircleRingAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r)
|
|
glyph-block-export CircleDotAt
|
|
define [CircleDotAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r) true
|
|
glyph-block-export RoundStrokeTerminalAt
|
|
define [RoundStrokeTerminalAt x y r] : CircleRing (y + r) (y - r) (x - [HSwToV r]) (x + [HSwToV r]) true
|
|
|
|
glyph-block-export OShapeT
|
|
define [OShapeT sink u d l r _width _ada _adb] : begin
|
|
local middle : (l + r) / 2
|
|
local width : fallback _width Stroke
|
|
local ada : fallback _ada SmallArchDepthA
|
|
local adb : fallback _adb SmallArchDepthB
|
|
local mc : CorrectionOMidX * width
|
|
if (u - d > ada + adb) : then : begin
|
|
return : sink
|
|
widths width 0
|
|
g4 (middle - mc) (u - O)
|
|
archv
|
|
flat (l + OX) (u - ada)
|
|
curl (l + OX) (d + adb)
|
|
arcvh
|
|
g4 (middle + mc) (d + O)
|
|
archv
|
|
flat (r - OX) (d + ada)
|
|
curl (r - OX) (u - adb)
|
|
arcvh
|
|
close
|
|
: else : begin
|
|
local ymiddlea : mix d u (adb / (ada + adb))
|
|
local ymiddleb : mix d u (ada / (ada + adb))
|
|
return : sink
|
|
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
|
|
|
|
glyph-block-export OShape
|
|
define [OShape u d l r _width _ada _adb] : OShapeT dispiro u d l r _width _ada _adb
|
|
glyph-block-export OShapeOutline
|
|
define [OShapeOutline u d l r _width _ada _adb] : OShapeT spiro-outline u d l r _width _ada _adb
|
|
|
|
set OShape.NoOvershoot : lambda [u d l r _width _ada _adb] : OShape (u + O) (d - O) (l - OX) (r + OX) _width _ada _adb
|
|
set OShapeOutline.NoOvershoot : lambda [u d l r _width _ada _adb] : OShapeOutline (u + O) (d - O) (l - OX) (r + OX) _width _ada _adb
|
|
|
|
glyph-block-export OShapeFlatTB
|
|
define [OShapeFlatTB u d l r _width _ada _adb gap] : glyph-proc
|
|
local middle : (l + r) / 2
|
|
local width : fallback _width Stroke
|
|
local ada : fallback _ada SmallArchDepthA
|
|
local adb : fallback _adb SmallArchDepthB
|
|
local mc : CorrectionOMidX * width
|
|
if (u - d > ada + adb) : then : begin
|
|
include : dispiro
|
|
flat (middle - mc) (u - O) [widths.lhs width]
|
|
curl (middle - mc - gap / 2) (u - O)
|
|
archv
|
|
flat (l + OX) (u - ada)
|
|
curl (l + OX) (d + adb)
|
|
arcvh
|
|
flat (middle + mc - gap / 2) (d + O)
|
|
curl (middle + mc + gap / 2) (d + O)
|
|
archv
|
|
flat (r - OX) (d + ada)
|
|
curl (r - OX) (u - adb)
|
|
arcvh
|
|
flat (middle - mc + gap / 2) (u - O)
|
|
curl (middle - mc) (u - O)
|
|
: else : begin
|
|
local ymiddlea : mix d u (adb / (ada + adb))
|
|
local ymiddleb : mix d u (ada / (ada + adb))
|
|
include : dispiro
|
|
flat (middle - mc) (u - O) [widths.lhs width]
|
|
curl (middle - mc - gap / 2) (u - O)
|
|
archv
|
|
g4 (l + OX) ymiddlea
|
|
arcvh
|
|
flat (middle + mc - gap / 2) (d + O)
|
|
curl (middle + mc + gap / 2) (d + O)
|
|
archv
|
|
g4 (r - OX) ymiddleb
|
|
arcvh
|
|
flat (middle - mc + gap / 2) (u - O)
|
|
curl (middle - mc) (u - O)
|
|
|
|
glyph-block-export HSerif
|
|
define HSerif : namespace
|
|
export : define [lt x y length _sw _swRef] : glyph-proc
|
|
local sw : fallback _sw Stroke
|
|
local swRef : fallback _swRef sw
|
|
include : dispiro
|
|
flat (x + [HSwToV : 0.5 * swRef]) y [widths.heading sw 0 Leftward]
|
|
curl (x - length - TanSlope * (sw * DesignParameters.serifShiftX)) y
|
|
|
|
export : define [lb x y length _sw _swRef] : glyph-proc
|
|
local sw : fallback _sw Stroke
|
|
local swRef : fallback _swRef sw
|
|
include : dispiro
|
|
flat (x + [HSwToV : 0.5 * swRef]) y [widths.heading 0 sw Leftward]
|
|
curl (x - length + TanSlope * (sw * DesignParameters.serifShiftX)) y
|
|
|
|
export : define [rt x y length _sw _swRef] : glyph-proc
|
|
local sw : fallback _sw Stroke
|
|
local swRef : fallback _swRef sw
|
|
include : dispiro
|
|
flat (x - [HSwToV : 0.5 * swRef]) y [widths.heading 0 sw Rightward]
|
|
curl (x + length - TanSlope * (sw * DesignParameters.serifShiftX)) y
|
|
|
|
export : define [rb x y length _sw _swRef] : glyph-proc
|
|
local sw : fallback _sw Stroke
|
|
local swRef : fallback _swRef sw
|
|
include : dispiro
|
|
flat (x - [HSwToV : 0.5 * swRef]) y [widths.heading sw 0 Rightward]
|
|
curl (x + length + TanSlope * (sw * DesignParameters.serifShiftX)) y
|
|
|
|
export : define [mt x y length _sw] : mtAsymmetric x y length length _sw
|
|
|
|
export : define [mtAsymmetric x y l r _sw] : begin
|
|
local sw : fallback _sw Stroke
|
|
return : dispiro
|
|
flat (x + r - TanSlope * (sw * DesignParameters.serifShiftX)) y [widths.lhs sw]
|
|
curl (x - l - TanSlope * (sw * DesignParameters.serifShiftX)) y
|
|
|
|
export : define [mb x y length _sw] : mbAsymmetric x y length length _sw
|
|
export : define [mbAsymmetric x y l r _sw] : begin
|
|
local sw : fallback _sw Stroke
|
|
return : dispiro
|
|
flat (x + r + TanSlope * (sw * DesignParameters.serifShiftX)) y [widths.rhs sw]
|
|
curl (x - l + TanSlope * (sw * DesignParameters.serifShiftX)) y
|
|
|
|
glyph-block-export VSerif
|
|
define VSerif : namespace
|
|
export : define [dr x y length sw] : glyph-proc
|
|
include : dispiro
|
|
widths.rhs [fallback sw VJutStroke]
|
|
flat x y [heading Downward]
|
|
curl x (y - length) [heading Downward]
|
|
|
|
export : define [ur x y length sw] : glyph-proc
|
|
include : dispiro
|
|
widths.lhs [fallback sw VJutStroke]
|
|
flat x y [heading Upward]
|
|
curl x (y + length) [heading Upward]
|
|
|
|
export : define [dl x y length sw] : glyph-proc
|
|
include : dispiro
|
|
widths.lhs [fallback sw VJutStroke]
|
|
flat x y [heading Downward]
|
|
curl x (y - length) [heading Downward]
|
|
|
|
export : define [ul x y length sw] : glyph-proc
|
|
include : dispiro
|
|
widths.rhs [fallback sw VJutStroke]
|
|
flat x y [heading Upward]
|
|
curl x (y + length) [heading Upward]
|
|
|
|
glyph-block-export NeedSlab
|
|
define [NeedSlab level p] : if level p [glyph-proc]
|
|
glyph-block-export NeedNotItalic
|
|
define [NeedNotItalic p] : if para.isItalic [glyph-proc] p
|
|
|
|
glyph-block-export DiagCor
|
|
define [DiagCor dy dx dyt dxt] : begin
|
|
local ay : Math.max 0 : [Math.abs dy] - [fallback dyt 0]
|
|
local ax : Math.max 0 : [Math.abs dx] - [fallback dxt 0]
|
|
return : [Math.hypot ay ax] / ay
|
|
|
|
glyph-block-export DiagCorDs
|
|
define [DiagCorDs dy dx ds] : begin
|
|
local kDiag : DiagCor dy dx
|
|
for [local n 0] (n < 4) [inc n] : begin
|
|
set kDiag : DiagCor dy (dx - ds * kDiag)
|
|
return kDiag
|
|
|
|
glyph-block-export HBar
|
|
define HBar : namespace
|
|
export : define [m xleft xright y _fine] : dispiro
|
|
widths.center [fallback _fine Stroke]
|
|
flat xleft y [heading Rightward]
|
|
curl xright y [heading Rightward]
|
|
export : define [t xl xr y _fine] : m xl xr (y - [fallback _fine Stroke] * 0.5) _fine
|
|
export : define [b xl xr y _fine] : m xl xr (y + [fallback _fine Stroke] * 0.5) _fine
|
|
|
|
glyph-block-export VBar
|
|
define VBar : namespace
|
|
export : define [m x ydown yup _sw] : begin
|
|
local sw : fallback _sw Stroke
|
|
return : dispiro
|
|
widths.center sw
|
|
flat x ydown [heading : if (ydown < yup) Upward Downward]
|
|
curl x yup [heading : if (ydown < yup) Upward Downward]
|
|
export : define [l x yd yu _sw] : m (x + [fallback _sw Stroke] * 0.5 * HVContrast) yd yu _sw
|
|
export : define [r x yd yu _sw] : m (x - [fallback _sw Stroke] * 0.5 * HVContrast) yd yu _sw
|
|
|
|
glyph-block-export HOverlayBar
|
|
define [HOverlayBar xleft xright y s] : dispiro
|
|
widths.center [fallback s OverlayStroke]
|
|
flat xleft y
|
|
curl xright y
|
|
|
|
glyph-block-export HCrossBar
|
|
define [HCrossBar xl xr y s] : dispiro
|
|
widths.center [fallback s OverlayStroke]
|
|
flat xl y
|
|
curl xr y
|
|
set HCrossBar.top : lambda [xl xr y _s] : begin
|
|
local s : fallback _s Stroke
|
|
return : HCrossBar (xl - 0 * s * TanSlope) (xr - 0 * s * TanSlope) (y - 0.5 * s) s
|
|
set HCrossBar.bottom : lambda [xl xr y _s] : begin
|
|
local s : fallback _s Stroke
|
|
return : HCrossBar (xl + 0 * s * TanSlope) (xr + 0 * s * TanSlope) (y + 0.5 * s) s
|
|
|
|
glyph-block-export FlatSlashShape
|
|
define [FlatSlashShape middlex middle fine kx ky] : glyph-proc
|
|
include : dispiro
|
|
flat (middlex - LongJut * [fallback kx 0.8]) (middle - LongJut * [fallback ky 0.4]) [widths.center : 2 * fine]
|
|
curl (middlex + LongJut * [fallback kx 0.8]) (middle + LongJut * [fallback ky 0.4])
|
|
|
|
# Spiro shapes
|
|
define [determineMixR w v u sw swash] : begin
|
|
if (!swash && w < v) : return : 1 - [determineMixR v w u sw swash]
|
|
local superness DesignParameters.superness
|
|
local r : piecewise
|
|
(w <= v) 0.5
|
|
true : 1 / ([Math.pow (1 - [Math.pow (1 - v / w) superness]) (1 / superness)] + 1)
|
|
if swash : begin
|
|
local idepth : w - sw
|
|
local iwidth : u * r - sw
|
|
if (iwidth > 0 && idepth > 0 && iwidth / idepth >= 2) : begin
|
|
local adjust : clamp 0.975 1 (1 - (iwidth / idepth - 2) * 0.0125)
|
|
r = r * adjust
|
|
: else : set r : 0.5 + (r - 0.5) * (v + w) / (u * 2)
|
|
|
|
if (r < 0.5) : set r 0.5
|
|
return r
|
|
|
|
define nHookSegments 12
|
|
define [HookShape toStraight toFinish isStart args] : begin
|
|
local [object y tight sw swItalicAdj noAdjTerminalY turnSlope] args
|
|
|
|
local atBottom : toStraight.y > y
|
|
local ltr : if isStart (toFinish.x < toStraight.x) (toFinish.x > toStraight.x)
|
|
local dtu : if isStart (y > toFinish.y) (y < toFinish.y)
|
|
local doSwash : !tight && para.isItalic && ltr && atBottom && !isStart
|
|
local superness : if tight DesignParameters.tightHookSuperness DesignParameters.superness
|
|
|
|
# Adjust terminal's position if necessary
|
|
toFinish.x = toFinish.x + OXHook * [if ltr (-1) 1] * [if isStart (-1) 1]
|
|
if (doSwash) : begin
|
|
toFinish.x = toFinish.x + TailAdjX * TanSlope
|
|
toFinish.y = toFinish.y - TailAdjY * TanSlope
|
|
|
|
# Compute key middle knot
|
|
local w : Math.abs (toStraight.y - y)
|
|
local v : Math.abs (toFinish.y - y)
|
|
local u : Math.abs (toFinish.x - toStraight.x)
|
|
local mixRatio : determineMixR w v u sw doSwash
|
|
local mxSwMultiplier : [if (tight && tight.shift) tight.shift (1 - (tight || 0))] * [if atBottom 1 (-1)]
|
|
local mx : [mix toStraight.x toFinish.x mixRatio] + mxSwMultiplier * CorrectionOMidX * swItalicAdj
|
|
local keyKnot : g4.[if ltr "right" "left"].mid
|
|
begin mx
|
|
begin y
|
|
piecewise
|
|
tight : begin
|
|
local s : if ltr Rightward Leftward
|
|
heading {.x (s.x * [fallback tight.skew 1]) .y s.y}
|
|
turnSlope : begin
|
|
local s : if ltr Rightward Leftward
|
|
heading {.x turnSlope .y s.y}
|
|
true : begin nothing
|
|
|
|
# Adjust terminal's direction
|
|
do "Adjust terminal's direction"
|
|
local rad : Math.min w (mixRatio * u)
|
|
local skew0 : [clamp 0 w (w - v)] / rad + ([clamp 1 1.5 (mixRatio * u / w)] - 1) * 0.5
|
|
local depth : v + skew0 * sw - sw
|
|
local shallowLimit : sw / 2
|
|
local skew : clamp 0 (1 / 2) : skew0 + [clamp 0 shallowLimit (shallowLimit - depth)] / rad
|
|
local faf toFinish.af
|
|
set toFinish.af : lambda [] : begin
|
|
if faf : faf.apply this arguments
|
|
if this.headsTo : this.headsTo : if doSwash
|
|
then : begin {
|
|
.x (Contrast / [Math.sqrt : 1 + skew * skew] * [if dtu (-1) 1])
|
|
.y (skew / [Math.sqrt : 1 + skew * skew] * [if ltr 1 (-1)])
|
|
}
|
|
else : begin {
|
|
.x (Contrast * [if dtu (-1) 1])
|
|
.y 0
|
|
}
|
|
if ([not noAdjTerminalY] && [not doSwash]) : begin
|
|
set toFinish.y : toFinish.y + skew * sw * [if (y > toFinish.y) (-1) (+1)]
|
|
|
|
# Create the arc knots
|
|
local segBefore {}
|
|
local segAfter {}
|
|
foreach [j : range 1 nHookSegments] : begin
|
|
local fraction : j / nHookSegments
|
|
local mixRatioAdjust : Math.max (1 / 2) : (1 / 2) + [if doSwash 1 : if tight 0 (1 / 8)] * (mixRatio - (1 / 2))
|
|
local fractionAfter : fraction * (1 - mixRatioAdjust) / mixRatioAdjust
|
|
local myfinal : _SuperXY ((1 - mixRatioAdjust) / mixRatioAdjust) superness
|
|
segBefore.push : g4
|
|
mix mx toStraight.x fraction
|
|
mix y toStraight.y (1 - [_SuperXY fraction superness])
|
|
begin unimportant
|
|
segAfter.push : g4
|
|
mix mx toFinish.x fraction
|
|
mix y toFinish.y ((1 - [_SuperXY fractionAfter superness]) / (1 - myfinal))
|
|
begin unimportant
|
|
# if (!tight && w < u * mixRatio) : set segAfter {}
|
|
|
|
if isStart
|
|
: then : return : list
|
|
segAfter.reverse
|
|
* keyKnot
|
|
* segBefore
|
|
: else : return : list
|
|
segBefore.reverse
|
|
* keyKnot
|
|
* segAfter
|
|
|
|
define [hookStartBlender before after args] : begin
|
|
return : HookShape after before true args
|
|
|
|
define [hookEndBlender before after args] : begin
|
|
return : HookShape before after false args
|
|
|
|
glyph-block-export hookstart
|
|
define [hookstart] : begin
|
|
postulate
|
|
y
|
|
tight
|
|
sw -- Stroke
|
|
swItalicAdj -- sw
|
|
noAdjTerminalY -- false
|
|
turnSlope -- nothing
|
|
return : Interpolator hookStartBlender : object y tight sw swItalicAdj noAdjTerminalY turnSlope
|
|
|
|
glyph-block-export hookend
|
|
define [hookend] : begin
|
|
postulate
|
|
y
|
|
tight
|
|
sw -- Stroke
|
|
swItalicAdj -- sw
|
|
noAdjTerminalY -- false
|
|
turnSlope -- nothing
|
|
return : Interpolator hookEndBlender : object y tight sw swItalicAdj noAdjTerminalY turnSlope
|
|
|
|
glyph-block-export Ungizmo
|
|
define [Ungizmo] : glyph-proc
|
|
include [this.gizmo.inverse]
|
|
|
|
glyph-block-export Regizmo
|
|
define [Regizmo] : glyph-proc
|
|
include this.gizmo
|
|
|
|
# Composite transformations
|
|
glyph-block-export FlipAround
|
|
define [FlipAround x y sx sy] : glyph-proc
|
|
include : Ungizmo
|
|
include : Translate (-x) (-y)
|
|
include : Scale [fallback sx (-1)] [fallback sy sx (-1)]
|
|
include : Translate x y
|
|
include : Regizmo
|
|
|
|
glyph-block-export ScaleAround
|
|
define ScaleAround FlipAround
|
|
|
|
glyph-block-export Realign
|
|
define [Realign x y sx sy] : ApparentTranslate (sx - x) (sy - y)
|
|
|
|
glyph-block-export ForceUpright
|
|
define [ForceUpright] : glyph-proc [set this.gizmo : Transform.Id]
|
|
|
|
glyph-block-export NameUni
|
|
define [NameUni unicode] : begin
|
|
local hex : [unicode.toString 16].toUpperCase
|
|
while (hex.length < 4) : set hex : '0' + hex
|
|
return : 'uni' + hex
|
|
|
|
glyph-block-export PointingTo
|
|
define [PointingTo x1 y1 x2 y2 G] : glyph-proc
|
|
local giz this.gizmo
|
|
local g : new-glyph : glyph-proc
|
|
set this.gizmo : Transform.Id
|
|
local {.x xo .y yo} : [Transform.Id].apply {.x x1 .y y1}
|
|
local {.x xt .y yt} : [Transform.Id].apply {.x x2 .y y2}
|
|
local mag : Math.hypot (yo - yt) (xo - xt)
|
|
include [G mag]
|
|
include : Rotate : Math.atan2 (yo - yt) (xo - xt)
|
|
include : Translate xt yt
|
|
include giz
|
|
include g
|
|
|
|
glyph-block-export with-transform
|
|
define [with-transform tfm gr] : new-glyph : composite-proc gr tfm
|
|
|
|
glyph-block-export clear-geometry
|
|
define [clear-geometry] : glyph-proc
|
|
currentGlyph.clearGeometry
|
|
|
|
glyph-block-export clear-anchors
|
|
define [clear-anchors] : glyph-proc
|
|
set currentGlyph.markAnchors {.}
|
|
set currentGlyph.markBnchors {.}
|
|
|
|
glyph-block-export AsRadical
|
|
define [AsRadical gr] : glyph-proc
|
|
Radical.set currentGlyph
|
|
include gr true true
|
|
|
|
glyph-block-export ExtLineCenter
|
|
define [ExtLineCenter k sw x1 y1 x2 y2] : dispiro
|
|
widths.center sw
|
|
corner [mix x1 x2 (-k)] [mix y1 y2 (-k)]
|
|
corner [mix x1 x2 (1+k)] [mix y1 y2 (1+k)]
|
|
|
|
glyph-block-export ExtLineLhs
|
|
define [ExtLineLhs k sw x1 y1 x2 y2] : dispiro
|
|
widths.lhs sw
|
|
corner [mix x1 x2 (-k)] [mix y1 y2 (-k)]
|
|
corner [mix x1 x2 (1+k)] [mix y1 y2 (1+k)]
|
|
|
|
glyph-block-export ExtLineRhs
|
|
define [ExtLineRhs k sw x1 y1 x2 y2] : dispiro
|
|
widths.rhs sw
|
|
corner [mix x1 x2 (-k)] [mix y1 y2 (-k)]
|
|
corner [mix x1 x2 (1+k)] [mix y1 y2 (1+k)]
|
|
|
|
# Dot variant constructor
|
|
glyph-block-export DotVariants
|
|
define DotVariants : object
|
|
round { DotAt 1 O }
|
|
square { SquareAt DesignParameters.squareDotScalar 0 }
|
|
|
|
glyph-block-export WithDotVariants
|
|
define [WithDotVariants name unicode F] : begin
|
|
foreach { suffix { DrawAt kDotRadius overshoot } } [Object.entries DotVariants] : do
|
|
create-glyph "\(name).\(suffix)" : F DrawAt kDotRadius overshoot
|
|
select-variant name unicode (follow -- 'punctuationDot')
|