renderer/Metal: change font size works again

This commit is contained in:
Mitchell Hashimoto
2024-04-06 10:55:58 -07:00
parent ebd31ad50f
commit b8d11e57c9
4 changed files with 47 additions and 25 deletions

View File

@ -970,11 +970,26 @@ pub fn setFontSize(self: *Surface, size: font.face.DesiredSize) void {
// Update our font size so future changes work // Update our font size so future changes work
self.font_size = size; 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(.{ _ = 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 = {} }); }, .{ .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 // Schedule render which also drains our mailbox
self.queueRender() catch unreachable; self.queueRender() catch unreachable;
} }

View File

@ -566,18 +566,17 @@ pub fn setFocus(self: *Metal, focus: bool) !void {
/// Set the new font size. /// Set the new font size.
/// ///
/// Must be called on the render thread. /// Must be called on the render thread.
pub fn setFontSize(self: *Metal, size: font.face.DesiredSize) !void { pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) !void {
log.info("set font size={}", .{size}); // Update our grid
if (true) @panic("TODO"); // TODO(fontmem) self.font_grid = grid;
self.texture_greyscale_modified = 0;
// Set our new size, this will also reset our font atlas. self.texture_color_modified = 0;
try self.font_group.setSize(size);
// Recalculate our metrics // Recalculate our metrics
const metrics = metrics: { const metrics = metrics: {
const index = (try self.font_group.indexForCodepoint(self.alloc, 'M', .regular, .text)).?; grid.lock.lockShared();
const face = try self.font_group.group.faceFromIndex(index); defer grid.lock.unlockShared();
break :metrics face.metrics; break :metrics grid.metrics;
}; };
// Update our uniforms // 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; if (std.meta.eql(self.grid_metrics, metrics)) return;
self.grid_metrics = metrics; 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. // Notify the window that the cell size changed.
_ = self.surface_mailbox.push(.{ _ = self.surface_mailbox.push(.{
.cell_size = .{ .cell_size = .{

View File

@ -321,8 +321,13 @@ fn drainMailbox(self: *Thread) !void {
} }
}, },
.font_size => |size| { .font_grid => |grid| if (self.renderer.setFontGrid(grid.grid)) {
try self.renderer.setFontSize(size); // 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| { .foreground_color => |color| {

View File

@ -22,10 +22,21 @@ pub const Message = union(enum) {
/// restarting the timer. /// restarting the timer.
reset_cursor_blink: void, reset_cursor_blink: void,
/// Change the font size. This should recalculate the grid size and /// Change the font grid. This can happen for any number of reasons
/// send a grid size change message back to the window thread if /// including a font size change, family change, etc.
/// the size changes. font_grid: struct {
font_size: font.face.DesiredSize, 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 /// Change the foreground color. This can be done separately from changing
/// the config file in response to an OSC 10 command. /// the config file in response to an OSC 10 command.