From 74bda5a6ebd14d5a9d6891f3fc21953879a36d16 Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Fri, 8 Nov 2024 20:26:21 +0100 Subject: [PATCH 01/13] feat: implement configurable freetype load flags --- src/build/fish_completions.zig | 2 +- src/build/mdgen/mdgen.zig | 2 +- src/config/Config.zig | 29 +++++++++++++++++++++++++++++ src/font/face.zig | 3 +++ src/font/face/freetype.zig | 8 +++++++- src/renderer/Metal.zig | 12 +++++++++++- src/renderer/OpenGL.zig | 13 ++++++++++++- 7 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/build/fish_completions.zig b/src/build/fish_completions.zig index 0ff0a2163..64fbea44e 100644 --- a/src/build/fish_completions.zig +++ b/src/build/fish_completions.zig @@ -12,7 +12,7 @@ pub const fish_completions = comptimeGenerateFishCompletions(); fn comptimeGenerateFishCompletions() []const u8 { comptime { - @setEvalBranchQuota(17000); + @setEvalBranchQuota(18000); var counter = std.io.countingWriter(std.io.null_writer); try writeFishCompletions(&counter.writer()); diff --git a/src/build/mdgen/mdgen.zig b/src/build/mdgen/mdgen.zig index 2e2884f1a..7e05596d7 100644 --- a/src/build/mdgen/mdgen.zig +++ b/src/build/mdgen/mdgen.zig @@ -26,7 +26,7 @@ pub fn genConfig(writer: anytype, cli: bool) !void { \\ ); - @setEvalBranchQuota(2000); + @setEvalBranchQuota(3000); inline for (@typeInfo(Config).Struct.fields) |field| { if (field.name[0] == '_') continue; diff --git a/src/config/Config.zig b/src/config/Config.zig index e6b9d35ab..908935a5d 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -287,6 +287,26 @@ const c = @cImport({ /// terminals. Only new terminals will use the new configuration. @"grapheme-width-method": GraphemeWidthMethod = .unicode, +/// Freetype load flags to enable. The format of this is a list of flags to +/// enable separated by commas. If you prefix a flag with `no-` then it is +/// disabled. If you omit a flag, it's default value is used, so you must +/// explicitely disable flags you don't want. You can also use `true` or `false` +/// to turn all flags on or off. +/// +/// Available flags: +/// +/// * `hinting` - Enable or disable hinting, enabled by default. +/// * `bitmap` - Enable or disable loading of any pre-rendered bitmap strikes, +/// enabled by default +/// * `force-autohint` - Use the freetype auto-hinter rather than the font's +/// native hinter. Enabled by default. +/// * `monochrome` - Instructs renderer to use 1-bit monochrome rendering. +/// This option doesn't impact the hinter. Enabled by default. +/// * `autohint` - Use the freetype auto-hinter. Enabled by default. +/// +/// Example: `hinting`, `no-hinting`, `force-autohint`, `no-force-autohint` +@"freetype-load-flag": FreetypeLoadFlags = .{}, + /// A theme to use. If the theme is an absolute pathname, Ghostty will attempt /// to load that file as a theme. If that file does not exist or is inaccessible, /// an error will be logged and no other directories will be searched. @@ -4565,6 +4585,15 @@ pub const GraphemeWidthMethod = enum { unicode, }; +/// See freetype-load-flag +pub const FreetypeLoadFlags = packed struct { + hinting: bool = true, + bitmap: bool = true, + @"force-autohint": bool = false, + monochrome: bool = false, + autohint: bool = true, +}; + /// See linux-cgroup pub const LinuxCgroup = enum { never, diff --git a/src/font/face.zig b/src/font/face.zig index 8bcfb8209..77fb9e45b 100644 --- a/src/font/face.zig +++ b/src/font/face.zig @@ -2,6 +2,7 @@ const std = @import("std"); const builtin = @import("builtin"); const options = @import("main.zig").options; pub const Metrics = @import("face/Metrics.zig"); +const FreetypeLoadFlags = @import("../config/Config.zig").FreetypeLoadFlags; const freetype = @import("face/freetype.zig"); const coretext = @import("face/coretext.zig"); pub const web_canvas = @import("face/web_canvas.zig"); @@ -90,6 +91,8 @@ pub const RenderOptions = struct { /// /// This only works with CoreText currently. thicken: bool = false, + + load_flags: FreetypeLoadFlags, }; test { diff --git a/src/font/face/freetype.zig b/src/font/face/freetype.zig index 7bb9ecbab..e3ad5322b 100644 --- a/src/font/face/freetype.zig +++ b/src/font/face/freetype.zig @@ -318,7 +318,13 @@ pub const Face = struct { // // This must be enabled for color faces though because those are // often colored bitmaps, which we support. - .no_bitmap = !self.face.hasColor(), + .no_bitmap = !self.face.hasColor() or !opts.load_flags.bitmap, + + // use options from config + .no_hinting = !opts.load_flags.hinting, + .force_autohint = !opts.load_flags.@"force-autohint", + .monochrome = !opts.load_flags.monochrome, + .no_autohint = !opts.load_flags.autohint, }); const glyph = self.face.handle.*.glyph; diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index 742dfbcd4..561168b90 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -354,6 +354,7 @@ pub const DerivedConfig = struct { font_thicken: bool, font_features: std.ArrayListUnmanaged([:0]const u8), font_styles: font.CodepointResolver.StyleStatus, + load_flags: configpkg.Config.FreetypeLoadFlags, cursor_color: ?terminal.color.RGB, cursor_invert: bool, cursor_opacity: f64, @@ -399,11 +400,14 @@ pub const DerivedConfig = struct { const cursor_invert = config.@"cursor-invert-fg-bg"; + const load_flags = config.@"freetype-load-flag"; + return .{ .background_opacity = @max(0, @min(1, config.@"background-opacity")), .font_thicken = config.@"font-thicken", .font_features = font_features, .font_styles = font_styles, + .load_flags = load_flags, .cursor_color = if (!cursor_invert and config.@"cursor-color" != null) config.@"cursor-color".?.toTerminalRGB() @@ -2719,6 +2723,7 @@ fn addUnderline( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, + .load_flags = self.config.load_flags, }, ); @@ -2751,6 +2756,7 @@ fn addOverline( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, + .load_flags = self.config.load_flags, }, ); @@ -2783,6 +2789,7 @@ fn addStrikethrough( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, + .load_flags = self.config.load_flags, }, ); @@ -2822,6 +2829,7 @@ fn addGlyph( .{ .grid_metrics = self.grid_metrics, .thicken = self.config.font_thicken, + .load_flags = self.config.load_flags, }, ); @@ -2901,6 +2909,7 @@ fn addCursor( .{ .cell_width = if (wide) 2 else 1, .grid_metrics = self.grid_metrics, + .load_flags = self.config.load_flags, }, ) catch |err| { log.warn("error rendering cursor glyph err={}", .{err}); @@ -2916,6 +2925,7 @@ fn addCursor( .{ .cell_width = if (wide) 2 else 1, .grid_metrics = self.grid_metrics, + .load_flags = self.config.load_flags, }, ) catch |err| { log.warn("error rendering cursor glyph err={}", .{err}); @@ -2956,7 +2966,7 @@ fn addPreeditCell( @intCast(cp.codepoint), .regular, .text, - .{ .grid_metrics = self.grid_metrics }, + .{ .grid_metrics = self.grid_metrics, .load_flags = self.config.load_flags }, ) catch |err| { log.warn("error rendering preedit glyph err={}", .{err}); return; diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 5313315b1..7cb391bcc 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -11,6 +11,7 @@ const ArenaAllocator = std.heap.ArenaAllocator; const link = @import("link.zig"); const isCovering = @import("cell.zig").isCovering; const fgMode = @import("cell.zig").fgMode; +const freetype = @import("freetype").Face; const shadertoy = @import("shadertoy.zig"); const apprt = @import("../apprt.zig"); const configpkg = @import("../config.zig"); @@ -288,6 +289,7 @@ pub const DerivedConfig = struct { font_thicken: bool, font_features: std.ArrayListUnmanaged([:0]const u8), font_styles: font.CodepointResolver.StyleStatus, + load_flags: configpkg.Config.FreetypeLoadFlags, cursor_color: ?terminal.color.RGB, cursor_invert: bool, cursor_text: ?terminal.color.RGB, @@ -332,11 +334,14 @@ pub const DerivedConfig = struct { const cursor_invert = config.@"cursor-invert-fg-bg"; + const load_flags = config.@"freetype-load-flag"; + return .{ .background_opacity = @max(0, @min(1, config.@"background-opacity")), .font_thicken = config.@"font-thicken", .font_features = font_features, .font_styles = font_styles, + .load_flags = load_flags, .cursor_color = if (!cursor_invert and config.@"cursor-color" != null) config.@"cursor-color".?.toTerminalRGB() @@ -1765,7 +1770,7 @@ fn addPreeditCell( @intCast(cp.codepoint), .regular, .text, - .{ .grid_metrics = self.grid_metrics }, + .{ .grid_metrics = self.grid_metrics, .load_flags = self.config.load_flags }, ) catch |err| { log.warn("error rendering preedit glyph err={}", .{err}); return; @@ -1866,6 +1871,7 @@ fn addCursor( .{ .cell_width = if (wide) 2 else 1, .grid_metrics = self.grid_metrics, + .load_flags = self.config.load_flags, }, ) catch |err| { log.warn("error rendering cursor glyph err={}", .{err}); @@ -1881,6 +1887,7 @@ fn addCursor( .{ .cell_width = if (wide) 2 else 1, .grid_metrics = self.grid_metrics, + .load_flags = self.config.load_flags, }, ) catch |err| { log.warn("error rendering cursor glyph err={}", .{err}); @@ -1943,6 +1950,7 @@ fn addUnderline( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, + .load_flags = self.config.load_flags, }, ); @@ -1984,6 +1992,7 @@ fn addOverline( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, + .load_flags = self.config.load_flags, }, ); @@ -2025,6 +2034,7 @@ fn addStrikethrough( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, + .load_flags = self.config.load_flags, }, ); @@ -2073,6 +2083,7 @@ fn addGlyph( .{ .grid_metrics = self.grid_metrics, .thicken = self.config.font_thicken, + .load_flags = self.config.load_flags, }, ); From 945a715b08d9955b759e06f0c7ce6726d4e2604f Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 00:41:55 +0100 Subject: [PATCH 02/13] refactor: handle freetype load flags in face instead of renderer --- src/config/Config.zig | 4 ++-- src/font/Collection.zig | 3 +++ src/font/SharedGridSet.zig | 7 +++++++ src/font/face.zig | 3 +-- src/font/face/freetype.zig | 15 ++++++++++----- src/renderer/Metal.zig | 12 +----------- src/renderer/OpenGL.zig | 12 +----------- 7 files changed, 25 insertions(+), 31 deletions(-) diff --git a/src/config/Config.zig b/src/config/Config.zig index 908935a5d..aef589571 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -305,7 +305,7 @@ const c = @cImport({ /// * `autohint` - Use the freetype auto-hinter. Enabled by default. /// /// Example: `hinting`, `no-hinting`, `force-autohint`, `no-force-autohint` -@"freetype-load-flag": FreetypeLoadFlags = .{}, +@"freetype-load-flags": FreetypeLoadFlags = .{}, /// A theme to use. If the theme is an absolute pathname, Ghostty will attempt /// to load that file as a theme. If that file does not exist or is inaccessible, @@ -4586,7 +4586,7 @@ pub const GraphemeWidthMethod = enum { }; /// See freetype-load-flag -pub const FreetypeLoadFlags = packed struct { +pub const FreetypeLoadFlags = packed struct { hinting: bool = true, bitmap: bool = true, @"force-autohint": bool = false, diff --git a/src/font/Collection.zig b/src/font/Collection.zig index 476787749..25615bde5 100644 --- a/src/font/Collection.zig +++ b/src/font/Collection.zig @@ -452,6 +452,8 @@ pub const LoadOptions = struct { /// for this is owned by the user and is not freed by the collection. metric_modifiers: Metrics.ModifierSet = .{}, + freetype_load_flags: config.Config.FreetypeLoadFlags = .{}, + pub fn deinit(self: *LoadOptions, alloc: Allocator) void { _ = self; _ = alloc; @@ -462,6 +464,7 @@ pub const LoadOptions = struct { return .{ .size = self.size, .metric_modifiers = &self.metric_modifiers, + .freetype_load_flags = self.freetype_load_flags, }; } }; diff --git a/src/font/SharedGridSet.zig b/src/font/SharedGridSet.zig index c3067fa6d..d4ad49a74 100644 --- a/src/font/SharedGridSet.zig +++ b/src/font/SharedGridSet.zig @@ -168,6 +168,7 @@ fn collection( .library = self.font_lib, .size = size, .metric_modifiers = key.metric_modifiers, + .freetype_load_flags = config.@"freetype-load-flags", }; var c = Collection.init(); @@ -427,6 +428,7 @@ pub const DerivedConfig = struct { @"adjust-strikethrough-position": ?Metrics.Modifier, @"adjust-strikethrough-thickness": ?Metrics.Modifier, @"adjust-cursor-thickness": ?Metrics.Modifier, + @"freetype-load-flags": configpkg.Config.FreetypeLoadFlags, /// Initialize a DerivedConfig. The config should be either a /// config.Config or another DerivedConfig to clone from. @@ -461,6 +463,7 @@ pub const DerivedConfig = struct { .@"adjust-strikethrough-position" = config.@"adjust-strikethrough-position", .@"adjust-strikethrough-thickness" = config.@"adjust-strikethrough-thickness", .@"adjust-cursor-thickness" = config.@"adjust-cursor-thickness", + .@"freetype-load-flags" = config.@"freetype-load-flags", // This must be last so the arena contains all our allocations // from above since Zig does assignment in order. @@ -500,6 +503,8 @@ pub const Key = struct { /// font grid. font_size: DesiredSize = .{ .points = 12 }, + load_flags: configpkg.Config.FreetypeLoadFlags = .{}, + const style_offsets_len = std.enums.directEnumArrayLen(Style, 0); const StyleOffsets = [style_offsets_len]usize; @@ -618,6 +623,7 @@ pub const Key = struct { .codepoint_map = codepoint_map, .metric_modifiers = metric_modifiers, .font_size = font_size, + .load_flags = config.@"freetype-load-flags", }; } @@ -647,6 +653,7 @@ pub const Key = struct { for (self.descriptors) |d| d.hash(hasher); self.codepoint_map.hash(hasher); autoHash(hasher, self.metric_modifiers.count()); + autoHash(hasher, self.load_flags); if (self.metric_modifiers.count() > 0) { inline for (@typeInfo(Metrics.Key).Enum.fields) |field| { const key = @field(Metrics.Key, field.name); diff --git a/src/font/face.zig b/src/font/face.zig index 77fb9e45b..d3fd89aa5 100644 --- a/src/font/face.zig +++ b/src/font/face.zig @@ -31,6 +31,7 @@ pub const default_dpi = if (builtin.os.tag == .macos) 72 else 96; pub const Options = struct { size: DesiredSize, metric_modifiers: ?*const Metrics.ModifierSet = null, + freetype_load_flags: FreetypeLoadFlags, }; /// The desired size for loading a font. @@ -91,8 +92,6 @@ pub const RenderOptions = struct { /// /// This only works with CoreText currently. thicken: bool = false, - - load_flags: FreetypeLoadFlags, }; test { diff --git a/src/font/face/freetype.zig b/src/font/face/freetype.zig index e3ad5322b..ac173d6dd 100644 --- a/src/font/face/freetype.zig +++ b/src/font/face/freetype.zig @@ -18,6 +18,7 @@ const Library = font.Library; const convert = @import("freetype_convert.zig"); const fastmem = @import("../../fastmem.zig"); const quirks = @import("../../quirks.zig"); +const FreetypeLoadFlags = @import("../../config/Config.zig").FreetypeLoadFlags; const log = std.log.scoped(.font_face); @@ -34,6 +35,9 @@ pub const Face = struct { /// Metrics for this font face. These are useful for renderers. metrics: font.face.Metrics, + /// Metrics for this font face. These are useful for renderers. + load_flags: FreetypeLoadFlags, + /// Set quirks.disableDefaultFontFeatures quirks_disable_default_font_features: bool = false, @@ -77,6 +81,7 @@ pub const Face = struct { .face = face, .hb_font = hb_font, .metrics = calcMetrics(face, opts.metric_modifiers), + .load_flags = opts.freetype_load_flags, }; result.quirks_disable_default_font_features = quirks.disableDefaultFontFeatures(&result); @@ -318,13 +323,13 @@ pub const Face = struct { // // This must be enabled for color faces though because those are // often colored bitmaps, which we support. - .no_bitmap = !self.face.hasColor() or !opts.load_flags.bitmap, + .no_bitmap = !self.face.hasColor() or !self.load_flags.bitmap, // use options from config - .no_hinting = !opts.load_flags.hinting, - .force_autohint = !opts.load_flags.@"force-autohint", - .monochrome = !opts.load_flags.monochrome, - .no_autohint = !opts.load_flags.autohint, + .no_hinting = !self.load_flags.hinting, + .force_autohint = !self.load_flags.@"force-autohint", + .monochrome = !self.load_flags.monochrome, + .no_autohint = !self.load_flags.autohint, }); const glyph = self.face.handle.*.glyph; diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index 561168b90..742dfbcd4 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -354,7 +354,6 @@ pub const DerivedConfig = struct { font_thicken: bool, font_features: std.ArrayListUnmanaged([:0]const u8), font_styles: font.CodepointResolver.StyleStatus, - load_flags: configpkg.Config.FreetypeLoadFlags, cursor_color: ?terminal.color.RGB, cursor_invert: bool, cursor_opacity: f64, @@ -400,14 +399,11 @@ pub const DerivedConfig = struct { const cursor_invert = config.@"cursor-invert-fg-bg"; - const load_flags = config.@"freetype-load-flag"; - return .{ .background_opacity = @max(0, @min(1, config.@"background-opacity")), .font_thicken = config.@"font-thicken", .font_features = font_features, .font_styles = font_styles, - .load_flags = load_flags, .cursor_color = if (!cursor_invert and config.@"cursor-color" != null) config.@"cursor-color".?.toTerminalRGB() @@ -2723,7 +2719,6 @@ fn addUnderline( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, - .load_flags = self.config.load_flags, }, ); @@ -2756,7 +2751,6 @@ fn addOverline( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, - .load_flags = self.config.load_flags, }, ); @@ -2789,7 +2783,6 @@ fn addStrikethrough( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, - .load_flags = self.config.load_flags, }, ); @@ -2829,7 +2822,6 @@ fn addGlyph( .{ .grid_metrics = self.grid_metrics, .thicken = self.config.font_thicken, - .load_flags = self.config.load_flags, }, ); @@ -2909,7 +2901,6 @@ fn addCursor( .{ .cell_width = if (wide) 2 else 1, .grid_metrics = self.grid_metrics, - .load_flags = self.config.load_flags, }, ) catch |err| { log.warn("error rendering cursor glyph err={}", .{err}); @@ -2925,7 +2916,6 @@ fn addCursor( .{ .cell_width = if (wide) 2 else 1, .grid_metrics = self.grid_metrics, - .load_flags = self.config.load_flags, }, ) catch |err| { log.warn("error rendering cursor glyph err={}", .{err}); @@ -2966,7 +2956,7 @@ fn addPreeditCell( @intCast(cp.codepoint), .regular, .text, - .{ .grid_metrics = self.grid_metrics, .load_flags = self.config.load_flags }, + .{ .grid_metrics = self.grid_metrics }, ) catch |err| { log.warn("error rendering preedit glyph err={}", .{err}); return; diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 7cb391bcc..9d1c1a27d 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -289,7 +289,6 @@ pub const DerivedConfig = struct { font_thicken: bool, font_features: std.ArrayListUnmanaged([:0]const u8), font_styles: font.CodepointResolver.StyleStatus, - load_flags: configpkg.Config.FreetypeLoadFlags, cursor_color: ?terminal.color.RGB, cursor_invert: bool, cursor_text: ?terminal.color.RGB, @@ -334,14 +333,11 @@ pub const DerivedConfig = struct { const cursor_invert = config.@"cursor-invert-fg-bg"; - const load_flags = config.@"freetype-load-flag"; - return .{ .background_opacity = @max(0, @min(1, config.@"background-opacity")), .font_thicken = config.@"font-thicken", .font_features = font_features, .font_styles = font_styles, - .load_flags = load_flags, .cursor_color = if (!cursor_invert and config.@"cursor-color" != null) config.@"cursor-color".?.toTerminalRGB() @@ -1770,7 +1766,7 @@ fn addPreeditCell( @intCast(cp.codepoint), .regular, .text, - .{ .grid_metrics = self.grid_metrics, .load_flags = self.config.load_flags }, + .{ .grid_metrics = self.grid_metrics }, ) catch |err| { log.warn("error rendering preedit glyph err={}", .{err}); return; @@ -1871,7 +1867,6 @@ fn addCursor( .{ .cell_width = if (wide) 2 else 1, .grid_metrics = self.grid_metrics, - .load_flags = self.config.load_flags, }, ) catch |err| { log.warn("error rendering cursor glyph err={}", .{err}); @@ -1887,7 +1882,6 @@ fn addCursor( .{ .cell_width = if (wide) 2 else 1, .grid_metrics = self.grid_metrics, - .load_flags = self.config.load_flags, }, ) catch |err| { log.warn("error rendering cursor glyph err={}", .{err}); @@ -1950,7 +1944,6 @@ fn addUnderline( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, - .load_flags = self.config.load_flags, }, ); @@ -1992,7 +1985,6 @@ fn addOverline( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, - .load_flags = self.config.load_flags, }, ); @@ -2034,7 +2026,6 @@ fn addStrikethrough( .{ .cell_width = 1, .grid_metrics = self.grid_metrics, - .load_flags = self.config.load_flags, }, ); @@ -2083,7 +2074,6 @@ fn addGlyph( .{ .grid_metrics = self.grid_metrics, .thicken = self.config.font_thicken, - .load_flags = self.config.load_flags, }, ); From 290857a87171d82e5c1e206fce490a8069f5dacc Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 00:44:19 +0100 Subject: [PATCH 03/13] chore: remove unused import --- src/renderer/OpenGL.zig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 9d1c1a27d..5313315b1 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -11,7 +11,6 @@ const ArenaAllocator = std.heap.ArenaAllocator; const link = @import("link.zig"); const isCovering = @import("cell.zig").isCovering; const fgMode = @import("cell.zig").fgMode; -const freetype = @import("freetype").Face; const shadertoy = @import("shadertoy.zig"); const apprt = @import("../apprt.zig"); const configpkg = @import("../config.zig"); From c0b24ee60d65bee135dea7c99ad9446e9649a574 Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 01:35:39 +0100 Subject: [PATCH 04/13] refactor: make freetype flags void for non-freetype backend This is an attempt to use `void` as type for Freetype Load Flags when backend does not use these flags. --- src/config.zig | 14 ++++++++++++++ src/font/Collection.zig | 13 ++++++++++++- src/font/SharedGridSet.zig | 28 +++++++++++++++++++++++++--- src/font/face.zig | 4 ++-- src/font/face/freetype.zig | 4 ++-- 5 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/config.zig b/src/config.zig index b9f214fc9..f2d4876ae 100644 --- a/src/config.zig +++ b/src/config.zig @@ -1,6 +1,8 @@ const builtin = @import("builtin"); const formatter = @import("config/formatter.zig"); +const font = @import("font/main.zig"); +const options = font.options; pub const Config = @import("config/Config.zig"); pub const string = @import("config/string.zig"); pub const edit = @import("config/edit.zig"); @@ -9,6 +11,18 @@ pub const url = @import("config/url.zig"); pub const FileFormatter = formatter.FileFormatter; pub const entryFormatter = formatter.entryFormatter; pub const formatEntry = formatter.formatEntry; +pub const FreetypeLoadFlags = switch (options.backend) { + .freetype, + .fontconfig_freetype, + .coretext_freetype, + => Config.FreetypeLoadFlags, + + .coretext, + .coretext_harfbuzz, + .coretext_noshape, + .web_canvas, + => void, +}; // Field types pub const ClipboardAccess = Config.ClipboardAccess; diff --git a/src/font/Collection.zig b/src/font/Collection.zig index 25615bde5..b65b4bd2e 100644 --- a/src/font/Collection.zig +++ b/src/font/Collection.zig @@ -452,7 +452,18 @@ pub const LoadOptions = struct { /// for this is owned by the user and is not freed by the collection. metric_modifiers: Metrics.ModifierSet = .{}, - freetype_load_flags: config.Config.FreetypeLoadFlags = .{}, + freetype_load_flags: config.FreetypeLoadFlags = switch (font.options.backend) { + .freetype, + .fontconfig_freetype, + .coretext_freetype, + => .{}, + + .coretext, + .coretext_harfbuzz, + .coretext_noshape, + .web_canvas, + => {}, + }, pub fn deinit(self: *LoadOptions, alloc: Allocator) void { _ = self; diff --git a/src/font/SharedGridSet.zig b/src/font/SharedGridSet.zig index d4ad49a74..49886c8f2 100644 --- a/src/font/SharedGridSet.zig +++ b/src/font/SharedGridSet.zig @@ -428,7 +428,7 @@ pub const DerivedConfig = struct { @"adjust-strikethrough-position": ?Metrics.Modifier, @"adjust-strikethrough-thickness": ?Metrics.Modifier, @"adjust-cursor-thickness": ?Metrics.Modifier, - @"freetype-load-flags": configpkg.Config.FreetypeLoadFlags, + @"freetype-load-flags": configpkg.FreetypeLoadFlags, /// Initialize a DerivedConfig. The config should be either a /// config.Config or another DerivedConfig to clone from. @@ -463,7 +463,18 @@ pub const DerivedConfig = struct { .@"adjust-strikethrough-position" = config.@"adjust-strikethrough-position", .@"adjust-strikethrough-thickness" = config.@"adjust-strikethrough-thickness", .@"adjust-cursor-thickness" = config.@"adjust-cursor-thickness", - .@"freetype-load-flags" = config.@"freetype-load-flags", + .@"freetype-load-flags" = switch (font.options.backend) { + .freetype, + .fontconfig_freetype, + .coretext_freetype, + => config.@"freetype-load-flags", + + .coretext, + .coretext_harfbuzz, + .coretext_noshape, + .web_canvas, + => {}, + }, // This must be last so the arena contains all our allocations // from above since Zig does assignment in order. @@ -503,7 +514,18 @@ pub const Key = struct { /// font grid. font_size: DesiredSize = .{ .points = 12 }, - load_flags: configpkg.Config.FreetypeLoadFlags = .{}, + load_flags: configpkg.FreetypeLoadFlags = switch (font.options.backend) { + .freetype, + .fontconfig_freetype, + .coretext_freetype, + => .{}, + + .coretext, + .coretext_harfbuzz, + .coretext_noshape, + .web_canvas, + => {}, + }, const style_offsets_len = std.enums.directEnumArrayLen(Style, 0); const StyleOffsets = [style_offsets_len]usize; diff --git a/src/font/face.zig b/src/font/face.zig index d3fd89aa5..663a86672 100644 --- a/src/font/face.zig +++ b/src/font/face.zig @@ -2,7 +2,7 @@ const std = @import("std"); const builtin = @import("builtin"); const options = @import("main.zig").options; pub const Metrics = @import("face/Metrics.zig"); -const FreetypeLoadFlags = @import("../config/Config.zig").FreetypeLoadFlags; +const config = @import("../config.zig"); const freetype = @import("face/freetype.zig"); const coretext = @import("face/coretext.zig"); pub const web_canvas = @import("face/web_canvas.zig"); @@ -31,7 +31,7 @@ pub const default_dpi = if (builtin.os.tag == .macos) 72 else 96; pub const Options = struct { size: DesiredSize, metric_modifiers: ?*const Metrics.ModifierSet = null, - freetype_load_flags: FreetypeLoadFlags, + freetype_load_flags: config.FreetypeLoadFlags, }; /// The desired size for loading a font. diff --git a/src/font/face/freetype.zig b/src/font/face/freetype.zig index ac173d6dd..2715d664a 100644 --- a/src/font/face/freetype.zig +++ b/src/font/face/freetype.zig @@ -18,7 +18,7 @@ const Library = font.Library; const convert = @import("freetype_convert.zig"); const fastmem = @import("../../fastmem.zig"); const quirks = @import("../../quirks.zig"); -const FreetypeLoadFlags = @import("../../config/Config.zig").FreetypeLoadFlags; +const config = @import("../../config.zig"); const log = std.log.scoped(.font_face); @@ -36,7 +36,7 @@ pub const Face = struct { metrics: font.face.Metrics, /// Metrics for this font face. These are useful for renderers. - load_flags: FreetypeLoadFlags, + load_flags: config.FreetypeLoadFlags, /// Set quirks.disableDefaultFontFeatures quirks_disable_default_font_features: bool = false, From e7f286d83fc5d43be519abd0e21a03fadb43377f Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 01:40:39 +0100 Subject: [PATCH 05/13] docs: describe `load_flags` field in `Face` struct --- src/font/face/freetype.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/font/face/freetype.zig b/src/font/face/freetype.zig index 2715d664a..5bbbb246b 100644 --- a/src/font/face/freetype.zig +++ b/src/font/face/freetype.zig @@ -35,7 +35,7 @@ pub const Face = struct { /// Metrics for this font face. These are useful for renderers. metrics: font.face.Metrics, - /// Metrics for this font face. These are useful for renderers. + /// Freetype load flags for this font face. load_flags: config.FreetypeLoadFlags, /// Set quirks.disableDefaultFontFeatures From 83c4d0077b7a06d487057fca3bddcc8a3685ed03 Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 11:55:29 +0100 Subject: [PATCH 06/13] refactor: define `FreetypeLoadFlags` struct and default in `font.face` --- src/config.zig | 12 ------------ src/font/Collection.zig | 13 +------------ src/font/SharedGridSet.zig | 15 ++------------- src/font/face.zig | 16 +++++++++++++++- src/font/face/freetype.zig | 2 +- 5 files changed, 19 insertions(+), 39 deletions(-) diff --git a/src/config.zig b/src/config.zig index f2d4876ae..08d93a6a3 100644 --- a/src/config.zig +++ b/src/config.zig @@ -11,18 +11,6 @@ pub const url = @import("config/url.zig"); pub const FileFormatter = formatter.FileFormatter; pub const entryFormatter = formatter.entryFormatter; pub const formatEntry = formatter.formatEntry; -pub const FreetypeLoadFlags = switch (options.backend) { - .freetype, - .fontconfig_freetype, - .coretext_freetype, - => Config.FreetypeLoadFlags, - - .coretext, - .coretext_harfbuzz, - .coretext_noshape, - .web_canvas, - => void, -}; // Field types pub const ClipboardAccess = Config.ClipboardAccess; diff --git a/src/font/Collection.zig b/src/font/Collection.zig index b65b4bd2e..478c39ded 100644 --- a/src/font/Collection.zig +++ b/src/font/Collection.zig @@ -452,18 +452,7 @@ pub const LoadOptions = struct { /// for this is owned by the user and is not freed by the collection. metric_modifiers: Metrics.ModifierSet = .{}, - freetype_load_flags: config.FreetypeLoadFlags = switch (font.options.backend) { - .freetype, - .fontconfig_freetype, - .coretext_freetype, - => .{}, - - .coretext, - .coretext_harfbuzz, - .coretext_noshape, - .web_canvas, - => {}, - }, + freetype_load_flags: font.face.FreetypeLoadFlags = font.face.freetype_load_flags_default, pub fn deinit(self: *LoadOptions, alloc: Allocator) void { _ = self; diff --git a/src/font/SharedGridSet.zig b/src/font/SharedGridSet.zig index 49886c8f2..6459435a1 100644 --- a/src/font/SharedGridSet.zig +++ b/src/font/SharedGridSet.zig @@ -428,7 +428,7 @@ pub const DerivedConfig = struct { @"adjust-strikethrough-position": ?Metrics.Modifier, @"adjust-strikethrough-thickness": ?Metrics.Modifier, @"adjust-cursor-thickness": ?Metrics.Modifier, - @"freetype-load-flags": configpkg.FreetypeLoadFlags, + @"freetype-load-flags": font.face.FreetypeLoadFlags, /// Initialize a DerivedConfig. The config should be either a /// config.Config or another DerivedConfig to clone from. @@ -514,18 +514,7 @@ pub const Key = struct { /// font grid. font_size: DesiredSize = .{ .points = 12 }, - load_flags: configpkg.FreetypeLoadFlags = switch (font.options.backend) { - .freetype, - .fontconfig_freetype, - .coretext_freetype, - => .{}, - - .coretext, - .coretext_harfbuzz, - .coretext_noshape, - .web_canvas, - => {}, - }, + load_flags: configpkg.FreetypeLoadFlags = font.face.freetype_load_flags_default, const style_offsets_len = std.enums.directEnumArrayLen(Style, 0); const StyleOffsets = [style_offsets_len]usize; diff --git a/src/font/face.zig b/src/font/face.zig index 663a86672..24c9b0422 100644 --- a/src/font/face.zig +++ b/src/font/face.zig @@ -27,11 +27,25 @@ pub const Face = switch (options.backend) { /// using whatever platform method you can. pub const default_dpi = if (builtin.os.tag == .macos) 72 else 96; +pub const FreetypeLoadFlags = switch (options.backend) { + .freetype, + .fontconfig_freetype, + .coretext_freetype, + => config.Config.FreetypeLoadFlags, + + .coretext, + .coretext_harfbuzz, + .coretext_noshape, + .web_canvas, + => void, +}; +pub const freetype_load_flags_default = if (options.backend.hasFreetype()) .{} else {}; + /// Options for initializing a font face. pub const Options = struct { size: DesiredSize, metric_modifiers: ?*const Metrics.ModifierSet = null, - freetype_load_flags: config.FreetypeLoadFlags, + freetype_load_flags: FreetypeLoadFlags, }; /// The desired size for loading a font. diff --git a/src/font/face/freetype.zig b/src/font/face/freetype.zig index 5bbbb246b..8a1465d7e 100644 --- a/src/font/face/freetype.zig +++ b/src/font/face/freetype.zig @@ -36,7 +36,7 @@ pub const Face = struct { metrics: font.face.Metrics, /// Freetype load flags for this font face. - load_flags: config.FreetypeLoadFlags, + load_flags: font.face.FreetypeLoadFlags, /// Set quirks.disableDefaultFontFeatures quirks_disable_default_font_features: bool = false, From 0e0751ad5b82c9926dd6fabd127edb086a915a9e Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 12:34:45 +0100 Subject: [PATCH 07/13] docs: write documentation for `freetype_load_flags` field --- src/font/Collection.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/font/Collection.zig b/src/font/Collection.zig index 478c39ded..f79c80936 100644 --- a/src/font/Collection.zig +++ b/src/font/Collection.zig @@ -452,6 +452,10 @@ pub const LoadOptions = struct { /// for this is owned by the user and is not freed by the collection. metric_modifiers: Metrics.ModifierSet = .{}, + /// Freetype Load Flags to use when loading glyphs. This is a list of + /// bitfield constants that controls operations to perform during glyph + /// loading. Only a subset is exposed for configuration, for the whole set + /// of flags see `pkg.freetype.face.LoadFlags`. freetype_load_flags: font.face.FreetypeLoadFlags = font.face.freetype_load_flags_default, pub fn deinit(self: *LoadOptions, alloc: Allocator) void { From 08720a6d23d71c9b4fd8ae5324a205122e6809b9 Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 12:49:53 +0100 Subject: [PATCH 08/13] chore: fix typo --- src/config/Config.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/Config.zig b/src/config/Config.zig index aef589571..4cc943859 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -290,7 +290,7 @@ const c = @cImport({ /// Freetype load flags to enable. The format of this is a list of flags to /// enable separated by commas. If you prefix a flag with `no-` then it is /// disabled. If you omit a flag, it's default value is used, so you must -/// explicitely disable flags you don't want. You can also use `true` or `false` +/// explicitly disable flags you don't want. You can also use `true` or `false` /// to turn all flags on or off. /// /// Available flags: From 4c086882758f0e855e2cfecddea44a105d575b84 Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 12:50:51 +0100 Subject: [PATCH 09/13] refactor: remove unused imports --- src/config.zig | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/config.zig b/src/config.zig index 08d93a6a3..b9f214fc9 100644 --- a/src/config.zig +++ b/src/config.zig @@ -1,8 +1,6 @@ const builtin = @import("builtin"); const formatter = @import("config/formatter.zig"); -const font = @import("font/main.zig"); -const options = font.options; pub const Config = @import("config/Config.zig"); pub const string = @import("config/string.zig"); pub const edit = @import("config/edit.zig"); From 69aa579ee3bc4a42ba7c3f4f86d83d4c46b52711 Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 12:51:28 +0100 Subject: [PATCH 10/13] fix: use ternary if expression and correct types --- src/font/SharedGridSet.zig | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/font/SharedGridSet.zig b/src/font/SharedGridSet.zig index 6459435a1..72bca7277 100644 --- a/src/font/SharedGridSet.zig +++ b/src/font/SharedGridSet.zig @@ -463,18 +463,7 @@ pub const DerivedConfig = struct { .@"adjust-strikethrough-position" = config.@"adjust-strikethrough-position", .@"adjust-strikethrough-thickness" = config.@"adjust-strikethrough-thickness", .@"adjust-cursor-thickness" = config.@"adjust-cursor-thickness", - .@"freetype-load-flags" = switch (font.options.backend) { - .freetype, - .fontconfig_freetype, - .coretext_freetype, - => config.@"freetype-load-flags", - - .coretext, - .coretext_harfbuzz, - .coretext_noshape, - .web_canvas, - => {}, - }, + .@"freetype-load-flags" = if (comptime font.options.backend.hasFreetype()) config.@"freetype-load-flags" else {}, // This must be last so the arena contains all our allocations // from above since Zig does assignment in order. @@ -514,7 +503,7 @@ pub const Key = struct { /// font grid. font_size: DesiredSize = .{ .points = 12 }, - load_flags: configpkg.FreetypeLoadFlags = font.face.freetype_load_flags_default, + load_flags: font.face.FreetypeLoadFlags = font.face.freetype_load_flags_default, const style_offsets_len = std.enums.directEnumArrayLen(Style, 0); const StyleOffsets = [style_offsets_len]usize; From 67966cb09189a05afa169e486f23e6cc1a57f7e6 Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 13:06:36 +0100 Subject: [PATCH 11/13] refactor: add default value for `freetype_load_flags' --- src/font/face.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/font/face.zig b/src/font/face.zig index 24c9b0422..991bfb7e0 100644 --- a/src/font/face.zig +++ b/src/font/face.zig @@ -45,7 +45,7 @@ pub const freetype_load_flags_default = if (options.backend.hasFreetype()) .{} e pub const Options = struct { size: DesiredSize, metric_modifiers: ?*const Metrics.ModifierSet = null, - freetype_load_flags: FreetypeLoadFlags, + freetype_load_flags: FreetypeLoadFlags = freetype_load_flags_default, }; /// The desired size for loading a font. From 4def80ce1670f522ee87932e53eb9238a59f0caf Mon Sep 17 00:00:00 2001 From: Nadir Fejzic Date: Sat, 9 Nov 2024 13:09:15 +0100 Subject: [PATCH 12/13] refactor: use if expression instead of switch --- src/font/face.zig | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/font/face.zig b/src/font/face.zig index 991bfb7e0..7b51d660c 100644 --- a/src/font/face.zig +++ b/src/font/face.zig @@ -27,18 +27,7 @@ pub const Face = switch (options.backend) { /// using whatever platform method you can. pub const default_dpi = if (builtin.os.tag == .macos) 72 else 96; -pub const FreetypeLoadFlags = switch (options.backend) { - .freetype, - .fontconfig_freetype, - .coretext_freetype, - => config.Config.FreetypeLoadFlags, - - .coretext, - .coretext_harfbuzz, - .coretext_noshape, - .web_canvas, - => void, -}; +pub const FreetypeLoadFlags = if (options.backend.hasFreetype()) config.Config.FreetypeLoadFlags else void; pub const freetype_load_flags_default = if (options.backend.hasFreetype()) .{} else {}; /// Options for initializing a font face. From 3ee6577154b8b78e4113dbaec4c153ee1535e073 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 9 Nov 2024 09:37:03 -0800 Subject: [PATCH 13/13] some tweaks --- src/config.zig | 1 + src/config/Config.zig | 25 +++++++++++++++---------- src/font/SharedGridSet.zig | 15 ++++++++++----- src/font/face.zig | 9 +++++++-- src/font/face/freetype.zig | 7 ++++++- 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/config.zig b/src/config.zig index b9f214fc9..5af7832dd 100644 --- a/src/config.zig +++ b/src/config.zig @@ -16,6 +16,7 @@ pub const CopyOnSelect = Config.CopyOnSelect; pub const CustomShaderAnimation = Config.CustomShaderAnimation; pub const FontSyntheticStyle = Config.FontSyntheticStyle; pub const FontStyle = Config.FontStyle; +pub const FreetypeLoadFlags = Config.FreetypeLoadFlags; pub const Keybinds = Config.Keybinds; pub const MouseShiftCapture = Config.MouseShiftCapture; pub const NonNativeFullscreen = Config.NonNativeFullscreen; diff --git a/src/config/Config.zig b/src/config/Config.zig index 4cc943859..d8f007435 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -287,21 +287,24 @@ const c = @cImport({ /// terminals. Only new terminals will use the new configuration. @"grapheme-width-method": GraphemeWidthMethod = .unicode, -/// Freetype load flags to enable. The format of this is a list of flags to +/// FreeType load flags to enable. The format of this is a list of flags to /// enable separated by commas. If you prefix a flag with `no-` then it is /// disabled. If you omit a flag, it's default value is used, so you must /// explicitly disable flags you don't want. You can also use `true` or `false` /// to turn all flags on or off. /// +/// This configuration only applies to Ghostty builds that use FreeType. +/// This is usually the case only for Linux builds. macOS uses CoreText +/// and does not have an equivalent configuration. +/// /// Available flags: /// /// * `hinting` - Enable or disable hinting, enabled by default. -/// * `bitmap` - Enable or disable loading of any pre-rendered bitmap strikes, -/// enabled by default -/// * `force-autohint` - Use the freetype auto-hinter rather than the font's -/// native hinter. Enabled by default. -/// * `monochrome` - Instructs renderer to use 1-bit monochrome rendering. -/// This option doesn't impact the hinter. Enabled by default. +/// * `force-autohint` - Use the freetype auto-hinter rather than the +/// font's native hinter. Enabled by default. +/// * `monochrome` - Instructs renderer to use 1-bit monochrome +/// rendering. This option doesn't impact the hinter. +/// Enabled by default. /// * `autohint` - Use the freetype auto-hinter. Enabled by default. /// /// Example: `hinting`, `no-hinting`, `force-autohint`, `no-force-autohint` @@ -4587,10 +4590,12 @@ pub const GraphemeWidthMethod = enum { /// See freetype-load-flag pub const FreetypeLoadFlags = packed struct { + // The defaults here at the time of writing this match the defaults + // for Freetype itself. Ghostty hasn't made any opinionated changes + // to these defaults. hinting: bool = true, - bitmap: bool = true, - @"force-autohint": bool = false, - monochrome: bool = false, + @"force-autohint": bool = true, + monochrome: bool = true, autohint: bool = true, }; diff --git a/src/font/SharedGridSet.zig b/src/font/SharedGridSet.zig index 72bca7277..ac2fcbf8a 100644 --- a/src/font/SharedGridSet.zig +++ b/src/font/SharedGridSet.zig @@ -168,7 +168,7 @@ fn collection( .library = self.font_lib, .size = size, .metric_modifiers = key.metric_modifiers, - .freetype_load_flags = config.@"freetype-load-flags", + .freetype_load_flags = key.freetype_load_flags, }; var c = Collection.init(); @@ -463,7 +463,7 @@ pub const DerivedConfig = struct { .@"adjust-strikethrough-position" = config.@"adjust-strikethrough-position", .@"adjust-strikethrough-thickness" = config.@"adjust-strikethrough-thickness", .@"adjust-cursor-thickness" = config.@"adjust-cursor-thickness", - .@"freetype-load-flags" = if (comptime font.options.backend.hasFreetype()) config.@"freetype-load-flags" else {}, + .@"freetype-load-flags" = if (font.face.FreetypeLoadFlags != void) config.@"freetype-load-flags" else {}, // This must be last so the arena contains all our allocations // from above since Zig does assignment in order. @@ -503,7 +503,9 @@ pub const Key = struct { /// font grid. font_size: DesiredSize = .{ .points = 12 }, - load_flags: font.face.FreetypeLoadFlags = font.face.freetype_load_flags_default, + /// The freetype load flags configuration, only non-void if the + /// freetype backend is enabled. + freetype_load_flags: font.face.FreetypeLoadFlags = font.face.freetype_load_flags_default, const style_offsets_len = std.enums.directEnumArrayLen(Style, 0); const StyleOffsets = [style_offsets_len]usize; @@ -623,7 +625,10 @@ pub const Key = struct { .codepoint_map = codepoint_map, .metric_modifiers = metric_modifiers, .font_size = font_size, - .load_flags = config.@"freetype-load-flags", + .freetype_load_flags = if (font.face.FreetypeLoadFlags != void) + config.@"freetype-load-flags" + else + font.face.freetype_load_flags_default, }; } @@ -653,7 +658,7 @@ pub const Key = struct { for (self.descriptors) |d| d.hash(hasher); self.codepoint_map.hash(hasher); autoHash(hasher, self.metric_modifiers.count()); - autoHash(hasher, self.load_flags); + autoHash(hasher, self.freetype_load_flags); if (self.metric_modifiers.count() > 0) { inline for (@typeInfo(Metrics.Key).Enum.fields) |field| { const key = @field(Metrics.Key, field.name); diff --git a/src/font/face.zig b/src/font/face.zig index 7b51d660c..9f80c5637 100644 --- a/src/font/face.zig +++ b/src/font/face.zig @@ -27,8 +27,13 @@ pub const Face = switch (options.backend) { /// using whatever platform method you can. pub const default_dpi = if (builtin.os.tag == .macos) 72 else 96; -pub const FreetypeLoadFlags = if (options.backend.hasFreetype()) config.Config.FreetypeLoadFlags else void; -pub const freetype_load_flags_default = if (options.backend.hasFreetype()) .{} else {}; +/// These are the flags to customize how freetype loads fonts. This is +/// only non-void if the freetype backend is enabled. +pub const FreetypeLoadFlags = if (options.backend.hasFreetype()) + config.FreetypeLoadFlags +else + void; +pub const freetype_load_flags_default = if (FreetypeLoadFlags != void) .{} else {}; /// Options for initializing a font face. pub const Options = struct { diff --git a/src/font/face/freetype.zig b/src/font/face/freetype.zig index 8a1465d7e..683f80cc8 100644 --- a/src/font/face/freetype.zig +++ b/src/font/face/freetype.zig @@ -23,6 +23,11 @@ const config = @import("../../config.zig"); const log = std.log.scoped(.font_face); pub const Face = struct { + comptime { + // If we have the freetype backend, we should have load flags. + assert(font.face.FreetypeLoadFlags != void); + } + /// Our freetype library lib: freetype.Library, @@ -323,7 +328,7 @@ pub const Face = struct { // // This must be enabled for color faces though because those are // often colored bitmaps, which we support. - .no_bitmap = !self.face.hasColor() or !self.load_flags.bitmap, + .no_bitmap = !self.face.hasColor(), // use options from config .no_hinting = !self.load_flags.hinting,