Merge pull request #1045 from vbasky/fix/926-underline-baseline

Underline follows baseline shift on whole-style text
This commit is contained in:
Brandon Thomas committed 2026-10-11 19:06:57 -04:00
commit dae3b99e96
2 files changed
+27 -1

No files matched your search

+2 -1
View File
@@ -682,7 +682,8 @@ pub fn layout_rich_uncached(text: &str, style: &TextStyle, runs: &[StyleRun], pa
lay.underline_runs.push(*si);
}
} else if style.underline && pl.content > 0.0 {
lay.underlines.push([x, baseline + pm.underline_pos, x + pl.content, baseline + pm.underline_pos + pm.underline_thickness]);
let y = baseline - style.baseline_shift + pm.underline_pos;
lay.underlines.push([x, y, x + pl.content, y + pm.underline_thickness]);
lay.underline_runs.push(0);
}
lay.lines.push(Line {
+25
View File
@@ -0,0 +1,25 @@
//! Whole-style underline must follow `baseline_shift` the same way character-style runs do.
use filmcraft_text::{ParagraphStyle, StyleRun, TextStyle, layout, layout_rich};
fn style(shift: f32) -> TextStyle {
TextStyle { size: 100.0, underline: true, baseline_shift: shift, ..Default::default() }
}
fn underline_y(shift: f32) -> (f32, f32) {
let para = ParagraphStyle::default();
let s = style(shift);
let plain = layout("Hi", &s, &para);
let rich = layout_rich("Hi", &s, &[StyleRun { range: 0..2, style: s.clone() }], &para);
(plain.underlines[0][1], rich.underlines[0][1])
}
#[test]
fn whole_style_underline_follows_baseline_shift() {
let (p0, r0) = underline_y(0.0);
for shift in [40.0, -40.0] {
let (plain, rich) = underline_y(shift);
assert!((plain - rich).abs() < 1e-3, "plain {plain} vs rich {rich} at shift {shift}");
assert!((plain - (p0 - shift)).abs() < 1e-3, "plain underline y {plain} should move with shift {shift}");
assert!((rich - (r0 - shift)).abs() < 1e-3, "rich underline y {rich} should move with shift {shift}");
}
}