render: premultiply alpha for user-provided colors

The wlroots rendering API expects colors to be provided with
premultipled alpha but we currently do not parse them as such. This
causes blending with e.g. a transparent border color to be very broken.
This commit is contained in:
MaxVerevkin 2023-01-06 10:37:21 +02:00 committed by Isaac Freund
parent 701d16c2ea
commit 030f7efd4f
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11
2 changed files with 11 additions and 9 deletions

View File

@ -46,19 +46,19 @@ pub const HideCursorWhenTypingMode = enum {
enabled,
};
/// Color of background in RGBA (alpha should only affect nested sessions)
/// Color of background in RGBA with premultiplied alpha (alpha should only affect nested sessions)
background_color: [4]f32 = [_]f32{ 0.0, 0.16862745, 0.21176471, 1.0 }, // Solarized base03
/// Width of borders in pixels
border_width: u31 = 2,
/// Color of border of focused window in RGBA
/// Color of border of focused window in RGBA with premultiplied alpha
border_color_focused: [4]f32 = [_]f32{ 0.57647059, 0.63137255, 0.63137255, 1.0 }, // Solarized base1
/// Color of border of unfocused window in RGBA
/// Color of border of unfocused window in RGBA with premultiplied alpha
border_color_unfocused: [4]f32 = [_]f32{ 0.34509804, 0.43137255, 0.45882353, 1.0 }, // Solarized base01
/// Color of border of urgent window in RGBA
/// Color of border of urgent window in RGBA with premultiplied alpha
border_color_urgent: [4]f32 = [_]f32{ 0.86274510, 0.19607843, 0.18431373, 1.0 }, // Solarized red
/// Map of keymap mode name to mode id

View File

@ -104,7 +104,7 @@ pub fn setCursorWarp(
return Error.UnknownOption;
}
/// Parse a color in the format 0xRRGGBB or 0xRRGGBBAA
/// Parse a color in the format 0xRRGGBB or 0xRRGGBBAA. Returned color has premultiplied alpha.
fn parseRgba(string: []const u8) ![4]f32 {
if (string.len != 8 and string.len != 10) return error.InvalidRgba;
if (string[0] != '0' or string[1] != 'x') return error.InvalidRgba;
@ -114,10 +114,12 @@ fn parseRgba(string: []const u8) ![4]f32 {
const b = try fmt.parseInt(u8, string[6..8], 16);
const a = if (string.len == 10) try fmt.parseInt(u8, string[8..10], 16) else 255;
const alpha = @intToFloat(f32, a) / 255.0;
return [4]f32{
@intToFloat(f32, r) / 255.0,
@intToFloat(f32, g) / 255.0,
@intToFloat(f32, b) / 255.0,
@intToFloat(f32, a) / 255.0,
@intToFloat(f32, r) / 255.0 * alpha,
@intToFloat(f32, g) / 255.0 * alpha,
@intToFloat(f32, b) / 255.0 * alpha,
alpha,
};
}