widget: use correct color in Icon

iconvg seems to expect a linear premultiplied color.

Fixes gio#132

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
This commit is contained in:
Egon Elbre
2021-01-11 11:04:02 +02:00
committed by Elias Naur
parent 0e3e446393
commit f114acdb02
4 changed files with 103 additions and 1 deletions
+34
View File
@@ -77,6 +77,40 @@ func NRGBAToRGBA(col color.NRGBA) color.RGBA {
}
}
// NRGBAToLinearRGBA converts from non-premultiplied sRGB color to premultiplied linear RGBA color.
//
// Each component in the result is `c * alpha`, where `c` is the linear color.
func NRGBAToLinearRGBA(col color.NRGBA) color.RGBA {
if col.A == 0xFF {
return color.RGBA(col)
}
c := 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 premultiplied 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 == 0xFF {
return color.RGBA(col)
} else if col.A == 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 sRGB color.
func RGBAToNRGBA(col color.RGBA) color.NRGBA {
if col.A == 0xFF {
+38
View File
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: Unlicense OR MIT
package f32color
import (
"image/color"
"testing"
)
func TestNRGBAToRGBA_PostAlpha_Boundary(t *testing.T) {
for col := 0; col <= 0xFF; col++ {
for alpha := 0; alpha <= 0xFF; alpha++ {
in := color.NRGBA{R: uint8(col), A: uint8(alpha)}
premul := NRGBAToRGBA_PostAlpha(in)
if premul.A != uint8(alpha) {
t.Errorf("%v: got %v expected %v", in, premul.A, alpha)
}
if premul.R > premul.A {
t.Errorf("%v: R=%v > A=%v", in, premul.R, premul.A)
}
}
}
}
func TestNRGBAToLinearRGBA_Boundary(t *testing.T) {
for col := 0; col <= 0xFF; col++ {
for alpha := 0; alpha <= 0xFF; alpha++ {
in := color.NRGBA{R: uint8(col), A: uint8(alpha)}
premul := NRGBAToLinearRGBA(in)
if premul.A != uint8(alpha) {
t.Errorf("%v: got %v expected %v", in, premul.A, alpha)
}
if premul.R > premul.A {
t.Errorf("%v: R=%v > A=%v", in, premul.R, premul.A)
}
}
}
}