From b8d11e57c9e4b20d4ef4fa9972693bb753be9e80 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 6 Apr 2024 10:55:58 -0700 Subject: [PATCH] renderer/Metal: change font size works again --- src/Surface.zig | 19 +++++++++++++++++-- src/renderer/Metal.zig | 25 ++++++++----------------- src/renderer/Thread.zig | 9 +++++++-- src/renderer/message.zig | 19 +++++++++++++++---- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index 187a64b83..095c94afd 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -970,11 +970,26 @@ pub fn setFontSize(self: *Surface, size: font.face.DesiredSize) void { // Update our font size so future changes work self.font_size = size; - // Notify our render thread of the font size. This triggers everything else. + // We need to build up a new font stack for this font size. + const font_grid_key, const font_grid = self.app.font_grid_set.ref( + &self.config.font, + self.font_size, + ) catch unreachable; + errdefer self.app.font_grid_set.deref(font_grid_key); + + // Notify our render thread of the new font stack _ = self.renderer_thread.mailbox.push(.{ - .font_size = size, + .font_grid = .{ + .grid = font_grid, + .set = &self.app.font_grid_set, + .old_key = self.font_grid_key, + .new_key = font_grid_key, + }, }, .{ .forever = {} }); + // Once we've sent the key we can replace our key + self.font_grid_key = font_grid_key; + // Schedule render which also drains our mailbox self.queueRender() catch unreachable; } diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index ea94a796d..6c75f9ad2 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -566,18 +566,17 @@ pub fn setFocus(self: *Metal, focus: bool) !void { /// Set the new font size. /// /// Must be called on the render thread. -pub fn setFontSize(self: *Metal, size: font.face.DesiredSize) !void { - log.info("set font size={}", .{size}); - if (true) @panic("TODO"); // TODO(fontmem) - - // Set our new size, this will also reset our font atlas. - try self.font_group.setSize(size); +pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) !void { + // Update our grid + self.font_grid = grid; + self.texture_greyscale_modified = 0; + self.texture_color_modified = 0; // Recalculate our metrics const metrics = metrics: { - const index = (try self.font_group.indexForCodepoint(self.alloc, 'M', .regular, .text)).?; - const face = try self.font_group.group.faceFromIndex(index); - break :metrics face.metrics; + grid.lock.lockShared(); + defer grid.lock.unlockShared(); + break :metrics grid.metrics; }; // Update our uniforms @@ -597,14 +596,6 @@ pub fn setFontSize(self: *Metal, size: font.face.DesiredSize) !void { if (std.meta.eql(self.grid_metrics, metrics)) return; self.grid_metrics = metrics; - // Set the sprite font up - self.font_group.group.sprite = font.sprite.Face{ - .width = metrics.cell_width, - .height = metrics.cell_height, - .thickness = metrics.underline_thickness * @as(u32, if (self.config.font_thicken) 2 else 1), - .underline_position = metrics.underline_position, - }; - // Notify the window that the cell size changed. _ = self.surface_mailbox.push(.{ .cell_size = .{ diff --git a/src/renderer/Thread.zig b/src/renderer/Thread.zig index 113f6761c..d73705653 100644 --- a/src/renderer/Thread.zig +++ b/src/renderer/Thread.zig @@ -321,8 +321,13 @@ fn drainMailbox(self: *Thread) !void { } }, - .font_size => |size| { - try self.renderer.setFontSize(size); + .font_grid => |grid| if (self.renderer.setFontGrid(grid.grid)) { + // Success, deref our old grid + grid.set.deref(grid.old_key); + } else |err| { + // Error, deref our new grid since we didn't use it. + grid.set.deref(grid.new_key); + return err; }, .foreground_color => |color| { diff --git a/src/renderer/message.zig b/src/renderer/message.zig index b215bd4d2..c15854266 100644 --- a/src/renderer/message.zig +++ b/src/renderer/message.zig @@ -22,10 +22,21 @@ pub const Message = union(enum) { /// restarting the timer. reset_cursor_blink: void, - /// Change the font size. This should recalculate the grid size and - /// send a grid size change message back to the window thread if - /// the size changes. - font_size: font.face.DesiredSize, + /// Change the font grid. This can happen for any number of reasons + /// including a font size change, family change, etc. + font_grid: struct { + grid: *font.SharedGrid, + set: *font.SharedGridSet, + + // The key for the new grid. If adopting the new grid fails for any + // reason, the old grid should be kept but the new key should be + // dereferenced. + new_key: font.SharedGridSet.Key, + + // After accepting the new grid, the old grid must be dereferenced + // using the fields below. + old_key: font.SharedGridSet.Key, + }, /// Change the foreground color. This can be done separately from changing /// the config file in response to an OSC 10 command.