package svg import "fmt" type ( Length struct { number float64 absUnit AbsoluteLengthUnit relUnit RelativeLengthUnit } LengthAttr[T Tag] Length ) func NewLength(n float64) *Length { return &Length{ number: n, } } func (l *Length) Number(n float64) *Length { l.number = n return l } func (l *Length) Unit(u AbsoluteLengthUnit) *Length { l.absUnit = u l.relUnit = 0 return l } func (l *Length) RUnit(u RelativeLengthUnit) *Length { l.relUnit = u l.absUnit = 0 return l } func (l Length) String() string { if l.absUnit != 0 { return fmt.Sprintf("%v%s", l.number, l.absUnit) } if l.relUnit != 0 { return fmt.Sprintf("%v%s", l.number, l.relUnit) } return fmt.Sprintf("%v", l.number) } func (LengthAttr[T]) PrintKey() string { var tag T return tag.PrintTag() } func (a LengthAttr[T]) PrintValue() (string, bool) { return fmt.Sprintf(`"%s"`, Length(a)), true } // Relative length units type RelativeLengthUnit int const ( _ RelativeLengthUnit = iota // based on font Cap Ch Em Ex Ic Lh // based on root element's font Rcap Rch Rem Rex Ric Rlh // based on viewport Vh Vw Vmax Vmin Vb Vi // small viewport Svh Svw Svmax Svmin Svb Svi // large viewport Lvh Lvw Lvmax Lvmin Lvb Lvi // dynamic viewport Dvh Dvw Dvmax Dvmin Dvb Dvi // container query Cqw Cqh Cqi Cqb Cqmin Cqmax ) func (u RelativeLengthUnit) String() string { switch u { case Cap: return "cap" case Ch: return "ch" case Em: return "em" case Ex: return "ex" case Ic: return "ic" case Lh: return "lh" case Rcap: return "rcap" case Rch: return "rch" case Rem: return "rem" case Rex: return "rex" case Ric: return "ric" case Rlh: return "rlh" case Vh: return "vh" case Vw: return "vw" case Vmax: return "vmax" case Vmin: return "vmin" case Vb: return "vb" case Vi: return "vi" case Svh: return "svh" case Svw: return "svw" case Svmax: return "svmax" case Svmin: return "svmin" case Svb: return "svb" case Svi: return "svi" case Lvh: return "lvh" case Lvw: return "lvw" case Lvmax: return "lvmax" case Lvmin: return "lvmin" case Lvb: return "lvb" case Lvi: return "lvi" case Dvh: return "dvh" case Dvw: return "dvw" case Dvmax: return "dvmax" case Dvmin: return "dvmin" case Dvb: return "dvb" case Dvi: return "dvi" case Cqw: return "cqw" case Cqh: return "cqh" case Cqi: return "cqi" case Cqb: return "cqb" case Cqmin: return "cqmin" case Cqmax: return "cqmax" default: return "" } } // Absolute length units type AbsoluteLengthUnit int const ( _ AbsoluteLengthUnit = iota Px Cm Mm Q In Pc Pt ) func (u AbsoluteLengthUnit) String() string { switch u { case Px: return "px" case Cm: return "cm" case Mm: return "mm" case Q: return "q" case In: return "in" case Pc: return "pc" case Pt: return "pt" default: return "" } }