Use transformations in svg context

also few minor changes in to svg transformation functions
This commit is contained in:
Drahoslav 2017-12-26 14:25:28 +01:00
parent 6d31bfac59
commit 215a761ccb
3 changed files with 57 additions and 33 deletions

View File

@ -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],
)
}

View File

@ -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

View File

@ -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 {