This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
package svg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type (
|
||||
D []PathCommand
|
||||
|
||||
PathCommand interface {
|
||||
PrintPathCommand() (string, string, bool)
|
||||
PrintPathCommandParameters() string
|
||||
}
|
||||
|
||||
// PathCommand implementations
|
||||
|
||||
// PathRelative makes any PathCommand and converts it into a relative command (makes lowercase)
|
||||
PathRelative[C PathCommand] struct {
|
||||
Command C
|
||||
}
|
||||
|
||||
PathMoveTo struct {
|
||||
X, Y float64
|
||||
}
|
||||
|
||||
PathLineTo struct {
|
||||
X, Y float64
|
||||
}
|
||||
PathHorizontalLine float64
|
||||
PathVerticalLine float64
|
||||
|
||||
PathCubicBezier []PathCubicBezierParameterTuple
|
||||
PathCubicBezierParameterTuple struct {
|
||||
X1, Y1 float64
|
||||
X2, Y2 float64
|
||||
X, Y float64
|
||||
}
|
||||
PathSmoothCubicBezier []PathSmoothCubicBezierParameterTuple
|
||||
PathSmoothCubicBezierParameterTuple struct {
|
||||
X2, Y2 float64
|
||||
X, Y float64
|
||||
}
|
||||
|
||||
PathQuadraticBezier []PathQuadraticBezierParameterTuple
|
||||
PathQuadraticBezierParameterTuple struct {
|
||||
X1, Y1 float64
|
||||
X, Y float64
|
||||
}
|
||||
PathSmoothQuadraticBezier []PathSmoothQuadraticBezierParameterTuple
|
||||
PathSmoothQuadraticBezierParameterTuple struct {
|
||||
X, Y float64
|
||||
}
|
||||
|
||||
PathElliptical []PathEllipticalParameterTuple
|
||||
PathEllipticalParameterTuple struct {
|
||||
RX, RY float64
|
||||
Angle float64
|
||||
LargeArc bool
|
||||
Clockwise bool
|
||||
X, Y float64
|
||||
}
|
||||
|
||||
PathClose struct{}
|
||||
)
|
||||
|
||||
func PrintPathCommand(c PathCommand) (string, bool) {
|
||||
cmd, params, ok := c.PrintPathCommand()
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
return fmt.Sprintf("%s %s", cmd, params), true
|
||||
}
|
||||
|
||||
func (c PathRelative[C]) PrintPathCommand() (string, string, bool) {
|
||||
cmd, params, ok := c.Command.PrintPathCommand()
|
||||
return strings.ToLower(cmd), params, ok
|
||||
}
|
||||
|
||||
func (c PathMoveTo) PrintPathCommand() (string, string, bool) {
|
||||
return "M", fmt.Sprintf("%v,%v", c.X, c.Y), true
|
||||
}
|
||||
|
||||
func (c PathLineTo) PrintPathCommand() (string, string, bool) {
|
||||
return "L", fmt.Sprintf("%v,%v", c.X, c.Y), true
|
||||
}
|
||||
|
||||
func (c PathHorizontalLine) PrintPathCommand() (string, string, bool) {
|
||||
return "H", fmt.Sprintf("%v", float64(c)), true
|
||||
}
|
||||
|
||||
func (c PathVerticalLine) PrintPathCommand() (string, string, bool) {
|
||||
return "V", fmt.Sprintf("%v", float64(c)), false
|
||||
}
|
||||
|
||||
func (c PathCubicBezier) PrintPathCommand() (string, string, bool) {
|
||||
if len(c) == 0 {
|
||||
return "", "", false
|
||||
}
|
||||
return "C", printTuples(c), true
|
||||
}
|
||||
|
||||
func (c PathCubicBezier) Append(x1, y1, x2, y2, x, y float64) PathCubicBezier {
|
||||
return append(c, PathCubicBezierParameterTuple{
|
||||
X1: x1,
|
||||
Y1: y1,
|
||||
X2: x2,
|
||||
Y2: y2,
|
||||
X: x,
|
||||
Y: y,
|
||||
})
|
||||
}
|
||||
|
||||
func (t PathCubicBezierParameterTuple) String() string {
|
||||
return fmt.Sprintf("%v,%v %v,%v %v,%v", t.X1, t.Y1, t.X2, t.Y2, t.X, t.Y)
|
||||
}
|
||||
|
||||
func (c PathSmoothCubicBezier) PrintPathCommand() (string, string, bool) {
|
||||
if len(c) == 0 {
|
||||
return "", "", false
|
||||
}
|
||||
return "S", printTuples(c), true
|
||||
}
|
||||
|
||||
func (c PathSmoothCubicBezier) Append(x2, y2, x, y float64) PathSmoothCubicBezier {
|
||||
return append(c, PathSmoothCubicBezierParameterTuple{
|
||||
X2: x2,
|
||||
Y2: y2,
|
||||
X: x,
|
||||
Y: y,
|
||||
})
|
||||
}
|
||||
|
||||
func (t PathSmoothCubicBezierParameterTuple) String() string {
|
||||
return fmt.Sprintf("%v,%v %v,%v", t.X2, t.Y2, t.X, t.Y)
|
||||
}
|
||||
|
||||
func (c PathQuadraticBezier) PrintPathCommand() (string, string, bool) {
|
||||
if len(c) == 0 {
|
||||
return "", "", false
|
||||
}
|
||||
return "Q", printTuples(c), true
|
||||
}
|
||||
|
||||
func (c PathQuadraticBezier) Append(x1, y1, x, y float64) PathQuadraticBezier {
|
||||
return append(c, PathQuadraticBezierParameterTuple{
|
||||
X1: x1,
|
||||
Y1: y1,
|
||||
X: x,
|
||||
Y: y,
|
||||
})
|
||||
}
|
||||
|
||||
func (t PathQuadraticBezierParameterTuple) String() string {
|
||||
return fmt.Sprintf("%v,%v %v,%v", t.X1, t.Y1, t.X, t.Y)
|
||||
}
|
||||
|
||||
func (c PathSmoothQuadraticBezier) PrintPathCommand() (string, string, bool) {
|
||||
if len(c) == 0 {
|
||||
return "", "", false
|
||||
}
|
||||
return "T", printTuples(c), true
|
||||
}
|
||||
|
||||
func (c PathSmoothQuadraticBezier) Append(x, y float64) PathSmoothQuadraticBezier {
|
||||
return append(c, PathSmoothQuadraticBezierParameterTuple{
|
||||
X: x,
|
||||
Y: y,
|
||||
})
|
||||
}
|
||||
|
||||
func (t PathSmoothQuadraticBezierParameterTuple) String() string {
|
||||
return fmt.Sprintf("%v,%v", t.X, t.Y)
|
||||
}
|
||||
|
||||
func (c PathElliptical) PrintPathCommand() (string, string, bool) {
|
||||
if len(c) == 0 {
|
||||
return "", "", false
|
||||
}
|
||||
return "A", printTuples(c), true
|
||||
}
|
||||
|
||||
func (c PathElliptical) Append(rx, ry, angle float64, largeArc, clockwise bool, x, y float64) PathElliptical {
|
||||
return append(c, PathEllipticalParameterTuple{
|
||||
RX: rx,
|
||||
RY: ry,
|
||||
Angle: angle,
|
||||
LargeArc: largeArc,
|
||||
Clockwise: clockwise,
|
||||
X: x,
|
||||
Y: y,
|
||||
})
|
||||
}
|
||||
|
||||
func (t PathEllipticalParameterTuple) String() string {
|
||||
var (
|
||||
largeArcFlag int
|
||||
sweepFlag int
|
||||
)
|
||||
|
||||
if t.LargeArc {
|
||||
largeArcFlag = 1
|
||||
}
|
||||
if t.Clockwise {
|
||||
sweepFlag = 1
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v,%v,%v,%d,%d,%v,%v", t.RX, t.RY, t.Angle, largeArcFlag, sweepFlag, t.X, t.Y)
|
||||
}
|
||||
|
||||
func printTuples[S fmt.Stringer](vs []S) string {
|
||||
ss := make([]string, len(vs))
|
||||
for i, v := range vs {
|
||||
ss[i] = fmt.Sprint(v)
|
||||
}
|
||||
return strings.Join(ss, " ")
|
||||
}
|
||||
Reference in New Issue
Block a user