diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-10 21:51:57 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-10 21:51:57 +0300 |
| commit | 425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch) | |
| tree | e52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/font/discovery.zig | |
| parent | 90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff) | |
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/src/font/discovery.zig')
| -rw-r--r-- | vendor/libghostty-vt/src/font/discovery.zig | 85 |
1 files changed, 76 insertions, 9 deletions
diff --git a/vendor/libghostty-vt/src/font/discovery.zig b/vendor/libghostty-vt/src/font/discovery.zig index b945aa01..1847693a 100644 --- a/vendor/libghostty-vt/src/font/discovery.zig +++ b/vendor/libghostty-vt/src/font/discovery.zig @@ -12,6 +12,7 @@ const Face = @import("main.zig").Face; const Library = @import("main.zig").Library; const Presentation = @import("main.zig").Presentation; const Variation = @import("main.zig").face.Variation; +const global = @import("../global.zig"); const log = std.log.scoped(.discovery); @@ -349,6 +350,22 @@ pub const CoreText = struct { _ = self; } + /// Warm up the system font registry. + /// + /// The first CoreText query in a process initializes the system font + /// database, which takes multiple milliseconds, while subsequent + /// queries are microseconds. + pub fn warmup() void { + const name = macos.foundation.String.createWithBytes( + "AppleColorEmoji", + .utf8, + false, + ) catch return; + defer name.release(); + const ct_font = macos.text.Font.createWithName(name, 12) catch return; + ct_font.release(); + } + /// Discover fonts from a descriptor. This returns an iterator that can /// be used to build up the deferred fonts. pub fn discover(self: *const CoreText, alloc: Allocator, desc: Descriptor) !DiscoverIterator { @@ -382,6 +399,54 @@ pub const CoreText = struct { }; } + /// Discover a font by its exact name (family, full, or PostScript + /// name). This is significantly faster than `discover` because it + /// avoids the system-wide font matching that CTFontCollection does + /// (which takes multiple milliseconds). This should be preferred + /// when the desired font is known exactly, e.g. system fonts such + /// as Apple Color Emoji. + /// + /// Returns null if no font with this exact family name exists; + /// CoreText fallback fonts are never returned. + pub fn discoverExactFamily( + self: *const CoreText, + family: []const u8, + ) !?DeferredFace { + _ = self; + + const family_str = try macos.foundation.String.createWithBytes( + family, + .utf8, + false, + ); + defer family_str.release(); + + // Create our font. We need a size to initialize it so we use size + // 12 but we will alter the size later (same as DiscoverIterator). + const ct_font = try macos.text.Font.createWithName(family_str, 12); + + // CTFontCreateWithName never returns null: if the requested font + // isn't installed it returns a substitute font. Verify we got + // the family we asked for, otherwise report not found. + const found: bool = found: { + const actual = ct_font.copyFamilyName(); + defer actual.release(); + var buf: [256]u8 = undefined; + const actual_slice = actual.cstring(&buf, .utf8) orelse + break :found false; + break :found std.mem.eql(u8, actual_slice, family); + }; + if (!found) { + ct_font.release(); + return null; + } + + return .{ .ct = .{ + .font = ct_font, + .variations = &.{}, + } }; + } + pub fn discoverFallback( self: *const CoreText, alloc: Allocator, @@ -942,15 +1007,15 @@ pub const Windows = struct { desc: Descriptor, variations: []const Variation, state: State, - dir: ?std.fs.Dir, - iter: ?std.fs.Dir.Iterator, + dir: ?std.Io.Dir, + iter: ?std.Io.Dir.Iterator, system_path: ?[:0]const u8, user_path: ?[:0]const u8, const State = enum { system, user, done }; pub fn deinit(self: *DiscoverIterator) void { - if (self.dir) |*d| d.close(); + if (self.dir) |*d| d.close(global.io()); if (self.system_path) |p| self.alloc.free(p); if (self.user_path) |p| self.alloc.free(p); self.* = undefined; @@ -967,7 +1032,8 @@ pub const Windows = struct { continue; }; self.system_path = path; - self.dir = std.fs.openDirAbsoluteZ( + self.dir = std.Io.Dir.openDirAbsolute( + global.io(), path, .{ .iterate = true }, ) catch { @@ -982,7 +1048,8 @@ pub const Windows = struct { continue; }; self.user_path = path; - self.dir = std.fs.openDirAbsoluteZ( + self.dir = std.Io.Dir.openDirAbsolute( + global.io(), path, .{ .iterate = true }, ) catch { @@ -995,9 +1062,9 @@ pub const Windows = struct { } } - const entry = (self.iter.?.next() catch null) orelse { + const entry = (self.iter.?.next(global.io()) catch null) orelse { // Finished this directory; advance state. - if (self.dir) |*d| d.close(); + if (self.dir) |*d| d.close(global.io()); self.dir = null; self.iter = null; self.state = switch (self.state) { @@ -1020,7 +1087,7 @@ pub const Windows = struct { /// Windows install but we just skip the directory rather than /// falling back to a hardcoded drive letter. fn systemFontsPath(self: *DiscoverIterator) ?[:0]const u8 { - const systemroot = std.process.getEnvVarOwned( + const systemroot = global.environ().getAlloc( self.alloc, "SYSTEMROOT", ) catch return null; @@ -1034,7 +1101,7 @@ pub const Windows = struct { } fn userFontsPath(self: *DiscoverIterator) ?[:0]const u8 { - const local_appdata = std.process.getEnvVarOwned( + const local_appdata = global.environ().getAlloc( self.alloc, "LOCALAPPDATA", ) catch return null; |
