render: pre-scale font_line_metrics by dpi_scale
Some checks failed
CI / build + test (push) Has been cancelled
CI / cargo audit (push) Has been cancelled

The text pipeline works in physical pixels: measure_text and draw_text multiply the font size by dpi_scale internally, and the layout rects widgets receive are physical too. font_line_metrics was the one exception — it returned line metrics at the logical size — so the line height and ascent the text and rich_text widgets derive from it came out divided by the surface scale factor. On any output with a scale other than 1 (e.g. a 200% display, or any fractional setting the compositor rounds up to buffer scale 2), wrapped lines overlapped, baselines sat too high, and preferred_size reported half the real text height.
Scale the size handed to horizontal_line_metrics by dpi_scale in both the Canvas wrapper and the GLES backend, matching the already pre-scaled font_metrics. At scale 1 the behaviour is unchanged.
This commit is contained in:
2026-08-11 22:04:22 +02:00
parent 98c82385c7
commit adbbc0248b
2 changed files with 6 additions and 5 deletions

View File

@@ -772,11 +772,11 @@ impl GlesCanvas
self.font_for_char( ch ).metrics( ch, size * self.dpi_scale )
}
/// Horizontal line metrics of the default font at `size` px (`None` if the
/// font lacks them). Not pre-scaled by `dpi_scale`.
/// Horizontal line metrics of the default font at `size` logical px (`None`
/// if the font lacks them), pre-scaled by `dpi_scale`.
pub fn font_line_metrics( &self, size: f32 ) -> Option<LineMetrics>
{
self.font.horizontal_line_metrics( size )
self.font.horizontal_line_metrics( size * self.dpi_scale )
}
/// Resize the FBO and viewport. The previous color attachment is freed and

View File

@@ -529,10 +529,11 @@ impl Canvas
self.font().metrics( ch, size * self.dpi_scale() )
}
/// Convenience wrapper around `font().horizontal_line_metrics(...)`.
/// Convenience wrapper around `font().horizontal_line_metrics(...)`,
/// pre-scaled by `dpi_scale` like [`Self::font_metrics`].
pub fn font_line_metrics( &self, size: f32 ) -> Option<LineMetrics>
{
self.font().horizontal_line_metrics( size )
self.font().horizontal_line_metrics( size * self.dpi_scale() )
}
pub fn resize( &mut self, width: u32, height: u32 )