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

import [mix fallback SuffixCfg] from "@iosevka/util"
import [MathSansSerif] from "@iosevka/glyph/relation"

glyph-module

glyph-block Letter-Latin-U : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Mark-Adjustment : LeaningAnchor
	glyph-block-import Letter-Shared : CreateAccentedComposition SetGrekUpperTonos
	glyph-block-import Letter-Shared-Shapes : uBowl RightwardTailedBar SerifFrame
	glyph-block-import Letter-Shared-Shapes : CyrDescender CyrTailDescender RetroflexHook TopHook

	define [UArcT] : with-params [sink df top bottom [stroke Stroke] [ada ArchDepthA] [adb ArchDepthB] [offset 0]] : sink
		widths.lhs stroke
		[if (sink == spiro-outline) corner flat] (df.leftSB + offset) top [heading Downward]
		curl (df.leftSB + offset) (bottom + adb + offset)
		arch.lhs (bottom + offset) (sw -- stroke)
		flat (df.rightSB - offset) (bottom + ada + offset)
		[if (sink == spiro-outline) corner curl] (df.rightSB - offset) top [heading Upward]

	glyph-block-export UShape
	define [UShape] : with-params [df top bottom [stroke Stroke] [ada ArchDepthA] [adb ArchDepthB] [offset 0]] : glyph-proc
		include : UArcT dispiro
			df     -- df
			top    -- top
			bottom -- bottom
			stroke -- stroke
			ada    -- ada
			adb    -- adb
			offset -- offset

	glyph-block-export UShapeGroup
	define [UShapeGroup ada adb] : namespace
		export : define [Toothed df top sw fHookLeft fShortLeg] : glyph-proc
			set-base-anchor 'trailing' df.rightSB 0
			include : uBowl.shape
				top    -- (top - [if fHookLeft (TailY + HalfStroke) 0])
				bottom -- 0
				left   -- df.leftSB
				right  -- (df.rightSB - [HSwToV sw])
				stroke -- sw
				fine   -- ShoulderFine
				ada    -- ada
				adb    -- adb
			if fHookLeft : include : TopHook.toLeft.lBarInner df.leftSB (adb + TINY) top (sw -- sw)
			include : tagged 'strokeR' : VBar.r df.rightSB 0 [if fShortLeg [mix ada top 0.5] top] sw

		export : define [Tailed df top sw fHookLeft fShortLeg] : glyph-proc
			set-base-anchor 'trailing' (df.rightSB + SideJut) 0
			include : uBowl.shape
				top    -- (top - [if fHookLeft (TailY + HalfStroke) 0])
				bottom -- 0
				left   -- df.leftSB
				right  -- (df.rightSB - [HSwToV sw])
				stroke -- sw
				fine   -- ShoulderFine
				ada    -- ada
				adb    -- adb
			if fHookLeft : include : TopHook.toLeft.lBarInner df.leftSB (adb + TINY) top (sw -- sw)
			include : tagged 'strokeR' : RightwardTailedBar df.rightSB 0 [if fShortLeg [mix ada top 0.5] top] (sw -- sw)

		export : define [ToothlessRounded df top sw fHookLeft fShortLeg] : glyph-proc
			if fHookLeft : begin
				include : dispiro
					widths.rhs sw
					flat df.leftSB [if fShortLeg [mix (top - ada) 0 0.5] 0] [heading Upward]
					curl df.leftSB (top - ada)
					arch.rhs top
					flat df.rightSB (top - adb)
					curl df.rightSB (TailY + HalfStroke) [heading Downward]
				include : RetroflexHook.rExt df.rightSB (TailY + HalfStroke) (sw -- sw)
				include : FlipAround df.middle (top / 2)
			: else : begin
				if fShortLeg : include : dispiro
					widths.lhs sw
					flat df.leftSB top [heading Downward]
					curl df.leftSB adb
					arch.lhs 0 (sw -- sw)
					flat df.rightSB ada
					curl df.rightSB [mix ada top 0.5] [heading Upward]
				: else : include : UShape df top 0 (stroke -- sw) (ada -- ada) (adb -- adb)

		export : define [ToothlessCorner df top sw fHookLeft fShortLeg] : glyph-proc
			include : VBar.l df.leftSB [if fShortLeg [mix (top - ada) 0 0.5] 0] (top - DToothlessRise) sw
			include : dispiro
				widths.rhs sw
				g4 df.leftSB (top - DToothlessRise)
				arch.rhs top (blendPre -- {})
				flat df.rightSB (top - adb)
				curl df.rightSB [if fHookLeft (TailY + HalfStroke) 0] [heading Downward]
			if fHookLeft : include : RetroflexHook.rExt df.rightSB (TailY + HalfStroke) (sw -- sw)
			include : FlipAround df.middle (top / 2)

	define UUpper : UShapeGroup ArchDepthA ArchDepthB
	define ULower : UShapeGroup SmallArchDepthA SmallArchDepthB

	define [UTopLeftSerif df yTop _sw] : begin
		local sf : SerifFrame.fromDf df yTop 0 (swSerif -- _sw)
		return sf.lt.outer

	define [UTopRightSerif df yTop _sw] : begin
		local sf : SerifFrame.fromDf df yTop 0 (swSerif -- _sw)
		return sf.rt.inner

	define [UBottomRightSerif df yTop _sw] : glyph-proc
		local sf : SerifFrame.fromDf df yTop 0 (swSerif -- _sw)
		include sf.rb.outer
		define trAnchor currentGlyph.baseAnchors.trailing
		if trAnchor : begin
			set-base-anchor 'trailing' (trAnchor.x + sf.sideJut) trAnchor.y

	glyph-block-export USerifs
	define USerifs : namespace
		export : define [Toothed df top _sw] : glyph-proc
			include : UTopLeftSerif df top _sw
			include : UTopRightSerif df top _sw
			include : UBottomRightSerif df top _sw

		export : define [RTBase df top _sw] : glyph-proc
			include : UTopLeftSerif df top _sw
			include : UTopRightSerif df top _sw

		export : define [Tailed df top _sw] : glyph-proc
			include : UTopLeftSerif df top _sw
			include : UTopRightSerif df top _sw

		export : define [BilateralMotion df top _sw] : begin
			local sf : SerifFrame.fromDf df top 0 (swSerif -- _sw)
			return : composite-proc sf.lt.outer sf.rt.outer

		export : define [SmallToothless df top _sw] : glyph-proc
			include : UTopLeftSerif df top _sw
			include : UTopRightSerif df top _sw

		export : define [MotionToothed df top _sw] : glyph-proc
			include : UTopLeftSerif df top _sw
			include : UBottomRightSerif df top _sw

		export : define [BottomRight df top _sw] : glyph-proc
			include : UBottomRightSerif df top _sw

		export : define [MotionToothless df top _sw] : glyph-proc
			include : UTopLeftSerif df top _sw

		export : define [Toothless df top _sw] : begin
			local sf : SerifFrame.fromDf df top 0 (swSerif -- _sw)
			return : composite-proc sf.lt.full sf.rt.full

	glyph-block-export CapitalUConfigT
	define [CapitalUConfigT shapeGroup] : SuffixCfg.weave
		object # body
			toothed           shapeGroup.Toothed
			tailed            shapeGroup.Tailed
			toothlessCorner   shapeGroup.ToothlessCorner
			toothlessRounded  shapeGroup.ToothlessRounded
		function [body] : object # serifs
			serifless               { no-shape                false }
			bottomRightSerifed      { USerifs.BottomRight     false }
			bilateralMotionSerifed  { USerifs.BilateralMotion true  }
			unilateralMotionSerifed : match body
				[Just 'toothed']    { USerifs.MotionToothed   true  }
				__                  { USerifs.MotionToothless true  }
			serifed : match body
				[Just 'toothed']    { USerifs.Toothed         true  }
				[Just 'tailed']     { USerifs.Tailed          true  }
				__                  { USerifs.Toothless       true  }

	foreach { suffix { Base {Slabs fLTSlab} } } [Object.entries : CapitalUConfigT UUpper] : do
		create-glyph "U.\(suffix)" : glyph-proc
			local df : DivFrame 1
			include : MarkSet.capital
			include : Base df CAP Stroke
			include : Slabs df CAP

		create-glyph "U/withTonos.\(suffix)" : glyph-proc
			include [refer-glyph "U.\(suffix)"] AS_BASE ALSO_METRICS
			include : SetGrekUpperTonos [if fLTSlab (-SideJut) 0]

		create-glyph "smcpU.\(suffix)" : glyph-proc
			local df : DivFrame 1
			include : MarkSet.e
			include : Base df XH Stroke
			include : Slabs df XH

	glyph-block-export SmallUConfigT
	define [SmallUConfigT shapeGroup] : SuffixCfg.weave
		object # body
			toothed           shapeGroup.Toothed
			tailed            shapeGroup.Tailed
			toothlessCorner   shapeGroup.ToothlessCorner
			toothlessRounded  shapeGroup.ToothlessRounded
			urtBase           shapeGroup.Toothed
		function [body] : object # serifs
			serifless              no-shape
			bottomRightSerifed     USerifs.BottomRight
			motionSerifed : match body
				[Just 'toothed']   USerifs.MotionToothed
				__                 USerifs.MotionToothless
			serifed : match body
				[Just 'toothed']   USerifs.Toothed
				[Just 'tailed']    USerifs.Tailed
				[Just 'urtBase']   USerifs.RTBase
				__                 USerifs.SmallToothless

	foreach { suffix { Base Slabs } } [Object.entries : SmallUConfigT ULower] : do
		create-glyph "u.\(suffix)" : glyph-proc
			local df : DivFrame 1
			include : df.markSet.e
			include : Base df XH Stroke
			include : Slabs df XH

		create-glyph "grek/mu.\(suffix)" : glyph-proc
			local df : DivFrame 1
			include : df.markSet.p
			include : Base df XH Stroke
			include : dispiro
				widths.rhs
				flat df.leftSB Descender [heading Upward]
				curl df.leftSB (Descender / 2) [heading Upward]
				straight.up.end df.leftSB SmallArchDepthB [widths.heading 0 [AdviceStroke 4] Upward]
			include : Slabs df XH
			include : LeaningAnchor.Below.VBar.l df.leftSB

		create-glyph "cyrl/tse.italic.\(suffix)" : glyph-proc
			include [refer-glyph "u.\(suffix)"] AS_BASE
			eject-contour 'serifRB'
			include : CyrDescender.rSideJut RightSB 0

		create-glyph "cyrl/tseRev.italic.\(suffix)" : glyph-proc
			include [refer-glyph "u.\(suffix)"] AS_BASE
			include : VBar.l SB 0 SmallArchDepthB [AdviceStroke 4]
			include : CyrDescender.lSideJut SB 0

		create-glyph "cyrl/dzhe.italic.\(suffix)" : glyph-proc
			include [refer-glyph "u.\(suffix)"] AS_BASE ALSO_METRICS
			include [refer-glyph 'descenderBarBelow']

		create-glyph "turnh.\(suffix)" : glyph-proc
			local df : DivFrame 1
			include : df.markSet.p
			include : Base df XH Stroke
			include : Slabs df XH
			eject-contour 'serifRB'
			include : VBar.r df.rightSB Descender XH Stroke
			if (Slabs !== no-shape) : begin
				local sf : SerifFrame.fromDf df XH Descender
				include sf.rb.fullSide
			include : LeaningAnchor.Below.VBar.r df.rightSB

		create-glyph "uShortLeg.\(suffix)" : glyph-proc
			local df : DivFrame 1
			include : df.markSet.e
			include : Base df XH Stroke false true
			include : Slabs df XH
			eject-contour 'serifRT'

		create-glyph "uHookLeft.\(suffix)" : glyph-proc
			local df : DivFrame 1
			include : df.markSet.e
			include : Base df XH Stroke true
			include : Slabs df XH
			eject-contour 'serifLT'

		create-glyph "turnhHookLeft.\(suffix)" : glyph-proc
			local df : DivFrame 1
			include : df.markSet.p
			include : Base df XH Stroke true
			include : Slabs df XH
			eject-contour 'serifLT'
			eject-contour 'serifRB'
			include : VBar.r df.rightSB Descender XH Stroke
			if (Slabs !== no-shape) : begin
				local sf : SerifFrame.fromDf df XH Descender
				include sf.rb.fullSide
			include : LeaningAnchor.Below.VBar.r df.rightSB

		create-glyph "turnhHookLeftRTail.\(suffix)" : glyph-proc
			local df : DivFrame 1
			include : df.markSet.p
			include : Base df XH Stroke true
			include : Slabs df XH
			eject-contour 'serifLT'
			eject-contour 'serifRB'
			include : VBar.r df.rightSB 0 XH Stroke
			include : RetroflexHook.rExt df.rightSB (Descender + TailY + HalfStroke) (yAttach -- 0)
			include : LeaningAnchor.Below.VBar.r df.rightSB

		create-glyph "uSideways.\(suffix)" : glyph-proc
			local df : DivFrame (XH / Width) 2 (XH * 0.1 / SB)
			include : df.markSet.e
			include : PointingTo Width XH Width 0 : function [] : glyph-proc
				include : Base  df (Width - SB) Stroke
				include : Slabs df (Width - SB)
				include : Translate 0 (SB / 2)

		create-glyph "uDieresisSidewaysBase.\(suffix)" : glyph-proc
			local df : DivFrame (XH / Width) 2 (XH * 0.1 / SB)
			include : df.markSet.e
			local ww : Width * para.advanceScaleT
			set-width ww
			set-base-anchor 'cvDecompose' 0 0
			include : PointingTo ww XH ww 0 : function [] : glyph-proc
				include : Base  df (ww - SB - 0.75 * para.advanceScaleT * AccentHeight) Stroke
				include : Slabs df (ww - SB - 0.75 * para.advanceScaleT * AccentHeight)
				include : Translate 0 (SB / 2)

	select-variant 'U' 'U'
	select-variant 'U/withTonos' (follow -- 'U')
	link-reduced-variant 'U/sansSerif' 'U' MathSansSerif
	select-variant 'smcpU' 0x1D1C (follow -- 'U')

	select-variant 'u' 'u'
	link-reduced-variant 'u/sansSerif' 'u' MathSansSerif
	select-variant 'u/uRTailBase' (shapeFrom -- 'u')
	select-variant 'uShortLeg' 0xAB4E
	select-variant 'uHookLeft' 0xAB52

	select-variant 'grek/mu' 0x3BC
	link-reduced-variant 'grek/mu/sansSerif' 'grek/mu' MathSansSerif
	select-variant 'micro'   0xB5  (shapeFrom -- 'grek/mu')

	select-variant 'cyrl/i.italic' (shapeFrom -- 'u')
	select-variant 'cyrl/i.italic/descBase' (shapeFrom -- 'u')
	alias 'cyrl/i.BGR' null 'cyrl/i.italic'

	select-variant 'cyrl/tse.italic'
	alias 'cyrl/tse.BGR' null 'cyrl/tse.italic'
	select-variant 'cyrl/tseRev.italic'
	select-variant 'cyrl/dzhe.italic'

	select-variant 'turnh' 0x265
	select-variant 'turnhHookLeft' 0x2AE
	select-variant 'turnhHookLeftRTail' 0x2AF

	select-variant 'uSideways' 0x1D1D (follow -- 'u')
	select-variant 'uDieresisSidewaysBase' null (follow -- 'u')

	derive-glyphs 'cyrl/ibreve.BGR' null 'cyrl/i.BGR' : lambda [src gr] : glyph-proc
		include [refer-glyph src] AS_BASE ALSO_METRICS
		include [refer-glyph 'breveAbove']

	derive-glyphs 'cyrl/igrave.BGR' null 'cyrl/i.BGR' : lambda [src gr] : glyph-proc
		include [refer-glyph src] AS_BASE ALSO_METRICS
		include [refer-glyph 'graveAbove']

	derive-composites 'cyrl/iShortTail.italic' null 'cyrl/i.italic/descBase'
		refer-glyph 'breveAbove'
		CyrTailDescender.rSideJut RightSB 0

	derive-glyphs 'cyrl/pe.SRB' null 'cyrl/i.italic' : lambda [src gr] : glyph-proc
		include [refer-glyph src] AS_BASE ALSO_METRICS
		include [refer-glyph 'cyrl/pe.SRB/overlineAbove']

	derive-glyphs 'cyrl/tetse.italic' null 'cyrl/tse.italic' : lambda [src gr] : glyph-proc
		include [refer-glyph src] AS_BASE ALSO_METRICS
		include [refer-glyph 'tildeAbove']

	derive-composites 'uRetroflexHook' 0x1D99 'u/uRTailBase'
		RetroflexHook.rSideJut RightSB 0 (yOverflow -- Stroke)

	derive-glyphs 'uWithLightCentralizationStroke' null 'u' : function [src gr] : glyph-proc
		include : MarkSet.p
		include : refer-glyph src
		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 (SB + outStand) (yTurn + outStandY)
				corner (SB - outStand) (yTurn - outStandY)
			spiro-outline
				corner (SB - O) XH
				curl (SB - O) SmallArchDepthB
				arch.lhs 0
				flat (RightSB + O) SmallArchDepthA
				corner (RightSB + O) XH
		if SLAB : begin
			include : HSerif.lt SB XH SideJut

	CreateAccentedComposition 'uDieresis' 0xFC 'u' 'dieresisAbove'
	CreateAccentedComposition 'uBar' 0x289 'u' 'hStrike'
	CreateAccentedComposition 'smcpUStroke' 0x1D7E 'smcpU' 'hStrike'

	# Sideways dieresis for U+1D1E
	derive-glyphs "uDieresisSidewaysMark" null "dieresisAboveAlwaysUpright" : function [gns] : glyph-proc
		local ww : Width * para.advanceScaleT
		set-width 0
		set-mark-anchor 'cvDecompose' 0 0
		include : PointingTo ww XH ww 0 : function [] : glyph-proc
			include : refer-glyph gns
			include : Translate (XH / 2 + Width / 2) (ww - SB - XH - AccentHeight)
			include : Translate 0 (SB / 2)

	CreateAccentedComposition 'uDieresisSideways' 0x1D1E 'uDieresisSidewaysBase' 'uDieresisSidewaysMark'

	glyph-block-import Letter-Blackboard : BBS BBD BBBarRight
	create-glyph 'mathbb/U' 0x1D54C : glyph-proc
		include : MarkSet.capital
		include : HBar.t SB (SB + BBD) CAP BBS
		include : UShape [DivFrame 1] CAP 0
			stroke -- BBS
		include : intersection
			VBar.l (SB + BBD) 0 CAP BBS
			UArcT spiro-outline [DivFrame 1] CAP 0
				stroke -- BBS
				oper   -- true
				offset -- 1

	create-glyph 'mathbb/u' 0x1D566 : glyph-proc
		include : MarkSet.e
		include [refer-glyph 'mathbb/n']
		include : FlipAround Middle (XH / 2)
