Zigzag Shape fixes (#2651)

* sharp-corner

* refine `ծ`

* Zigzag rewrite (part 1)

* Zigzag rewrite (part 2)

* use Zigzag for resistors

* doc
This commit is contained in:
Logo 2025-01-22 08:47:34 +08:00 committed by GitHub
parent 1b0774aa97
commit d81c0347f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 319 additions and 182 deletions

View file

@ -1,2 +1,12 @@
* Add variant selector for decorative angle brackets (U+276C...U+2771) (#2603, #2623).
* Refine shape of:
- ARMENIAN SMALL LETTER CA (`U+056E`).
- VERTICAL ZIGZAG LINE (`U+299A`).
- LEFT WIGGLY FENCE (`U+29D8`).
- RIGHT WIGGLY FENCE (`U+29D9`).
- LEFT DOUBLE WIGGLY FENCE (`U+29DA`).
- RIGHT DOUBLE WIGGLY FENCE (`U+29DB`).
- HORIZONTAL RESISTOR SEGMENT (`U+1CC09`).
- VERTICAL RESISTOR SEGMENT (`U+1CC0A`).
- HORIZONTAL ZIGZAG LINE (`U+1CEB0`).
* Optimize metrics for bowl of Cyrillic Lower Ef (`ф`) and Greek Small Letter Phi Symbol (`ϕ`).

View file

@ -2,6 +2,7 @@ $$include '../meta/macros.ptl'
import [mix linreg clamp fallback boole boolePn] from "@iosevka/util"
import [Transform] from "@iosevka/geometry/transform"
import [Point] from "@iosevka/geometry/point"
import [FunctionInterpolator AfCombine] from "@iosevka/geometry/spiro-control"
import [RadicalGeometry StrokeGeometry RemoveHolesGeometry] from "@iosevka/geometry"
@ -797,3 +798,41 @@ glyph-block CommonShapes : begin
foreach { suffix { DrawAt kDotRadius overshoot } } [Object.entries DotVariants] : do
create-glyph "\(name).\(suffix)" : F DrawAt kDotRadius overshoot
select-variant name unicode (follow -- 'punctuationDot')
# Sharp Corner Interpolator
glyph-block-export TangentToNormal VectorDot
define [TangentToNormal offset contrast _tanSlope] : begin
local r : Math.hypot offset.x offset.y
return : new Point Point.Type.Corner
contrast * (-offset.y / r)
(offset.x + offset.y * [fallback _tanSlope TanSlope]) / r
define [VectorDot p1 p2] : p1.x * p2.x + p1.y * p2.y
define [SharpCornerImpl before after args] : begin
if [not (before.af && before.af.l !== undefined)] : throw : new Error "Unable to infer stroke information for previous knot"
if [not (after.af && after.af.l !== undefined)] : throw : new Error "Unable to infer stroke information for next knot"
local beforeT : new Point Point.Type.Corner (args.x - before.x) (args.y - before.y)
local afterT : new Point Point.Type.Corner (after.x - args.x) (after.y - args.y)
local beforeN : fallback before.af.d : TangentToNormal beforeT args.contrast [if args.upright 0]
local afterN : fallback after.af.d : TangentToNormal afterT args.contrast [if args.upright 0]
local beforeR : beforeN.addScale (-[VectorDot beforeN beforeT] / [VectorDot beforeT beforeT]) beforeT
local afterR : afterN.addScale (-[VectorDot afterN afterT ] / [VectorDot afterT afterT ]) afterT
local beforeD : afterT.scale ([VectorDot beforeR beforeR] / [VectorDot beforeR afterT ])
local afterD : beforeT.scale ([VectorDot afterR afterR ] / [VectorDot afterR beforeT])
local lOffset : [beforeD.scale before.af.l ].addScale after.af.l afterD
local rOffset : [beforeD.scale (-before.af.r)].addScale (-after.af.r) afterD
local midPoint : lOffset.mix rOffset 0.5
local refPoint : Point.translated midPoint args.x args.y
return : corner refPoint.x refPoint.y [widths.center.heading 1 { .x (lOffset.x - rOffset.x) .y (lOffset.y - rOffset.y) }]
glyph-block-export sharp-corner
define [sharp-corner] : with-params [x y [contrast HVContrast] [upright 0]] : begin
local args : object x y contrast upright
return : new FunctionInterpolator SharpCornerImpl args

View file

@ -41,25 +41,19 @@ glyph-block Letter-Armenian-Ca : begin
local x1 : mix df.leftSB df.rightSB 0.45
local x2 : mix df.leftSB df.rightSB 0.3
local xOffset : HSwToV : 0.5 * df.mvs
local y2 : mix XH Ascender 0.5
include : dispiro
widths.rhs df.mvs
flat (x1 + xOffset) Ascender [heading Downward]
curl (x2 + xOffset) y2 [heading Downward]
local x3 : mix df.leftSB df.rightSB 0.1
local x4 : mix df.leftSB df.rightSB 0.6
local rExt : Math.max df.rightSB : Math.min
x4 + [HSwToV : 1.5 * df.mvs] + jut
df.rightSB + jut - [HSwToV : 0.5 * df.mvs]
include : intersection [MaskBelowLine (x1 - xOffset) Ascender (x2 - xOffset) y2 100] : dispiro
widths.rhs df.mvs
flat (x3 + xOffset) Ascender
curl (x4 + xOffset) XH
flat (df.rightSB - OX) (XH - SmallArchDepthB)
include : dispiro
flat x1 Ascender [widths.center.heading df.mvs Downward]
sharp-corner x2 y2
curl x4 XH [widths.center df.mvs]
flat (df.rightSB - OX) (XH - SmallArchDepthB) [widths.rhs df.mvs]
curl (df.rightSB - OX) (0 + SmallArchDepthA)
arch.rhs 0 (sw -- df.mvs)
flat (df.leftSB + OX) (0 + SmallArchDepthB)

View file

@ -312,7 +312,7 @@ define-macro glyph-block-import : syntax-rules
DiagCor NameUni PointingTo with-transform with-outlined remove-holes radicalize clear-geometry
clear-anchors ExtLineCenter ExtLineLhs ExtLineRhs DiagCorDs HCrossBar MaskAbove
MaskBelow MaskLeft MaskRight HalfRectTriangle MaskAboveLine MaskBelowLine
MaskLeftLine MaskRightLine DotVariants WithDotVariants]
MaskLeftLine MaskRightLine DotVariants WithDotVariants TangentToNormal VectorDot sharp-corner]
define vartiableFilter : if externEnv.$glyphBlockVariableUsage$
lambda [x] externEnv.$glyphBlockVariableUsage$.(x)

