ae38f777
Render actual cell colors
a73x 2026-04-08 11:53
diff --git a/src/main.zig b/src/main.zig index abb172e..02f4d78 100644 --- a/src/main.zig +++ b/src/main.zig @@ -198,13 +198,15 @@ fn runTerminal(alloc: std.mem.Allocator) !void { const term_rows = term.render_state.row_data.items(.cells); var row_idx: u32 = 0; while (row_idx < term_rows.len) : (row_idx += 1) { const raw_cells = term_rows[row_idx].items(.raw); const row_cells = term_rows[row_idx]; const raw_cells = row_cells.items(.raw); var col_idx: u32 = 0; while (col_idx < raw_cells.len) : (col_idx += 1) { const cp = raw_cells[col_idx].codepoint(); if (cp == 0 or cp == ' ') continue; const uv = atlas.getOrInsert(&face, @intCast(cp)) catch continue; const colors = term.cellColors(row_cells.get(col_idx)); try instances.append(alloc, .{ .cell_pos = .{ @floatFromInt(col_idx), @floatFromInt(row_idx) }, @@ -216,8 +218,8 @@ fn runTerminal(alloc: std.mem.Allocator) !void { @as(f32, @floatFromInt(cell_h)) - @as(f32, @floatFromInt(uv.bearing_y)), }, .uv_rect = .{ uv.u0, uv.v0, uv.u1, uv.v1 }, .fg = .{ 0.9, 0.9, 0.9, 1.0 }, .bg = .{ 0.08, 0.08, 0.08, 1.0 }, .fg = colors.fg, .bg = colors.bg, }); } } diff --git a/src/vt.zig b/src/vt.zig index 71c55bf..cf18589 100644 --- a/src/vt.zig +++ b/src/vt.zig @@ -53,6 +53,10 @@ const ghostty_vt = @import("ghostty-vt"); pub const InputAction = ghostty_vt.input.KeyAction; pub const InputKey = ghostty_vt.input.Key; pub const InputMods = ghostty_vt.input.KeyMods; pub const CellColors = struct { fg: [4]f32, bg: [4]f32, }; pub const Terminal = struct { alloc: std.mem.Allocator, @@ -126,6 +130,26 @@ pub const Terminal = struct { return writer.buffered(); } pub fn cellColors( self: *const Terminal, cell: ghostty_vt.RenderState.Cell, ) CellColors { const style: ghostty_vt.Style = switch (cell.raw.content_tag) { .bg_color_palette, .bg_color_rgb => cell.style, else => if (cell.raw.style_id != 0) cell.style else .{}, }; const colors = self.render_state.colors; const fg = style.fg(.{ .default = colors.foreground, .palette = &colors.palette, }); const bg = style.bg(&cell.raw, &colors.palette) orelse colors.background; return .{ .fg = rgbToFloat4(fg), .bg = rgbToFloat4(bg), }; } pub fn resize(self: *Terminal, new_cols: u16, new_rows: u16) !void { try self.inner.resize(self.alloc, @intCast(new_cols), @intCast(new_rows)); } @@ -145,6 +169,15 @@ pub const Terminal = struct { } }; fn rgbToFloat4(rgb: ghostty_vt.color.RGB) [4]f32 { return .{ @as(f32, @floatFromInt(rgb.r)) / 255.0, @as(f32, @floatFromInt(rgb.g)) / 255.0, @as(f32, @floatFromInt(rgb.b)) / 255.0, 1.0, }; } test "Terminal init/deinit" { var term = try Terminal.init(std.testing.allocator, .{ .cols = 80, @@ -191,3 +224,21 @@ test "Terminal encodes non-text arrow keys" { const encoded = try term.encodeKey(.arrow_left, .{}, .press, &buf); try std.testing.expectEqualStrings("\x1b[D", encoded); } test "Terminal resolves ANSI fg and bg colors from render state" { var term = try Terminal.init(std.testing.allocator, .{ .cols = 80, .rows = 24, }); defer term.deinit(); term.write("\x1b[31;44mA\x1b[0m"); try term.snapshot(); const cell = term.render_state.row_data.get(0).cells.get(0); const colors = term.cellColors(cell); const palette = term.render_state.colors.palette; try std.testing.expectEqualDeep(rgbToFloat4(palette[1]), colors.fg); try std.testing.expectEqualDeep(rgbToFloat4(palette[4]), colors.bg); }