diff --git a/vector/atlas.go b/vector/atlas.go index 233bab3fd..abb23dc25 100644 --- a/vector/atlas.go +++ b/vector/atlas.go @@ -90,8 +90,13 @@ func (a *atlas) setPaths(dstBounds image.Rectangle, paths []*Path, bounds []imag a.pathIndexToAtlasRegionIndex[r.pathIndex] = i } + w, h := dstBounds.Dx(), dstBounds.Dy() + // For antialiasing, doubled regions in the X direction are used. + if antialias { + w *= 2 + } // Use 2^n - 1, as a region in internal/atlas has 1px padding. - maxImageSize := max(4093, dstBounds.Dx(), dstBounds.Dy()) + maxImageSize := max(4093, w, h) // Pack the regions into an atlas with a very simple algorithm: // Order the regions by height and then place them in a row. diff --git a/vector/util_test.go b/vector/util_test.go index 23a4ed7b5..dfb899884 100644 --- a/vector/util_test.go +++ b/vector/util_test.go @@ -126,3 +126,23 @@ func TestFillRects(t *testing.T) { t.Errorf("got: %v, want: %v", got, want) } } + +// Issue #3377 +func TestFillRectOnBigImage(t *testing.T) { + dst := ebiten.NewImage(3000, 3000) + defer dst.Deallocate() + + vector.FillRect(dst, 0, 0, 3000, 3000, color.White, true) + if got, want := dst.At(0, 0), (color.RGBA{0xff, 0xff, 0xff, 0xff}); got != want { + t.Errorf("got: %v, want: %v", got, want) + } + if got, want := dst.At(2980, 0), (color.RGBA{0xff, 0xff, 0xff, 0xff}); got != want { + t.Errorf("got: %v, want: %v", got, want) + } + if got, want := dst.At(0, 2980), (color.RGBA{0xff, 0xff, 0xff, 0xff}); got != want { + t.Errorf("got: %v, want: %v", got, want) + } + if got, want := dst.At(2980, 2980), (color.RGBA{0xff, 0xff, 0xff, 0xff}); got != want { + t.Errorf("got: %v, want: %v", got, want) + } +}