summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/code.google.com/p/draw2d/draw2d/dasher.go
blob: 521029992292ffef4b926d58d28e2797eb9119da (plain)
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
// 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
}