From 1551e409c31992437cb2fa864f576d45c8433801 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Sun, 16 Aug 2026 15:49:12 -0300 Subject: big slow change: prebuilt shaders (SPIR-V/Metal), core gui reflow, docs, web + snapshot refresh --- src/fonts.zig | 46 ++++++++++++++-------------------------------- 1 file changed, 14 insertions(+), 32 deletions(-) (limited to 'src/fonts.zig') diff --git a/src/fonts.zig b/src/fonts.zig index 1e82956e..4cfba44c 100644 --- a/src/fonts.zig +++ b/src/fonts.zig @@ -58,29 +58,6 @@ const max_depth = 8; pub const Font = struct { name: []const u8, path: []const u8 }; -/// The font the shell should be wearing, as a PATH — written by the Font -/// builtin, taken by the shell on its next pass through the loop. Exactly the -/// shape Pardes.restore_req has, including the buffer behind it: the request -/// outlives the scratch arena the walk found the path in. -/// -/// A module var rather than a field on Pardes because the core does not have a -/// font, has no opinion about one, and on every other platform does not have -/// this file either — a field would be state the tty build carries around to -/// never touch. -pub var want_buf: [4096]u8 = undefined; -pub var want: ?[]const u8 = null; - -/// ...and the same request as a NAME, for the Debug overlay to show. A slice -/// of `want_buf` rather than a second buffer: the stem of the path IS the name -/// the picker listed, and the only writer of one is the writer of the other. -/// -/// What was CHOSEN, not what is worn: the shell may turn a file down (gui.zig -/// keeps the face that works when FreeType refuses one) and it alone knows -/// what it booted in — embedded Adwaita Mono under SDL, the system monospace -/// face under AppKit. Empty means nothing has been chosen and the shell is -/// still wearing whichever of those it is. -pub var chosen: []const u8 = ""; - /// Optional fallback faces, in preference order after the always-available /// embedded Adwaita Mono face. Keep text faces before symbol faces so ordinary /// letters retain terminal-like metrics; DejaVu Sans is the final broad, @@ -99,22 +76,27 @@ pub const fallback_names = [_][]const u8{ pub fn list(arena: std.mem.Allocator, want_name: ?[]const u8) []const Font { if (want_name) |name| { const wanted = [1][]const u8{name}; - return scan(arena, &wanted); + return scan(arena, &wanted, true); } - return scan(arena, null); + return scan(arena, null, true); } /// Installed members of `fallback_names`, returned in preference order. This /// is runtime discovery only: no local font path or exploration result enters /// the build, and a machine with none simply uses embedded Adwaita Mono. pub fn fallbacks(arena: std.mem.Allocator) []const Font { - return scan(arena, &fallback_names); + return scan(arena, &fallback_names, false); } /// One bounded directory walk for the picker, one named font, or the fallback -/// chain. `wanted == null` means every monospace face; named scans accept -/// proportional symbol/general faces and preserve the requested priority. -fn scan(arena: std.mem.Allocator, wanted: ?[]const []const u8) []const Font { +/// chain. User-facing lists always require a fixed-pitch face, including an +/// exact `Font ` request. The fallback chain opts out deliberately so a +/// broad symbol face may fill glyphs the primary grid face does not contain. +fn scan( + arena: std.mem.Allocator, + wanted: ?[]const []const u8, + require_monospaced: bool, +) []const Font { // ...from the arena, not the stack: 4096 faces of {name, path} is 128 KiB, // which is a fine thing to hand back to an arena that resets at the end of // the keystroke and not a thing to put on a call stack. An allocator that @@ -123,8 +105,8 @@ fn scan(arena: std.mem.Allocator, wanted: ?[]const []const u8) []const Font { const found = arena.alloc(Font, max_fonts) catch return &.{}; var found_len: usize = 0; // Zig 0.16 moved the filesystem behind std.Io; the blocking - // single-threaded implementation is the synchronous walk a sans-IO core - // wants, the same one look.find uses. + // single-threaded implementation is the synchronous walk the core uses, + // the same one look.find uses. const io = std.Io.Threaded.global_single_threaded.io(); const home: []const u8 = if (libc.getenv("HOME")) |h| std.mem.span(h) else ""; var root_buf: [512]u8 = undefined; @@ -179,7 +161,7 @@ fn scan(arena: std.mem.Allocator, wanted: ?[]const []const u8) []const Font { // e.path points into the walker's own buffer and dies at the next // next(), so the path is spelled out here and copied below const path = std.fmt.bufPrintSentinel(&path_buf, "{s}/{s}", .{ root, e.path }, 0) catch continue; - if (wanted == null and !monospaced(path)) continue; + if (require_monospaced and !monospaced(path)) continue; found[found_len] = .{ .name = arena.dupe(u8, name) catch break, .path = arena.dupe(u8, path) catch break, -- cgit v1.3