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

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


glyph-module

glyph-block Mark-Adjustment : begin
	glyph-block-export ExtendBelowBaseAnchors
	define [ExtendBelowBaseAnchors y] : glyph-proc
		if currentGlyph.baseAnchors.below : begin
			local a : currentGlyph.gizmo.unapply currentGlyph.baseAnchors.below
			if (a.y > y) : set-base-anchor 'below' a.x y
		if currentGlyph.baseAnchors.leaningBelow : begin
			local a : currentGlyph.gizmo.unapply currentGlyph.baseAnchors.leaningBelow
			if (a.y > y) : set-base-anchor 'leaningBelow' a.x y

	glyph-block-export ExtendAboveBaseAnchors
	define [ExtendAboveBaseAnchors y] : glyph-proc
		if currentGlyph.baseAnchors.above : begin
			local a : currentGlyph.gizmo.unapply currentGlyph.baseAnchors.above
			if (a.y < y) : set-base-anchor 'above' a.x y
		if currentGlyph.baseAnchors.leaningAbove : begin
			local a : currentGlyph.gizmo.unapply currentGlyph.baseAnchors.leaningAbove
			if (a.y < y) : set-base-anchor 'leaningAbove' a.x y

	glyph-block-export TurnMarks
	define [TurnMarks cx cy _df] : glyph-proc
		# Get position of existing marks, prior to flipping
		local bAbove        : currentGlyph.gizmo.unapplyIfPresent currentGlyph.baseAnchors.above
		local bBelow        : currentGlyph.gizmo.unapplyIfPresent currentGlyph.baseAnchors.below
		local bLeaningAbove : currentGlyph.gizmo.unapplyIfPresent currentGlyph.baseAnchors.leaningAbove
		local bLeaningBelow : currentGlyph.gizmo.unapplyIfPresent currentGlyph.baseAnchors.leaningBelow

		# If there are no marks, or if there are no marks above or below, do nothing
		if (!bAbove || !bBelow) : return nothing

		# Apply the new mark set, with flipped dimensions
		local df : _df || [if currentGlyph.divFrameParams
			[DivFrame.fromParams currentGlyph.divFrameParams]
			[DivFrame (currentGlyph.advanceWidth / Width)]]
		local topAfterFlip : mix cy bBelow.y (-1)
		local botAfterFlip : mix cy bAbove.y (-1)
		local markSet : df.markSet.OfZone { .top topAfterFlip .bot botAfterFlip }
		include : markSet

		# Set the new marks' X coordinates to the flipped X coordinates of the old marks
		if (bBelow && currentGlyph.baseAnchors.above)
			set-base-anchor 'above' [mix cx bBelow.x (-1)] currentGlyph.baseAnchors.above.y
		if (bAbove && currentGlyph.baseAnchors.below)
			set-base-anchor 'below' [mix cx bAbove.x (-1)] currentGlyph.baseAnchors.below.y

		# Handle leaning marks
		if (bLeaningBelow && currentGlyph.baseAnchors.above)
			set-base-anchor 'leaningAbove' [mix cx bLeaningBelow.x (-1)] currentGlyph.baseAnchors.above.y
		if (bLeaningAbove && currentGlyph.baseAnchors.below)
			set-base-anchor 'leaningBelow' [mix cx bLeaningAbove.x (-1)] currentGlyph.baseAnchors.below.y

	glyph-block-export TieAnchorMap
	define TieAnchorMap : list
		list 'above' 'tieAbove'
		list 'below' 'tieBelow'

	glyph-block-export LeaningAnchorMap
	define LeaningAnchorMap : list
		list 'above' 'leaningAbove'
		list 'below' 'leaningBelow'

	glyph-block-export LeaningAnchor
	define LeaningAnchor : namespace
		define [SetProcImpl mkCenter mkLeaning x] : glyph-proc
			local existing currentGlyph.baseAnchors.(mkCenter)
			if [not existing] : return nothing
			local existingNT : currentGlyph.gizmo.unapply existing
			currentGlyph.setBaseAnchor mkLeaning x existingNT.y

		define [Impl mkCenter mkLeaning] : namespace
			export : define [At x] : SetProcImpl mkCenter mkLeaning x

			export : define VBar : namespace
				export : define [m x] : At x
				export : define [l x sw] : At (x + [HSwToV : 0.5 * [fallback sw Stroke]])
				export : define [r x sw] : At (x - [HSwToV : 0.5 * [fallback sw Stroke]])

			export : define [Hook xOutsideBar xOutsideHook sw] : begin
				local xAnchor : mix xOutsideBar xOutsideHook (7/16)
				return : SetProcImpl mkCenter mkLeaning xAnchor

		export : define Above : Impl 'above' 'leaningAbove'
		export : define Below : Impl 'below' 'leaningBelow'

	# "Technical" marks, used to suppress leaning anchors.
	# Used in the build process of precomposed glyphs.
	create-glyph "mark/suppressLeaningAboveAnchor" : glyph-proc
		set-width 0
		set-mark-anchor 'leaningAbove' 0 0
	create-glyph "mark/suppressLeaningBelowAnchor" : glyph-proc
		set-width 0
		set-mark-anchor 'leaningBelow' 0 0