View file

@ -163,9 +163,12 @@ glyph-block Symbol-Math-Geometry : begin
straight.right.end right top
do 'Zigzags'
create-glyph 'vertZigzag' 0x299A : VZigzag Middle ParenBot ParenTop (radiusBox / 4) 9 0 GeometryStroke
create-glyph 'wigglyFenceLeft' 0x29D8 : VZigzag Middle ParenBot ParenTop (radiusBox / 4) 10 1 GeometryStroke
create-glyph 'wigglyFenceRight' 0x29D9 : VZigzag Middle ParenBot ParenTop (radiusBox / 4) 10 0 GeometryStroke
create-glyph 'vertZigzag' 0x299A : intersection [MaskAbove ParenBot] [MaskBelow ParenTop]
VZigzag.fromSide Middle ParenBot ParenTop (radiusBox / 4) 9 0 GeometryStroke
create-glyph 'wigglyFenceLeft' 0x29D8 : intersection [MaskAbove ParenBot] [MaskBelow ParenTop]
VZigzag.fromSide Middle ParenBot ParenTop (radiusBox / 4) 10 1 GeometryStroke
create-glyph 'wigglyFenceRight' 0x29D9 : intersection [MaskAbove ParenBot] [MaskBelow ParenTop]
VZigzag.fromSide Middle ParenBot ParenTop (radiusBox / 4) 10 0 GeometryStroke
define space : (rightBox - leftBox - [HSwToV GeometryStroke] * 2) / 3
create-glyph 'doubleWigglyFenceLeft' 0x29DA : glyph-proc

