90 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package drawing
 | |
| 
 | |
| // NewDashVertexConverter creates a new dash converter.
 | |
| func NewDashVertexConverter(dash []float64, dashOffset float64, flattener Flattener) *DashVertexConverter {
 | |
| 	var dasher DashVertexConverter
 | |
| 	dasher.dash = dash
 | |
| 	dasher.currentDash = 0
 | |
| 	dasher.dashOffset = dashOffset
 | |
| 	dasher.next = flattener
 | |
| 	return &dasher
 | |
| }
 | |
| 
 | |
| // DashVertexConverter is a converter for dash vertexes.
 | |
| type DashVertexConverter struct {
 | |
| 	next           Flattener
 | |
| 	x, y, distance float64
 | |
| 	dash           []float64
 | |
| 	currentDash    int
 | |
| 	dashOffset     float64
 | |
| }
 | |
| 
 | |
| // LineTo implements the pathbuilder interface.
 | |
| func (dasher *DashVertexConverter) LineTo(x, y float64) {
 | |
| 	dasher.lineTo(x, y)
 | |
| }
 | |
| 
 | |
| // MoveTo implements the pathbuilder interface.
 | |
| func (dasher *DashVertexConverter) MoveTo(x, y float64) {
 | |
| 	dasher.next.MoveTo(x, y)
 | |
| 	dasher.x, dasher.y = x, y
 | |
| 	dasher.distance = dasher.dashOffset
 | |
| 	dasher.currentDash = 0
 | |
| }
 | |
| 
 | |
| // LineJoin implements the pathbuilder interface.
 | |
| func (dasher *DashVertexConverter) LineJoin() {
 | |
| 	dasher.next.LineJoin()
 | |
| }
 | |
| 
 | |
| // Close implements the pathbuilder interface.
 | |
| func (dasher *DashVertexConverter) Close() {
 | |
| 	dasher.next.Close()
 | |
| }
 | |
| 
 | |
| // End implements the pathbuilder interface.
 | |
| func (dasher *DashVertexConverter) End() {
 | |
| 	dasher.next.End()
 | |
| }
 | |
| 
 | |
| func (dasher *DashVertexConverter) lineTo(x, y float64) {
 | |
| 	rest := dasher.dash[dasher.currentDash] - dasher.distance
 | |
| 	for rest < 0 {
 | |
| 		dasher.distance = dasher.distance - dasher.dash[dasher.currentDash]
 | |
| 		dasher.currentDash = (dasher.currentDash + 1) % len(dasher.dash)
 | |
| 		rest = dasher.dash[dasher.currentDash] - dasher.distance
 | |
| 	}
 | |
| 	d := distance(dasher.x, dasher.y, x, y)
 | |
| 	for d >= rest {
 | |
| 		k := rest / d
 | |
| 		lx := dasher.x + k*(x-dasher.x)
 | |
| 		ly := dasher.y + k*(y-dasher.y)
 | |
| 		if dasher.currentDash%2 == 0 {
 | |
| 			// line
 | |
| 			dasher.next.LineTo(lx, ly)
 | |
| 		} else {
 | |
| 			// gap
 | |
| 			dasher.next.End()
 | |
| 			dasher.next.MoveTo(lx, ly)
 | |
| 		}
 | |
| 		d = d - rest
 | |
| 		dasher.x, dasher.y = lx, ly
 | |
| 		dasher.currentDash = (dasher.currentDash + 1) % len(dasher.dash)
 | |
| 		rest = dasher.dash[dasher.currentDash]
 | |
| 	}
 | |
| 	dasher.distance = d
 | |
| 	if dasher.currentDash%2 == 0 {
 | |
| 		// line
 | |
| 		dasher.next.LineTo(x, y)
 | |
| 	} else {
 | |
| 		// gap
 | |
| 		dasher.next.End()
 | |
| 		dasher.next.MoveTo(x, y)
 | |
| 	}
 | |
| 	if dasher.distance >= dasher.dash[dasher.currentDash] {
 | |
| 		dasher.distance = dasher.distance - dasher.dash[dasher.currentDash]
 | |
| 		dasher.currentDash = (dasher.currentDash + 1) % len(dasher.dash)
 | |
| 	}
 | |
| 	dasher.x, dasher.y = x, y
 | |
| }
 |