From b9efd837982d83961c2d7a30fa1d45364d5796c2 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 6 Apr 2024 10:37:26 -0700 Subject: [PATCH] font: SharedGridSet uses DerivedConfig --- src/Surface.zig | 10 ++++- src/config.zig | 8 +++- src/config/Config.zig | 2 + src/font/SharedGridSet.zig | 91 +++++++++++++++++++++++++++++++++++--- 4 files changed, 100 insertions(+), 11 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index 25a8b800d..187a64b83 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -205,6 +205,7 @@ const DerivedConfig = struct { confirm_close_surface: bool, cursor_click_to_move: bool, desktop_notifications: bool, + font: font.SharedGridSet.DerivedConfig, mouse_interval: u64, mouse_hide_while_typing: bool, mouse_scroll_multiplier: f64, @@ -262,6 +263,7 @@ const DerivedConfig = struct { .confirm_close_surface = config.@"confirm-close-surface", .cursor_click_to_move = config.@"cursor-click-to-move", .desktop_notifications = config.@"desktop-notifications", + .font = try font.SharedGridSet.DerivedConfig.init(alloc, config), .mouse_interval = config.@"click-repeat-interval" * 1_000_000, // 500ms .mouse_hide_while_typing = config.@"mouse-hide-while-typing", .mouse_scroll_multiplier = config.@"mouse-scroll-multiplier", @@ -297,6 +299,10 @@ pub fn init( rt_app: *apprt.runtime.App, rt_surface: *apprt.runtime.Surface, ) !void { + // Get our configuration + var derived_config = try DerivedConfig.init(alloc, config); + errdefer derived_config.deinit(); + // Initialize our renderer with our initialized surface. try Renderer.surfaceInit(rt_surface); @@ -322,7 +328,7 @@ pub fn init( // Setup our font group. This will reuse an existing font group if // it was already loaded. const font_grid_key, const font_grid = try app.font_grid_set.ref( - config, + &derived_config.font, font_size, ); @@ -427,7 +433,7 @@ pub fn init( .grid_size = .{}, .cell_size = cell_size, .padding = padding, - .config = try DerivedConfig.init(alloc, config), + .config = derived_config, }; // Report initial cell size on surface creation diff --git a/src/config.zig b/src/config.zig index 73c014a01..ba87fb6db 100644 --- a/src/config.zig +++ b/src/config.zig @@ -8,14 +8,18 @@ pub const edit = @import("config/edit.zig"); pub const url = @import("config/url.zig"); // Field types +pub const ClipboardAccess = Config.ClipboardAccess; pub const CopyOnSelect = Config.CopyOnSelect; +pub const CustomShaderAnimation = Config.CustomShaderAnimation; +pub const FontStyle = Config.FontStyle; pub const Keybinds = Config.Keybinds; pub const MouseShiftCapture = Config.MouseShiftCapture; -pub const CustomShaderAnimation = Config.CustomShaderAnimation; pub const NonNativeFullscreen = Config.NonNativeFullscreen; pub const OptionAsAlt = Config.OptionAsAlt; +pub const RepeatableCodepointMap = Config.RepeatableCodepointMap; +pub const RepeatableFontVariation = Config.RepeatableFontVariation; +pub const RepeatableString = Config.RepeatableString; pub const ShellIntegrationFeatures = Config.ShellIntegrationFeatures; -pub const ClipboardAccess = Config.ClipboardAccess; // Alternate APIs pub const CAPI = @import("config/CAPI.zig"); diff --git a/src/config/Config.zig b/src/config/Config.zig index 34adf7b56..03b6183c1 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -2965,6 +2965,8 @@ pub const RepeatableCodepointMap = struct { /// Deep copy of the struct. Required by Config. pub fn clone(self: *const Self, alloc: Allocator) !Self { + // TODO(fontmem): clone the codemap descriptors + return .{ .map = .{ .list = try self.map.list.clone(alloc) }, }; diff --git a/src/font/SharedGridSet.zig b/src/font/SharedGridSet.zig index 4b3303ab1..03f805d18 100644 --- a/src/font/SharedGridSet.zig +++ b/src/font/SharedGridSet.zig @@ -92,7 +92,7 @@ pub fn count(self: *SharedGridSet) usize { /// owned by the set and will be freed when the ref count reaches zero. pub fn ref( self: *SharedGridSet, - config: *const Config, + config: *const DerivedConfig, font_size: DesiredSize, ) !struct { Key, *SharedGrid } { var key = try Key.init(self.alloc, config); @@ -340,6 +340,74 @@ const ReffedGrid = struct { ref: u32 = 0, }; +/// This is the configuration required to create a key without having +/// to keep the full Ghostty configuration around. +pub const DerivedConfig = struct { + arena: ArenaAllocator, + + @"font-family": configpkg.RepeatableString, + @"font-family-bold": configpkg.RepeatableString, + @"font-family-italic": configpkg.RepeatableString, + @"font-family-bold-italic": configpkg.RepeatableString, + @"font-style": configpkg.FontStyle, + @"font-style-bold": configpkg.FontStyle, + @"font-style-italic": configpkg.FontStyle, + @"font-style-bold-italic": configpkg.FontStyle, + @"font-size": u8, + @"font-variation": configpkg.RepeatableFontVariation, + @"font-variation-bold": configpkg.RepeatableFontVariation, + @"font-variation-italic": configpkg.RepeatableFontVariation, + @"font-variation-bold-italic": configpkg.RepeatableFontVariation, + @"font-codepoint-map": configpkg.RepeatableCodepointMap, + @"font-thicken": bool, + @"adjust-cell-width": ?Metrics.Modifier, + @"adjust-cell-height": ?Metrics.Modifier, + @"adjust-font-baseline": ?Metrics.Modifier, + @"adjust-underline-position": ?Metrics.Modifier, + @"adjust-underline-thickness": ?Metrics.Modifier, + @"adjust-strikethrough-position": ?Metrics.Modifier, + @"adjust-strikethrough-thickness": ?Metrics.Modifier, + + pub fn init(alloc_gpa: Allocator, config: *const Config) !DerivedConfig { + var arena = ArenaAllocator.init(alloc_gpa); + errdefer arena.deinit(); + const alloc = arena.allocator(); + + return .{ + .@"font-family" = try config.@"font-family".clone(alloc), + .@"font-family-bold" = try config.@"font-family-bold".clone(alloc), + .@"font-family-italic" = try config.@"font-family-italic".clone(alloc), + .@"font-family-bold-italic" = try config.@"font-family-bold-italic".clone(alloc), + .@"font-style" = try config.@"font-style".clone(alloc), + .@"font-style-bold" = try config.@"font-style-bold".clone(alloc), + .@"font-style-italic" = try config.@"font-style-italic".clone(alloc), + .@"font-style-bold-italic" = try config.@"font-style-bold-italic".clone(alloc), + .@"font-size" = config.@"font-size", + .@"font-variation" = try config.@"font-variation".clone(alloc), + .@"font-variation-bold" = try config.@"font-variation-bold".clone(alloc), + .@"font-variation-italic" = try config.@"font-variation-italic".clone(alloc), + .@"font-variation-bold-italic" = try config.@"font-variation-bold-italic".clone(alloc), + .@"font-codepoint-map" = try config.@"font-codepoint-map".clone(alloc), + .@"font-thicken" = config.@"font-thicken", + .@"adjust-cell-width" = config.@"adjust-cell-width", + .@"adjust-cell-height" = config.@"adjust-cell-height", + .@"adjust-font-baseline" = config.@"adjust-font-baseline", + .@"adjust-underline-position" = config.@"adjust-underline-position", + .@"adjust-underline-thickness" = config.@"adjust-underline-thickness", + .@"adjust-strikethrough-position" = config.@"adjust-strikethrough-position", + .@"adjust-strikethrough-thickness" = config.@"adjust-strikethrough-thickness", + + // This must be last so the arena contains all our allocations + // from above since Zig does assignment in order. + .arena = arena, + }; + } + + pub fn deinit(self: *DerivedConfig) void { + self.arena.deinit(); + } +}; + /// The key used to uniquely identify a font configuration. pub const Key = struct { arena: ArenaAllocator, @@ -376,7 +444,7 @@ pub const Key = struct { pub fn init( alloc_gpa: Allocator, - config: *const Config, + config: *const DerivedConfig, ) !Key { var arena = ArenaAllocator.init(alloc_gpa); errdefer arena.deinit(); @@ -522,7 +590,10 @@ test "Key" { var cfg = try Config.default(alloc); defer cfg.deinit(); - var k = try Key.init(alloc, &cfg); + var keycfg = try DerivedConfig.init(alloc, &cfg); + defer keycfg.deinit(); + + var k = try Key.init(alloc, &keycfg); defer k.deinit(); try testing.expect(k.hashcode() > 0); @@ -535,15 +606,21 @@ test SharedGridSet { var set = try SharedGridSet.init(alloc); defer set.deinit(); - var config = try Config.default(alloc); - defer config.deinit(); + var cfg = try Config.default(alloc); + defer cfg.deinit(); + + var keycfg = try DerivedConfig.init(alloc, &cfg); + defer keycfg.deinit(); + + var k = try Key.init(alloc, &keycfg); + defer k.deinit(); // Get a grid for the given config - const key1, const grid1 = try set.ref(&config, .{ .points = 12 }); + const key1, const grid1 = try set.ref(&keycfg, .{ .points = 12 }); try testing.expectEqual(@as(usize, 1), set.count()); // Get another - const key2, const grid2 = try set.ref(&config, .{ .points = 12 }); + const key2, const grid2 = try set.ref(&keycfg, .{ .points = 12 }); try testing.expectEqual(@as(usize, 1), set.count()); // They should be pointer equivalent