package svg import "regexp" import "fmt" import "strconv" import "encoding/xml" type Unit string // Relative units are: // em: the 'font-size' of the relevant font // ex: the 'x-height' of the relevant font // px: pixels, relative to the viewing device // ebisvg uses exactly one ebiten pixel for px unit. // const UnitEx = Unit(ex) // As the CSS2 standard states "1px thus corresponds to about 0.28 mm" // This then means that there are 3.571428571428571 pixels per mm. // ebisvg uses this scale factor for the absolute SVG units. // const MM2PX = 3.571428571428571 const IN2MM = 254 const PT2IN = 1 / 72 const PC2IN = 1 / 6 const UnitNo = Unit("") const UnitPx = Unit("px") const UnitEm = Unit("em") const UnitEx = Unit("ex") const UnitIn = Unit("in") const UnitCm = Unit("cm") const UnitMm = Unit("mm") const UnitPt = Unit("pt") const UnitPc = Unit("pc") const UnitPe = Unit("%") type Length struct { Magnitude float32 Unit } func (l Length) Pixels(parent ...float32) float32 { switch l.Unit { case UnitNo, UnitPx: return l.Magnitude case UnitEx, UnitEm, UnitPe: if len(parent) > 0 { return l.Magnitude * parent[0] } else { return l.Magnitude } case UnitPc: return l.Magnitude * PC2IN * IN2MM * MM2PX case UnitPt: return l.Magnitude * PT2IN * IN2MM * MM2PX case UnitMm: return l.Magnitude * MM2PX case UnitCm: return l.Magnitude * MM2PX * 100 case UnitIn: return l.Magnitude * IN2MM * MM2PX default: return l.Magnitude } } var ParseLengthRe = regexp.MustCompile(`([0-9]*\.?[0-9]*)(em|ex|px|in|cm|mm|pt|pc|%)?`) func ParseLength(s string) (Length, error) { parts := ParseLengthRe.FindStringSubmatch(s) res := Length{} if len(parts) < 2 { return res, fmt.Errorf("empty length") } magnitude, err := strconv.ParseFloat(parts[1], 32) if err != nil { return res, err } res.Magnitude = float32(magnitude) if len(parts) > 2 { res.Unit = Unit(parts[2]) } return res, nil } func (l *Length) UnmarshalXMLAttr(attr xml.Attr) error { length, err := ParseLength(attr.Value) if err != nil { return err } *l = length return nil } var _ xml.UnmarshalerAttr = &Length{}