use bit flags instead of booleans for more compact storage
This commit is contained in:
parent
f0d9b83afb
commit
d5a4c0b4bb
2 changed files with 36 additions and 28 deletions
10
canvas.go
10
canvas.go
|
@ -17,19 +17,13 @@ type Canvas struct {
|
||||||
|
|
||||||
polyPath []pathPoint
|
polyPath []pathPoint
|
||||||
linePath []pathPoint
|
linePath []pathPoint
|
||||||
|
convex bool
|
||||||
|
rect bool
|
||||||
|
|
||||||
state drawState
|
state drawState
|
||||||
stateStack []drawState
|
stateStack []drawState
|
||||||
}
|
}
|
||||||
|
|
||||||
type pathPoint struct {
|
|
||||||
pos vec
|
|
||||||
tf vec
|
|
||||||
move bool
|
|
||||||
next vec
|
|
||||||
attach bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type drawState struct {
|
type drawState struct {
|
||||||
transform mat
|
transform mat
|
||||||
fill drawStyle
|
fill drawStyle
|
||||||
|
|
54
paths.go
54
paths.go
|
@ -5,6 +5,20 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type pathPoint struct {
|
||||||
|
pos vec
|
||||||
|
tf vec
|
||||||
|
next vec
|
||||||
|
flags pathPointFlag
|
||||||
|
}
|
||||||
|
|
||||||
|
type pathPointFlag uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
pathMove pathPointFlag = 1 << iota
|
||||||
|
pathAttach
|
||||||
|
)
|
||||||
|
|
||||||
func (cv *Canvas) BeginPath() {
|
func (cv *Canvas) BeginPath() {
|
||||||
if cv.linePath == nil {
|
if cv.linePath == nil {
|
||||||
cv.linePath = make([]pathPoint, 0, 100)
|
cv.linePath = make([]pathPoint, 0, 100)
|
||||||
|
@ -25,8 +39,8 @@ func (cv *Canvas) MoveTo(x, y float64) {
|
||||||
if len(cv.linePath) > 0 && isSamePoint(cv.linePath[len(cv.linePath)-1].tf, tf, 0.1) {
|
if len(cv.linePath) > 0 && isSamePoint(cv.linePath[len(cv.linePath)-1].tf, tf, 0.1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cv.linePath = append(cv.linePath, pathPoint{pos: vec{x, y}, tf: tf, move: true})
|
cv.linePath = append(cv.linePath, pathPoint{pos: vec{x, y}, tf: tf, flags: pathMove})
|
||||||
cv.polyPath = append(cv.polyPath, pathPoint{pos: vec{x, y}, tf: tf, move: true})
|
cv.polyPath = append(cv.polyPath, pathPoint{pos: vec{x, y}, tf: tf, flags: pathMove})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cv *Canvas) LineTo(x, y float64) {
|
func (cv *Canvas) LineTo(x, y float64) {
|
||||||
|
@ -39,7 +53,7 @@ func (cv *Canvas) strokeLineTo(x, y float64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(cv.linePath) == 0 {
|
if len(cv.linePath) == 0 {
|
||||||
cv.linePath = append(cv.linePath, pathPoint{pos: vec{x, y}, tf: cv.tf(vec{x, y}), move: true})
|
cv.linePath = append(cv.linePath, pathPoint{pos: vec{x, y}, tf: cv.tf(vec{x, y}), flags: pathMove})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(cv.state.lineDash) > 0 {
|
if len(cv.state.lineDash) > 0 {
|
||||||
|
@ -66,10 +80,10 @@ func (cv *Canvas) strokeLineTo(x, y float64) {
|
||||||
|
|
||||||
if draw {
|
if draw {
|
||||||
cv.linePath[len(cv.linePath)-1].next = cv.tf(p)
|
cv.linePath[len(cv.linePath)-1].next = cv.tf(p)
|
||||||
cv.linePath[len(cv.linePath)-1].attach = true
|
cv.linePath[len(cv.linePath)-1].flags |= pathAttach
|
||||||
cv.linePath = append(cv.linePath, pathPoint{pos: p, tf: cv.tf(p), move: false})
|
cv.linePath = append(cv.linePath, pathPoint{pos: p, tf: cv.tf(p)})
|
||||||
} else {
|
} else {
|
||||||
cv.linePath = append(cv.linePath, pathPoint{pos: p, tf: cv.tf(p), move: true})
|
cv.linePath = append(cv.linePath, pathPoint{pos: p, tf: cv.tf(p), flags: pathMove})
|
||||||
}
|
}
|
||||||
|
|
||||||
lp = p
|
lp = p
|
||||||
|
@ -78,8 +92,8 @@ func (cv *Canvas) strokeLineTo(x, y float64) {
|
||||||
} else {
|
} else {
|
||||||
tf := cv.tf(vec{x, y})
|
tf := cv.tf(vec{x, y})
|
||||||
cv.linePath[len(cv.linePath)-1].next = tf
|
cv.linePath[len(cv.linePath)-1].next = tf
|
||||||
cv.linePath[len(cv.linePath)-1].attach = true
|
cv.linePath[len(cv.linePath)-1].flags |= pathAttach
|
||||||
cv.linePath = append(cv.linePath, pathPoint{pos: vec{x, y}, tf: tf, move: false})
|
cv.linePath = append(cv.linePath, pathPoint{pos: vec{x, y}, tf: tf})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,13 +102,13 @@ func (cv *Canvas) fillLineTo(x, y float64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(cv.polyPath) == 0 {
|
if len(cv.polyPath) == 0 {
|
||||||
cv.polyPath = append(cv.polyPath, pathPoint{pos: vec{x, y}, tf: cv.tf(vec{x, y}), move: true})
|
cv.polyPath = append(cv.polyPath, pathPoint{pos: vec{x, y}, tf: cv.tf(vec{x, y}), flags: pathMove})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tf := cv.tf(vec{x, y})
|
tf := cv.tf(vec{x, y})
|
||||||
cv.polyPath[len(cv.polyPath)-1].next = tf
|
cv.polyPath[len(cv.polyPath)-1].next = tf
|
||||||
cv.polyPath[len(cv.polyPath)-1].attach = true
|
cv.polyPath[len(cv.polyPath)-1].flags |= pathAttach
|
||||||
cv.polyPath = append(cv.polyPath, pathPoint{pos: vec{x, y}, tf: tf, move: false})
|
cv.polyPath = append(cv.polyPath, pathPoint{pos: vec{x, y}, tf: tf})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cv *Canvas) Arc(x, y, radius, startAngle, endAngle float64, anticlockwise bool) {
|
func (cv *Canvas) Arc(x, y, radius, startAngle, endAngle float64, anticlockwise bool) {
|
||||||
|
@ -233,7 +247,7 @@ func (cv *Canvas) ClosePath() {
|
||||||
}
|
}
|
||||||
closeIdx := 0
|
closeIdx := 0
|
||||||
for i := len(cv.linePath) - 1; i >= 0; i-- {
|
for i := len(cv.linePath) - 1; i >= 0; i-- {
|
||||||
if cv.linePath[i].move {
|
if cv.linePath[i].flags&pathMove != 0 {
|
||||||
closeIdx = i
|
closeIdx = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -261,7 +275,7 @@ func (cv *Canvas) stroke(path []pathPoint) {
|
||||||
start := true
|
start := true
|
||||||
var p0 vec
|
var p0 vec
|
||||||
for _, p := range path {
|
for _, p := range path {
|
||||||
if p.move {
|
if p.flags&pathMove != 0 {
|
||||||
p0 = p.tf
|
p0 = p.tf
|
||||||
start = true
|
start = true
|
||||||
continue
|
continue
|
||||||
|
@ -289,7 +303,7 @@ func (cv *Canvas) stroke(path []pathPoint) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !p.attach {
|
if p.flags&pathAttach == 0 {
|
||||||
switch cv.state.lineEnd {
|
switch cv.state.lineEnd {
|
||||||
case Butt:
|
case Butt:
|
||||||
// no need to do anything
|
// no need to do anything
|
||||||
|
@ -305,7 +319,7 @@ func (cv *Canvas) stroke(path []pathPoint) {
|
||||||
float32(lp0[0]), float32(lp0[1]), float32(lp1[0]), float32(lp1[1]), float32(lp3[0]), float32(lp3[1]),
|
float32(lp0[0]), float32(lp0[1]), float32(lp1[0]), float32(lp1[1]), float32(lp3[0]), float32(lp3[1]),
|
||||||
float32(lp0[0]), float32(lp0[1]), float32(lp3[0]), float32(lp3[1]), float32(lp2[0]), float32(lp2[1]))
|
float32(lp0[0]), float32(lp0[1]), float32(lp3[0]), float32(lp3[1]), float32(lp2[0]), float32(lp2[1]))
|
||||||
|
|
||||||
if p.attach {
|
if p.flags&pathAttach != 0 {
|
||||||
tris = cv.lineJoint(p, p0, p1, p.next, lp0, lp1, lp2, lp3, tris)
|
tris = cv.lineJoint(p, p0, p1, p.next, lp0, lp1, lp2, lp3, tris)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,7 +455,7 @@ func (cv *Canvas) Fill() {
|
||||||
cv.activate()
|
cv.activate()
|
||||||
start := 0
|
start := 0
|
||||||
for i, p := range cv.polyPath {
|
for i, p := range cv.polyPath {
|
||||||
if !p.move {
|
if p.flags&pathMove == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if i >= start+3 {
|
if i >= start+3 {
|
||||||
|
@ -552,10 +566,10 @@ func (cv *Canvas) StrokeRect(x, y, w, h float64) {
|
||||||
v3 := vec{x, y + h}
|
v3 := vec{x, y + h}
|
||||||
v0t, v1t, v2t, v3t := cv.tf(v0), cv.tf(v1), cv.tf(v2), cv.tf(v3)
|
v0t, v1t, v2t, v3t := cv.tf(v0), cv.tf(v1), cv.tf(v2), cv.tf(v3)
|
||||||
var path [5]pathPoint
|
var path [5]pathPoint
|
||||||
path[0] = pathPoint{pos: v0, tf: v0t, move: true, next: v1t, attach: true}
|
path[0] = pathPoint{pos: v0, tf: v0t, flags: pathMove | pathAttach, next: v1t}
|
||||||
path[1] = pathPoint{pos: v1, tf: v1t, next: v2t, attach: true}
|
path[1] = pathPoint{pos: v1, tf: v1t, next: v2t, flags: pathAttach}
|
||||||
path[2] = pathPoint{pos: v2, tf: v2t, next: v3t, attach: true}
|
path[2] = pathPoint{pos: v2, tf: v2t, next: v3t, flags: pathAttach}
|
||||||
path[3] = pathPoint{pos: v3, tf: v3t, next: v0t, attach: true}
|
path[3] = pathPoint{pos: v3, tf: v3t, next: v0t, flags: pathAttach}
|
||||||
path[4] = pathPoint{pos: v0, tf: v0t}
|
path[4] = pathPoint{pos: v0, tf: v0t}
|
||||||
cv.stroke(path[:])
|
cv.stroke(path[:])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue