From b6c22b93748e1389a9ca9cb90ec365d55670c4d0 Mon Sep 17 00:00:00 2001 From: Thomas Friedel Date: Mon, 30 Jul 2018 14:55:45 +0200 Subject: [PATCH] line dash bugfix, implemented getLineDash, added a test --- README.md | 4 ++-- canvas.go | 7 +++++++ canvas_test.go | 28 ++++++++++++++++++++++++++++ paths.go | 24 ++++++++++++++++-------- testimages/LineDash.png | Bin 0 -> 597 bytes 5 files changed, 53 insertions(+), 10 deletions(-) create mode 100755 testimages/LineDash.png diff --git a/README.md b/README.md index ba53863..bf43298 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,9 @@ These features *should* work just like their HTML5 counterparts, but there are l - lineWidth - lineEnd (square, butt, round) - lineJoin (bevel, miter, round) +- miterLimit - lineDash +- getLineDash - global alpha - drawImage - getImageData @@ -115,7 +117,6 @@ These features *should* work just like their HTML5 counterparts, but there are l - clearRect - shadowColor - shadowOffset(X/Y) -- miterLimit - shadowBlur # Missing features @@ -123,7 +124,6 @@ These features *should* work just like their HTML5 counterparts, but there are l - globalCompositeOperation - lineDashOffset - textBaseline -- getLineDash - isPointInPath - isPointInStroke - strokeText diff --git a/canvas.go b/canvas.go index 7885450..42a2792 100644 --- a/canvas.go +++ b/canvas.go @@ -682,6 +682,13 @@ func (cv *Canvas) SetLineDash(dash []float64) { 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. // The fallback is a bevel join func (cv *Canvas) SetMiterLimit(limit float64) { diff --git a/canvas_test.go b/canvas_test.go index 9dee506..a7680c9 100644 --- a/canvas_test.go +++ b/canvas_test.go @@ -206,3 +206,31 @@ func TestMiterLimit(t *testing.T) { 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() + } + }) +} diff --git a/paths.go b/paths.go index ed6dbbf..f7eaf7f 100644 --- a/paths.go +++ b/paths.go @@ -19,6 +19,7 @@ const ( pathAttach pathIsRect pathIsConvex + pathExplicitMove ) // 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) { return } - 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, 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 | pathExplicitMove}) } // 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) { return } - closeIdx := 0 + lineCloseIdx := 0 for i := len(cv.linePath) - 1; i >= 0; i-- { - if cv.linePath[i].flags&pathMove != 0 { - closeIdx = i + if cv.linePath[i].flags&pathExplicitMove != 0 { + lineCloseIdx = i break } } - cv.LineTo(cv.linePath[closeIdx].pos[0], cv.linePath[closeIdx].pos[1]) - cv.linePath[len(cv.linePath)-1].next = cv.linePath[closeIdx].next + polyCloseIdx := 0 + 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.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 diff --git a/testimages/LineDash.png b/testimages/LineDash.png new file mode 100755 index 0000000000000000000000000000000000000000..e9c5f2a17157b19c1f83b6931c3c04bf620d18c3 GIT binary patch literal 597 zcmeAS@N?(olHy`uVBq!ia0vp^DImz!OEUl(Q zoc&%o^Sj)G)GNm?OnNW=?GCfaVF|7sy$_vK@9S@QUi2F%C2`!~N|a|4yZj3s4z9VX z4`gJ+gtw_Kem-^T-vckd^%ozI$#*<^f0{}BA!VX6J$YONJ_&4SG=k4|n%|MK(Qi{GbMAN_6GzWKN5?~1viGbUPV|1qtu zXSzQh=vh#BKVY7#Dqw9T@qYDB=a+Kx&fm9hGJF;Lsr1VGLsIWIKX<+++hN=G_I^t3 quNREz268$vs2Dp`A+IU4uhwwpUXO@geCwFrw~>E literal 0 HcmV?d00001