From 124bde4883bb7e4fbe40e28c12ef93a79e402504 Mon Sep 17 00:00:00 2001 From: RndUsr123 <150948884+RndUsr123@users.noreply.github.com> Date: Tue, 3 Mar 2026 07:46:45 +0000 Subject: [PATCH] Fixes the overly aggressive overflow elision in `truncate()` and similar for os scaling other than 100% (#7867) * Closes #7818 * [x] I have followed the instructions in the PR template --------- Co-authored-by: Emil Ernerfeldt --- crates/epaint/src/text/text_layout.rs | 40 ++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/crates/epaint/src/text/text_layout.rs b/crates/epaint/src/text/text_layout.rs index 5b2400646..9aeeff137 100644 --- a/crates/epaint/src/text/text_layout.rs +++ b/crates/epaint/src/text/text_layout.rs @@ -495,7 +495,9 @@ fn replace_last_glyph_with_overflow_character( let replacement_glyph_width = font_face .as_mut() .and_then(|f| f.glyph_info(overflow_character)) - .map(|i| i.advance_width_unscaled.0 * font_face_metrics.px_scale_factor) + .map(|i| { + i.advance_width_unscaled.0 * font_face_metrics.px_scale_factor / pixels_per_point + }) .unwrap_or_default(); // Check if we're within width budget: @@ -1166,6 +1168,42 @@ mod tests { assert_eq!(row.rect().max.x, row.glyphs.last().unwrap().max_x()); } + #[test] + fn test_truncate_with_pixels_per_point() { + let mut fonts = FontsImpl::new(TextOptions::default(), FontDefinitions::default()); + + for pixels_per_point in [ + 0.33, 0.5, 0.67, 1.0, 1.25, 1.33, 1.5, 1.75, 2.0, 3.0, 4.0, 5.0, + ] { + for ch in ['W', 'A', 'n', 't', 'i'] { + let target_width = 50.0; + let text = (0..20).map(|_| ch).collect::(); + + let mut job = LayoutJob::single_section(text, TextFormat::default()); + job.wrap.max_width = target_width; + job.wrap.max_rows = 1; + let elided_galley = layout(&mut fonts, pixels_per_point, job.into()); + assert!(elided_galley.elided); + + let test_galley = layout( + &mut fonts, + pixels_per_point, + Arc::new(LayoutJob::single_section( + (0..elided_galley.rows[0].char_count_excluding_newline()) + .map(|_| ch) + .chain(std::iter::once('…')) + .collect::(), + TextFormat::default(), + )), + ); + + assert!(elided_galley.size().x >= 0.0); + assert!(elided_galley.size().x <= target_width); + assert!(test_galley.size().x > target_width); + } + } + } + #[test] fn test_empty_row() { let pixels_per_point = 1.0;