From 215a761ccb998d630ccad2bd1687c7d4355ab3a7 Mon Sep 17 00:00:00 2001 From: Drahoslav Date: Tue, 26 Dec 2017 14:25:28 +0100 Subject: [PATCH] Use transformations in svg context also few minor changes in to svg transformation functions --- draw2dsvg/converters.go | 24 +++++++++++++---- draw2dsvg/gc.go | 59 ++++++++++++++++++++++++----------------- draw2dsvg/svg.go | 7 ++--- 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/draw2dsvg/converters.go b/draw2dsvg/converters.go index 7b5c6a3..59d5064 100644 --- a/draw2dsvg/converters.go +++ b/draw2dsvg/converters.go @@ -13,7 +13,11 @@ import ( func toSvgRGBA(c color.Color) string { r, g, b, a := c.RGBA() - return fmt.Sprintf("rgba(%v, %v, %v, %.3f)", r>>8, g>>8, b>>8, float64(a>>8)/255) + r, g, b, a = r>>8, g>>8, b>>8, a>>8 + if a == 255 { + return fmt.Sprintf("#%02X%02X%02X", r, g, b) + } + return fmt.Sprintf("rgba(%v,%v,%v,%.3f)", r, g, b, float64(a)/255) } func toSvgLength(l float64) string { @@ -84,10 +88,7 @@ func toSvgPathDesc(p *draw2d.Path) string { // rx ry x-axis-rotation large-arc-flag sweep-flag x y parts[i] = fmt.Sprintf("A %.4f %.4f %v %v %v %.4f %.4f", - rx, ry, - 0, - large, sweep, - x, y, + rx, ry, 0, large, sweep, x, y, ) ps = ps[6:] case draw2d.CloseCmp: @@ -96,3 +97,16 @@ func toSvgPathDesc(p *draw2d.Path) string { } return strings.Join(parts, " ") } + +func toSvgTransform(mat draw2d.Matrix) string { + if mat.IsIdentity() { + return "" + } + if mat.IsTranslation() { + x, y := mat.GetTranslation() + return fmt.Sprintf("translate(%f,%f)", x, y) + } + return fmt.Sprintf("matrix(%f,%f,%f,%f,%f,%f)", + mat[0], mat[1], mat[2], mat[3], mat[4], mat[5], + ) +} diff --git a/draw2dsvg/gc.go b/draw2dsvg/gc.go index 3ef6adb..1daa5fe 100644 --- a/draw2dsvg/gc.go +++ b/draw2dsvg/gc.go @@ -70,38 +70,45 @@ func (gc *GraphicContext) FillStroke(paths ...*draw2d.Path) { } func (gc *GraphicContext) drawPaths(drawType drawType, paths ...*draw2d.Path) { - paths = append(paths, gc.Current.Path) - + // create elements svgPath := Path{} group := Group{} - svgPathsDesc := make([]string, len(paths)) - - // multiple pathes has to be joined to single svg path description - // because fill-rule wont work for whole group - for i, path := range paths { - svgPathsDesc[i] = toSvgPathDesc(path) - } - svgPath.Desc = strings.Join(svgPathsDesc, " ") - - if drawType&stroked == stroked { - group.Stroke = toSvgRGBA(gc.Current.StrokeColor) - group.StrokeWidth = toSvgLength(gc.Current.LineWidth) - group.StrokeLinecap = gc.Current.Cap.String() - group.StrokeLinejoin = gc.Current.Join.String() - if len(gc.Current.Dash) > 0 { - group.StrokeDasharray = toSvgArray(gc.Current.Dash) - group.StrokeDashoffset = toSvgLength(gc.Current.DashOffset) + // set attrs to path + { + paths = append(paths, gc.Current.Path) + svgPathsDesc := make([]string, len(paths)) + // multiple pathes has to be joined to single svg path description + // because fill-rule wont work for whole group as excepted + for i, path := range paths { + svgPathsDesc[i] = toSvgPathDesc(path) } + svgPath.Desc = strings.Join(svgPathsDesc, " ") } - if drawType&filled == filled { - group.Fill = toSvgRGBA(gc.Current.FillColor) - group.FillRule = toSvgFillRule(gc.Current.FillRule) + // set attrs to group + { + if drawType&stroked == stroked { + group.Stroke = toSvgRGBA(gc.Current.StrokeColor) + group.StrokeWidth = toSvgLength(gc.Current.LineWidth) + group.StrokeLinecap = gc.Current.Cap.String() + group.StrokeLinejoin = gc.Current.Join.String() + if len(gc.Current.Dash) > 0 { + group.StrokeDasharray = toSvgArray(gc.Current.Dash) + group.StrokeDashoffset = toSvgLength(gc.Current.DashOffset) + } + } + + if drawType&filled == filled { + group.Fill = toSvgRGBA(gc.Current.FillColor) + group.FillRule = toSvgFillRule(gc.Current.FillRule) + } + + group.Transform = toSvgTransform(gc.Current.Tr) } + // link elements group.Paths = []Path{svgPath} - gc.svg.Groups = append(gc.svg.Groups, group) } @@ -130,12 +137,14 @@ func (gc *GraphicContext) DrawImage(image image.Image) { // Save the context and push it to the context stack func (gc *GraphicContext) Save() { - + gc.StackGraphicContext.Save() + // TODO use common transformation group for multiple elements } // Restore remove the current context and restore the last one func (gc *GraphicContext) Restore() { - + gc.StackGraphicContext.Restore() + // TODO use common transformation group for multiple elements } // ClearRect fills the specified rectangle with a default transparent color diff --git a/draw2dsvg/svg.go b/draw2dsvg/svg.go index ec16e1b..e9a414a 100644 --- a/draw2dsvg/svg.go +++ b/draw2dsvg/svg.go @@ -18,9 +18,10 @@ type Svg struct { type Group struct { FillStroke - Groups []Group `xml:"g"` - Paths []Path `xml:"path"` - Texts []Text `xml:"text"` + Transform string `xml:"transform,attr,omitempty"` + Groups []Group `xml:"g"` + Paths []Path `xml:"path"` + Texts []Text `xml:"text"` } type Path struct {