Text layout: align on the last glyph's ink

The letter spacing after a line's last stroke-font glyph is left out of
the width used for centring and right alignment, so a right-aligned
line's last stroke sits on the edge as in the reference.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ramox81andClaude Opus 5.5 committed 2026-10-06 14:30:07 +03:00
1 parent acafb3be29
commit d567db0970
1 file changed
+24 -1
+24 -1
View File
@@ -1131,6 +1131,23 @@ pub fn word_cells(
)
}
/// The letter spacing a stroke-font word leaves after its last glyph (0 for
/// shaped words, whose advance carries no extra spacing).
fn trailing_letter_gap(atom: &LayoutAtom, entity_h: f32, base_wf: f32, base_font: &str) -> f32 {
let AtomKind::Word(text) = &atom.kind else {
return 0.0;
};
let font_name = resolve_font(&atom.state, base_font);
let face = Face::resolve(&font_name);
if face.ttf_family().is_some() || crate::scene::text::web_font::requires_shaping(text) {
return 0.0;
}
text.chars()
.rev()
.find(|c| *c != LRM)
.map_or(0.0, |c| face.spacing_after(c) * atom.state.tracking * run_scale(&atom.state, entity_h, base_wf))
}
pub fn measure_space(state: &RunState, entity_h: f32, base_wf: f32, base_font: &str) -> f32 {
let scale = run_scale(state, entity_h, base_wf);
let font_name = resolve_font(state, base_font);
@@ -2180,7 +2197,13 @@ pub fn layout_mtext(opts: &MTextRenderOpts) -> MTextLayout {
0.0,
sub.indent_left,
&sub.tab_stops,
);
)
// Aligned on the last glyph's ink: the letter spacing after it is not
// part of the width centring / right alignment use (the reference
// puts a right-aligned line's last stroke on the edge).
- sub.atoms[..visible_atoms]
.last()
.map_or(0.0, |atom| trailing_letter_gap(atom, entity_h, base_wf, &base_font_name));
line_widths.push(line_w);
let cursor_start = if rect_w > 0.0 {