From 3a7dc355a028c0350a4771ed00d45c98756dcb24 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 27 Apr 2024 22:13:17 -0700 Subject: [PATCH] renderer/metal: invert text under cursor again --- src/renderer/Metal.zig | 27 ++++++++++++++++++++++++++- src/renderer/metal/shaders.zig | 12 ++++++++---- src/renderer/shaders/cell.metal | 17 ++++++++++++++--- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index 30dfc6d52..a5f48c179 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -565,6 +565,8 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal { .projection_matrix = undefined, .cell_size = undefined, .min_contrast = options.config.min_contrast, + .cursor_pos = .{ std.math.maxInt(u16), std.math.maxInt(u16) }, + .cursor_color = undefined, }, // Fonts @@ -683,6 +685,8 @@ pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void { @floatFromInt(metrics.cell_height), }, .min_contrast = self.uniforms.min_contrast, + .cursor_pos = self.uniforms.cursor_pos, + .cursor_color = self.uniforms.cursor_color, }; } @@ -1586,6 +1590,8 @@ pub fn setScreenSize( @floatFromInt(self.grid_metrics.cell_height), }, .min_contrast = old.min_contrast, + .cursor_pos = old.cursor_pos, + .cursor_color = old.cursor_color, }; // Reset our cell contents. @@ -1987,11 +1993,30 @@ fn rebuildCells2( // If we have no cursor style then we don't render the cursor. const style = cursor_style_ orelse { self.cells.setCursor(null); + self.uniforms.cursor_pos = .{ + std.math.maxInt(u16), + std.math.maxInt(u16), + }; break :cursor; }; // Prepare the cursor cell contents. self.addCursor2(screen, style); + + // Setup our uniforms for the cursor so that any data + // under the cursor can render differently. + self.uniforms.cursor_pos = .{ screen.cursor.x, screen.cursor.y }; + self.uniforms.cursor_color = if (self.config.cursor_text) |txt| .{ + txt.r, + txt.g, + txt.b, + 255, + } else .{ + self.background_color.r, + self.background_color.g, + self.background_color.b, + 255, + }; } // If we have a preedit, we try to render the preedit text on top @@ -2512,7 +2537,7 @@ fn addCursor2( }; self.cells.setCursor(.{ - .mode = .fg, + .mode = .cursor, .grid_pos = .{ x, screen.cursor.y }, .cell_width = if (wide) 2 else 1, .color = .{ color.r, color.g, color.b, alpha }, diff --git a/src/renderer/metal/shaders.zig b/src/renderer/metal/shaders.zig index 2d7fb9700..a6303c78d 100644 --- a/src/renderer/metal/shaders.zig +++ b/src/renderer/metal/shaders.zig @@ -116,6 +116,10 @@ pub const Uniforms = extern struct { /// The minimum contrast ratio for text. The contrast ratio is calculated /// according to the WCAG 2.0 spec. min_contrast: f32, + + /// The cursor position and color. + cursor_pos: [2]u16, + cursor_color: [4]u8, }; /// The uniforms used for custom postprocess shaders. @@ -296,10 +300,10 @@ pub const CellText = extern struct { cell_width: u8, pub const Mode = enum(u8) { - bg = 1, - fg = 2, - fg_constrained = 3, - fg_color = 7, + fg = 1, + fg_constrained = 2, + fg_color = 3, + cursor = 4, }; }; diff --git a/src/renderer/shaders/cell.metal b/src/renderer/shaders/cell.metal index 3aae45ef5..f486d4ecf 100644 --- a/src/renderer/shaders/cell.metal +++ b/src/renderer/shaders/cell.metal @@ -4,6 +4,8 @@ struct Uniforms { float4x4 projection_matrix; float2 cell_size; float min_contrast; + ushort2 cursor_pos; + uchar4 cursor_color; }; //------------------------------------------------------------------- @@ -134,9 +136,10 @@ fragment float4 cell_bg_fragment(CellBgVertexOut in [[stage_in]]) { // The possible modes that a cell fg entry can take. enum CellTextMode : uint8_t { - MODE_TEXT = 2u, - MODE_TEXT_CONSTRAINED = 3u, - MODE_TEXT_COLOR = 7u, + MODE_TEXT = 1u, + MODE_TEXT_CONSTRAINED = 2u, + MODE_TEXT_COLOR = 3u, + MODE_TEXT_CURSOR = 4u, }; struct CellTextVertexIn { @@ -243,6 +246,13 @@ vertex CellTextVertexOut cell_text_vertex(unsigned int vid [[vertex_id]], out.color = contrasted_color(uniforms.min_contrast, out.color, bg_color); } + // If this cell is the cursor cell, then we need to change the color. + if (input.mode != MODE_TEXT_CURSOR && + input.grid_pos.x == uniforms.cursor_pos.x && + input.grid_pos.y == uniforms.cursor_pos.y) { + out.color = float4(uniforms.cursor_color) / 255.0f; + } + return out; } @@ -254,6 +264,7 @@ fragment float4 cell_text_fragment(CellTextVertexOut in [[stage_in]], constexpr sampler textureSampler(address::clamp_to_edge, filter::linear); switch (in.mode) { + case MODE_TEXT_CURSOR: case MODE_TEXT_CONSTRAINED: case MODE_TEXT: { // Normalize the texture coordinates to [0,1]