$$include '../../meta/macros.ptl'

import [mix linreg clamp fallback strokeOffset] from "@iosevka/util"
import [DesignParameters] from "../../meta/aesthetics.mjs"

glyph-module

glyph-block Symbol-Geometric-Plain : for-width-kinds WideWidth1
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Symbol-Geometric-Shared : GeometricDim GeometricSizes ConvexPolygonOutline

	define Geom : GeometricDim MosaicUnitWidth MosaicWidth
	define Size : GeometricSizes Geom

	define [StdBlackShape fn name unicode props] : begin
		local pp : fallback props {.}
		create-glyph [MangleName name] [MangleUnicode unicode] : glyph-proc
			set-width Geom.Width
			include : fn
				fallback pp.cx Geom.MidX
				fallback pp.cy Geom.MidY
				Geom.Size * [fallback pp.size 1]
				begin 0

	define [StdWhiteShapeImpl fn s out in props] : begin
		local pp : fallback props {.}
		local sw : fallback pp.sw GeometryStroke
		return : difference
			fn
				fallback pp.cx Geom.MidX
				fallback pp.cy Geom.MidY
				s * Geom.Size * [fallback pp.size 1] + out * sw
				(-out) * sw
			fn
				fallback pp.cx Geom.MidX
				fallback pp.cy Geom.MidY
				s * Geom.Size * [fallback pp.size 1] - in * sw
				in * sw

	define [ConvexWhitePolygonImpl fn props] : begin
		local pp : fallback props {.}
		local sh : new-glyph : fn
			fallback pp.cx Geom.MidX
			fallback pp.cy Geom.MidY
			Geom.Size * [fallback pp.size 1]
			begin 0
		return : ConvexPolygonOutline sh [fallback pp.sw GeometryStroke]

	define [StdWhiteShape fn name unicode props] : begin
		create-glyph [MangleName name] [MangleUnicode unicode] : glyph-proc
			set-width Geom.Width
			include : StdWhiteShapeImpl fn 1 0 1 props

	define [InnerShapeSize props] : begin
		local pp : fallback props {.}
		return : [fallback pp.innerSize 0.5] * (Geom.Size * [fallback pp.size 1] - [fallback pp.sw GeometryStroke])

	define [StdWhiteContainingBlackShape fn name unicode props] : begin
		local pp : fallback props {.}
		create-glyph [MangleName name] [MangleUnicode unicode] : glyph-proc
			set-width Geom.Width
			include : fn
				fallback pp.cx Geom.MidX
				fallback pp.cy Geom.MidY
				InnerShapeSize pp
				begin 0
			include : StdWhiteShapeImpl fn 1 0 1 props

	define [ConvexPolygonWhiteContainingBlackShape fn name unicode props] : begin
		local pp : fallback props {.}
		create-glyph [MangleName name] [MangleUnicode unicode] : glyph-proc
			set-width Geom.Width
			local sw : fallback pp.sw GeometryStroke
			include : fn
				fallback pp.cx Geom.MidX
				fallback pp.cy Geom.MidY
				InnerShapeSize pp
				begin 0
			include : ConvexWhitePolygonImpl fn props

	define [StdGeomTargetShape fn name unicode props] : begin
		local pp : fallback props {.}
		create-glyph [MangleName name] [MangleUnicode unicode] : glyph-proc
			set-width Geom.Width
			local sw : fallback pp.sw GeometryStroke
			include : fn
				fallback pp.cx Geom.MidX
				fallback pp.cy Geom.MidY
				[fallback pp.innerSize 0.25] * (Geom.Size * [fallback pp.size 1] - sw * 2)
				begin 0
			include : StdWhiteShapeImpl fn 1                                        0   1   props
			include : StdWhiteShapeImpl fn [mix 1 [fallback pp.innerSize 0.25] 0.5] 0   1   props

	define [StdDoubleWhite fn name unicode props] : begin
		local pp : fallback props {.}
		create-glyph [MangleName name] [MangleUnicode unicode] : glyph-proc
			set-width Geom.Width
			local sw : fallback pp.sw GeometryStroke
			include : difference
				fn
					fallback pp.cx Geom.MidX
					fallback pp.cy Geom.MidY
					0.5 * (Geom.Size * [fallback pp.size 1] - sw)
					begin 0
				fn
					fallback pp.cx Geom.MidX
					fallback pp.cy Geom.MidY
					0.5 * (Geom.Size * [fallback pp.size 1] - sw) - sw
					begin sw
			include : difference
				fn
					fallback pp.cx Geom.MidX
					fallback pp.cy Geom.MidY
					Geom.Size * [fallback pp.size 1]
					begin 0
				fn
					fallback pp.cx Geom.MidX
					fallback pp.cy Geom.MidY
					Geom.Size * [fallback pp.size 1] - sw
					begin sw

	define [ConvexWhitePolygon fn name unicode props] : begin
		create-glyph [MangleName name] [MangleUnicode unicode] : glyph-proc
			set-width Geom.Width
			include : ConvexWhitePolygonImpl fn props


	do "Square and Half-square triangle"
		define [SquareShape cx cy size] : spiro-outline
			corner (cx - size) (cy + size)
			corner (cx + size) (cy + size)
			corner (cx + size) (cy - size)
			corner (cx - size) (cy - size)

		StdBlackShape SquareShape 'blackSquare' 0x25A0
		StdWhiteShape SquareShape 'whiteSquare' 0x25A1

		StdWhiteShape SquareShape 'lightWhiteSquare'     0x1F78E {.sw [UnicodeWeightGrade 300  Geom.Scalar GeometryStroke]}
		StdWhiteShape SquareShape 'mediumWhiteSquare'    0x1F78F {.sw [UnicodeWeightGrade 500  Geom.Scalar GeometryStroke]}
		StdWhiteShape SquareShape 'boldWhiteSquare'      0x1F790 {.sw [UnicodeWeightGrade 700  Geom.Scalar GeometryStroke]}
		StdWhiteShape SquareShape 'heavyWhiteSquare'     0x1F791 {.sw [UnicodeWeightGrade 900  Geom.Scalar GeometryStroke]}
		StdWhiteShape SquareShape 'veryHeavyWhiteSquare' 0x1F792 {.sw [UnicodeWeightGrade 1000 Geom.Scalar GeometryStroke]}
		StdWhiteShape SquareShape 'exHeavyWhiteSquare'   0x1F793 {.sw [UnicodeWeightGrade 1100 Geom.Scalar GeometryStroke]}

		StdBlackShape SquareShape 'blackLargeSquare' 0x2B1B Size.Large
		StdBlackShape SquareShape 'blackMediumSquare' 0x25FC Size.Medium
		StdBlackShape SquareShape 'blackMediumSmallSquare' 0x25FE Size.MediumSmall
		StdBlackShape SquareShape 'blackSmallSquare' 0x25AA Size.Small
		StdBlackShape SquareShape 'blackVerySmallSquare' 0x2B1D Size.VerySmall
		StdBlackShape SquareShape 'blackSlightlySmallSquare' 0x1F78D Size.SlightlySmall
		StdBlackShape SquareShape 'blackTinySmallSquare' 0x1F78C Size.Tiny
		StdBlackShape SquareShape 'blackCenteredSquare' 0x2BC0

		StdWhiteShape SquareShape 'whiteLargeSquare' 0x2B1C Size.Large
		StdWhiteShape SquareShape 'whiteMediumSquare' 0x25FB Size.Medium
		StdWhiteShape SquareShape 'whiteMediumSmallSquare' 0x25FD Size.MediumSmall
		StdWhiteShape SquareShape 'whiteSmallSquare' 0x25AB Size.Small
		StdWhiteShape SquareShape 'whiteVerySmallSquare' 0x2B1E Size.VerySmall

		StdWhiteContainingBlackShape SquareShape 'whiteSquareWithCenter' 0x25A3
		StdWhiteContainingBlackShape SquareShape 'whiteSquareContainingBlackVerySmallSquare' 0x1F794 Size.TinyInner
		StdWhiteContainingBlackShape SquareShape 'whiteSquareContainingBlackMediumSquare' 0x1F795 Size.MediumInner
		StdWhiteContainingBlackShape SquareShape 'heavyWhiteSquareContainingBlackMediumSquare' 0x1CE05 : Object.assign Size.TinyInner {.sw [UnicodeWeightGrade 900 Geom.Scalar GeometryStroke]}

		StdGeomTargetShape SquareShape 'squareTarget' 0x1F796

		define [TriangleRBFill cx cy size] : spiro-outline
			corner (cx + size) (cy + size)
			corner (cx + size) (cy - size)
			corner (cx - size) (cy - size)

		define [TriangleLBFill cx cy size] : spiro-outline
			corner (cx - size) (cy + size)
			corner (cx + size) (cy - size)
			corner (cx - size) (cy - size)

		define [TriangleLTFill cx cy size] : spiro-outline
			corner (cx - size) (cy + size)
			corner (cx + size) (cy + size)
			corner (cx - size) (cy - size)

		define [TriangleRTFill cx cy size] : spiro-outline
			corner (cx - size) (cy + size)
			corner (cx + size) (cy + size)
			corner (cx + size) (cy - size)

		StdBlackShape TriangleRBFill 'blackTriangleRB' 0x25E2
		ConvexWhitePolygon TriangleRBFill 'whiteTriangleRB' 0x25FF
		StdBlackShape TriangleLBFill 'blackTriangleLB' 0x25E3
		ConvexWhitePolygon TriangleLBFill 'whiteTriangleLB' 0x25FA
		StdBlackShape TriangleLTFill 'blackTriangleLT' 0x25E4
		ConvexWhitePolygon TriangleLTFill 'whiteTriangleLT' 0x25F8
		StdBlackShape TriangleRTFill 'blackTriangleRT' 0x25E5
		ConvexWhitePolygon TriangleRTFill 'whiteTriangleRT' 0x25F9

		define [SquareOverlap name unicode rev square1 square2] : begin
			create-glyph [MangleName name] [MangleUnicode unicode] : glyph-proc
				set-width Geom.Width
				local space : Geom.Width * (1 - Size.Medium.size)
				local offsetX : space * 0.45 * [if rev (-1) 1]
				local offsetY : space * 0.45
				include : union
					with-transform [Translate (-offsetX) (-offsetY)] : refer-glyph : MangleName [if square1 'blackMediumSquare' 'whiteMediumSquare']
					with-transform [Translate offsetX offsetY] : refer-glyph : MangleName [if square2 'blackMediumSquare' 'whiteMediumSquare']

		SquareOverlap 'overlapWWSquareRev' 0x29C9 1 0 0
		SquareOverlap 'overlapWWSquare' 0x2BBA 0 0 0
		SquareOverlap 'overlapWBSquare' 0x2BBB 0 0 1
		SquareOverlap 'overlapBBSquare' 0x2BBC 0 1 1

	do "Rectangle"
		define [HoriRectangleFill cx cy r] : spiro-outline
			corner (cx - r) (cy + r / 1.5)
			corner (cx + r) (cy + r / 1.5)
			corner (cx + r) (cy - r / 1.5)
			corner (cx - r) (cy - r / 1.5)

		StdBlackShape HoriRectangleFill 'blackHoriRectangle' 0x25AC
		ConvexWhitePolygon HoriRectangleFill 'whiteHoriRectangle' 0x25AD

		define [VertRectangleFill cx cy r] : spiro-outline
			corner (cx - r / 1.5) (cy + r)
			corner (cx + r / 1.5) (cy + r)
			corner (cx + r / 1.5) (cy - r)
			corner (cx - r / 1.5) (cy - r)

		StdBlackShape VertRectangleFill 'blackVertRectangle' 0x25AE
		ConvexWhitePolygon VertRectangleFill 'whiteVertRectangle' 0x25AF

		create-glyph [MangleName 'whiteVertRectangleBar'] [MangleUnicode 0x1CE06] : glyph-proc
			set-width Geom.Width
			include : refer-glyph : MangleName 'whiteVertRectangle'
			include : HBar.m (Geom.MidX - Geom.Size) (Geom.MidX + Geom.Size) Geom.MidY GeometryStroke

		define [ParallelogramFill cx cy r] : begin
			define skew : r * 1 / 4
			return : spiro-outline
				corner (cx - r + skew) (cy + r / 1.5)
				corner (cx + r + skew) (cy + r / 1.5)
				corner (cx + r - skew) (cy - r / 1.5)
				corner (cx - r - skew) (cy - r / 1.5)

		StdBlackShape ParallelogramFill 'blackParallelogram' 0x25B0
		ConvexWhitePolygon ParallelogramFill 'whiteParallelogram' 0x25B1

		alias [MangleName 'flatness'] [MangleUnicode 0x23E5] [MangleName 'whiteParallelogram']

		define [TrapeziumFill cx cy r] : begin
			define skew : r * 1 / 4
			return : spiro-outline
				corner (cx - r) (cy + r / 1.5)
				corner (cx + r - skew) (cy + r / 1.5)
				corner (cx + r) (cy - r / 1.5)
				corner (cx - r) (cy - r / 1.5)

		ConvexWhitePolygon TrapeziumFill 'whiteTrapezium' 0x23E2

	do "Triangles"
		define triangleOvershoot : 2.1 / [Math.sqrt 3]
		define [TriangleUpFill cx cy size] : spiro-outline
			corner cx (cy + size)
			corner (cx + size * triangleOvershoot) (cy - size)
			corner (cx - size * triangleOvershoot) (cy - size)

		define [TriangleDownFill cx cy size] : spiro-outline
			corner cx (cy - size)
			corner (cx + size * triangleOvershoot) (cy + size)
			corner (cx - size * triangleOvershoot) (cy + size)

		define [TriangleLeftFill cx cy size] : spiro-outline
			corner (cx - size) cy
			corner (cx + size) (cy - size * triangleOvershoot)
			corner (cx + size) (cy + size * triangleOvershoot)

		define [TriangleLeftThinFill cx cy size] : spiro-outline
			corner (cx - size) cy
			corner (cx + size) (cy - size * triangleOvershoot * (2 / 3))
			corner (cx + size) (cy + size * triangleOvershoot * (2 / 3))

		define [TriangleRightFill cx cy size] : spiro-outline
			corner (cx + size) cy
			corner (cx - size) (cy - size * triangleOvershoot)
			corner (cx - size) (cy + size * triangleOvershoot)

		define [TriangleRightThinFill cx cy size] : spiro-outline
			corner (cx + size) cy
			corner (cx - size) (cy - size * triangleOvershoot * (2 / 3))
			corner (cx - size) (cy + size * triangleOvershoot * (2 / 3))

		define [IsoRtTriangleUpFill cx cy size] : spiro-outline
			corner cx (cy + size / 2)
			corner (cx + size) (cy - size / 2)
			corner (cx - size) (cy - size / 2)

		define [IsoRtTriangleDownFill cx cy size] : spiro-outline
			corner (cx + size) (cy + size / 2)
			corner (cx - size) (cy + size / 2)
			corner cx (cy - size / 2)

		define [IsoRtTriangleLeftFill cx cy size] : spiro-outline
			corner (cx - size / 2) cy
			corner (cx + size / 2) (cy - size)
			corner (cx + size / 2) (cy + size)

		define [IsoRtTriangleRightFill cx cy size] : spiro-outline
			corner (cx + size / 2) cy
			corner (cx - size / 2) (cy - size)
			corner (cx - size / 2) (cy + size)

		StdBlackShape TriangleUpFill 'blackTriangleUp' 0x25B2 Size.Oblique
		ConvexWhitePolygon TriangleUpFill 'whiteTriangleUp' 0x25B3 Size.Oblique
		StdBlackShape TriangleUpFill 'blackSmallTriangleUp' 0x25B4 Size.SmallOblique
		ConvexWhitePolygon TriangleUpFill 'whiteSmallTriangleUp' 0x25B5 Size.SmallOblique
		StdBlackShape TriangleRightFill 'blackTriangleRight' 0x25B6 Size.Oblique
		ConvexWhitePolygon TriangleRightFill 'whiteTriangleRight' 0x25B7 Size.Oblique
		StdBlackShape TriangleRightFill 'blackSmallTriangleRight' 0x25B8 Size.SmallOblique
		ConvexWhitePolygon TriangleRightFill 'whiteSmallTriangleRight' 0x25B9 Size.SmallOblique
		StdBlackShape TriangleRightThinFill 'blackThinTriangleRight' 0x25BA Size.Oblique
		ConvexWhitePolygon TriangleRightThinFill 'whiteThinTriangleRight' 0x25BB Size.Oblique
		StdBlackShape TriangleDownFill 'blackTriangleDown' 0x25BC Size.Oblique
		ConvexWhitePolygon TriangleDownFill 'whiteTriangleDown' 0x25BD Size.Oblique
		StdBlackShape TriangleDownFill 'blackSmallTriangleDown' 0x25BE Size.SmallOblique
		ConvexWhitePolygon TriangleDownFill 'whiteSmallTriangleDown' 0x25BF Size.SmallOblique
		StdBlackShape TriangleLeftFill 'blackTriangleLeft' 0x25C0 Size.Oblique
		ConvexWhitePolygon TriangleLeftFill 'whiteTriangleLeft' 0x25C1 Size.Oblique
		StdBlackShape TriangleLeftFill 'blackSmallTriangleLeft' 0x25C2 Size.SmallOblique
		ConvexWhitePolygon TriangleLeftFill 'whiteSmallTriangleLeft' 0x25C3 Size.SmallOblique
		StdBlackShape TriangleLeftThinFill 'blackThinTriangleLeft' 0x25C4 Size.Oblique
		ConvexWhitePolygon TriangleLeftThinFill 'whiteThinTriangleLeft' 0x25C5 Size.Oblique

		StdBlackShape TriangleUpFill 'blackCenterMediumTriangleUp' 0x2BC5 Size.MediumOblique
		StdBlackShape TriangleDownFill 'blackCenterMediumTriangleDown' 0x2BC6 Size.MediumOblique
		StdBlackShape TriangleLeftFill 'blackCenterMediumTriangleLeft' 0x2BC7 Size.MediumOblique
		StdBlackShape TriangleRightFill 'blackCenterMediumTriangleRight' 0x2BC8 Size.MediumOblique

		StdBlackShape IsoRtTriangleLeftFill 'isoRtTriangleLeft' 0x1F780 Size.Oblique
		StdBlackShape IsoRtTriangleUpFill 'isoRtTriangleUp' 0x1F781 Size.Oblique
		StdBlackShape IsoRtTriangleRightFill 'isoRtTriangleRight' 0x1F782 Size.Oblique
		StdBlackShape IsoRtTriangleDownFill 'isoRtTriangleDown' 0x1F783 Size.Oblique

		define [TriangularWedgeFill cx cy size] : intersection
			TriangleUpFill cx cy size
			union
				dispiro
					widths.rhs GeometryStroke
					corner cx (cy + size)
					corner (cx + size * triangleOvershoot) (cy - size)
				dispiro
					widths.lhs GeometryStroke
					corner cx (cy + size)
					corner (cx - size * triangleOvershoot) (cy - size)

		define [TriangularVeeFill cx cy size] : intersection
			TriangleDownFill cx cy size
			union
				dispiro
					widths.lhs GeometryStroke
					corner cx (cy - size)
					corner (cx + size * triangleOvershoot) (cy + size)
				dispiro
					widths.rhs GeometryStroke
					corner cx (cy - size)
					corner (cx - size * triangleOvershoot) (cy + size)

		StdBlackShape TriangularWedgeFill 'triangularWedge' null
		StdBlackShape TriangularVeeFill 'triangularVee' null

	do "Diamond"
		define [DiamondFill cx cy size] : spiro-outline
			corner cx (cy + size)
			corner (cx + size) cy
			corner cx (cy - size)
			corner (cx - size) cy

		StdBlackShape DiamondFill 'blackDiamond' 0x25C6 Size.Oblique
		StdBlackShape DiamondFill 'blackCenteredDiamond' 0x2BC1 Size.Oblique

		StdWhiteShape DiamondFill 'whiteDiamond' 0x25C7 Size.Oblique
		StdWhiteShape DiamondFill 'whiteDiamondOperatorImpl' null [Object.assign {.} Size.Oblique {.sw (Math.SQRT2 * [AdviceStroke 4])}]

		StdBlackShape DiamondFill 'blackMediumDiamond' 0x2B25 Size.MediumOblique
		StdBlackShape DiamondFill 'blackSmallDiamond' 0x2B29 Size.SmallOblique
		StdBlackShape DiamondFill 'blackTinyDiamond' 0x1F797 Size.TinyOblique
		StdBlackShape DiamondFill 'blackVerySmallDiamond' 0x1F798 Size.VerySmallOblique
		StdBlackShape DiamondFill 'blackMediumSmallDiamond' 0x1F799 Size.MediumSmallOblique

		StdWhiteShape DiamondFill 'whiteMediumDiamond' 0x2B26 Size.MediumOblique

		StdWhiteContainingBlackShape DiamondFill 'whiteDiamondWithCenter' 0x25C8 Size.Oblique
		StdWhiteContainingBlackShape DiamondFill 'whiteDiamondContainingBlackVerySmallDiamond' 0x1F79A [Object.assign {.} Size.TinyInner Size.Oblique]
		StdWhiteContainingBlackShape DiamondFill 'whiteDiamondContainingBlackMediumDiamond' 0x1F79B [Object.assign {.} Size.MediumInner Size.Oblique]

		StdGeomTargetShape DiamondFill 'diamondTarget' 0x1F79C Size.Oblique

	do "Lozenge"
		define [LozengeFill cx cy size] : spiro-outline
			corner cx (cy + size)
			corner (cx + size * 2 / 3) cy
			corner cx (cy - size)
			corner (cx - size * 2 / 3) cy

		StdBlackShape LozengeFill 'blackLozenge' 0x29EB Size.Oblique
		ConvexWhitePolygon LozengeFill 'whiteLozenge' 0x25CA Size.Oblique

		StdBlackShape LozengeFill 'blackMediumLozenge' 0x2B27 Size.MediumOblique
		StdBlackShape LozengeFill 'blackSmallLozenge' 0x2B2A Size.SmallOblique

		ConvexWhitePolygon LozengeFill 'whiteMediumLozenge' 0x2B28 Size.MediumOblique
		ConvexWhitePolygon LozengeFill 'whiteSmallLozenge' 0x2B2B Size.SmallOblique

		StdBlackShape LozengeFill 'blackTinyLozenge' 0x1F79D Size.TinyOblique
		StdBlackShape LozengeFill 'blackVerySmallLozenge' 0x1F79E Size.VerySmallOblique
		StdBlackShape LozengeFill 'blackMediumSmallLozenge' 0x1F79F Size.MediumSmallOblique

		ConvexPolygonWhiteContainingBlackShape LozengeFill 'whiteLozengeContainingBlackSmallLozenge' 0x1F7A0 [Object.assign {.} Size.SmallInner Size.Oblique]

	do "Square-lozenge"
		define [SquareLozengeShape cx cy size] : begin
			define p 0.7
			return : spiro-outline
				corner (cx - size) (cy + size)
				g4     cx (cy + p * size)
				corner (cx + size) (cy + size)
				g4     (cx + p * size) cy
				corner (cx + size) (cy - size)
				g4     cx (cy - p * size)
				corner (cx - size) (cy - size)
				g4     (cx - p * size) cy
				close

		StdWhiteShape SquareLozengeShape 'squareLozenge' 0x2311 Size.SmallOblique
		StdWhiteShape SquareLozengeShape 'rotatedWhiteFourPointedCusp' 0x2BCF Size.MediumOblique
		StdBlackShape SquareLozengeShape 'rotatedBlackFourPointedCusp' 0x2BCD Size.MediumOblique

	do "Diamond-lozenge"
		define [DiamondLazongeShape cx cy size] : begin
			define p 0.7
			return : spiro-outline
				corner (cx - size) cy
				g4     [mix cx [mix (cx - size) cx 0.5] p] [mix cy [mix cy (cy - size) 0.5] p]
				corner cx (cy - size)
				g4     [mix cx [mix cx (cx + size) 0.5] p] [mix cy [mix (cy - size) cy 0.5] p]
				corner (cx + size) cy
				g4     [mix cx [mix (cx + size) cx 0.5] p] [mix cy [mix cy (cy + size) 0.5] p]
				corner cx (cy + size)
				g4     [mix cx [mix cx (cx - size) 0.5] p] [mix cy [mix (cy + size) cy 0.5] p]
				close

		StdWhiteShape DiamondLazongeShape 'whiteConcaveSidedDiamond'  0x27E1 [Object.assign {.} Size.Oblique {.sw (Math.SQRT2 * [UnicodeWeightGrade 600 Geom.Scalar GeometryStroke])}]
		StdBlackShape DiamondLazongeShape 'lightFourPointedBlackCusp' 0x2BCC Size.Oblique
		StdWhiteShape DiamondLazongeShape 'whiteFourPointedBlackCusp' 0x2BCE Size.ObliqueSA

	do "Circle"
		define [CircleShape cx cy size] : spiro-outline
			g4 (cx - size) cy
			arcvh.superness 2
			g4 cx (cy - size)
			archv.superness 2
			g4 (cx + size) cy
			arcvh.superness 2
			g4 cx (cy + size)
			archv.superness 2
			close

		define [CircleInvertInnerShape cx cy size sw] : begin
			define sizeOrig : size + sw
			define rs : Geom.TallSize / (sizeOrig * 1.5)
			return : CircleShape cx cy (sizeOrig * rs - sw)

		StdBlackShape CircleShape 'blackCircleO' null {.size 0.995}
		StdBlackShape CircleShape 'blackCircle' 0x25CF

		StdWhiteShape CircleShape 'whiteCircle' 0x25CB
		StdWhiteShape CircleShape 'mediumWhiteCircle'    0x1F785 {.sw [UnicodeWeightGrade 600 Geom.Scalar GeometryStroke]}
		StdWhiteShape CircleShape 'boldWhiteCircle'      0x1F786 {.sw [UnicodeWeightGrade 700 Geom.Scalar GeometryStroke]}
		StdWhiteShape CircleShape 'heavyWhiteCircle'     0x1F787 {.sw [UnicodeWeightGrade 900 Geom.Scalar GeometryStroke]}
		StdWhiteShape CircleShape 'veryHeavyWhiteCircle' 0x1F788 {.sw [UnicodeWeightGrade 1000 Geom.Scalar GeometryStroke]}
		StdWhiteShape CircleShape 'exHeavyWhiteCircle'   0x1F789 {.sw [UnicodeWeightGrade 1100 Geom.Scalar GeometryStroke]}
		StdWhiteShape CircleShape 'heavyLargeCircle'     0x2B55  [Object.assign {.sw [UnicodeWeightGrade 900 Geom.Scalar GeometryStroke]} Size.Large]

		StdBlackShape CircleShape 'blackVerySmallCircle' null Size.VerySmall
		StdBlackShape CircleShape 'blackSmallCircle' null Size.Small
		StdBlackShape CircleShape 'blackMediumSmallCircle' 0x2981 Size.MediumSmall
		StdBlackShape CircleShape 'blackSlightlySmallCircle' 0x1F784 Size.SlightlySmall
		StdBlackShape CircleShape 'blackMediumCircle' 0x26AB Size.Medium
		StdBlackShape CircleShape 'blackLargeCircle' 0x2B24 Size.Large

		StdWhiteShape CircleShape 'whiteVerySmallCircle' null Size.VerySmall
		StdWhiteShape CircleShape 'whiteSmallCircle' null Size.Small
		StdWhiteShape CircleShape 'whiteSlightlySmallCircle' null Size.SlightlySmall
		StdWhiteShape CircleShape 'whiteMediumSmallCircle' 0x26AC Size.MediumSmall
		StdWhiteShape CircleShape 'whiteMediumCircle' 0x26AA Size.Medium
		StdWhiteShape CircleShape 'whiteLargeCircle' 0x25EF Size.Large

		StdDoubleWhite CircleShape 'doubleWhiteCircle' 0x25CE {.sw [Math.min GeometryStroke : AdviceStroke 4 Geom.Scalar]}

		StdWhiteContainingBlackShape CircleShape 'whiteCircleWithCenter' 0x25C9
		StdWhiteContainingBlackShape CircleShape 'whiteCircleContainingBlackSmallCircle' 0x1F78A Size.SmallInner

		StdGeomTargetShape CircleShape 'circleTarget' 0x1F78B

		StdBlackShape CircleInvertInnerShape 'blackInvInnerCircle' null
		StdWhiteShape CircleInvertInnerShape 'whiteInvInnerCircle' null

		create-glyph [MangleName 'blackCircleMinusQuarterLeft'] [MangleUnicode 0x1CC6B] : glyph-proc
			set-width Geom.Width
			include : difference
				refer-glyph : MangleName 'blackCircle'
				spiro-outline [corner (Geom.MidX - Geom.Size) (Geom.MidY + Geom.Size)] [corner Geom.MidX Geom.MidY] [corner (Geom.MidX - Geom.Size) (Geom.MidY - Geom.Size)]
		create-glyph [MangleName 'blackCircleMinusQuarterUp'] [MangleUnicode 0x1CC6C] : glyph-proc
			set-width Geom.Width
			include : difference
				refer-glyph : MangleName 'blackCircle'
				spiro-outline [corner (Geom.MidX + Geom.Size) (Geom.MidY + Geom.Size)] [corner Geom.MidX Geom.MidY] [corner (Geom.MidX - Geom.Size) (Geom.MidY + Geom.Size)]
		create-glyph [MangleName 'blackCircleMinusQuarterRight'] [MangleUnicode 0x1CC6D] : glyph-proc
			set-width Geom.Width
			include : difference
				refer-glyph : MangleName 'blackCircle'
				spiro-outline [corner (Geom.MidX + Geom.Size) (Geom.MidY - Geom.Size)] [corner Geom.MidX Geom.MidY] [corner (Geom.MidX + Geom.Size) (Geom.MidY + Geom.Size)]
		create-glyph [MangleName 'blackCircleMinusQuarterDown'] [MangleUnicode 0x1CC6E] : glyph-proc
			set-width Geom.Width
			include : difference
				refer-glyph : MangleName 'blackCircle'
				spiro-outline [corner (Geom.MidX - Geom.Size) (Geom.MidY - Geom.Size)] [corner Geom.MidX Geom.MidY] [corner (Geom.MidX + Geom.Size) (Geom.MidY - Geom.Size)]

	do "Ellipse"
		define [EllipseFillT kx ky] : lambda  [cx cy r s] : begin
			define rOrig : r + s
			return : spiro-outline
				g4 (cx - (rOrig * kx - s)) cy
				arcvh.superness 2
				g4 cx (cy - (rOrig * ky - s))
				archv.superness 2
				g4 (cx + (rOrig * kx - s)) cy
				arcvh.superness 2
				g4 cx (cy + (rOrig * ky - s))
				archv.superness 2
				close

		StdBlackShape [EllipseFillT 1 (1 / 1.5)] 'blackEllipse' 0x2B2C
		StdWhiteShape [EllipseFillT 1 (1 / 1.5)] 'whiteEllipse' 0x2B2D
		StdBlackShape [EllipseFillT (1 / 1.5) 1] 'blackLongEllipse' 0x2B2E
		StdWhiteShape [EllipseFillT (1 / 1.5) 1] 'whiteLongEllipse' 0x2B2F

	do "Regular Polygon"
		define [RegularPolygonFill sides skip overflow phase] : lambda [cx cy size] : begin
			local corners {}
			foreach [j : range 0 sides] : begin
				local angle : 2 * Math.PI * j * skip / sides + Math.PI * phase
				corners.push : corner
					cx + size * overflow * [Math.sin angle]
					cy + size * overflow * [Math.cos angle]
			return : spiro-outline corners

		StdBlackShape [RegularPolygonFill 5  1  1.05 0] 'blackPentagon' 0x2B1F
		StdBlackShape [RegularPolygonFill 5  1  1.05 1] 'turnBlackPentagon' 0x2BC2
		ConvexWhitePolygon [RegularPolygonFill 5  1  1.05 0] 'whitePentagon' 0x2B20
		StdBlackShape [RegularPolygonFill 5  1  1.05 0.5] 'rhBlackPentagon' 0x2B53
		ConvexWhitePolygon [RegularPolygonFill 5  1  1.05 0.5] 'rhWhitePentagon' 0x2B54
		StdBlackShape [RegularPolygonFill 6  1  1.05 0] 'blackHexagon' 0x2B22
		ConvexWhitePolygon [RegularPolygonFill 6  1  1.05 0] 'whiteHexagon' 0x2B21
		ConvexWhitePolygon [RegularPolygonFill 6  1  1.05 0.5] 'hWhiteHexagon' 0x2394
		StdBlackShape [RegularPolygonFill 6  1  1.05 0.5] 'hBlackHexagon' 0x2B23
		StdBlackShape [RegularPolygonFill 8  1  1.05 0] 'blackHorizontalOctagon' 0x2BC3
		StdBlackShape [RegularPolygonFill 8  1  1.05 0.128] 'blackOctagon' 0x2BC4

		ConvexWhitePolygon [RegularPolygonFill 3 1 1 1] 'whiteEqualTriangleDown' null
		StdBlackShape      [RegularPolygonFill 4 1 1 0.5] 'blackMediumEqualDiamond' null
		ConvexWhitePolygon [RegularPolygonFill 4 1 1 0.5] 'whiteMediumEqualDiamond' null

		define [PentagramSw c] {.sw ([AdviceStroke c : Math.sqrt Geom.Scalar] * [Math.sqrt 5])}
		StdBlackShape [RegularPolygonFill 5  2  1.1  0] 'blackStar' 0x2605
		StdWhiteShape [RegularPolygonFill 5  2  1.1  0] 'whiteStar' 0x2606 [PentagramSw 5.5]
		StdWhiteShape [RegularPolygonFill 5  2  1.1  0] 'lightWhiteStar' null {.sw ([UnicodeWeightGrade 300 [Math.sqrt Geom.Scalar] GeometryStroke] * [Math.sqrt 5])}
		StdWhiteShape [RegularPolygonFill 5  2  1.1  0] 'whiteMediumStar' 0x2B50 [Object.assign [PentagramSw 7] Size.Medium]
		StdBlackShape [RegularPolygonFill 5  2  1.1  0] 'blackSmallStar' 0x2B51 Size.Small
		StdWhiteShape [RegularPolygonFill 5  2  1.1  0] 'whiteSmallStar' 0x2B52 [Object.assign [PentagramSw 3] Size.Small]

		create-glyph [MangleName 'Hexagram'] [MangleUnicode 0x2721] : glyph-proc
			set-width Geom.Width
			local offset : Geom.Size / 3
			include : union
				with-transform [Translate 0   offset ] : refer-glyph : MangleName 'whiteTriangleUp'
				with-transform [Translate 0 (-offset)] : refer-glyph : MangleName 'whiteTriangleDown'

	do "Other Stars"
		define [CurlyEdgeStar sides shrink overflow phase] : lambda [cx cy size] : begin
			local corners {}
			foreach [j : range 0 sides] : begin
				local angleCorner : 2 * Math.PI * j / sides           + Math.PI * phase
				local angleArc    : 2 * Math.PI * (j + 1 / 2) / sides + Math.PI * phase
				corners.push : corner
					cx + size * overflow * [Math.sin angleCorner]
					cy + size * overflow * [Math.cos angleCorner]
				corners.push : g2
					cx + size * shrink * [Math.sin angleArc]
					cy + size * shrink * [Math.cos angleArc]
			return : spiro-outline corners [close]

		define [PentagramSw c] {.sw ([AdviceStroke c : Math.sqrt Geom.Scalar] * [Math.sqrt 5])}
		StdBlackShape [CurlyEdgeStar 4  0.6  1.1  0] 'blackFourPointedStar' 0x2726
		StdWhiteShape [CurlyEdgeStar 4  0.6  1.1  0] 'whiteFourPointedStar' 0x2727 [PentagramSw 5]

	do "Arrow head"
		define [RightArrowHeadShape cx cy size] : spiro-outline
			corner (cx - size)       (cy + size)
			corner (cx + size)        cy
			corner (cx - size)       (cy - size)
			corner (cx - 0.5 * size)  cy

		StdBlackShape RightArrowHeadShape 'blackArrowHeadRight' 0x27A4 Size.Oblique
		StdWhiteShape RightArrowHeadShape 'whiteArrowHeadRight' null {.sw ([Math.min GeometryStroke : AdviceStroke 4.75 : Math.sqrt Geom.Scalar] * [Math.sqrt 5])}
