From 966166015f148fe1a781be5000844acea5cf07d3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 24 Sep 2023 09:02:35 -0700 Subject: [PATCH 1/5] font/core-text: discovery supports style search --- src/cli/list_fonts.zig | 4 ++++ src/font/discovery.zig | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/cli/list_fonts.zig b/src/cli/list_fonts.zig index f34df3cf1..1f02eb2cf 100644 --- a/src/cli/list_fonts.zig +++ b/src/cli/list_fonts.zig @@ -14,6 +14,9 @@ pub const Config = struct { /// matching this family will be listed. family: ?[:0]const u8 = null, + /// The style name to search for. + style: ?[:0]const u8 = null, + /// Font styles to search for. If this is set, then only fonts that /// match the given styles will be listed. bold: bool = false, @@ -84,6 +87,7 @@ fn runArgs(alloc_gpa: Allocator, argsIter: anytype) !u8 { defer disco.deinit(); var disco_it = try disco.discover(.{ .family = config.family, + .style = config.style, .bold = config.bold, .italic = config.italic, }); diff --git a/src/font/discovery.zig b/src/font/discovery.zig index 19b7141d6..828117865 100644 --- a/src/font/discovery.zig +++ b/src/font/discovery.zig @@ -31,6 +31,12 @@ pub const Descriptor = struct { /// fontconfig pattern, such as "Fira Code-14:bold". family: ?[:0]const u8 = null, + /// Specific font style to search for. This will filter the style + /// string the font advertises. The "bold/italic" booleans later in this + /// struct filter by the style trait the font has, not the string, so + /// these can be used in conjunction or not. + style: ?[:0]const u8 = null, + /// A codepoint that this font must be able to render. codepoint: u32 = 0, @@ -99,6 +105,16 @@ pub const Descriptor = struct { ); } + // Style + if (self.style) |style_bytes| { + const style = try macos.foundation.String.createWithBytes(style_bytes, .utf8, false); + defer style.release(); + attrs.setValue( + macos.text.FontAttribute.style_name.key(), + style, + ); + } + // Codepoint support if (self.codepoint > 0) { const cs = try macos.foundation.CharacterSet.createWithCharactersInRange(.{ From 8e083d86180b7dd26b4e98bf7717c21aed61d8dd Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 24 Sep 2023 09:05:07 -0700 Subject: [PATCH 2/5] font/fontconfig: support style descriptor --- src/font/discovery.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/font/discovery.zig b/src/font/discovery.zig index 828117865..7ac5d6fff 100644 --- a/src/font/discovery.zig +++ b/src/font/discovery.zig @@ -64,6 +64,9 @@ pub const Descriptor = struct { if (self.family) |family| { assert(pat.add(.family, .{ .string = family }, false)); } + if (self.style) |style| { + assert(pat.add(.style, .{ .string = style }, false)); + } if (self.codepoint > 0) { const cs = fontconfig.CharSet.create(); defer cs.destroy(); From 16cecc082aeb286e363049d367eedeefbc7940e2 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 24 Sep 2023 09:05:40 -0700 Subject: [PATCH 3/5] font: fallback should not restrict to only monospace --- src/font/Group.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/font/Group.zig b/src/font/Group.zig index 404c3c322..e6ba73b13 100644 --- a/src/font/Group.zig +++ b/src/font/Group.zig @@ -257,6 +257,7 @@ pub fn indexForCodepoint( .size = self.size.points, .bold = style == .bold or style == .bold_italic, .italic = style == .italic or style == .bold_italic, + .monospace = false, }) catch break :discover; defer disco_it.deinit(); From 52591161bc1eec8bc881c65a7271a3f69bd83e21 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 24 Sep 2023 09:12:25 -0700 Subject: [PATCH 4/5] config: add font-style configurations --- src/Surface.zig | 4 ++++ src/config/Config.zig | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/Surface.zig b/src/Surface.zig index d33760f68..7bbe31745 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -238,6 +238,7 @@ pub fn init( if (config.@"font-family") |family| { var disco_it = try disco.discover(.{ .family = family, + .style = config.@"font-style", .size = font_size.points, .variations = config.@"font-variation".list.items, }); @@ -250,6 +251,7 @@ pub fn init( if (config.@"font-family-bold") |family| { var disco_it = try disco.discover(.{ .family = family, + .style = config.@"font-style-bold", .size = font_size.points, .bold = true, .variations = config.@"font-variation-bold".list.items, @@ -263,6 +265,7 @@ pub fn init( if (config.@"font-family-italic") |family| { var disco_it = try disco.discover(.{ .family = family, + .style = config.@"font-style-italic", .size = font_size.points, .italic = true, .variations = config.@"font-variation-italic".list.items, @@ -276,6 +279,7 @@ pub fn init( if (config.@"font-family-bold-italic") |family| { var disco_it = try disco.discover(.{ .family = family, + .style = config.@"font-style-bold-italic", .size = font_size.points, .bold = true, .italic = true, diff --git a/src/config/Config.zig b/src/config/Config.zig index b0fac6b43..1f2c3e82e 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -29,6 +29,14 @@ const c = @cImport({ @"font-family-italic": ?[:0]const u8 = null, @"font-family-bold-italic": ?[:0]const u8 = null, +/// 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 +/// by the font itself. For example, "Iosevka Heavy" has a style of "Heavy". +@"font-style": ?[:0]const u8 = null, +@"font-style-bold": ?[:0]const u8 = null, +@"font-style-italic": ?[:0]const u8 = null, +@"font-style-bold-italic": ?[:0]const u8 = null, + /// Apply a font feature. This can be repeated multiple times to enable /// multiple font features. You can NOT set multiple font features with /// a single value (yet). From efa6d85855f2416b7d1c580a346a2639db5bba9e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 24 Sep 2023 09:15:32 -0700 Subject: [PATCH 5/5] config: update docs --- src/config/Config.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/config/Config.zig b/src/config/Config.zig index 1f2c3e82e..5e79e0630 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -32,6 +32,9 @@ const c = @cImport({ /// 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 /// by the font itself. For example, "Iosevka Heavy" has a style of "Heavy". +/// +/// These are only valid if there is an exact font-family also specified. +/// If no font-family is specified, then the font-style is ignored. @"font-style": ?[:0]const u8 = null, @"font-style-bold": ?[:0]const u8 = null, @"font-style-italic": ?[:0]const u8 = null,