123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- 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{}
|