From bea63946fc4484c1ef08d7381cc9dbb673c93797 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Tue, 27 Feb 2018 12:16:16 +0900 Subject: [PATCH] affine: Bug fix: ColorM.Apply was wrong when alpha is 0 --- colorm_test.go | 23 ++++++++++++++++------- internal/affine/colorm.go | 14 +++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/colorm_test.go b/colorm_test.go index 1937e5e65..40e995816 100644 --- a/colorm_test.go +++ b/colorm_test.go @@ -170,11 +170,11 @@ func TestColorMConcatSelf(t *testing.T) { } } -func absU32(x uint32) uint32 { - if x < 0 { - return -x +func absDiffU32(x, y uint32) uint32 { + if x < y { + return y - x } - return x + return x - y } func TestColorMApply(t *testing.T) { @@ -184,6 +184,9 @@ func TestColorMApply(t *testing.T) { shiny := ColorM{} shiny.Translate(1, 1, 1, 0) + shift := ColorM{} + shift.Translate(0.5, 0.5, 0.5, 0.5) + cases := []struct { ColorM ColorM In color.Color @@ -214,14 +217,20 @@ func TestColorMApply(t *testing.T) { Out: color.RGBA{0xb0, 0xb0, 0xb0, 0xb0}, Delta: 1, }, + { + ColorM: shift, + In: color.RGBA{0x00, 0x00, 0x00, 0x00}, + Out: color.RGBA{0x40, 0x40, 0x40, 0x80}, + Delta: 0x101, + }, } for _, c := range cases { out := c.ColorM.Apply(c.In) r0, g0, b0, a0 := out.RGBA() r1, g1, b1, a1 := c.Out.RGBA() - if absU32(r0-r1) > c.Delta || absU32(g0-g1) > c.Delta || - absU32(b0-b1) > c.Delta || absU32(a0-a1) > c.Delta { - t.Errorf("%v.Apply(%v) = %v, want %v", c.ColorM, c.In, out, c.Out) + if absDiffU32(r0, r1) > c.Delta || absDiffU32(g0, g1) > c.Delta || + absDiffU32(b0, b1) > c.Delta || absDiffU32(a0, a1) > c.Delta { + t.Errorf("%v.Apply(%v) = {%d, %d, %d, %d}, want {%d, %d, %d, %d}", c.ColorM, c.In, r0, g0, b0, a0, r1, g1, b1, a1) } } } diff --git a/internal/affine/colorm.go b/internal/affine/colorm.go index 079ccbb2f..9661c993f 100644 --- a/internal/affine/colorm.go +++ b/internal/affine/colorm.go @@ -69,14 +69,14 @@ func (c *ColorM) Apply(clr color.Color) color.Color { return clr } r, g, b, a := clr.RGBA() - if a == 0 { - return color.Transparent - } + rf, gf, bf, af := float32(0.0), float32(0.0), float32(0.0), float32(0.0) // Unmultiply alpha - rf := float32(r) / float32(a) - gf := float32(g) / float32(a) - bf := float32(b) / float32(a) - af := float32(a) / 0xffff + if a > 0 { + rf = float32(r) / float32(a) + gf = float32(g) / float32(a) + bf = float32(b) / float32(a) + af = float32(a) / 0xffff + } eb := c.body et := c.translate rf2 := eb[0]*rf + eb[4]*gf + eb[8]*bf + eb[12]*af + et[0]