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

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


glyph-module

glyph-block Letter-Latin-O : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Mark-Horn-And-Angle : HornBaseAnchor
	glyph-block-import Mark-Above : RingDims RingShape
	glyph-block-import Mark-Adjustment : ExtendAboveBaseAnchors ExtendBelowBaseAnchors
	glyph-block-import Letter-Shared : CreateAccentedComposition SetGrekUpperTonos
	glyph-block-import Letter-Shared-Shapes : RetroflexHook
	glyph-block-import Letter-Blackboard : BBS BBD

	create-glyph 'O' 'O' : glyph-proc
		include : MarkSet.capital
		include : OShape CAP 0 SB RightSB nothing ArchDepthA ArchDepthB

	create-glyph 'smcpO' 0x1D0F : glyph-proc
		include : MarkSet.e
		include : OShape XH 0 SB RightSB nothing ArchDepthA ArchDepthB

	create-glyph 'o' 'o' : glyph-proc
		include : MarkSet.e
		include : OShape XH 0 SB RightSB nothing nothing nothing

	create-glyph 'grek/Omicron' 0x39F : glyph-proc
		include [refer-glyph 'O'] AS_BASE ALSO_METRICS
		include : SetGrekUpperTonos 0

	alias 'grek/omicron' 0x3BF 'o'

	alias 'cyrl/O' 0x41E 'O'
	alias 'cyrl/o' 0x43E 'o'

	create-glyph 'cyrl/uk/o' : glyph-proc
		local df : include : DivFrame para.advanceScaleF 2
		include : df.markSet.e
		include : OShape XH 0 df.leftSB df.rightSB df.mvs df.smallArchDepthA df.smallArchDepthB

	create-glyph 'cyrl/oNarrow' 0x1C82 : glyph-proc
		local df : include : DivFrame para.advanceScaleF 2
		include : df.markSet.e
		local subDf : DivFrame (5 / 6) 2
		include : with-transform [ApparentTranslate (0.5 * (df.width - subDf.width)) 0]
			OShape XH 0 subDf.leftSB subDf.rightSB subDf.mvs subDf.smallArchDepthA subDf.smallArchDepthB

	define rBroadOn : DotRadius * [StrokeWidthBlend 1.625 1]
	create-glyph 'cyrl/BroadOn' 0x47A : glyph-proc
		define df : include : DivFrame para.advanceScaleT 3
		include : df.markSet.capital
		local dist : df.rightSB - df.leftSB
		include : OShapeFlatTB CAP 0 df.leftSB df.rightSB df.mvs df.archDepthA df.archDepthB : Math.min
			Math.max (0.25 * dist) [HSwToV : Math.SQRT2 * rBroadOn]
			Math.max (dist - [HSwToV : 3 * df.mvs]) [HSwToV df.mvs]
		include : DotAt df.middle (0   + df.mvs / 2 + O) rBroadOn
		include : DotAt df.middle (CAP - df.mvs / 2 - O) rBroadOn

	create-glyph 'cyrl/broadOn' 0x47B : glyph-proc
		define df : include : DivFrame para.advanceScaleT 3
		include : df.markSet.e
		local dist : df.rightSB - df.leftSB
		include : OShapeFlatTB XH 0 df.leftSB df.rightSB df.mvs df.smallArchDepthA df.smallArchDepthB : Math.min
			Math.max (0.25 * dist) [HSwToV : Math.SQRT2 * rBroadOn]
			Math.max (dist - [HSwToV : 3 * df.mvs]) [HSwToV df.mvs]
		include : DotAt df.middle (0  + df.mvs / 2 + O) rBroadOn
		include : DotAt df.middle (XH - df.mvs / 2 - O) rBroadOn

	derive-multi-part-glyphs 'OHorn' 0x01A0 {'O' 'longHorn'} : function [srcs gr] : glyph-proc
		local { base horn } srcs
		include : MarkSet.capital
		include : HornBaseAnchor RightSB CAP (Width / 2) (ArchDepthB) 0.5
		include : difference
			new-glyph : glyph-proc
				include : MarkSet.capital
				include [refer-glyph horn]
			OShapeOutline.NoOvershoot CAP 0 SB RightSB nothing ArchDepthA ArchDepthB
		include : refer-glyph base

	derive-multi-part-glyphs 'oHorn' 0x01A1 {'o' 'longHorn'} : function [srcs gr] : glyph-proc
		local { base horn } srcs
		include : MarkSet.e
		include : HornBaseAnchor RightSB XH (Width / 2) (ArchDepthB) 0.5
		include : difference
			new-glyph : glyph-proc
				include : MarkSet.e
				include [refer-glyph horn]
			OShapeOutline.NoOvershoot XH 0 SB RightSB nothing nothing nothing
		include : refer-glyph base

	create-glyph 'OSlash' 0xD8 : glyph-proc
		local fine : 0.5 * OverlayStroke
		include [refer-glyph 'O'] AS_BASE
		include : dispiro
			widths.center (2 * fine)
			flat (SB + O + fine) [mix CAP 0 1.05]
			curl (RightSB - O - fine) [mix 0 CAP 1.05]

	create-glyph 'oSlash' 0xF8 : glyph-proc
		local fine : 0.5 * OverlayStroke
		include [refer-glyph 'o'] AS_BASE
		include : dispiro
			widths.center (2 * fine)
			flat (SB + O + fine) [mix XH 0 1.05]
			curl (RightSB - O - fine) [mix 0 XH 1.05]

	create-glyph 'oSideways' 0x1D11 : glyph-proc
		include : MarkSet.e
		include : PointingTo Width XH Width 0 : function []
			OShape (Width - SB / 2) (SB / 2) (XH * 0.1) (XH * 0.9) nothing nothing nothing

	create-glyph 'oSlashSideways' 0x1D13 : glyph-proc
		include : MarkSet.e
		include : PointingTo Width XH Width 0 : function [] : glyph-proc
			local fine : 0.5 * OverlayStroke
			include : OShape (Width - SB / 2) (SB / 2) (XH * 0.1) (XH * 0.9) nothing nothing nothing
			include : dispiro
				widths.center (2 * fine)
				flat (SB + O + fine) [mix Width 0 1.05]
				curl (XH - SB - O - fine) [mix 0 Width 1.05]

	create-glyph 'Obar' 0x19F : glyph-proc
		include : MarkSet.capital
		local stroke : AdviceStroke2 2 3 CAP
		include : OShape CAP 0 SB RightSB stroke ArchDepthA ArchDepthB
		include : intersection
			OShapeOutline.NoOvershoot CAP 0 SB RightSB stroke ArchDepthA ArchDepthB
			HBar.m (SB + OX) (RightSB - OX) (CAP * 0.5) stroke

	create-glyph 'obar' 0x275 : glyph-proc
		include : MarkSet.e
		local stroke : AdviceStroke2 2 3 XH
		include : OShape XH 0 SB RightSB stroke nothing nothing
		include : intersection
			OShapeOutline.NoOvershoot XH 0 SB RightSB stroke nothing nothing
			HBar.m (SB + OX) (RightSB - OX) (XH * 0.5) stroke

	alias 'grek/capSymbolTheta' 0x3F4 'Obar'

	alias 'cyrl/Oe' 0x4E8 'Obar'
	alias 'cyrl/oe' 0x4E9 'obar'

	derive-composites 'cyrl/OMonocular' 0xA668 'O' 'innerDot'
	derive-composites 'cyrl/oMonocular' 0xA669 'o' 'innerDotSmall'
	derive-composites 'cyrl/OBinocular' 0xA66A 'O' 'innerDoubleDot'
	derive-composites 'cyrl/oBinocular' 0xA66B 'o' 'innerDoubleDotSmall'

	alias 'bullEye' 0x298 'cyrl/OMonocular'

	create-glyph 'cyrl/OCross' 0xA69A : glyph-proc
		include : MarkSet.capital
		local stroke : AdviceStroke2 3 3 CAP
		include : OShape CAP 0 SB RightSB stroke ArchDepthA ArchDepthB
		include : intersection
			OShapeOutline.NoOvershoot CAP 0 SB RightSB stroke ArchDepthA ArchDepthB
			union
				HBar.m (SB + OX) (RightSB - OX) (CAP * 0.5) stroke
				VBar.m Middle O (CAP - O) [Math.min stroke : VSwToH : (RightSB - SB) / 2 - [HSwToV stroke]]

	create-glyph 'cyrl/oCross' 0xA69B : glyph-proc
		include : MarkSet.e
		local stroke : AdviceStroke2 3 3 XH
		include : OShape XH 0 SB RightSB stroke nothing nothing
		include : intersection
			OShapeOutline.NoOvershoot XH 0 SB RightSB stroke nothing nothing
			union
				HBar.m (SB + OX) (RightSB - OX) (XH * 0.5) stroke
				VBar.m Middle O (XH - O) [Math.min stroke : VSwToH : (RightSB - SB) / 2 - [HSwToV stroke]]

	create-glyph 'romanThousandCD' 0x2180 : glyph-proc
		local df : include : DivFrame para.advanceScaleMM 3
		include : df.markSet.capital
		local dist : df.rightSB - df.leftSB
		local gap : Math.max (dist / 4) : HSwToV df.mvs
		local ada : ArchDepthA * df.adws
		local adb : ArchDepthB * df.adws
		include : OShapeFlatTB CAP 0 df.leftSB df.rightSB df.mvs ada adb gap
		include : VBar.m df.middle (df.mvs / 2) (CAP - df.mvs / 2) df.mvs
		set-base-anchor 'trailing' Middle 0

	create-glyph 'romanTenThousand' 0x2182 : glyph-proc
		local df : include : DivFrame para.advanceScaleMM 5
		include : df.markSet.capital
		local dist : df.rightSB - df.leftSB
		local gap : Math.max (dist / 4) : HSwToV df.mvs
		local gapInner : Math.max (dist / 8) : HSwToV df.mvs
		local ada : ArchDepthA * df.adws
		local adb : ArchDepthB * df.adws
		local innerDist : dist - [HSwToV : 5 * df.mvs]
		local arcXL : df.leftSB + innerDist * (1 / 4) + [HSwToV : 1 * df.mvs]
		local arcXR : df.leftSB + innerDist * (3 / 4) + [HSwToV : 4 * df.mvs]
		local heightGap : Math.min (df.mvs + (CAP - df.mvs * 4) / 5) (innerDist / 4 + df.mvs)
		local heightInner : CAP - 2 * heightGap
		local smInner  : clamp (df.mvs * 1.5) (heightInner / 2 - TINY) (ArchDepth * heightInner / CAP)
		local adaInner : [ArchDepthAOf smInner : arcXR - arcXL + df.leftSB * 2] * df.adws
		local adbInner : [ArchDepthBOf smInner : arcXR - arcXL + df.leftSB * 2] * df.adws
		include : OShapeFlatTB CAP 0 df.leftSB df.rightSB df.mvs ada adb gap
		include : OShapeFlatTB (CAP - heightGap) (0 + heightGap) arcXL arcXR df.mvs adaInner adbInner gapInner
		include : VBar.m df.middle (df.mvs / 2) (CAP - df.mvs / 2) df.mvs

	create-glyph 'romanHundredThousand' 0x2188 : glyph-proc
		local df : include : DivFrame para.advanceScaleMM 7
		include : df.markSet.capital
		local dist : df.rightSB - df.leftSB
		local gap : Math.max (dist / 4) : HSwToV df.mvs
		local gapInner1 : Math.max (dist / 6) : HSwToV df.mvs
		local gapInner2 : Math.max (dist / 12) : HSwToV df.mvs
		local ada : ArchDepthA * df.adws
		local adb : ArchDepthB * df.adws
		local innerDist : dist - [HSwToV : 7 * df.mvs]
		local arcXL1 : df.leftSB + innerDist * (1 / 6) + [HSwToV : 1 * df.mvs]
		local arcXR1 : df.leftSB + innerDist * (5 / 6) + [HSwToV : 6 * df.mvs]
		local arcXL2 : df.leftSB + innerDist * (2 / 6) + [HSwToV : 2 * df.mvs]
		local arcXR2 : df.leftSB + innerDist * (4 / 6) + [HSwToV : 5 * df.mvs]
		local heightGap : Math.min (df.mvs + (CAP - df.mvs * 6) / 7) (innerDist / 6 + df.mvs)
		local heightInner1 : CAP - 2 * heightGap
		local heightInner2 : CAP - 4 * heightGap
		local smInner1  : clamp (df.mvs * 1.5) (heightInner1 / 2 - TINY) (ArchDepth * heightInner1 / CAP)
		local adaInner1 : [ArchDepthAOf smInner1 : arcXR1 - arcXL1 + df.leftSB * 2] * df.adws
		local adbInner1 : [ArchDepthBOf smInner1 : arcXR1 - arcXL1 + df.leftSB * 2] * df.adws
		local smInner2  : clamp (df.mvs * 1.5) (heightInner2 / 2 - TINY) (ArchDepth * heightInner2 / CAP)
		local adaInner2 : [ArchDepthAOf smInner2 : arcXR2 - arcXL2 + df.leftSB * 2] * df.adws
		local adbInner2 : [ArchDepthBOf smInner2 : arcXR2 - arcXL2 + df.leftSB * 2] * df.adws
		include : OShapeFlatTB CAP 0 df.leftSB df.rightSB df.mvs ada adb gap
		include : OShapeFlatTB (CAP - heightGap) (0 + heightGap) arcXL1 arcXR1 df.mvs adaInner1 adbInner1 gapInner1
		include : OShapeFlatTB (CAP - 2 * heightGap) (0 + 2 * heightGap) arcXL2 arcXR2 df.mvs adaInner2 adbInner2 gapInner2
		include : VBar.m df.middle (df.mvs / 2) (CAP - df.mvs / 2) df.mvs

	create-glyph 'oupperhalf' 0x1D16 : glyph-proc
		include : MarkSet.e
		include : dispiro
			widths.rhs
			flat (SB + OX) (XH / 2) [heading Upward]
			curl (SB + OX) (XH - [Math.min SmallArchDepthA : XH / 2 - TINY])
			arch.rhs XH
			flat (RightSB - OX) (XH - [Math.min SmallArchDepthB : XH / 2 - TINY])
			curl (RightSB - OX) (XH / 2) [heading Downward]

	create-glyph 'olowerhalf' 0x1D17 : glyph-proc
		include : MarkSet.e
		include : dispiro
			widths.lhs
			flat (SB + OX) (XH / 2) [heading Downward]
			curl (SB + OX) [Math.min SmallArchDepthB : XH / 2 - TINY]
			arch.lhs 0
			flat (RightSB - OX) [Math.min SmallArchDepthA : XH / 2 - TINY]
			curl (RightSB - OX) (XH / 2) [heading Upward]

	create-glyph 'oWithLightCentralizationStroke' : glyph-proc
		include : MarkSet.p
		include : refer-glyph "o"
		local fine      : AdviceStroke 4
		local outStand  : SB * 0.75 + fine * 0.25
		local outStandY : SmallArchDepthB / 2 - Descender * 0.6
		local yTurn     : SmallArchDepthB / 2
		include : difference
			dispiro
				widths.lhs fine
				corner Middle          (yTurn + outStandY)
				corner (SB - outStand) (yTurn - outStandY)
			OShapeOutline.NoOvershoot XH 0 SB RightSB nothing nothing nothing

	CreateAccentedComposition 'OAcute' 0xD3 'O' 'acuteAbove'
	CreateAccentedComposition 'oAcute' 0xF3 'o' 'acuteAbove'

	CreateAccentedComposition 'OAcute.PLK' null 'O' 'kreskaAbove'
	CreateAccentedComposition 'oAcute.PLK' null 'o' 'kreskaAbove'

	CreateAccentedComposition 'oDieresis' 0xF6 'o' 'dieresisAbove'

	create-glyph 'numeroRightHalf' : glyph-proc
		local obot : Math.max (CAP * 0.1) (OverlayStroke + HalfStroke)
		include : OShape XH obot SB RightSB [AdviceStroke2 2 2 (XH - obot)] nothing nothing
		include : HBar.b SB RightSB 0 OverlayStroke

	CreateAccentedComposition 'oSbRsbUnderlineBelow' null 'o' 'sbRsbUnderlineBelow'

	create-glyph 'oLowRingInside' 0x2C7A : glyph-proc
		include [refer-glyph 'o'] AS_BASE
		local [object radiusIn radiusOut] : RingDims
		include : RingShape Middle (O + Stroke + radiusIn)

	create-glyph 'OPolish' 0xA7C0 : glyph-proc
		include [refer-glyph 'O'] AS_BASE
		include : MarkSet.capital
		include : ExtendAboveBaseAnchors (CAP + LongVJut - QuarterStroke)
		include : ExtendBelowBaseAnchors (0   - LongVJut + QuarterStroke)
		include : VBar.m Middle CAP (CAP + LongVJut - QuarterStroke) VJutStroke
		include : VBar.m Middle 0   (0   - LongVJut + QuarterStroke) VJutStroke

	create-glyph 'oPolish' 0xA7C1 : glyph-proc
		include [refer-glyph 'o'] AS_BASE
		include : MarkSet.e
		include : ExtendAboveBaseAnchors (XH + LongVJut - QuarterStroke)
		include : ExtendBelowBaseAnchors (0  - LongVJut + QuarterStroke)
		include : VBar.m Middle XH (XH + LongVJut - QuarterStroke) VJutStroke
		include : VBar.m Middle 0  (0  - LongVJut + QuarterStroke) VJutStroke

	derive-composites 'oRetroflexHook' 0x1DF1B 'o' : RetroflexHook.l
		x -- [mix [arch.adjust-x.bot Middle] SB 0.75]
		y -- 0
		yAttach -- [mix O SmallArchDepthB : archv.yFromX 0.75]

	create-glyph 'mathbb/O' 0x1D546 : glyph-proc
		include : MarkSet.capital
		include : OShape CAP 0 SB RightSB BBS ArchDepthA ArchDepthB
		include : intersection
			OShapeOutline.NoOvershoot CAP 0 SB RightSB BBS ArchDepthA ArchDepthB
			union
				VBar.l (SB      + OX + BBD) 0 CAP BBS
				VBar.r (RightSB - OX - BBD) 0 CAP BBS

	create-glyph 'mathbb/o' 0x1D560 : glyph-proc
		include : MarkSet.e
		include : OShape XH 0 SB RightSB BBS
		include : intersection
			OShapeOutline.NoOvershoot XH 0 SB RightSB BBS
			union
				VBar.l (SB      + OX + BBD) 0 XH BBS
				VBar.r (RightSB - OX - BBD) 0 XH BBS
