From 1cafd458287e790d893cffcb729a44cabba2cb04 Mon Sep 17 00:00:00 2001 From: Daniel Wennberg Date: Fri, 11 Jul 2025 11:54:37 -0700 Subject: [PATCH] Decouple icon width from adjust-cell-{height,width} --- src/font/Metrics.zig | 19 +++++++++++++++++++ src/font/face.zig | 15 ++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/font/Metrics.zig b/src/font/Metrics.zig index 89f6a507f..d6325f3d7 100644 --- a/src/font/Metrics.zig +++ b/src/font/Metrics.zig @@ -38,6 +38,9 @@ cursor_height: u32, /// The constraint height for nerd fonts icons. icon_height: u32, +/// The constraint width for nerd fonts icons. +icon_width: u32, + /// Minimum acceptable values for some fields to prevent modifiers /// from being able to, for example, cause 0-thickness underlines. const Minimums = struct { @@ -50,6 +53,7 @@ const Minimums = struct { const cursor_thickness = 1; const cursor_height = 1; const icon_height = 1; + const icon_width = 1; }; /// Metrics extracted from a font face, based on @@ -188,6 +192,19 @@ pub fn calc(face: FaceMetrics) Metrics { // We do cap it at `cell_height` though for obvious reasons. const icon_height = @min(cell_height, cap_height * 1.2); + // We set icon_width using the icon_height / cell_height + // ratio, such that + // icon_width / (2 * cell_width) == icon_height / cell_height + // This only applies when the constraint width is two cells; + // icons constrained to a single cell can take up the full + // cell width. + // + // It's important that the icon_width is calculated here using + // the cell_width and cell_height derived from the face, and + // not in Constraint.constrain, which is called after the + // adjust-cell-{width,height} modifiers have been applied. + const icon_width = 2 * cell_width * icon_height / cell_height; + var result: Metrics = .{ .cell_width = @intFromFloat(cell_width), .cell_height = @intFromFloat(cell_height), @@ -201,6 +218,7 @@ pub fn calc(face: FaceMetrics) Metrics { .box_thickness = @intFromFloat(underline_thickness), .cursor_height = @intFromFloat(cell_height), .icon_height = @intFromFloat(icon_height), + .icon_width = @intFromFloat(icon_width), }; // Ensure all metrics are within their allowable range. @@ -440,6 +458,7 @@ fn init() Metrics { .box_thickness = 0, .cursor_height = 0, .icon_height = 0, + .icon_width = 0, }; } diff --git a/src/font/face.zig b/src/font/face.zig index fc5118c3d..992161f19 100644 --- a/src/font/face.zig +++ b/src/font/face.zig @@ -233,20 +233,13 @@ pub const RenderOptions = struct { .icon => metrics.icon_height, }); - // We make the opinionated choice here to reduce the width - // of icon-height symbols by the same amount horizontally, - // since otherwise wide aspect ratio icons like folders end - // up far too wide. - // - // But we *only* do this if the constraint width is 2, since - // otherwise it would make them way too small when sized for - // a single cell. + // We use icon_width only for icon-height symbols with + // constraint width 2. When the constraint width is 1, + // icons can take the up full cell width. const is_icon_width = self.height == .icon and @min(self.max_constraint_width, constraint_width) > 1; const orig_avail_width = available_width; if (is_icon_width) { - const cell_height: f64 = @floatFromInt(metrics.cell_height); - const ratio = available_height / cell_height; - available_width *= ratio; + available_width = @floatFromInt(metrics.icon_width); } const w = available_width -