fix(terminal): correct SGR direct color parsing

This commit is contained in:
Qwerasd
2024-12-31 14:37:23 -05:00
parent 5ba8fee38a
commit 4543cdeac8

View File

@ -189,11 +189,20 @@ pub const Parser = struct {
.@"8_fg" = @enumFromInt(slice[0] - 30), .@"8_fg" = @enumFromInt(slice[0] - 30),
}, },
38 => if (slice.len >= 5 and slice[1] == 2) { 38 => if (slice.len >= 2) switch (slice[1]) {
// `2` indicates direct-color (r, g, b).
// We need at least 3 more params for this to make sense.
2 => if (slice.len >= 5) {
self.idx += 4; self.idx += 4;
// When a colon separator is used, there may or may not be
// In the 6-len form, ignore the 3rd param. // a color space identifier as the third param, which we
const rgb = slice[2..5]; // need to ignore (it has no standardized behavior).
const rgb = if (slice.len == 5 or !self.colon)
slice[2..5]
else rgb: {
self.idx += 1;
break :rgb slice[3..6];
};
// We use @truncate because the value should be 0 to 255. If // We use @truncate because the value should be 0 to 255. If
// it isn't, the behavior is undefined so we just... truncate it. // it isn't, the behavior is undefined so we just... truncate it.
@ -204,12 +213,16 @@ pub const Parser = struct {
.b = @truncate(rgb[2]), .b = @truncate(rgb[2]),
}, },
}; };
} else if (slice.len >= 3 and slice[1] == 5) { },
// `5` indicates indexed color.
5 => if (slice.len >= 3) {
self.idx += 2; self.idx += 2;
return Attribute{ return Attribute{
.@"256_fg" = @truncate(slice[2]), .@"256_fg" = @truncate(slice[2]),
}; };
}, },
else => {},
},
39 => return Attribute{ .reset_fg = {} }, 39 => return Attribute{ .reset_fg = {} },
@ -217,11 +230,20 @@ pub const Parser = struct {
.@"8_bg" = @enumFromInt(slice[0] - 40), .@"8_bg" = @enumFromInt(slice[0] - 40),
}, },
48 => if (slice.len >= 5 and slice[1] == 2) { 48 => if (slice.len >= 2) switch (slice[1]) {
// `2` indicates direct-color (r, g, b).
// We need at least 3 more params for this to make sense.
2 => if (slice.len >= 5) {
self.idx += 4; self.idx += 4;
// When a colon separator is used, there may or may not be
// We only support the 5-len form. // a color space identifier as the third param, which we
const rgb = slice[2..5]; // need to ignore (it has no standardized behavior).
const rgb = if (slice.len == 5 or !self.colon)
slice[2..5]
else rgb: {
self.idx += 1;
break :rgb slice[3..6];
};
// We use @truncate because the value should be 0 to 255. If // We use @truncate because the value should be 0 to 255. If
// it isn't, the behavior is undefined so we just... truncate it. // it isn't, the behavior is undefined so we just... truncate it.
@ -232,24 +254,33 @@ pub const Parser = struct {
.b = @truncate(rgb[2]), .b = @truncate(rgb[2]),
}, },
}; };
} else if (slice.len >= 3 and slice[1] == 5) { },
// `5` indicates indexed color.
5 => if (slice.len >= 3) {
self.idx += 2; self.idx += 2;
return Attribute{ return Attribute{
.@"256_bg" = @truncate(slice[2]), .@"256_bg" = @truncate(slice[2]),
}; };
}, },
else => {},
},
49 => return Attribute{ .reset_bg = {} }, 49 => return Attribute{ .reset_bg = {} },
53 => return Attribute{ .overline = {} }, 53 => return Attribute{ .overline = {} },
55 => return Attribute{ .reset_overline = {} }, 55 => return Attribute{ .reset_overline = {} },
58 => if (slice.len >= 5 and slice[1] == 2) { 58 => if (slice.len >= 2) switch (slice[1]) {
// `2` indicates direct-color (r, g, b).
// We need at least 3 more params for this to make sense.
2 => if (slice.len >= 5) {
self.idx += 4; self.idx += 4;
// When a colon separator is used, there may or may not be
// In the 6-len form, ignore the 3rd param. Otherwise, use it. // a color space identifier as the third param, which we
const rgb = if (slice.len == 5) slice[2..5] else rgb: { // need to ignore (it has no standardized behavior).
// Consume one more element const rgb = if (slice.len == 5 or !self.colon)
slice[2..5]
else rgb: {
self.idx += 1; self.idx += 1;
break :rgb slice[3..6]; break :rgb slice[3..6];
}; };
@ -263,12 +294,16 @@ pub const Parser = struct {
.b = @truncate(rgb[2]), .b = @truncate(rgb[2]),
}, },
}; };
} else if (slice.len >= 3 and slice[1] == 5) { },
// `5` indicates indexed color.
5 => if (slice.len >= 3) {
self.idx += 2; self.idx += 2;
return Attribute{ return Attribute{
.@"256_underline_color" = @truncate(slice[2]), .@"256_underline_color" = @truncate(slice[2]),
}; };
}, },
else => {},
},
59 => return Attribute{ .reset_underline_color = {} }, 59 => return Attribute{ .reset_underline_color = {} },