draw2d/draw2dsvg/svg.go
2018-01-10 23:00:49 +01:00

172 lines
3.7 KiB
Go

// Copyright 2015 The draw2d Authors. All rights reserved.
// created: 16/12/2017 by Drahoslav Bednář
package draw2dsvg
import (
"encoding/xml"
)
/* svg elements */
type FontMode int
// Modes of font handling in svg
const (
// Does nothing special
// Makes sense only for common system fonts
SysFontMode FontMode = 1 << iota
// Links font files in css def
// Requires distribution of font files with outputed svg
LinkFontMode // TODO implement
// Embeds glyphs definition in svg file itself in svg font format
// Has poor browser support
SvgFontMode
// Embeds font definiton in svg file itself in woff format as part of css def
CssFontMode // TODO implement
// Converts texts to paths
PathFontMode
)
type Svg struct {
XMLName xml.Name `xml:"svg"`
Xmlns string `xml:"xmlns,attr"`
Fonts []*Font `xml:"defs>font"`
Masks []*Mask `xml:"defs>mask"`
Groups []*Group `xml:"g"`
FontMode FontMode `xml:"-"`
FillStroke
}
func NewSvg() *Svg {
return &Svg{
Xmlns: "http://www.w3.org/2000/svg",
FillStroke: FillStroke{Fill: "none", Stroke: "none"},
FontMode: PathFontMode,
}
}
type Group struct {
FillStroke
Transform string `xml:"transform,attr,omitempty"`
Groups []*Group `xml:"g"`
Paths []*Path `xml:"path"`
Texts []*Text `xml:"text"`
Image *Image `xml:"image"`
Mask string `xml:"mask,attr,omitempty"`
}
type Path struct {
FillStroke
Desc string `xml:"d,attr"`
}
type Text struct {
FillStroke
Position
FontSize float64 `xml:"font-size,attr,omitempty"`
FontFamily string `xml:"font-family,attr,omitempty"`
Text string `xml:",innerxml"`
Style string `xml:"style,attr,omitempty"`
}
type Image struct {
Position
Dimension
Href string `xml:"href,attr"`
}
type Mask struct {
Identity
Position
Dimension
}
type Rect struct {
Position
Dimension
FillStroke
}
func (m Mask) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
bigRect := Rect{}
bigRect.X, bigRect.Y = 0, 0
bigRect.Width, bigRect.Height = "100%", "100%"
bigRect.Fill = "#fff"
rect := Rect{}
rect.X, rect.Y = m.X, m.Y
rect.Width, rect.Height = m.Width, m.Height
rect.Fill = "#000"
return e.EncodeElement(struct {
XMLName xml.Name `xml:"mask"`
Rects [2]Rect `xml:"rect"`
Id string `xml:"id,attr"`
}{
Rects: [2]Rect{bigRect, rect},
Id: m.Id,
}, start)
}
/* font related elements */
type Font struct {
Identity
Face *Face `xml:"font-face"`
Glyphs []*Glyph `xml:"glyph"`
}
type Face struct {
Family string `xml:"font-family,attr"`
Units int `xml:"units-per-em,attr"`
HorizAdvX float64 `xml:"horiz-adv-x,attr"`
// TODO add other attrs, like style, variant, weight...
}
type Glyph struct {
Rune Rune `xml:"unicode,attr"`
Desc string `xml:"d,attr"`
HorizAdvX float64 `xml:"horiz-adv-x,attr"`
}
type Rune rune
func (r Rune) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
return xml.Attr{
Name: name,
Value: string(rune(r)),
}, nil
}
/* shared attrs */
type Identity struct {
Id string `xml:"id,attr"`
Name string `xml:"name,attr"`
}
type Position struct {
X float64 `xml:"x,attr,omitempty"`
Y float64 `xml:"y,attr,omitempty"`
}
type Dimension struct {
Width string `xml:"width,attr"`
Height string `xml:"height,attr"`
}
type FillStroke struct {
Fill string `xml:"fill,attr,omitempty"`
FillRule string `xml:"fill-rule,attr,omitempty"`
Stroke string `xml:"stroke,attr,omitempty"`
StrokeWidth string `xml:"stroke-width,attr,omitempty"`
StrokeLinecap string `xml:"stroke-linecap,attr,omitempty"`
StrokeLinejoin string `xml:"stroke-linejoin,attr,omitempty"`
StrokeDasharray string `xml:"stroke-dasharray,attr,omitempty"`
StrokeDashoffset string `xml:"stroke-dashoffset,attr,omitempty"`
}