### Punctuation symbols
$$include '../../meta/macros.ptl'

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

glyph-module

glyph-block Symbol-Punctuation-Ampersand : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Letter-Latin-Ezh : RevEzhShape
	glyph-block-import Letter-Shared-Shapes : RightwardTailedBar SerifedArcEnd

	define SwAmpersand : AdviceStroke2 2.5 3 CAP
	define fineAmp : AdviceStroke 3.5
	define pxUpperLoopRight : 0.75 + HalfStroke / (RightSB - SB)
	define pxUpperLoopLeft  0.05
	define pXTerminal 1.1
	define pStraightBar 0.4

	define adaUpperLoop : ArchDepthAOf (ArchDepth * (pxUpperLoopRight - pxUpperLoopLeft)) Width
	define adbUpperLoop : ArchDepthBOf (ArchDepth * (pxUpperLoopRight - pxUpperLoopLeft)) Width

	define xTerminal : [mix SB RightSB pXTerminal] - [HSwToV SwAmpersand]
	define xUpperLoopLeft : mix SB RightSB pxUpperLoopLeft
	define yUpperLoopLeft : CAP - adaUpperLoop
	define xUpperLoopRight : mix SB RightSB pxUpperLoopRight
	define yUpperLoopRight : CAP - adbUpperLoop
	define xUpperLoopTop : mix xUpperLoopLeft xUpperLoopRight 0.5
	define yMockUpperLoopLeftBottom : CAP - adaUpperLoop - adbUpperLoop * 0.3

	define ClosedTipSw     : AdviceStroke 3
	define ClosedIncisedSw : AdviceStroke 5
	define ClosedBottomSlopeVal : (-0.5) * (SwAmpersand - ClosedIncisedSw) / SwAmpersand
	define ClosedBottomSlope {.x ClosedBottomSlopeVal .y (-1)}
	define xClosedAmpersandBottom : [mix SB RightSB 0.44] + (0.125 + 0.5 * CorrectionOMidX + ClosedBottomSlopeVal) * SwAmpersand
	define [ClosedAmpersandLeadDim sw swTip offset] : begin
		define x1 : [mix SB RightSB 0.80] - offset
		define x2 : [mix SB RightSB pXTerminal] + [HSwToV : 0.1 * sw] - offset
		define y1   0
		define y2 : CAP * 0.375 + sw / 2
		define k1   0.5
		return : object x1 x2 y1 y2 k1
	define [ClosedAmpersandLead sw swTip] : begin
		define [object x1 x2 y1 y2 k1] : ClosedAmpersandLeadDim sw swTip 0
		return : intersection [MaskBelow y2] : dispiro
			flat [mix x1 x2 4]  [mix y1 y2 4]  [widths.rhs swTip]
			curl [mix x1 x2 k1] [mix y1 y2 k1]
			g4.left.mid xClosedAmpersandBottom O [widths.rhs.heading sw ClosedBottomSlope]

	define [ClosedAmpersandLeadMask2 sw swTip] : begin
		define [object x1 x2 y1 y2 k1] : ClosedAmpersandLeadDim sw swTip [HSwToV : sw - swTip]
		return : intersection [MaskBelow y2] : spiro-outline
			flat [mix x1 x2 4]  [mix y1 y2 4]  [widths.rhs swTip]
			curl [mix x1 x2 k1] [mix y1 y2 k1]
			g4.left.mid xClosedAmpersandBottom O [widths.rhs sw]
			corner 0 O
			corner 0 [mix y1 y2 4]

	define [ClosedAmpersandLeadMask] : union
		intersection
			MaskAbove [mix yMockUpperLoopLeftBottom 0 pStraightBar]
			MaskRight xClosedAmpersandBottom
		spiro-outline
			corner [mix xUpperLoopLeft xTerminal pStraightBar] [mix yMockUpperLoopLeftBottom 0 pStraightBar]
			corner [mix xUpperLoopLeft xTerminal 2]            (-yMockUpperLoopLeftBottom)
			corner [mix xUpperLoopLeft xTerminal 4]            (-yMockUpperLoopLeftBottom)
			corner [mix xUpperLoopLeft xTerminal 4]            [mix yMockUpperLoopLeftBottom 0 pStraightBar]


	create-glyph 'ampersand.closed' : union
		intersection
			ClosedAmpersandLead SwAmpersand ClosedTipSw
			ClosedAmpersandLeadMask
		difference
			intersection
				ClosedAmpersandLead SwAmpersand ClosedTipSw
				ClosedAmpersandLeadMask2 SwAmpersand ClosedIncisedSw
			ClosedAmpersandLeadMask
		difference
			dispiro
				g4.left.mid xClosedAmpersandBottom O [widths.rhs.heading SwAmpersand ClosedBottomSlope]
				archv
				g4   (SB + OX) [YSmoothMidL (0.66 * yUpperLoopRight + HalfStroke) O ArchDepthA ArchDepthB]
				alsoThru 0.5 0.5 [widths.center SwAmpersand]
				g4   xUpperLoopRight yUpperLoopRight [widths.lhs SwAmpersand]
				arch.lhs CAP (sw -- SwAmpersand)
				g4   xUpperLoopLeft yUpperLoopLeft
				flat [mix xUpperLoopLeft xTerminal pStraightBar] [mix yMockUpperLoopLeftBottom 0 pStraightBar]
				curl [mix xUpperLoopLeft xTerminal 2] (-yMockUpperLoopLeftBottom)
			Rect 0 ((-CAP) * 2) xTerminal (Width * 2)

	create-glyph 'ampersand.upperOpen' : union
		intersection
			ClosedAmpersandLead SwAmpersand ClosedTipSw
			ClosedAmpersandLeadMask
		difference
			intersection
				ClosedAmpersandLead SwAmpersand ClosedTipSw
				ClosedAmpersandLeadMask2 SwAmpersand ClosedIncisedSw
			ClosedAmpersandLeadMask
		difference
			dispiro
				g4.left.mid xClosedAmpersandBottom O [widths.rhs.heading SwAmpersand ClosedBottomSlope]
				archv
				g4   (SB + OX) [YSmoothMidL (0.66 * yUpperLoopRight + HalfStroke) O ArchDepthA ArchDepthB]
				alsoThru 0.5 0.5 [widths.center SwAmpersand]
				g4   xUpperLoopRight yUpperLoopRight [widths.lhs SwAmpersand]
			Rect (CAP * 2) yUpperLoopRight 0 Width
			Rect (CAP * 2) (0.5 * CAP) Middle Width
			intersection
				Rect (CAP * 2) ArchDepthA 0 (RightSB - [HSwToV fineAmp])
				with-transform [Translate (-O) 0] : spiro-outline
					arch.lhs.centerAt.rtl.t xUpperLoopTop CAP (sw -- SwAmpersand)
					archv
					g4   xUpperLoopLeft yUpperLoopLeft
					flat [mix xUpperLoopLeft xTerminal pStraightBar] [mix yMockUpperLoopLeftBottom 0 pStraightBar]
					corner [mix xUpperLoopLeft xTerminal 2] (-yMockUpperLoopLeftBottom)
					corner ([mix xUpperLoopLeft xTerminal 2] + Width * 2) (-yMockUpperLoopLeftBottom)
					corner ([mix xUpperLoopLeft xTerminal 2] + Width * 2) (CAP - O)
		difference
			dispiro
				g4.up.start xUpperLoopRight yUpperLoopRight [widths.heading SwAmpersand 0 Upward]
				arcvh
				arch.lhs.centerAt.rtl.t xUpperLoopTop CAP (sw -- SwAmpersand)
				archv
				g4  xUpperLoopLeft yUpperLoopLeft
				flat [mix xUpperLoopLeft xTerminal pStraightBar] [mix yMockUpperLoopLeftBottom 0 pStraightBar]
				curl [mix xUpperLoopLeft xTerminal 2] (-yMockUpperLoopLeftBottom)
			Rect 0 ((-CAP) * 2) xTerminal (Width * 2)

	define xLowerOpenRight : mix xUpperLoopRight RightSB 0.5
	define xLowerOpenBottom : mix SB xLowerOpenRight 0.5
	define yLowerOpenEnd : Math.max (ArchDepthA + fineAmp) (CAP * 0.45)
	define xLowerOpenBarRight : mix xLowerOpenRight Width 0.5
	define xLowerOpenBarLeft : Math.min
		xLowerOpenRight - [HSwToV Stroke] - xLowerOpenBarRight + xLowerOpenRight
		mix Middle xLowerOpenRight 0.5
	define [LowerOpenCrossbar y] : dispiro
		widths.rhs fineAmp
		corner (xLowerOpenBarLeft  + TanSlope * fineAmp / 2) y
		corner (xLowerOpenBarRight + TanSlope * fineAmp / 2) y

	create-glyph 'ampersand.lowerOpen' : union
		LowerOpenCrossbar yLowerOpenEnd
		dispiro
			widths.rhs SwAmpersand
			flat (xLowerOpenRight - O) yLowerOpenEnd [heading Downward]
			curl (xLowerOpenRight - O) ArchDepthA
			arcvh
			arch.rhs.centerAt.rtl.b xLowerOpenBottom 0 (sw -- SwAmpersand)
			archv
			g4   (SB + O) ArchDepthB
			alsoThru 0.5 0.5 [widths.center SwAmpersand]
			g4   xUpperLoopRight yUpperLoopRight [widths.lhs SwAmpersand]
			arcvh
			arch.lhs.centerAt.rtl.t xUpperLoopTop CAP (sw -- SwAmpersand)

		difference
			dispiro
				arch.lhs.centerAt.rtl.t xUpperLoopTop CAP (sw -- SwAmpersand)
				archv
				g4   xUpperLoopLeft yUpperLoopLeft
				flat [mix xUpperLoopLeft xTerminal pStraightBar] [mix yMockUpperLoopLeftBottom 0 pStraightBar]
				curl xTerminal 0
			spiro-outline
				arch.rhs.centerAt.rtl.b xLowerOpenBottom 0 (sw -- SwAmpersand)
				archv
				g4   (SB + OX) [YSmoothMidL (0.66 * yUpperLoopRight + HalfStroke) O ArchDepthA ArchDepthB]
				alsoThru 0.5 0.5 [widths.center SwAmpersand]
				g4   xUpperLoopRight yUpperLoopRight
				arcvh
				arch.lhs.centerAt.rtl.t (knot-ty -- corner) xUpperLoopTop CAP (sw -- SwAmpersand)
				arch.lhs.centerAt.rtl.t (knot-ty -- corner) xUpperLoopTop (CAP * 2) (sw -- SwAmpersand)
				corner (Width * 2) (CAP * 2)
				corner (Width * 2) O

	define yEtMiddle : CAP * OverlayPos
	define adaEt : CAP - [mix (yEtMiddle + SwAmpersand / 2) (CAP - O - SwAmpersand) (ArchDepthB / (ArchDepthA + ArchDepthB))] - [HSwToV TanSlope] * SwAmpersand
	define adbEt : [mix (SwAmpersand + O) (yEtMiddle - SwAmpersand / 2) (ArchDepthB / (ArchDepthA + ArchDepthB))] + [HSwToV TanSlope] * SwAmpersand
	define fineEt : SwAmpersand * CThin
	define xEtLeft SB
	define xEtRight : mix xUpperLoopRight RightSB 0.5
	define xEtCenterBarRight : mix xEtRight Width 0.5
	define yEtRightBarTop : mix (yEtMiddle + SwAmpersand / 2) (CAP - SHook) 0.375

	define FORM-TOOTHLESS-CORNER  1
	define FORM-TOOTHLESS-ROUNDED 2
	define FORM-TOOTHED           3

	define [EtUpperHalf] : dispiro
		g4 xEtRight (CAP - SHook) [widths.lhs]
		hookstart CAP
		g4 xEtLeft (CAP - adaEt)
		arcvh
		flat Middle (yEtMiddle - (fineEt - SwAmpersand / 2)) [widths.heading fineEt 0 Rightward]
		curl xEtCenterBarRight (yEtMiddle - (fineEt - SwAmpersand / 2)) [heading Rightward]

	define [EtLowerHalf form] : dispiro
		flat xEtCenterBarRight (yEtMiddle + (fineEt - SwAmpersand / 2)) [widths.heading fineEt 0 Leftward]
		curl Middle (yEtMiddle + (fineEt - SwAmpersand / 2)) [heading Leftward]
		archv
		g4 (xEtLeft + O * 2) adbEt [widths.lhs]
		match form
			[Just FORM-TOOTHLESS-CORNER] : list
				arch.lhs 0 (blendPost -- {})
				g4   xEtRight DToothlessRise

			[Just FORM-TOOTHLESS-ROUNDED] : list
				arch.lhs 0
				flat xEtRight adaEt
				curl xEtRight yEtRightBarTop [heading Upward]

			[Just FORM-TOOTHED] : begin
				SerifedArcEnd.LtrLhs xEtRight 0 Stroke adaEt Stroke
			_ : list


	create-glyph 'ampersand.etToothlessCorner' : union
		EtUpperHalf
		EtLowerHalf FORM-TOOTHLESS-CORNER
		VBar.r xEtRight DToothlessRise yEtRightBarTop

	create-glyph 'ampersand.etToothlessRounded' : union
		EtUpperHalf
		EtLowerHalf FORM-TOOTHLESS-ROUNDED

	create-glyph 'ampersand.etToothed' : union
		EtUpperHalf
		EtLowerHalf FORM-TOOTHED
		VBar.r xEtRight (adaEt + O) yEtRightBarTop
		VBar.r xEtRight adaEt 0 [Math.max [AdviceStroke 5] (Stroke - ShoulderFine / 2)]

	create-glyph 'ampersand.etTailed' : union
		EtUpperHalf
		EtLowerHalf FORM-TOOTHED
		RightwardTailedBar xEtRight 0 yEtRightBarTop

	define yEtFlatTopEnd : Math.max (ArchDepthA + fineAmp) (CAP * 0.4)
	define yEtFlatTopBarPos : (OverlayPos * CAP + Stroke * 0.625) / CAP

	create-glyph 'ampersand.flatTop' : union
		LowerOpenCrossbar yEtFlatTopEnd
		RevEzhShape CAP 0 (hookless -- true) (ada -- ArchDepthA) (adb -- ArchDepthB) (pyBar -- yEtFlatTopBarPos) (diagCoeff -- 1.2)
		dispiro
			widths.lhs
			g4.down.start (SB + OX) [RevEzhShape.yLoopLeft CAP 0 yEtFlatTopBarPos adaEt adbEt]
			arch.lhs 0 (swAfter -- fineAmp)
			flat (xLowerOpenRight - OX) adaEt [widths.lhs fineAmp]
			curl (xLowerOpenRight - OX) yEtFlatTopEnd [heading Upward]

	select-variant 'ampersand' '&'
