diff --git a/internal/f32color/rgba.go b/internal/f32color/rgba.go index eecf0184..3c0140d4 100644 --- a/internal/f32color/rgba.go +++ b/internal/f32color/rgba.go @@ -146,22 +146,26 @@ func MulAlpha(c color.NRGBA, alpha uint8) color.NRGBA { func Disabled(c color.NRGBA) (d color.NRGBA) { const r = 80 // blend ratio lum := approxLuminance(c) - return color.NRGBA{ - R: byte((int(c.R)*r + int(lum)*(256-r)) / 256), - G: byte((int(c.G)*r + int(lum)*(256-r)) / 256), - B: byte((int(c.B)*r + int(lum)*(256-r)) / 256), - A: byte(int(c.A) * (128 + 32) / 256), - } + d = mix(c, color.NRGBA{A: c.A, R: lum, G: lum, B: lum}, r) + d = MulAlpha(d, 128+32) + return } -// Hovered blends color towards a brighter color. -func Hovered(c color.NRGBA) (d color.NRGBA) { +// Hovered blends color towards a brighter color. It is approximate +// because it operates in non-linear sRGB space. +func Hovered(c color.NRGBA) (h color.NRGBA) { const r = 0x20 // lighten ratio + return mix(color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: c.A}, c, r) +} + +// mix mixes c1 and c2 weighted by (1 - a/256) and a/256 respectively. +func mix(c1, c2 color.NRGBA, a uint8) color.NRGBA { + ai := int(a) return color.NRGBA{ - R: byte(255 - int(255-c.R)*(255-r)/256), - G: byte(255 - int(255-c.G)*(255-r)/256), - B: byte(255 - int(255-c.B)*(255-r)/256), - A: c.A, + R: byte((int(c1.R)*ai + int(c2.R)*(256-ai)) / 256), + G: byte((int(c1.G)*ai + int(c2.G)*(256-ai)) / 256), + B: byte((int(c1.B)*ai + int(c2.B)*(256-ai)) / 256), + A: byte((int(c1.A)*ai + int(c2.A)*(256-ai)) / 256), } }