// Copyright 2018-2022 The MathJax Consortium
// SPDX-License-Identifier: Apache-2.0
// This file is a Go translation and modification of MathJax 3.2.2.

package svg

import (
	
	

	
	
)

const (
	verticalFuzz   = .1
	horizontalFuzz = .1
)

func ( *wrapper) ( int) (rune, font.Variant, font.Metrics, bool) {
	if  < 0 ||  >= len(.stretch.Stretch) || .stretch.Stretch[] == 0 {
		return 0, "", font.Metrics{}, false
	}
	,  := .stretch.StretchVariant()
	if ! {
		return 0, "", font.Metrics{}, false
	}
	 := .stretch.Stretch[]
	,  := font.Lookup(, )
	if ! {
		return 0, "", font.Metrics{}, false
	}
	return , , .Metrics, true
}

func ( *wrapper) ( *Element,  int, ,  float64) float64 {
	, , ,  := .stretchPart()
	if ! {
		return 0
	}
	.placeChar(, , , , )
	return .Width
}

func ( *wrapper) ( *Element) {
	 := .getBBox()
	, ,  := .H, .D, .W
	 := .addTop(, , )
	 := .addBottom(, , )
	if len(.stretch.Stretch) == 4 {
		,  := .addMiddleVertical(, )
		.addExtenderVertical(, , 0, , , )
		.addExtenderVertical(, 0, , , , )
	} else {
		.addExtenderVertical(, , , , , )
	}
}

func ( *wrapper) ( *Element, ,  float64) float64 {
	, , ,  := .stretchPart(0)
	if ! {
		return 0
	}
	.addStretchGlyph(, 0, (-.Width)/2, -.Height)
	return .Height + .Depth
}

func ( *wrapper) ( *Element, ,  float64) float64 {
	, , ,  := .stretchPart(2)
	if ! {
		return 0
	}
	.addStretchGlyph(, 2, (-.Width)/2, .Depth-)
	return .Height + .Depth
}

func ( *wrapper) ( *Element,  float64) (float64, float64) {
	, , ,  := .stretchPart(3)
	if ! {
		return 0, 0
	}
	 := (.Depth-.Height)/2 + .renderer.params.Axis
	.addStretchGlyph(, 3, (-.Width)/2, )
	return .Height + , .Depth - 
}

func ( *wrapper) ( *Element, , , , ,  float64) {
	, , ,  := .stretchPart(1)
	if ! {
		return
	}
	 = math.Max(0, -verticalFuzz)
	 = math.Max(0, -verticalFuzz)
	 :=  +  -  - 
	if  <= 0 || .Height+.Depth == 0 {
		return
	}
	 := 1.5 *  / (.Height + .Depth)
	 := (*(.Height-.Depth) - ) / 2
	 := NewElement("svg").
		SetAttr("width", fixed(.Width)).
		SetAttr("height", fixed()).
		SetAttr("y", fixed(-)).
		SetAttr("x", fixed((-.Width)/2)).
		SetAttr("viewBox", strings.Join([]string{fixed(), fixed(.Width), fixed()}, " "))
	.Attributes[len(.Attributes)-1].Value = "0 " + .Attributes[len(.Attributes)-1].Value
	.placeChar(, 0, 0, , )
	if  := lastElement();  != nil {
		.SetAttr("transform", "scale(1,"+jscompat.Fixed(, 3)+")")
	}
	.Append()
}

func ( *wrapper) ( *Element) {
	 := .getBBox().W
	 := .addLeft()
	 := .addRight(, )
	if len(.stretch.Stretch) == 4 {
		,  := .addMiddleHorizontal(, )
		 :=  / 2
		.addExtenderHorizontal(, , , -, 0)
		.addExtenderHorizontal(, , -, , )
	} else {
		.addExtenderHorizontal(, , , , 0)
	}
}

func ( *wrapper) ( *Element) float64 {
	return .addStretchGlyph(, 0, 0, 0)
}

func ( *wrapper) ( *Element,  float64) float64 {
	, , ,  := .stretchPart(2)
	if ! {
		return 0
	}
	.addStretchGlyph(, 2, -.Width, 0)
	return .Width
}

func ( *wrapper) ( *Element,  float64) (float64, float64) {
	, , ,  := .stretchPart(3)
	if ! {
		return 0, 0
	}
	 := ( - .Width) / 2
	.addStretchGlyph(, 3, , 0)
	return , ( + .Width) / 2
}

func ( *wrapper) ( *Element, , , ,  float64) {
	, , ,  := .stretchPart(1)
	if ! {
		return
	}
	 = math.Max(0, -horizontalFuzz)
	 = math.Max(0, -horizontalFuzz)
	 :=  -  - 
	if  <= 0 || .Width == 0 {
		return
	}
	 := .Height + .Depth + 2*verticalFuzz
	// SVGmo.addExtH divides before multiplying. Preserve the source order
	// because its rounded clipping viewBox exposes the floating-point result.
	 := 1.5 * ( / .Width)
	// JavaScript rounds the product before subtracting the extender width.
	 := (float64(*.Width) - ) / 2
	 := -(.Depth + verticalFuzz)
	 := NewElement("svg").
		SetAttr("width", fixed()).
		SetAttr("height", fixed()).
		SetAttr("x", fixed(+)).
		SetAttr("y", fixed()).
		SetAttr("viewBox", strings.Join([]string{
			fixed(), fixed(), fixed(), fixed(),
		}, " "))
	.placeChar(, 0, 0, , )
	if  := lastElement();  != nil {
		.SetAttr("transform", "scale("+jscompat.Fixed(, 3)+",1)")
	}
	.Append()
}

func lastElement( *Element) *Element {
	if  == nil || len(.Children) == 0 {
		return nil
	}
	,  := .Children[len(.Children)-1].(*Element)
	return 
}