1package drawing 2 3// Liner receive segment definition 4type Liner interface { 5 // LineTo Draw a line from the current position to the point (x, y) 6 LineTo(x, y float64) 7} 8 9// Flattener receive segment definition 10type Flattener interface { 11 // MoveTo Start a New line from the point (x, y) 12 MoveTo(x, y float64) 13 // LineTo Draw a line from the current position to the point (x, y) 14 LineTo(x, y float64) 15 // LineJoin add the most recent starting point to close the path to create a polygon 16 LineJoin() 17 // Close add the most recent starting point to close the path to create a polygon 18 Close() 19 // End mark the current line as finished so we can draw caps 20 End() 21} 22 23// Flatten convert curves into straight segments keeping join segments info 24func Flatten(path *Path, flattener Flattener, scale float64) { 25 // First Point 26 var startX, startY float64 27 // Current Point 28 var x, y float64 29 var i int 30 for _, cmp := range path.Components { 31 switch cmp { 32 case MoveToComponent: 33 x, y = path.Points[i], path.Points[i+1] 34 startX, startY = x, y 35 if i != 0 { 36 flattener.End() 37 } 38 flattener.MoveTo(x, y) 39 i += 2 40 case LineToComponent: 41 x, y = path.Points[i], path.Points[i+1] 42 flattener.LineTo(x, y) 43 flattener.LineJoin() 44 i += 2 45 case QuadCurveToComponent: 46 // we include the previous point for the start of the curve 47 TraceQuad(flattener, path.Points[i-2:], 0.5) 48 x, y = path.Points[i+2], path.Points[i+3] 49 flattener.LineTo(x, y) 50 i += 4 51 case CubicCurveToComponent: 52 TraceCubic(flattener, path.Points[i-2:], 0.5) 53 x, y = path.Points[i+4], path.Points[i+5] 54 flattener.LineTo(x, y) 55 i += 6 56 case ArcToComponent: 57 x, y = TraceArc(flattener, path.Points[i], path.Points[i+1], path.Points[i+2], path.Points[i+3], path.Points[i+4], path.Points[i+5], scale) 58 flattener.LineTo(x, y) 59 i += 6 60 case CloseComponent: 61 flattener.LineTo(startX, startY) 62 flattener.Close() 63 } 64 } 65 flattener.End() 66} 67 68// SegmentedPath is a path of disparate point sectinos. 69type SegmentedPath struct { 70 Points []float64 71} 72 73// MoveTo implements the path interface. 74func (p *SegmentedPath) MoveTo(x, y float64) { 75 p.Points = append(p.Points, x, y) 76 // TODO need to mark this point as moveto 77} 78 79// LineTo implements the path interface. 80func (p *SegmentedPath) LineTo(x, y float64) { 81 p.Points = append(p.Points, x, y) 82} 83 84// LineJoin implements the path interface. 85func (p *SegmentedPath) LineJoin() { 86 // TODO need to mark the current point as linejoin 87} 88 89// Close implements the path interface. 90func (p *SegmentedPath) Close() { 91 // TODO Close 92} 93 94// End implements the path interface. 95func (p *SegmentedPath) End() { 96 // Nothing to do 97} 98