mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
optimize Style
hashing to be single-shot
This commit is contained in:
@ -95,7 +95,7 @@ pub const Name = enum(u8) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// RGB
|
/// RGB
|
||||||
pub const RGB = struct {
|
pub const RGB = packed struct(u24) {
|
||||||
r: u8 = 0,
|
r: u8 = 0,
|
||||||
g: u8 = 0,
|
g: u8 = 0,
|
||||||
b: u8 = 0,
|
b: u8 = 0,
|
||||||
@ -155,9 +155,9 @@ pub const RGB = struct {
|
|||||||
return 0.299 * (r_f64 / 255) + 0.587 * (g_f64 / 255) + 0.114 * (b_f64 / 255);
|
return 0.299 * (r_f64 / 255) + 0.587 * (g_f64 / 255) + 0.114 * (b_f64 / 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "size" {
|
comptime {
|
||||||
try std.testing.expectEqual(@as(usize, 24), @bitSizeOf(RGB));
|
assert(@bitSizeOf(RGB) == 24);
|
||||||
try std.testing.expectEqual(@as(usize, 3), @sizeOf(RGB));
|
assert(@sizeOf(RGB) == 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a color from a floating point intensity value.
|
/// Parse a color from a floating point intensity value.
|
||||||
|
@ -27,7 +27,9 @@ pub const Style = struct {
|
|||||||
|
|
||||||
/// On/off attributes that don't require much bit width so we use
|
/// On/off attributes that don't require much bit width so we use
|
||||||
/// a packed struct to make this take up significantly less space.
|
/// a packed struct to make this take up significantly less space.
|
||||||
flags: packed struct {
|
flags: Flags = .{},
|
||||||
|
|
||||||
|
const Flags = packed struct(u16) {
|
||||||
bold: bool = false,
|
bold: bool = false,
|
||||||
italic: bool = false,
|
italic: bool = false,
|
||||||
faint: bool = false,
|
faint: bool = false,
|
||||||
@ -37,16 +39,23 @@ pub const Style = struct {
|
|||||||
strikethrough: bool = false,
|
strikethrough: bool = false,
|
||||||
overline: bool = false,
|
overline: bool = false,
|
||||||
underline: sgr.Attribute.Underline = .none,
|
underline: sgr.Attribute.Underline = .none,
|
||||||
} = .{},
|
_padding: u5 = 0,
|
||||||
|
};
|
||||||
|
|
||||||
/// The color for an SGR attribute. A color can come from multiple
|
/// The color for an SGR attribute. A color can come from multiple
|
||||||
/// sources so we use this to track the source plus color value so that
|
/// sources so we use this to track the source plus color value so that
|
||||||
/// we can properly react to things like palette changes.
|
/// we can properly react to things like palette changes.
|
||||||
pub const Color = union(enum) {
|
pub const Color = union(Tag) {
|
||||||
none: void,
|
none: void,
|
||||||
palette: u8,
|
palette: u8,
|
||||||
rgb: color.RGB,
|
rgb: color.RGB,
|
||||||
|
|
||||||
|
const Tag = enum(u8) {
|
||||||
|
none,
|
||||||
|
palette,
|
||||||
|
rgb,
|
||||||
|
};
|
||||||
|
|
||||||
/// Formatting to make debug logs easier to read
|
/// Formatting to make debug logs easier to read
|
||||||
/// by only including non-default attributes.
|
/// by only including non-default attributes.
|
||||||
pub fn format(
|
pub fn format(
|
||||||
@ -230,16 +239,68 @@ pub const Style = struct {
|
|||||||
_ = try writer.write(" }");
|
_ = try writer.write(" }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PackedStyle = packed struct(u128) {
|
||||||
|
tags: packed struct {
|
||||||
|
fg: Color.Tag,
|
||||||
|
bg: Color.Tag,
|
||||||
|
underline: Color.Tag,
|
||||||
|
},
|
||||||
|
data: packed struct {
|
||||||
|
fg: Data,
|
||||||
|
bg: Data,
|
||||||
|
underline: Data,
|
||||||
|
},
|
||||||
|
flags: Flags,
|
||||||
|
_padding: u16 = 0,
|
||||||
|
|
||||||
|
const Data = packed union {
|
||||||
|
none: u24,
|
||||||
|
palette: packed struct(u24) {
|
||||||
|
idx: u8,
|
||||||
|
_padding: u16 = 0,
|
||||||
|
},
|
||||||
|
rgb: color.RGB,
|
||||||
|
|
||||||
|
fn fromColor(c: Color) Data {
|
||||||
|
return switch (c) {
|
||||||
|
inline else => |v, t| @unionInit(
|
||||||
|
Data,
|
||||||
|
@tagName(t),
|
||||||
|
switch (t) {
|
||||||
|
.none => 0,
|
||||||
|
.palette => .{ .idx = v },
|
||||||
|
.rgb => v,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn fromStyle(style: Style) PackedStyle {
|
||||||
|
return .{
|
||||||
|
.tags = .{
|
||||||
|
.fg = std.meta.activeTag(style.fg_color),
|
||||||
|
.bg = std.meta.activeTag(style.bg_color),
|
||||||
|
.underline = std.meta.activeTag(style.underline_color),
|
||||||
|
},
|
||||||
|
.data = .{
|
||||||
|
.fg = Data.fromColor(style.fg_color),
|
||||||
|
.bg = Data.fromColor(style.bg_color),
|
||||||
|
.underline = Data.fromColor(style.underline_color),
|
||||||
|
},
|
||||||
|
.flags = style.flags,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub fn hash(self: *const Style) u64 {
|
pub fn hash(self: *const Style) u64 {
|
||||||
var hasher = XxHash3.init(0);
|
const packed_style = PackedStyle.fromStyle(self.*);
|
||||||
autoHash(&hasher, self.*);
|
return XxHash3.hash(0, std.mem.asBytes(&packed_style));
|
||||||
return hasher.final();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
comptime {
|
||||||
// The size of the struct so we can be aware of changes.
|
assert(@sizeOf(PackedStyle) == 16);
|
||||||
const testing = std.testing;
|
assert(std.meta.hasUniqueRepresentation(PackedStyle));
|
||||||
try testing.expectEqual(@as(usize, 14), @sizeOf(Style));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user