diff --git a/src/Surface.zig b/src/Surface.zig index fea791be1..07db137fa 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -757,6 +757,13 @@ fn changeConfig(self: *Surface, config: *const configpkg.Config) !void { self.showMouse(); } + // Before sending any other config changes, we give the renderer a new font + // grid. We could check to see if there was an actual change to the font, + // but this is easier and pretty rare so it's not a performance concern. + // + // (Calling setFontSize builds and sends a new font grid to the renderer.) + try self.setFontSize(self.font_size); + // We need to store our configs in a heap-allocated pointer so that // our messages aren't huge. var renderer_message = try renderer.Message.initChangeConfig(self.alloc, config); diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index f34aac2aa..591293783 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -783,7 +783,7 @@ pub fn setVisible(self: *Metal, visible: bool) void { } } -/// Set the new font size. +/// Set the new font grid. /// /// Must be called on the render thread. pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void { @@ -812,6 +812,13 @@ pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void { log.err("error resizing cells buffer err={}", .{err}); }; + // Reset our shaper cache. If our font changed (not just the size) then + // the data in the shaper cache may be invalid and cannot be used, so we + // always clear the cache just in case. + const font_shaper_cache = font.ShaperCache.init(); + self.font_shaper_cache.deinit(self.alloc); + self.font_shaper_cache = font_shaper_cache; + // Reset our viewport to force a rebuild self.cells_viewport = null; @@ -1726,6 +1733,12 @@ pub fn changeConfig(self: *Metal, config: *DerivedConfig) !void { self.font_shaper = font_shaper; } + // We also need to reset the shaper cache so shaper info + // from the previous font isn't re-used for the new font. + const font_shaper_cache = font.ShaperCache.init(); + self.font_shaper_cache.deinit(self.alloc); + self.font_shaper_cache = font_shaper_cache; + // Set our new minimum contrast self.uniforms.min_contrast = config.min_contrast; @@ -1736,6 +1749,9 @@ pub fn changeConfig(self: *Metal, config: *DerivedConfig) !void { self.config.deinit(); self.config = config.*; + + // Reset our viewport to force a rebuild, in case of a font change. + self.cells_viewport = null; } /// Resize the screen. diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index ba1f8837a..71803d49a 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -595,7 +595,7 @@ pub fn setVisible(self: *OpenGL, visible: bool) void { _ = visible; } -/// Set the new font size. +/// Set the new font grid. /// /// Must be called on the render thread. pub fn setFontGrid(self: *OpenGL, grid: *font.SharedGrid) void { @@ -610,6 +610,13 @@ pub fn setFontGrid(self: *OpenGL, grid: *font.SharedGrid) void { self.texture_color_modified = 0; self.texture_color_resized = 0; + // Reset our shaper cache. If our font changed (not just the size) then + // the data in the shaper cache may be invalid and cannot be used, so we + // always clear the cache just in case. + const font_shaper_cache = font.ShaperCache.init(); + self.font_shaper_cache.deinit(self.alloc); + self.font_shaper_cache = font_shaper_cache; + // Defer our GPU updates self.deferred_font_size = .{ .metrics = grid.metrics }; } @@ -1577,6 +1584,12 @@ pub fn changeConfig(self: *OpenGL, config: *DerivedConfig) !void { self.font_shaper = font_shaper; } + // We also need to reset the shaper cache so shaper info + // from the previous font isn't re-used for the new font. + const font_shaper_cache = font.ShaperCache.init(); + self.font_shaper_cache.deinit(self.alloc); + self.font_shaper_cache = font_shaper_cache; + // Set our new colors self.background_color = config.background; self.foreground_color = config.foreground;