-
Notifications
You must be signed in to change notification settings - Fork 0
/
pathprocess.go
154 lines (128 loc) · 3.57 KB
/
pathprocess.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package graphics2d
// General purpose interface that takes a path and turns it into
// a slice of paths. For example, a stroked outline of the path or breaks the
// path up into a series of dashes.
// PathProcessor defines the interface required for function passed to the Process function in Path.
type PathProcessor interface {
Process(p *Path) []*Path
}
// CompoundProc applies a collection of PathProcessors to a path.
type CompoundProc struct {
Procs []PathProcessor
Concatenate bool // If set, concatenate processed paths into a single path after every processor
}
// NewCompoundProc creates a new CompoundProcessor with the supplied path processors.
func NewCompoundProc(procs ...PathProcessor) *CompoundProc {
return &CompoundProc{procs, false}
}
// Process implements the PathProcessor interface.
func (cp *CompoundProc) Process(p *Path) []*Path {
paths := []*Path{p}
if len(cp.Procs) == 0 {
return paths
}
for _, proc := range cp.Procs {
npaths := []*Path{}
for _, path := range paths {
npaths = append(npaths, proc.Process(path)...)
}
if cp.Concatenate {
path, _ := ConcatenatePaths(npaths...)
paths = []*Path{path}
} else {
paths = npaths
}
}
if cp.Concatenate && p.Closed() {
paths[0].Close()
}
return paths
}
// PathProcessor wrappers for Flatten, Simplify, Line and Parts path functions
// FlattenProc is a wrapper around Path.Flatten() and contains the minimum required
// distance to the control points.
type FlattenProc struct {
Flatten float64
}
// Process implements the PathProcessor interface.
func (fp *FlattenProc) Process(p *Path) []*Path {
path := p.Flatten(fp.Flatten)
if p.Closed() {
path.Close()
}
return []*Path{path}
}
// LineProc replaces a path with a single line.
type LineProc struct{}
// Process implements the PathProcessor interface.
func (lp *LineProc) Process(p *Path) []*Path {
path := p.Line()
if p.Closed() {
path.Close()
}
return []*Path{path}
}
// LinesProc replaces a path step with a line.
type LinesProc struct {
IncludeCP bool
}
// Process implements the PathProcessor interface.
func (lp *LinesProc) Process(p *Path) []*Path {
path := p.Lines(lp.IncludeCP)
if p.Closed() {
path.Close()
}
return []*Path{path}
}
// OpenProc replaces a path with its open version.
type OpenProc struct{}
// Process implements the PathProcessor interface.
func (op *OpenProc) Process(p *Path) []*Path {
path := p.Open()
return []*Path{path}
}
// ReverseProc replaces a path with its reverse.
type ReverseProc struct{}
// Process implements the PathProcessor interface.
func (rp *ReverseProc) Process(p *Path) []*Path {
path := p.Reverse()
if p.Closed() {
path.Close()
}
return []*Path{path}
}
// SimplifyProc is a wrpper around Path.Simplify().
type SimplifyProc struct{}
// Process implements the PathProcessor interface.
func (sp *SimplifyProc) Process(p *Path) []*Path {
path := p.Simplify()
if p.Closed() {
path.Close()
}
return []*Path{path}
}
// StepsProc converts each path step into its own path.
type StepsProc struct{}
// Process implements the PathProcessor interface.
func (sp *StepsProc) Process(p *Path) []*Path {
parts := p.Parts()
np := len(parts)
paths := make([]*Path, np)
for i, part := range parts {
paths[i] = PartsToPath(part)
}
return paths
}
// TransformProc is a wrapper around Path.Transform() and contains the Aff3
// transform to be applied.
type TransformProc struct {
Transform *Aff3
}
// Process implements the PathProcessor interface.
func (tp *TransformProc) Process(p *Path) []*Path {
path := p.Transform(tp.Transform)
if p.Closed() {
path.Close()
}
return []*Path{path}
}