-
Notifications
You must be signed in to change notification settings - Fork 38
/
svg_path.go
109 lines (98 loc) · 3.41 KB
/
svg_path.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright 2017 The oksvg Authors. All rights reserved.
// created: 2/12/2017 by S.R.Wiley
//
// utils.go implements translation of an SVG2.0 path into a rasterx Path.
package oksvg
import (
"image/color"
"github.com/srwiley/rasterx"
"golang.org/x/image/math/fixed"
)
// SvgPath binds a style to a path.
type SvgPath struct {
PathStyle
Path rasterx.Path
}
// Draw the compiled SvgPath into the Dasher.
func (svgp *SvgPath) Draw(r *rasterx.Dasher, opacity float64) {
svgp.DrawTransformed(r, opacity, rasterx.Identity)
}
// DrawTransformed draws the compiled SvgPath into the Dasher while applying transform t.
func (svgp *SvgPath) DrawTransformed(r *rasterx.Dasher, opacity float64, t rasterx.Matrix2D) {
m := svgp.mAdder.M
svgp.mAdder.M = t.Mult(m)
defer func() { svgp.mAdder.M = m }() // Restore untransformed matrix
if svgp.fillerColor != nil {
r.Clear()
rf := &r.Filler
rf.SetWinding(svgp.UseNonZeroWinding)
svgp.mAdder.Adder = rf // This allows transformations to be applied
svgp.Path.AddTo(&svgp.mAdder)
switch fillerColor := svgp.fillerColor.(type) {
case color.Color:
rf.SetColor(rasterx.ApplyOpacity(fillerColor, svgp.FillOpacity*opacity))
case rasterx.Gradient:
if fillerColor.Units == rasterx.ObjectBoundingBox {
fRect := rf.Scanner.GetPathExtent()
mnx, mny := float64(fRect.Min.X)/64, float64(fRect.Min.Y)/64
mxx, mxy := float64(fRect.Max.X)/64, float64(fRect.Max.Y)/64
fillerColor.Bounds.X, fillerColor.Bounds.Y = mnx, mny
fillerColor.Bounds.W, fillerColor.Bounds.H = mxx-mnx, mxy-mny
}
rf.SetColor(fillerColor.GetColorFunction(svgp.FillOpacity * opacity))
}
rf.Draw()
// default is true
rf.SetWinding(true)
}
if svgp.linerColor != nil {
r.Clear()
svgp.mAdder.Adder = r
lineGap := svgp.LineGap
if lineGap == nil {
lineGap = DefaultStyle.LineGap
}
lineCap := svgp.LineCap
if lineCap == nil {
lineCap = DefaultStyle.LineCap
}
leadLineCap := lineCap
if svgp.LeadLineCap != nil {
leadLineCap = svgp.LeadLineCap
}
r.SetStroke(fixed.Int26_6(svgp.LineWidth*64),
fixed.Int26_6(svgp.MiterLimit*64), leadLineCap, lineCap,
lineGap, svgp.LineJoin, svgp.Dash, svgp.DashOffset)
svgp.Path.AddTo(&svgp.mAdder)
switch linerColor := svgp.linerColor.(type) {
case color.Color:
r.SetColor(rasterx.ApplyOpacity(linerColor, svgp.LineOpacity*opacity))
case rasterx.Gradient:
if linerColor.Units == rasterx.ObjectBoundingBox {
fRect := r.Scanner.GetPathExtent()
mnx, mny := float64(fRect.Min.X)/64, float64(fRect.Min.Y)/64
mxx, mxy := float64(fRect.Max.X)/64, float64(fRect.Max.Y)/64
linerColor.Bounds.X, linerColor.Bounds.Y = mnx, mny
linerColor.Bounds.W, linerColor.Bounds.H = mxx-mnx, mxy-mny
}
r.SetColor(linerColor.GetColorFunction(svgp.LineOpacity * opacity))
}
r.Draw()
}
}
// GetFillColor returns the fill color of the SvgPath if one is defined and otherwise returns colornames.Black
func (svgp *SvgPath) GetFillColor() color.Color {
return getColor(svgp.fillerColor)
}
// GetLineColor returns the stroke color of the SvgPath if one is defined and otherwise returns colornames.Black
func (svgp *SvgPath) GetLineColor() color.Color {
return getColor(svgp.linerColor)
}
// SetFillColor sets the fill color of the SvgPath
func (svgp *SvgPath) SetFillColor(clr color.Color) {
svgp.fillerColor = clr
}
// SetLineColor sets the line color of the SvgPath
func (svgp *SvgPath) SetLineColor(clr color.Color) {
svgp.linerColor = clr
}