line dash bugfix, implemented getLineDash, added a test

This commit is contained in:
Thomas Friedel 2018-07-30 14:55:45 +02:00
parent a68d11e11a
commit b6c22b9374
5 changed files with 53 additions and 10 deletions

View file

@ -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

View file

@ -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) {

View file

@ -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()
}
})
}

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B