Skip to content

text: Use font metrics to determine line heights#31291

Open
QuLogic wants to merge 4 commits intomatplotlib:text-overhaulfrom
QuLogic:font-heights
Open

text: Use font metrics to determine line heights#31291
QuLogic wants to merge 4 commits intomatplotlib:text-overhaulfrom
QuLogic:font-heights

Conversation

@QuLogic
Copy link
Member

@QuLogic QuLogic commented Mar 12, 2026

PR summary

As outlined in #31220, we follow the process from the CSS Inline Layout module, specifically:

  1. The default ascent and descent come from the OS/2 font table, or failing that, the hhea table, with final fallback to the measurement we used to do.
  2. If linespacing (cf line height in CSS) is normal, then we do as before and size each line based on the maximum ascent/descent of its contents. Additionally, apply the line gap from the font metrics as half-leading around each line.
  3. If linespacing is a float, then scale it by font size of the first available font, and keep it fixed for each line.

Additionally, the first commit changes mathtext to use the x-height from the default fonts. We can read that from font metrics, but I thought I'd leave the general case to something like #31048.

Note, this is based on the text-overhaul-figures branch, so more test images than necessary are changed here. Please look at the last commit for the test images. Most test image changes are minor, maybe half a pixel or so with the text. The main ones you probably want to look at are those with multiple lines, such as 'basictext_wrap.png`.

One thing to decide is whether to apply the line gap for a single line. Previously, I don't believe we ended up doing that, because the line spacing was added before the second and subsequent lines. This PR currently always adds it, which means the text bounding box is taller in all cases. This causes such changes as the fancy bbox patches in boxarrow_test_image.png to all be larger, or e.g., every multi-artist legend to be larger. To minimize such changes, we can decide to drop the line gap for single-line text entries, if we want?

AI Disclosure

None

PR checklist

@QuLogic QuLogic added this to the v3.11.0 milestone Mar 12, 2026
@github-project-automation github-project-automation bot moved this to Waiting for other PR in Font and text overhaul Mar 12, 2026
@QuLogic QuLogic moved this from Waiting for other PR to Ready for Review in Font and text overhaul Mar 12, 2026
@QuLogic
Copy link
Member Author

QuLogic commented Mar 12, 2026

One thing to decide is whether to apply the line gap for a single line. Previously, I don't believe we ended up doing that, because the line spacing was added before the second and subsequent lines. This PR currently always adds it, which means the text bounding box is taller in all cases. This causes such changes as the fancy bbox patches in boxarrow_test_image.png to all be larger, or e.g., every multi-artist legend to be larger. To minimize such changes, we can decide to drop the line gap for single-line text entries, if we want?

Discussed on the call today and decided not to add line gap for a single-line text. This should be closer to what we used to do, and will minimize the number of changes that occur due to this.

QuLogic added 4 commits March 13, 2026 21:47
This is minimally different from the `x` measurement, but technically
more correct. We still do the measurement for fonts we don't ship, but
that may change with Unicode Math fonts in the future.
This follows from CSS' default for line height. At the moment, the
behaviour has not been changed, and still just falls back to 1.2 for
'normal'.
We follow the process from [the CSS Inline Layout
module](https://www.w3.org/TR/css-inline-3/), specifically:

1. The default ascent and descent come from the `OS/2` font table, or
   failing that, the `hhea` table, with final fallback to the
   measurement we used to do.
2. If `linespacing` (cf line height in CSS) is normal, then we do as
   before and size each line based on the maximum ascent/descent of its
   contents. Additionally, apply the line gap from the font metrics as
   half-leading around each line.
3. If `linespacing` is a float, then scale it by font size of the first
   available font, and keep it fixed for each line.

However, if we are drawing a single line, then we do not add the line
gap around the line, to keep them a similar height as before.
@QuLogic
Copy link
Member Author

QuLogic commented Mar 14, 2026

I've now pushed fixes to the text_placeholders fixture, which should reduce the number of test image changes. Also fixed some tests that explicitly check values of text locations/sizes/etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Ready for Review

Development

Successfully merging this pull request may close these issues.

1 participant