From b4f403f152193aa8f6280e37a4ad76b6ffd8c952 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 3 Jan 2024 09:30:12 -0800 Subject: [PATCH] font-family settings are repeatable to specify fallback --- src/Surface.zig | 8 ++++---- src/config/Config.zig | 29 ++++++++++++++++++++--------- src/config/key.zig | 2 +- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index d8bf5ea60..0ed3b47d3 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -342,7 +342,7 @@ pub fn init( // A buffer we use to store the font names for logging. var name_buf: [256]u8 = undefined; - if (config.@"font-family") |family| { + for (config.@"font-family".list.items) |family| { var disco_it = try disco.discover(alloc, .{ .family = family, .style = config.@"font-style".nameValue(), @@ -364,7 +364,7 @@ pub fn init( // a user says `font-style = italic` for the bold face for example, // no results would be found if we restrict to ALSO searching for // italic. - if (config.@"font-family-bold") |family| { + for (config.@"font-family-bold".list.items) |family| { const style = config.@"font-style-bold".nameValue(); var disco_it = try disco.discover(alloc, .{ .family = family, @@ -379,7 +379,7 @@ pub fn init( _ = try group.addFace(.bold, .{ .deferred = face }); } else log.warn("font-family-bold not found: {s}", .{family}); } - if (config.@"font-family-italic") |family| { + for (config.@"font-family-italic".list.items) |family| { const style = config.@"font-style-italic".nameValue(); var disco_it = try disco.discover(alloc, .{ .family = family, @@ -394,7 +394,7 @@ pub fn init( _ = try group.addFace(.italic, .{ .deferred = face }); } else log.warn("font-family-italic not found: {s}", .{family}); } - if (config.@"font-family-bold-italic") |family| { + for (config.@"font-family-bold-italic".list.items) |family| { const style = config.@"font-style-bold-italic".nameValue(); var disco_it = try disco.discover(alloc, .{ .family = family, diff --git a/src/config/Config.zig b/src/config/Config.zig index 6c705b96b..154e010a4 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -29,15 +29,21 @@ const c = @cImport({ }); /// The font families to use. +/// /// You can generate the list of valid values using the CLI: /// path/to/ghostty/cli +list-fonts /// +/// This configuration can be repeated multiple times to specify +/// preferred fallback fonts when the requested codepoint is not +/// available in the primary font. This is particularly useful for +/// multiple languages, symbolic fonts, etc. +/// /// Changing this configuration at runtime will only affect new terminals, /// i.e. new windows, tabs, etc. -@"font-family": ?[:0]const u8 = null, -@"font-family-bold": ?[:0]const u8 = null, -@"font-family-italic": ?[:0]const u8 = null, -@"font-family-bold-italic": ?[:0]const u8 = null, +@"font-family": RepeatableString = .{}, +@"font-family-bold": RepeatableString = .{}, +@"font-family-italic": RepeatableString = .{}, +@"font-family-bold-italic": RepeatableString = .{}, /// The named font style to use for each of the requested terminal font /// styles. This looks up the style based on the font style string advertised @@ -1623,15 +1629,15 @@ pub fn finalize(self: *Config) !void { // the others to the font family. This way, if someone does // --font-family=foo, then we try to get the stylized versions of // "foo" as well. - if (self.@"font-family") |family| { + if (self.@"font-family".count() > 0) { const fields = &[_][]const u8{ "font-family-bold", "font-family-italic", "font-family-bold-italic", }; inline for (fields) |field| { - if (@field(self, field) == null) { - @field(self, field) = family; + if (@field(self, field).count() == 0) { + @field(self, field) = try self.@"font-family".clone(alloc); } } } @@ -1984,9 +1990,9 @@ test "changed" { defer source.deinit(); var dest = try source.clone(alloc); defer dest.deinit(); - dest.@"font-family" = "something else"; + dest.@"font-thicken" = true; - try testing.expect(source.changed(&dest, .@"font-family")); + try testing.expect(source.changed(&dest, .@"font-thicken")); try testing.expect(!source.changed(&dest, .@"font-size")); } @@ -2218,6 +2224,11 @@ pub const RepeatableString = struct { }; } + /// The number of itemsin the list + pub fn count(self: Self) usize { + return self.list.items.len; + } + /// Compare if two of our value are requal. Required by Config. pub fn equal(self: Self, other: Self) bool { const itemsA = self.list.items; diff --git a/src/config/key.zig b/src/config/key.zig index b3d64fcea..f56376238 100644 --- a/src/config/key.zig +++ b/src/config/key.zig @@ -50,6 +50,6 @@ pub fn Value(comptime key: Key) type { test "Value" { const testing = std.testing; - try testing.expectEqual(?[:0]const u8, Value(.@"font-family")); + try testing.expectEqual(Config.RepeatableString, Value(.@"font-family")); try testing.expectEqual(?bool, Value(.@"cursor-style-blink")); }