Use ch-width (`0`) instead of em-width (`m`) for gutter width calculation (#32548)
Max Mynter
created
Closes #21860
Release Notes:
- Added `ch_width` and `ch_advance` function alongside their `em_*`
counterparts
- Use `ch_*` version to calculate gutter layouts
- Update a stale comment from changes in #31959
The ch units refer to the width of the number `0` whereas em is the
width of `m` and the actual font size (e.g. 16px means 16 px width of
`m`).
This change has no effect for monospaced fonts but can be drastic for
proportional ones as seen below for "Zed Plex Sans" with a
`"min_line_number_width" = 4`.
<img width="726" alt="Screenshot 2025-06-11 at 15 47 35"
src="https://github.com/user-attachments/assets/aa73f4d4-32bc-42cf-a9f6-7e25fee68c9a"
/>
@@ -209,6 +209,20 @@ impl TextSystem {
Ok(self.advance(font_id, font_size, 'm')?.width)
}
+ /// Returns the width of an `ch`.
+ ///
+ /// Uses the width of the `0` character in the given font and size.
+ pub fn ch_width(&self, font_id: FontId, font_size: Pixels) -> Result<Pixels> {
+ Ok(self.typographic_bounds(font_id, font_size, '0')?.size.width)
+ }
+
+ /// Returns the advance width of an `ch`.
+ ///
+ /// Uses the advance width of the `0` character in the given font and size.
+ pub fn ch_advance(&self, font_id: FontId, font_size: Pixels) -> Result<Pixels> {
+ Ok(self.advance(font_id, font_size, '0')?.width)
+ }
+
/// Get the number of font size units per 'em square',
/// Per MDN: "an abstract square whose height is the intended distance between
/// lines of type in the same type size"