View file

@ -13,6 +13,7 @@ export : define [apply] : begin
run-glyph-module "./pictograph/faces.mjs"
run-glyph-module "./pictograph/flags.mjs"
run-glyph-module "./pictograph/game-sprite.mjs"
run-glyph-module "./pictograph/geometric.mjs"
run-glyph-module "./pictograph/heart.mjs"
run-glyph-module "./pictograph/hourglass.mjs"
run-glyph-module "./pictograph/i-ching.mjs"

View file

@ -12,7 +12,6 @@ glyph-block Symbol-Pictograph-Game-Sprite : for-width-kinds WideWidth4
glyph-block-import Shared-Symbol-Shapes : TriangleShape
glyph-block-import Symbol-Pictograph-Stick-Figure : StickFigureKit WithD4Transform D4Transform
glyph-block-import Symbol-Geometric-Shared : GeometricDim
glyph-block-import Symbol-Mosaic-Block : HShade VShade
define top fontMetrics.os2.sTypoAscender
define bottom fontMetrics.os2.sTypoDescender
@ -365,7 +364,7 @@ glyph-block Symbol-Pictograph-Game-Sprite : for-width-kinds WideWidth4
set scaffold.tipHeight : 1 / 4
define [RightRocket box] : glyph-proc
local rocketLeft : box.mixY (0.5 + scaffold.width / 2)
local rocketLeft : box.mixY (0.5 + scaffold.width / 2)
local rocketRight : box.mixY (0.5 - scaffold.width / 2)
local rocketBase : box.mixX scaffold.baseHeight
local rocketTip : box.mixX (1 - scaffold.tipHeight)
@ -483,91 +482,6 @@ glyph-block Symbol-Pictograph-Game-Sprite : for-width-kinds WideWidth4
include : UpFrog squareBox : D4Transform midX 2 0
do "Square Spiral"
define directions : list
* {.dx 1 .dy 0 .heading Rightward}
* {.dx 0 .dy 1 .heading Upward}
* {.dx (-1) .dy 0 .heading Leftward}
* {.dx 0 .dy (-1) .heading Downward}
define spiralSw : AdviceStroke 4 : Math.sqrt (MosaicWidthScalar / 2)
define oneStep : Geom.Size / 4.5
define stepsPerTurn { 9 9 9 7 7 5 5 3 3 }
define [SquareSpiral startx starty startidx] : glyph-proc
local x1 startx
local y1 starty
foreach [idx : range 0 stepsPerTurn.length] : begin
local {.dx dx .dy dy .heading dir} directions.((startidx + idx) % 4)
local x2 : x1 + dx * oneStep * stepsPerTurn.(idx)
local y2 : y1 + dy * oneStep * stepsPerTurn.(idx)
include : dispiro
widths.lhs spiralSw
disable-contrast
flat x1 y1 [heading dir]
curl x2 y2 [heading dir]
set x1 x2
set y1 y2
create-glyph [MangleName "squareSpiralFromTopLeft"] [MangleUnicode 0x1CC7C] : glyph-proc
set-width MosaicWidth
include : SquareSpiral Geom.Left Geom.Top 3
create-glyph [MangleName "squareSpiralFromTopRight"] [MangleUnicode 0x1CC7D] : glyph-proc
set-width MosaicWidth
include : SquareSpiral Geom.Right Geom.Top 2
create-glyph [MangleName "squareSpiralFromBottomRight"] [MangleUnicode 0x1CC7E] : glyph-proc
set-width MosaicWidth
include : SquareSpiral Geom.Right Geom.Bot 1
create-glyph [MangleName "squareSpiralFromBottomLeft"] [MangleUnicode 0x1CC7F] : glyph-proc
set-width MosaicWidth
include : SquareSpiral Geom.Left Geom.Bot 0
do "Ladder"
create-glyph [MangleName "vertLadder"] [MangleUnicode 0x1CC84] : glyph-proc
set-width MosaicWidth
include : HShade 8 top bottom Geom.Left Geom.Right
include : VBar.l Geom.Left bottom top GeometryStroke
include : VBar.r Geom.Right bottom top GeometryStroke
create-glyph [MangleName "horiLadder"] [MangleUnicode 0x1CC85] : glyph-proc
set-width MosaicWidth
include : VShade (4 * MosaicWidthScalar) Geom.Top Geom.Bot left right
include : HBar.b left right Geom.Bot GeometryStroke
include : HBar.t left right Geom.Top GeometryStroke
do "Striped Triangles"
define stripes : 2 + 2 * MosaicWidthScalar
define coTop : mix Geom.Top Geom.Bot (0 - 1 / (2 * stripes))
define coBot : mix Geom.Top Geom.Bot (1 + 1 / (2 * stripes))
define coLeft : mix Geom.Left Geom.Right (0 - 1 / (2 * stripes))
define coRight : mix Geom.Left Geom.Right (1 + 1 / (2 * stripes))
create-glyph [MangleName "stripedTriangleLeft"] [MangleUnicode 0x1CC80] : glyph-proc
set-width MosaicWidth
include : intersection
refer-glyph : MangleName "blackTriangleLeft"
VShade stripes top bottom coLeft coRight
create-glyph [MangleName "stripedTriangleUp"] [MangleUnicode 0x1CC81] : glyph-proc
set-width MosaicWidth
include : intersection
refer-glyph : MangleName "blackTriangleUp"
HShade stripes coTop coBot left right
create-glyph [MangleName "stripedTriangleRight"] [MangleUnicode 0x1CC82] : glyph-proc
set-width MosaicWidth
include : intersection
refer-glyph : MangleName "blackTriangleRight"
VShade stripes top bottom coLeft coRight
create-glyph [MangleName "stripedTriangleDown"] [MangleUnicode 0x1CC83] : glyph-proc
set-width MosaicWidth
include : intersection
refer-glyph : MangleName "blackTriangleDown"
HShade stripes coTop coBot left right
do "Moon Lander"
define scaffold : object
set scaffold.tipSize 0.2

