From cdf301b7bec72db36466e346e6ad8a9a4d6a7456 Mon Sep 17 00:00:00 2001 From: Drahoslav Date: Thu, 21 Dec 2017 18:18:29 +0100 Subject: [PATCH] Use encoding/xml to encode svg --- draw2dsvg/fileutil.go | 11 ++++++--- draw2dsvg/gc.go | 8 +++--- draw2dsvg/svg.go | 28 +++++++++++++++++++++ draw2dsvg/xml_test.go | 57 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 draw2dsvg/svg.go create mode 100644 draw2dsvg/xml_test.go diff --git a/draw2dsvg/fileutil.go b/draw2dsvg/fileutil.go index e864c83..ed28f03 100644 --- a/draw2dsvg/fileutil.go +++ b/draw2dsvg/fileutil.go @@ -2,18 +2,21 @@ package draw2dsvg import ( "os" - "bytes" + "encoding/xml" _ "errors" ) -func SaveToSvgFile(filePath string, svg *SVG) error { +func SaveToSvgFile(filePath string, svg *Svg) error { f, err := os.Create(filePath) if err != nil { return err } defer f.Close() - bytes.NewBuffer((*bytes.Buffer)(svg).Bytes()).WriteTo(f) // clone buffer to make multiple writes possible + f.Write([]byte(xml.Header)) + encoder := xml.NewEncoder(f) + encoder.Indent("", "\t") + err = encoder.Encode(svg) - return nil + return err } \ No newline at end of file diff --git a/draw2dsvg/gc.go b/draw2dsvg/gc.go index c3596d8..6ff10be 100644 --- a/draw2dsvg/gc.go +++ b/draw2dsvg/gc.go @@ -19,18 +19,18 @@ var ( type SVG bytes.Buffer -func NewSvg() *SVG { - return &SVG{} +func NewSvg() *Svg { + return &Svg{Xmlns: "http://www.w3.org/2000/svg"} } // GraphicContext implements the draw2d.GraphicContext interface // It provides draw2d with a svg backend type GraphicContext struct { *draw2dbase.StackGraphicContext - svg *SVG + svg *Svg } -func NewGraphicContext(svg *SVG) *GraphicContext { +func NewGraphicContext(svg *Svg) *GraphicContext { gc := &GraphicContext{draw2dbase.NewStackGraphicContext(), svg} return gc } diff --git a/draw2dsvg/svg.go b/draw2dsvg/svg.go new file mode 100644 index 0000000..9e99d0e --- /dev/null +++ b/draw2dsvg/svg.go @@ -0,0 +1,28 @@ +// Copyright 2015 The draw2d Authors. All rights reserved. +// created: 16/12/2017 by Drahoslav Bednář +package draw2dsvg + +import ( + "encoding/xml" +) + +type Svg struct { + XMLName xml.Name `xml:"svg"` + Xmlns string `xml:"xmlns,attr"` + Groups []Group `xml:"g"` +} + +type Group struct { + Groups []Group `xml:"g"` + Paths []Path `xml:"path"` + Texts []Text `xml:"text"` +} + +type Path struct { + Data string `xml:"d,attr"` +} + +type Text struct { + Text string `xml:",innerxml"` + Style string `xml:",attr,omitempty"` +} \ No newline at end of file diff --git a/draw2dsvg/xml_test.go b/draw2dsvg/xml_test.go new file mode 100644 index 0000000..4be778b --- /dev/null +++ b/draw2dsvg/xml_test.go @@ -0,0 +1,57 @@ +// Copyright 2015 The draw2d Authors. All rights reserved. +// created: 16/12/2017 by Drahoslav Bednář + +// Package draw2dsvg_test gives test coverage with the command: +// go test -cover ./... | grep -v "no test" +// (It should be run from its parent draw2d directory.) +package draw2dsvg + +import ( + "testing" + "encoding/xml" +) + +// Test basic encoding of svg/xml elements +func TestXml(t *testing.T) { + + svg := NewSvg() + svg.Groups = []Group{Group{ + Groups: []Group{ + Group{}, // nested groups + Group{}, + }, + Texts: []Text{ + Text{Text: "Hello"}, // text + Text{Text: "world", Style: "opacity: 0.5"}, // text with style + }, + Paths: []Path{ + Path{Data: "M100,200 C100,100 250,100 250,200 S400,300 400,200"}, // simple path + Path{}, // empty path + }, + }} + + expectedOut := ` + + + + + + Hello + world + +` + + out, err := xml.MarshalIndent(svg, "", " ") + + if err != nil { + t.Error(err) + } + if string(out) != expectedOut { + t.Errorf("svg output is not as expected\n"+ + "got:\n%s\n\n"+ + "want:\n%s\n", + string(out), + expectedOut, + ) + } +}