Use ch-width (0) instead of em-width (m) for gutter width calculation (#32548)

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"
/>
This commit is contained in:
Max Mynter 2025-06-12 07:28:04 +02:00 committed by GitHub
parent f428d54b74
commit 242af863f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 12 deletions

View file

@ -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"