draw2d/draw2d/dasher.go

90 lines
2.4 KiB
Go

// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 13/12/2010 by Laurent Le Goff
package draw2d
type DashVertexConverter struct {
command VertexCommand
next VertexConverter
x, y, distance float64
dash []float64
currentDash int
dashOffset float64
}
func NewDashConverter(dash []float64, dashOffset float64, converter VertexConverter) *DashVertexConverter {
var dasher DashVertexConverter
dasher.dash = dash
dasher.currentDash = 0
dasher.dashOffset = dashOffset
dasher.next = converter
return &dasher
}
func (dasher *DashVertexConverter) NextCommand(cmd VertexCommand) {
dasher.command = cmd
if dasher.command == VertexStopCommand {
dasher.next.NextCommand(VertexStopCommand)
}
}
func (dasher *DashVertexConverter) Vertex(x, y float64) {
switch dasher.command {
case VertexStartCommand:
dasher.start(x, y)
default:
dasher.lineTo(x, y)
}
dasher.command = VertexNoCommand
}
func (dasher *DashVertexConverter) start(x, y float64) {
dasher.next.NextCommand(VertexStartCommand)
dasher.next.Vertex(x, y)
dasher.x, dasher.y = x, y
dasher.distance = dasher.dashOffset
dasher.currentDash = 0
}
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.Vertex(lx, ly)
} else {
// gap
dasher.next.NextCommand(VertexStopCommand)
dasher.next.NextCommand(VertexStartCommand)
dasher.next.Vertex(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.Vertex(x, y)
} else {
// gap
dasher.next.NextCommand(VertexStopCommand)
dasher.next.NextCommand(VertexStartCommand)
dasher.next.Vertex(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
}