line dash bugfix, implemented getLineDash, added a test
This commit is contained in:
parent
a68d11e11a
commit
b6c22b9374
5 changed files with 53 additions and 10 deletions
|
@ -107,7 +107,9 @@ These features *should* work just like their HTML5 counterparts, but there are l
|
||||||
- lineWidth
|
- lineWidth
|
||||||
- lineEnd (square, butt, round)
|
- lineEnd (square, butt, round)
|
||||||
- lineJoin (bevel, miter, round)
|
- lineJoin (bevel, miter, round)
|
||||||
|
- miterLimit
|
||||||
- lineDash
|
- lineDash
|
||||||
|
- getLineDash
|
||||||
- global alpha
|
- global alpha
|
||||||
- drawImage
|
- drawImage
|
||||||
- getImageData
|
- getImageData
|
||||||
|
@ -115,7 +117,6 @@ These features *should* work just like their HTML5 counterparts, but there are l
|
||||||
- clearRect
|
- clearRect
|
||||||
- shadowColor
|
- shadowColor
|
||||||
- shadowOffset(X/Y)
|
- shadowOffset(X/Y)
|
||||||
- miterLimit
|
|
||||||
- shadowBlur
|
- shadowBlur
|
||||||
|
|
||||||
# Missing features
|
# Missing features
|
||||||
|
@ -123,7 +124,6 @@ These features *should* work just like their HTML5 counterparts, but there are l
|
||||||
- globalCompositeOperation
|
- globalCompositeOperation
|
||||||
- lineDashOffset
|
- lineDashOffset
|
||||||
- textBaseline
|
- textBaseline
|
||||||
- getLineDash
|
|
||||||
- isPointInPath
|
- isPointInPath
|
||||||
- isPointInStroke
|
- isPointInStroke
|
||||||
- strokeText
|
- strokeText
|
||||||
|
|
|
@ -682,6 +682,13 @@ func (cv *Canvas) SetLineDash(dash []float64) {
|
||||||
cv.state.lineDashOffset = 0
|
cv.state.lineDashOffset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLineDash gets the line dash style
|
||||||
|
func (cv *Canvas) GetLineDash() []float64 {
|
||||||
|
result := make([]float64, len(cv.state.lineDash))
|
||||||
|
copy(result, cv.state.lineDash)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// SetMiterLimit sets the limit for how far a miter line join can be extend.
|
// SetMiterLimit sets the limit for how far a miter line join can be extend.
|
||||||
// The fallback is a bevel join
|
// The fallback is a bevel join
|
||||||
func (cv *Canvas) SetMiterLimit(limit float64) {
|
func (cv *Canvas) SetMiterLimit(limit float64) {
|
||||||
|
|
|
@ -206,3 +206,31 @@ func TestMiterLimit(t *testing.T) {
|
||||||
cv.Stroke()
|
cv.Stroke()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLineDash(t *testing.T) {
|
||||||
|
run(t, func(cv *canvas.Canvas) {
|
||||||
|
cv.SetStrokeStyle("#0F0")
|
||||||
|
cv.SetLineWidth(2.5)
|
||||||
|
cv.SetLineDash([]float64{4, 6, 8})
|
||||||
|
cv.BeginPath()
|
||||||
|
cv.MoveTo(20, 20)
|
||||||
|
cv.LineTo(80, 20)
|
||||||
|
cv.LineTo(80, 80)
|
||||||
|
cv.LineTo(50, 80)
|
||||||
|
cv.LineTo(50, 50)
|
||||||
|
cv.LineTo(20, 50)
|
||||||
|
cv.ClosePath()
|
||||||
|
cv.MoveTo(30, 30)
|
||||||
|
cv.LineTo(70, 30)
|
||||||
|
cv.LineTo(70, 70)
|
||||||
|
cv.LineTo(60, 70)
|
||||||
|
cv.LineTo(60, 40)
|
||||||
|
cv.LineTo(30, 40)
|
||||||
|
cv.ClosePath()
|
||||||
|
cv.Stroke()
|
||||||
|
ld := cv.GetLineDash()
|
||||||
|
if ld[0] != 4 || ld[1] != 6 || ld[2] != 8 || ld[3] != 4 || ld[4] != 6 || ld[5] != 8 {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
24
paths.go
24
paths.go
|
@ -19,6 +19,7 @@ const (
|
||||||
pathAttach
|
pathAttach
|
||||||
pathIsRect
|
pathIsRect
|
||||||
pathIsConvex
|
pathIsConvex
|
||||||
|
pathExplicitMove
|
||||||
)
|
)
|
||||||
|
|
||||||
// BeginPath clears the current path and starts a new one
|
// BeginPath clears the current path and starts a new one
|
||||||
|
@ -43,8 +44,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, flags: pathMove})
|
cv.linePath = append(cv.linePath, pathPoint{pos: vec{x, y}, tf: tf, flags: pathMove | pathExplicitMove})
|
||||||
cv.polyPath = append(cv.polyPath, pathPoint{pos: vec{x, y}, tf: tf, flags: pathMove})
|
cv.polyPath = append(cv.polyPath, pathPoint{pos: vec{x, y}, tf: tf, flags: pathMove | pathExplicitMove})
|
||||||
}
|
}
|
||||||
|
|
||||||
// LineTo adds a line to the end of the path
|
// LineTo adds a line to the end of the path
|
||||||
|
@ -273,17 +274,24 @@ func (cv *Canvas) ClosePath() {
|
||||||
if isSamePoint(cv.linePath[len(cv.linePath)-1].tf, cv.linePath[0].tf, 0.1) {
|
if isSamePoint(cv.linePath[len(cv.linePath)-1].tf, cv.linePath[0].tf, 0.1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
closeIdx := 0
|
lineCloseIdx := 0
|
||||||
for i := len(cv.linePath) - 1; i >= 0; i-- {
|
for i := len(cv.linePath) - 1; i >= 0; i-- {
|
||||||
if cv.linePath[i].flags&pathMove != 0 {
|
if cv.linePath[i].flags&pathExplicitMove != 0 {
|
||||||
closeIdx = i
|
lineCloseIdx = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cv.LineTo(cv.linePath[closeIdx].pos[0], cv.linePath[closeIdx].pos[1])
|
polyCloseIdx := 0
|
||||||
cv.linePath[len(cv.linePath)-1].next = cv.linePath[closeIdx].next
|
for i := len(cv.polyPath) - 1; i >= 0; i-- {
|
||||||
|
if cv.polyPath[i].flags&pathExplicitMove != 0 {
|
||||||
|
polyCloseIdx = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cv.LineTo(cv.linePath[lineCloseIdx].pos[0], cv.linePath[lineCloseIdx].pos[1])
|
||||||
|
cv.linePath[len(cv.linePath)-1].next = cv.linePath[lineCloseIdx].next
|
||||||
cv.linePath[len(cv.linePath)-1].flags |= pathAttach
|
cv.linePath[len(cv.linePath)-1].flags |= pathAttach
|
||||||
cv.polyPath[len(cv.polyPath)-1].next = cv.polyPath[closeIdx].next
|
cv.polyPath[len(cv.polyPath)-1].next = cv.polyPath[polyCloseIdx].next
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stroke uses the current StrokeStyle to draw the path
|
// Stroke uses the current StrokeStyle to draw the path
|
||||||
|
|
BIN
testimages/LineDash.png
Executable file
BIN
testimages/LineDash.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 597 B |
Loading…
Reference in a new issue