View file

@ -0,0 +1,118 @@
$$include '../../meta/macros.ptl'
import [mix linreg clamp fallback strokeOffset] from "@iosevka/util"
import [Box] from "@iosevka/geometry/box"
import [Transform] from "@iosevka/geometry/transform"
glyph-module
glyph-block Symbol-Pictograph-Geometric : for-width-kinds WideWidth4
glyph-block-import CommonShapes
glyph-block-import Common-Derivatives
glyph-block-import Symbol-Geometric-Shared : GeometricDim
glyph-block-import Symbol-Mosaic-Block : HShade VShade
define top fontMetrics.os2.sTypoAscender
define bottom fontMetrics.os2.sTypoDescender
define left 0
define right MosaicWidth
define midX : mix left right 0.5
define midY : mix top bottom 0.5
define Geom : GeometricDim MosaicUnitWidth MosaicWidth
do "Square Spiral"
define directions : list
* {.dx 1 .dy 0 .heading Rightward}
* {.dx 0 .dy 1 .heading Upward}
* {.dx (-1) .dy 0 .heading Leftward}
* {.dx 0 .dy (-1) .heading Downward}
define spiralSw : AdviceStroke 4 : Math.sqrt (MosaicWidthScalar / 2)
define oneStep : Geom.Size / 4.5
define stepsPerTurn { 9 9 9 7 7 5 5 3 3 }
define [SquareSpiral startx starty startidx] : glyph-proc
local x1 startx
local y1 starty
foreach [idx : range 0 stepsPerTurn.length] : begin
local {.dx dx .dy dy .heading dir} directions.((startidx + idx) % 4)
local x2 : x1 + dx * oneStep * stepsPerTurn.(idx)
local y2 : y1 + dy * oneStep * stepsPerTurn.(idx)
include : dispiro
widths.lhs spiralSw
disable-contrast
flat x1 y1 [heading dir]
curl x2 y2 [heading dir]
set x1 x2
set y1 y2
create-glyph [MangleName "squareSpiralFromTopLeft"] [MangleUnicode 0x1CC7C] : glyph-proc
set-width MosaicWidth
include : SquareSpiral Geom.Left Geom.Top 3
create-glyph [MangleName "squareSpiralFromTopRight"] [MangleUnicode 0x1CC7D] : glyph-proc
set-width MosaicWidth
include : SquareSpiral Geom.Right Geom.Top 2
create-glyph [MangleName "squareSpiralFromBottomRight"] [MangleUnicode 0x1CC7E] : glyph-proc
set-width MosaicWidth
include : SquareSpiral Geom.Right Geom.Bot 1
create-glyph [MangleName "squareSpiralFromBottomLeft"] [MangleUnicode 0x1CC7F] : glyph-proc
set-width MosaicWidth
include : SquareSpiral Geom.Left Geom.Bot 0
do "Ladder"
create-glyph [MangleName "vertLadder"] [MangleUnicode 0x1CC84] : glyph-proc
set-width MosaicWidth
include : HShade 8 top bottom Geom.Left Geom.Right
include : VBar.l Geom.Left bottom top GeometryStroke
include : VBar.r Geom.Right bottom top GeometryStroke
create-glyph [MangleName "horiLadder"] [MangleUnicode 0x1CC85] : glyph-proc
set-width MosaicWidth
include : VShade (4 * MosaicWidthScalar) Geom.Top Geom.Bot left right
include : HBar.b left right Geom.Bot GeometryStroke
include : HBar.t left right Geom.Top GeometryStroke
do "Striped Triangles"
define stripes : 2 + 2 * MosaicWidthScalar
define coTop : mix Geom.Top Geom.Bot (0 - 1 / (2 * stripes))
define coBot : mix Geom.Top Geom.Bot (1 + 1 / (2 * stripes))
define coLeft : mix Geom.Left Geom.Right (0 - 1 / (2 * stripes))
define coRight : mix Geom.Left Geom.Right (1 + 1 / (2 * stripes))
create-glyph [MangleName "stripedTriangleLeft"] [MangleUnicode 0x1CC80] : glyph-proc
set-width MosaicWidth
include : intersection
refer-glyph : MangleName "blackTriangleLeft"
VShade stripes top bottom coLeft coRight
create-glyph [MangleName "stripedTriangleUp"] [MangleUnicode 0x1CC81] : glyph-proc
set-width MosaicWidth
include : intersection
refer-glyph : MangleName "blackTriangleUp"
HShade stripes coTop coBot left right
create-glyph [MangleName "stripedTriangleRight"] [MangleUnicode 0x1CC82] : glyph-proc
set-width MosaicWidth
include : intersection
refer-glyph : MangleName "blackTriangleRight"
VShade stripes top bottom coLeft coRight
create-glyph [MangleName "stripedTriangleDown"] [MangleUnicode 0x1CC83] : glyph-proc
set-width MosaicWidth
include : intersection
refer-glyph : MangleName "blackTriangleDown"
HShade stripes coTop coBot left right
do "Horizontal Zigzag"
glyph-block-import Shared-Symbol-Shapes : HZigzag
create-glyph [MangleName 'horiZigzag'] [MangleUnicode 0x1CEB0] : glyph-proc
set-width Geom.Width
define left : SB * MosaicWidthScalar
define right : RightSB * MosaicWidthScalar
define amp : (OperTop - OperBot) / 8
define sgmts : 4 * MosaicWidthScalar + 1
include : HZigzag.fromSide Geom.MidY left right amp sgmts 1 GeometryStroke

View file

@ -123,64 +123,30 @@ glyph-block Symbol-Pictograph-Schematic : for-width-kinds WideWidth4 : begin
corner midx midy
do "Resistor"
glyph-block-import Shared-Symbol-Shapes : HZigzag VZigzag
define amplitude : Geom.Size * 0.8
define vWaves 2
define hWaves MosaicWidthScalar
define [HoriWaveSegment left right lefty righty sw] : intersection
MaskRight left
MaskLeft right
ExtLineCenter 1 sw left lefty right righty
define [VertWaveSegment bot top botx topx sw] : intersection
MaskAbove bot
MaskBelow top
ExtLineCenter 1 sw botx bot topx top
create-glyph [MangleName 'resistorHori'] [MangleUnicode 0x1CC09] : glyph-proc
set-width MosaicWidth
include : ForceUpright
local segs : 2 * hWaves - 1
local halfPeriod : MosaicWidth / (2 * hWaves)
local up : midy + amplitude
local down : midy - amplitude
include : intersection
MaskLeft : left + 0.5 * halfPeriod
MaskAbove : midy - 0.5 * boxDrawingStroke
ExtLineCenter 1 boxDrawingStroke left midy (left + 0.5 * halfPeriod) up
foreach [j : range 0 segs] : begin
include : HoriWaveSegment
left + (j + 0.5) * halfPeriod
left + (j + 1.5) * halfPeriod
if (j % 2) down up
if (j % 2) up down
* boxDrawingStroke
include : intersection
MaskRight : right - 0.5 * halfPeriod
MaskBelow : midy + 0.5 * boxDrawingStroke
ExtLineCenter 1 boxDrawingStroke (right - 0.5 * halfPeriod) down right midy
local segs : 2 * hWaves
local mask : (right - left) / (segs * 2)
include : difference
HZigzag.fromCenter midy left right amplitude segs 0 boxDrawingStroke 1
MaskLeftLine (left + mask) bottom (left + mask) (midy - boxDrawingStroke / 2)
MaskRightLine (right - mask) (midy + boxDrawingStroke / 2) (right - mask) top
create-glyph [MangleName 'resistorVert'] [MangleUnicode 0x1CC0A] : glyph-proc
set-width MosaicWidth
include : ForceUpright
local segs : 2 * vWaves - 1
local halfPeriod : MosaicHeight / (2 * vWaves)
local up : midx + amplitude
local down : midx - amplitude
include : intersection
MaskBelow : bottom + 0.5 * halfPeriod
MaskRight : midx - [HSwToV : 0.5 * boxDrawingStroke]
ExtLineCenter 1 boxDrawingStroke midx bottom up (bottom + 0.5 * halfPeriod)
foreach [j : range 0 segs] : begin
include : VertWaveSegment
bottom + (j + 0.5) * halfPeriod
bottom + (j + 1.5) * halfPeriod
if (j % 2) down up
if (j % 2) up down
* boxDrawingStroke
include : intersection
MaskAbove : top - 0.5 * halfPeriod
MaskLeft : midx + [HSwToV : 0.5 * boxDrawingStroke]
ExtLineCenter 1 boxDrawingStroke down (top - 0.5 * halfPeriod) midx top
local segs : 2 * vWaves
local mask : (top - bottom) / (segs * 2)
include : difference
VZigzag.fromCenter midx bottom top amplitude segs 0 boxDrawingStroke 1
MaskBelowLine left (bottom + mask) (midx - [HSwToV : boxDrawingStroke / 2]) (bottom + mask)
MaskAboveLine (midx + [HSwToV : boxDrawingStroke / 2]) (top - mask) right (top - mask)
do "Coil"
glyph-block-import Symbol-Mosaic-Split-Graphic : Multicell
@ -258,7 +224,7 @@ glyph-block Symbol-Pictograph-Schematic : for-width-kinds WideWidth4 : begin
local tipDy : tipDx * (-slope)
local baseDx : -tipDy / [Math.sqrt 3] * 2
local baseDy : baseDx / (-slope)
define arrowPos : (1 - [HSwToV boxDrawingStroke] / (MosaicWidth / 2)) * 0.4
define arrowPos : (1 - [HSwToV boxDrawingStroke] / MosaicMiddle) * 0.4
define [VerticalPart] : intersection
Rect top bottom left (midx + [HSwToV : 0.5 * boxDrawingStroke])

