diff --git a/examples/edge/main.go b/examples/edge/main.go deleted file mode 100644 index ac5ffd8a6..000000000 --- a/examples/edge/main.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2017 The Ebiten Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build example - -package main - -import ( - "fmt" - "image/color" - "log" - "math" - - "github.com/hajimehoshi/ebiten" - "github.com/hajimehoshi/ebiten/ebitenutil" -) - -const ( - screenWidth = 320 - screenHeight = 240 -) - -var ( - colorImage *ebiten.Image - colorImageWidth = 64 - colorImageHeight = 64 - angle = 0 -) - -type parts struct { - image *ebiten.Image -} - -func (p *parts) Len() int { - return 1 -} - -func (p *parts) Src(index int) (int, int, int, int) { - w, h := p.image.Size() - return 0, 0, w, h / 2 -} - -func (p *parts) Dst(index int) (int, int, int, int) { - w, h := p.image.Size() - return 0, 0, w, h / 2 -} - -func update(screen *ebiten.Image) error { - if ebiten.IsKeyPressed(ebiten.KeyLeft) { - angle += 359 - } - if ebiten.IsKeyPressed(ebiten.KeyRight) { - angle++ - } - angle %= 360 - if err := screen.Fill(color.White); err != nil { - return err - } - op := &ebiten.DrawImageOptions{} - op.ImageParts = &parts{colorImage} - op.GeoM.Translate(-float64(colorImageWidth)/2, -float64(colorImageHeight)/2) - op.GeoM.Rotate(float64(angle) * math.Pi / 180) - op.GeoM.Scale(4, 4) - op.GeoM.Translate(screenWidth/2, screenHeight/2) - if err := screen.DrawImage(colorImage, op); err != nil { - return err - } - if err := ebitenutil.DebugPrint(screen, fmt.Sprintf("Angle: %d [deg]", angle)); err != nil { - return err - } - return nil -} - -func main() { - var err error - colorImage, err = ebiten.NewImage(colorImageWidth, colorImageHeight, ebiten.FilterNearest) - if err != nil { - log.Fatal(err) - } - pixels := make([]uint8, 4*colorImageWidth*colorImageHeight) - for j := 0; j < colorImageHeight; j++ { - for i := 0; i < colorImageWidth; i++ { - idx := 4 * (i + j*colorImageWidth) - switch { - case j < colorImageHeight/2: - pixels[idx] = 0xff - pixels[idx+1] = 0 - pixels[idx+2] = 0 - pixels[idx+3] = 0xff - default: - pixels[idx] = 0 - pixels[idx+1] = 0xff - pixels[idx+2] = 0 - pixels[idx+3] = 0xff - } - } - } - if err := colorImage.ReplacePixels(pixels); err != nil { - log.Fatal(err) - } - if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Edge (Ebiten Demo)"); err != nil { - log.Fatal(err) - } -} diff --git a/image_test.go b/image_test.go index e6e700ba1..6c95e5c5d 100644 --- a/image_test.go +++ b/image_test.go @@ -563,3 +563,87 @@ func TestImageSize(t *testing.T) { } } } + +type halfImagePart struct { + image *Image +} + +func (p *halfImagePart) Len() int { + return 1 +} + +func (p *halfImagePart) Src(index int) (int, int, int, int) { + w, h := p.image.Size() + return 0, 0, w, h / 2 +} + +func (p *halfImagePart) Dst(index int) (int, int, int, int) { + w, h := p.image.Size() + return 0, 0, w, h / 2 +} + +// Issue 317 +func TestImageEdge(t *testing.T) { + const ( + img0Width = 16 + img0Height = 16 + img1Width = 32 + img1Height = 32 + ) + img0, err := NewImage(img0Width, img0Height, FilterNearest) + if err != nil { + t.Fatal(err) + } + pixels := make([]uint8, 4*img0Width*img0Height) + for j := 0; j < img0Height; j++ { + for i := 0; i < img0Width; i++ { + idx := 4 * (i + j*img0Width) + switch { + case j < img0Height/2: + pixels[idx] = 0xff + pixels[idx+1] = 0 + pixels[idx+2] = 0 + pixels[idx+3] = 0xff + default: + pixels[idx] = 0 + pixels[idx+1] = 0xff + pixels[idx+2] = 0 + pixels[idx+3] = 0xff + } + } + } + if err := img0.ReplacePixels(pixels); err != nil { + t.Fatal(err) + } + img1, err := NewImage(img1Width, img1Height, FilterNearest) + if err != nil { + t.Fatal(err) + } + red := color.RGBA{0xff, 0, 0, 0xff} + transparent := color.RGBA{0, 0, 0, 0} + for a := 0; a < 360; a++ { + if err := img1.Clear(); err != nil { + t.Fatal(err) + } + op := &DrawImageOptions{} + op.ImageParts = &halfImagePart{img0} + op.GeoM.Translate(-float64(img0Width)/2, -float64(img0Height)/2) + op.GeoM.Rotate(float64(a) * math.Pi / 180) + op.GeoM.Translate(img1Width/2, img1Height/2) + if err := img1.DrawImage(img0, op); err != nil { + t.Fatal(err) + } + for j := 0; j < img1Height; j++ { + for i := 0; i < img1Width; i++ { + c := img1.At(i, j) + if c == red { + continue + } + if c == transparent { + continue + } + t.Errorf("img1.At(%d, %d) want: red or transparent, got: %v", i, j, c) + } + } + } +}