Authentication-Results: mail-b.sr.ht; dkim=none Received: from git.sr.ht (unknown [173.195.146.142]) by mail-b.sr.ht (Postfix) with ESMTPSA id D5FDEFF1C1 for <~eliasnaur/gio-patches@lists.sr.ht>; Mon, 11 Jan 2021 09:18:08 +0000 (UTC) From: ~egonelbre Date: Mon, 11 Jan 2021 11:04:02 +0200 Subject: [PATCH gio] widget: use correct color in Icon Message-ID: <161035668868.18065.4407285431413627246-0@git.sr.ht> X-Mailer: git.sr.ht Reply-to: ~egonelbre To: ~eliasnaur/gio-patches@lists.sr.ht Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 From: Egon Elbre iconvg seems to expect a linear premultiplied color. Signed-off-by: Egon Elbre --- internal/f32color/rgba.go | 34 ++++++++++++++++++++++++++++++++ internal/f32color/rgba_test.go | 36 ++++++++++++++++++++++++++++++++++ widget/icon.go | 2 +- 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 internal/f32color/rgba_test.go diff --git a/internal/f32color/rgba.go b/internal/f32color/rgba.go index d1b7564..4fc2742 100644 --- a/internal/f32color/rgba.go +++ b/internal/f32color/rgba.go @@ -77,6 +77,40 @@ func NRGBAToRGBA(col color.NRGBA) color.RGBA { } } =20 +// NRGBAToLinearRGBA converts from non-premultiplied sRGB color to premultip= lied linear RGBA color. +// +// Each component in the result is `c * alpha`, where `c` is the linear colo= r. +func NRGBAToLinearRGBA(col color.NRGBA) color.RGBA { + if col.A =3D=3D 0xFF { + return color.RGBA(col) + } + c :=3D LinearFromSRGB(col) + return color.RGBA{ + R: uint8(c.R*255 + .5), + G: uint8(c.G*255 + .5), + B: uint8(c.B*255 + .5), + A: col.A, + } +} + +// NRGBAToRGBA_PostAlpha converts from non-premultiplied sRGB color to premu= ltiplied sRGB color. +// +// Each component in the result is `sRGBToLinear(c) * alpha`, where `c` +// is the linear color. +func NRGBAToRGBA_PostAlpha(col color.NRGBA) color.RGBA { + if col.A =3D=3D 0xFF { + return color.RGBA(col) + } else if col.A =3D=3D 0x00 { + return color.RGBA{} + } + return color.RGBA{ + R: uint8(uint32(col.R) * uint32(col.A) / 0xFF), + G: uint8(uint32(col.G) * uint32(col.A) / 0xFF), + B: uint8(uint32(col.B) * uint32(col.A) / 0xFF), + A: col.A, + } +} + // RGBAToNRGBA converts from premultiplied sRGB color to non-premultiplied s= RGB color. func RGBAToNRGBA(col color.RGBA) color.NRGBA { if col.A =3D=3D 0xFF { diff --git a/internal/f32color/rgba_test.go b/internal/f32color/rgba_test.go new file mode 100644 index 0000000..eba1262 --- /dev/null +++ b/internal/f32color/rgba_test.go @@ -0,0 +1,36 @@ +package f32color + +import ( + "image/color" + "testing" +) + +func TestNRGBAToRGBA_PostAlpha_Boundary(t *testing.T) { + for col :=3D 0; col <=3D 0xFF; col++ { + for alpha :=3D 0; alpha <=3D 0xFF; alpha++ { + in :=3D color.NRGBA{R: uint8(col), A: uint8(alpha)} + premul :=3D NRGBAToRGBA_PostAlpha(in) + if premul.A !=3D uint8(alpha) { + t.Errorf("%v: got %v expected %v", in, premul.A, alpha) + } + if premul.R > premul.A { + t.Errorf("%v: R=3D%v > A=3D%v", in, premul.R, premul.A) + } + } + } +} + +func TestNRGBAToLinearRGBA_Boundary(t *testing.T) { + for col :=3D 0; col <=3D 0xFF; col++ { + for alpha :=3D 0; alpha <=3D 0xFF; alpha++ { + in :=3D color.NRGBA{R: uint8(col), A: uint8(alpha)} + premul :=3D NRGBAToLinearRGBA(in) + if premul.A !=3D uint8(alpha) { + t.Errorf("%v: got %v expected %v", in, premul.A, alpha) + } + if premul.R > premul.A { + t.Errorf("%v: R=3D%v > A=3D%v", in, premul.R, premul.A) + } + } + } +} diff --git a/widget/icon.go b/widget/icon.go index f6f88d3..4e6350d 100644 --- a/widget/icon.go +++ b/widget/icon.go @@ -51,7 +51,7 @@ func (ic *Icon) image(sz int) paint.ImageOp { img :=3D image.NewRGBA(image.Rectangle{Max: image.Point{X: sz, Y: int(float= 32(sz) * dy / dx)}}) var ico iconvg.Rasterizer ico.SetDstImage(img, img.Bounds(), draw.Src) - m.Palette[0] =3D f32color.NRGBAToRGBA(ic.Color) + m.Palette[0] =3D f32color.NRGBAToLinearRGBA(ic.Color) iconvg.Decode(&ico, ic.src, &iconvg.DecodeOptions{ Palette: &m.Palette, }) --=20 2.26.2