View file

@ -1,6 +1,7 @@
$$include '../meta/macros.ptl'
import [mix linreg clamp fallback] from "@iosevka/util"
import [Point] from "@iosevka/geometry/point"
glyph-module
@ -36,6 +37,32 @@ glyph-block Shared-Symbol-Shapes : begin
define [WaveShape] : with-params [left right xsJoin xfJoin diagJoinS diagJoinF [waveCount 1] [unitWidth Width]] : WaveShapeImpl (unitWidth * -left) (unitWidth * (1 + right)) (-left * waveCount) ((1 + right) * waveCount) xsJoin xfJoin diagJoinS diagJoinF
return WaveShape
glyph-block-export Polyline ClosedPolyline
define [Polyline] : with-params [af points [contrast HVContrast] [upright 0]] : begin
local {{x0 y0} {xp yp}} points
local knots : list
flat x0 y0 af
sharp-corner xp yp contrast upright
foreach {x y} [items-of : points.slice 2 (-1)] : begin
knots.push : virt [mix xp x 0.5] [mix yp y 0.5] af
knots.push : sharp-corner x y contrast upright
set {xp yp} {x y}
set {xp yp} points.[points.length - 1]
knots.push : curl xp yp af
return knots
define [ClosedPolyline] : with-params [af points [contrast HVContrast] [upright 0]] : begin
local {xp yp} points.[points.length - 1]
local knots : list
foreach {x y} [items-of points] : begin
knots.push : virt [mix xp x 0.5] [mix yp y 0.5] af
knots.push : sharp-corner x y contrast upright
set {xp yp} {x y}
knots.push : close
return knots
glyph-block-export TriangleShape
define [TriangleShape x1 y1 x2 y2 x3 y3 sw] : begin
local widthSide : if ((y2 - y1) * (y3 - y2) + (x2 - x1) * (x3 - x2) < 0) widths.rhs widths.lhs
@ -59,36 +86,101 @@ glyph-block Shared-Symbol-Shapes : begin
corner x3 y3
corner x1 y1
define [HZigzagSegment x1 x2 y1 y2 sw] : intersection
MaskRight x1
MaskLeft x2
ExtLineCenter 1 sw x1 y1 x2 y2
define [VZigzagSegment y1 y2 x1 x2 sw] : intersection
MaskAbove y1
MaskBelow y2
ExtLineCenter 1 sw x1 y1 x2 y2
glyph-block-export HZigzag VZigzag
define [HZigzag midy left right amp sgmts phase sw] : glyph-proc
local halfPeriod : (right - left) / sgmts
local up : midy + amp
local down : midy - amp
foreach [j : range 0 sgmts] : begin
include : HZigzagSegment
left + j * halfPeriod
left + (j + 1) * halfPeriod
if ((j + phase) % 2) down up
if ((j + phase) % 2) up down
* sw
define [VZigzag midx bot top amp sgmts phase sw] : glyph-proc
local halfPeriod : (top - bot) / sgmts
local up : midx + amp
local down : midx - amp
foreach [j : range 0 sgmts] : begin
include : VZigzagSegment
bot + j * halfPeriod
bot + (j + 1) * halfPeriod
if ((j + phase) % 2) down up
if ((j + phase) % 2) up down
* sw
define HZigzag : namespace
define [getOffset dx dy upright sw] : begin
local T : new Point Point.Type.Corner dx dy
local N : TangentToNormal T HVContrast [if upright 0]
local D : T.scale : N.x / T.x * sw / 2
return D
export : define [fromSide midy left right amp sgmts phase sw upright] : glyph-proc
local halfPeriod : (right - left) / sgmts
local posOff : getOffset halfPeriod ( 2 * amp) upright (-sw)
local negOff : getOffset halfPeriod (-2 * amp) upright sw
local pos : midy + amp
local neg : midy - amp
local points : list
points.push : list
if phase (left - posOff.x) (left - negOff.x)
if phase (neg - posOff.y) (pos - negOff.y)
foreach [j : range 1 sgmts] : begin
points.push : list
left + j * halfPeriod
if ((j + phase) % 2) neg pos
points.push : list
if ((sgmts + phase) % 2) (right + negOff.x) (right + posOff.x)
if ((sgmts + phase) % 2) (neg + negOff.y) (pos + posOff.y)
include : dispiro : Polyline [widths.center sw] points (upright -- upright)
export : define [fromCenter midy left right amp sgmts phase sw upright] : glyph-proc
local halfPeriod : (right - left) / sgmts
local posOff : getOffset halfPeriod ( 2 * amp) upright (-sw)
local negOff : getOffset halfPeriod (-2 * amp) upright sw
local pos : midy + amp
local neg : midy - amp
local points : list
points.push : list
if phase (left - negOff.x) (left - posOff.x)
if phase (midy - negOff.y) (midy - posOff.y)
foreach [j : range 0 sgmts] : begin
points.push : list
left + (j + 0.5) * halfPeriod
if ((j + phase) % 2) neg pos
points.push : list
if ((sgmts + phase) % 2) (right + negOff.x) (right + posOff.x)
if ((sgmts + phase) % 2) (midy + negOff.y) (midy + posOff.y)
include : dispiro : Polyline [widths.center sw] points (upright -- upright)
define VZigzag : namespace
define [getOffset dx dy upright sw] : begin
local T : new Point Point.Type.Corner dx dy
local N : TangentToNormal T HVContrast [if upright 0]
local D : T.scale : N.y / T.y * sw / 2
return D
export : define [fromSide midx bot top amp sgmts phase sw upright] : glyph-proc
local halfPeriod : (top - bot) / sgmts
local posOff : getOffset ( 2 * amp) halfPeriod upright sw
local negOff : getOffset (-2 * amp) halfPeriod upright (-sw)
local pos : midx + amp
local neg : midx - amp
local points : list
points.push : list
if phase (neg - posOff.x) (pos - negOff.x)
if phase (bot - posOff.y) (bot - negOff.y)
foreach [j : range 1 sgmts] : begin
points.push : list
if ((j + phase) % 2) neg pos
bot + j * halfPeriod
points.push : list
if ((sgmts + phase) % 2) (neg + negOff.x) (pos + posOff.x)
if ((sgmts + phase) % 2) (top + negOff.y) (top + posOff.y)
include : dispiro : Polyline [widths.center sw] points (upright -- upright)
export : define [fromCenter midx bot top amp sgmts phase sw upright] : glyph-proc
local halfPeriod : (top - bot) / sgmts
local posOff : getOffset ( 2 * amp) halfPeriod upright sw
local negOff : getOffset (-2 * amp) halfPeriod upright (-sw)
local pos : midx + amp
local neg : midx - amp
local points : list
points.push : list
if phase (midx - negOff.x) (midx - posOff.x)
if phase (bot - negOff.y) (bot - posOff.y)
foreach [j : range 0 sgmts] : begin
points.push : list
if ((j + phase) % 2) neg pos
bot + (j + 0.5) * halfPeriod
points.push : list
if ((sgmts + phase) % 2) (midx + negOff.x) (midx + posOff.x)
if ((sgmts + phase) % 2) (top + negOff.y) (top + posOff.y)
include : dispiro : Polyline [widths.center sw] points (upright -- upright)