git.lucas.co / go_mono
git clone https://git.lucas.co/go_mono.git

commitbeb967560992db4585e2134a9ef7c2d2cd77f0d4
parent8edbaf3f9e
authorNigel Tao <nigeltao@golang.org>
date2016-10-13 18:47
vector: fix overflow when rasterizing wide lines.

Change-Id: Iea92b74ca9533de2ef17534ee3acf4f40c3d03ef
Reviewed-on: https://go-review.googlesource.com/30899
Reviewed-by: David Crawshaw <crawshaw@golang.org>

 vector/raster_fixed.go |  6 +++---
 vector/vector_test.go  | 21 +++++++++++++++++++++
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/vector/raster_fixed.go b/vector/raster_fixed.go
index 21e10d6..7a8ea36 100644
--- a/vector/raster_fixed.go
+++ b/vector/raster_fixed.go
@@ -176,9 +176,9 @@ func (z *Rasterizer) fixedLineTo(b f32.Vec2) {
 					//
 					// Convert to int64 to avoid overflow. Without that,
 					// TestRasterizePolygon fails.
-					D := int64(twoOverS << ϕ)
-					D -= int64((fxOneAndAHalf - x0f) << (ϕ + 1))
-					D -= int64((x1i - x0i - 3) << (2*ϕ + 1))
+					D := int64(twoOverS) << ϕ
+					D -= int64((fxOneAndAHalf - x0f)) << (ϕ + 1)
+					D -= int64((x1i - x0i - 3)) << (2*ϕ + 1)
 					D -= int64(x1fSquared)
 					D *= int64(d)
 					D /= int64(twoOverS)
diff --git a/vector/vector_test.go b/vector/vector_test.go
index 8e9191f..6e8a1d1 100644
--- a/vector/vector_test.go
+++ b/vector/vector_test.go
@@ -125,6 +125,27 @@ func TestRasterizeAlmostAxisAligned(t *testing.T) {
 	}
 }
 
+func TestRasterizeWideAlmostHorizontalLines(t *testing.T) {
+	var z Rasterizer
+	for i := uint(3); i < 16; i++ {
+		x := float32(int(1 << i))
+
+		z.Reset(8, 8)
+		z.MoveTo(f32.Vec2{-x, 3})
+		z.LineTo(f32.Vec2{+x, 4})
+		z.LineTo(f32.Vec2{+x, 6})
+		z.LineTo(f32.Vec2{-x, 6})
+		z.ClosePath()
+
+		dst := image.NewAlpha(z.Bounds())
+		z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
+
+		if err := checkCornersCenter(dst); err != nil {
+			t.Errorf("i=%d: %v", i, err)
+		}
+	}
+}
+
 // checkCornersCenter checks that the corners of the image are all 0x00 and the
 // center is 0xff.
 func checkCornersCenter(m *image.Alpha) error {