diff --git a/image.go b/image.go index 7eb111e72..d9a83628d 100644 --- a/image.go +++ b/image.go @@ -325,6 +325,17 @@ func (i *Image) drawImage(img *Image, options *DrawImageOptions) { if level < 0 { panic(fmt.Sprintf("ebiten: level must be >= 0 but %d", level)) } + + // If the image can be scaled into 0 size, adjust the level. (#839) + w, h := bounds.Dx(), bounds.Dy() + for level >= 0 { + s := 1 << uint(level) + if w/s == 0 || h/s == 0 { + level-- + continue + } + break + } } if level > 6 { level = 6 diff --git a/image_test.go b/image_test.go index 700cc3589..745c3dc2f 100644 --- a/image_test.go +++ b/image_test.go @@ -1652,3 +1652,21 @@ func TestImageSubImageSubImage(t *testing.T) { } } } + +// Issue 839 +func TestImageTooSmallMipmap(t *testing.T) { + const w, h = 16, 16 + src, _ := NewImage(w, h, FilterDefault) + dst, _ := NewImage(w, h, FilterDefault) + + src.Fill(color.White) + op := &DrawImageOptions{} + op.GeoM.Scale(1, 0.24) + op.Filter = FilterLinear + dst.DrawImage(src.SubImage(image.Rect(5, 0, 6, 16)).(*Image), op) + got := dst.At(0, 0).(color.RGBA) + want := color.RGBA{0xff, 0xff, 0xff, 0xff} + if got != want { + t.Errorf("got: %v, want: %v", got, want) + } +}