From 45b8ce842ec4345b6d80adb599dcb47c907dc6c9 Mon Sep 17 00:00:00 2001 From: Charles Nicholson Date: Fri, 31 Oct 2025 14:42:57 -0400 Subject: [PATCH 1/2] Cell width calculation from ceil to round, fix horizontal spacing --- src/font/Metrics.zig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/font/Metrics.zig b/src/font/Metrics.zig index ec89763ea..d4400a340 100644 --- a/src/font/Metrics.zig +++ b/src/font/Metrics.zig @@ -223,12 +223,12 @@ pub const FaceMetrics = struct { /// /// For any nullable options that are not provided, estimates will be used. pub fn calc(face: FaceMetrics) Metrics { - // We use the ceiling of the provided cell width and height to ensure - // that the cell is large enough for the provided size, since we cast - // it to an integer later. + // We use rounding for cell width to match the glyph advances from CoreText, + // which avoids spacing issues on non-Retina displays. + // We keep ceiling for cell height to ensure vertical space is sufficient. const face_width = face.cell_width; const face_height = face.lineHeight(); - const cell_width = @ceil(face_width); + const cell_width = @round(face_width); const cell_height = @ceil(face_height); // We split our line gap in two parts, and put half of it on the top From 801a399f41a1e65a60297e5e1b11ea6e706a15e4 Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Wed, 19 Nov 2025 11:09:37 -0700 Subject: [PATCH 2/2] clarify comment --- src/font/Metrics.zig | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/font/Metrics.zig b/src/font/Metrics.zig index d4400a340..3bd8ed69c 100644 --- a/src/font/Metrics.zig +++ b/src/font/Metrics.zig @@ -223,11 +223,33 @@ pub const FaceMetrics = struct { /// /// For any nullable options that are not provided, estimates will be used. pub fn calc(face: FaceMetrics) Metrics { - // We use rounding for cell width to match the glyph advances from CoreText, - // which avoids spacing issues on non-Retina displays. - // We keep ceiling for cell height to ensure vertical space is sufficient. + // These are the unrounded advance width and line height values, + // which are retained separately from the rounded cell width and + // height values (below), for calculations that need to know how + // much error there is between the design dimensions of the font + // and the pixel dimensions of our cells. const face_width = face.cell_width; const face_height = face.lineHeight(); + + // The cell width and height values need to be integers since they + // represent pixel dimensions of the grid cells in the terminal. + // + // We use @round for the cell width to limit the difference from + // the "true" width value to no more than 0.5px. This is a better + // approximation of the authorial intent of the font than ceiling + // would be, and makes the apparent spacing match better between + // low and high DPI displays. + // + // This does mean that it's possible for a glyph to overflow the + // edge of the cell by a pixel if it has no side bearings, but in + // reality such glyphs are generally meant to connect to adjacent + // glyphs in some way so it's not really an issue. + // + // TODO: Reconsider cell height, should it also be rounded? + // We use @ceil because that's what we used initially, + // with the idea that it makes sure there's enough room + // for glyphs that use the entire line height, but it + // does create the same high/low DPI disparity issue... const cell_width = @round(face_width); const cell_height = @ceil(face_height);