Layout: the caret on the empty line after a trailing line break follows the paragraph's alignment (#4293)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilverandClaude Haiku 5.5 authored and GitHub committed 2026-11-04 21:57:34 +01:00
1 parent 75fc50fb77
commit 0802b4fe70
2 files changed
+34 -1

No files matched your search

+8 -1
View File
@@ -584,6 +584,13 @@ impl<'e> Breaker<'e> {
(LineSpacing::AtLeast(v), None) => natural.max(v),
(LineSpacing::Exactly(v), _) => v,
};
// The empty line's caret follows the alignment, as an empty paragraph's does.
let slack = (self.base_right - rp.indent_left).max(0.0);
let shift = match rp.align {
Align::Center => slack / 2.0,
Align::Right => slack,
_ => 0.0,
};
let (width, x0) = (self.width, rp.indent_left);
let (x0, left, right) = if self.rtl_para { (width - x0, width - self.base_right, width - x0) } else { (x0, x0, self.base_right) };
self.lines.push(Line {
@@ -594,7 +601,7 @@ impl<'e> Breaker<'e> {
text_desc: desc,
c0: self.n,
c1: self.n,
xs: vec![x0],
xs: vec![if self.rtl_para { x0 - shift } else { x0 + shift }],
leaders: Vec::new(),
end: LineEnd::Para,
start: pl.text_len,
+26
View File
@@ -1422,6 +1422,32 @@ fn center_and_right_alignment() {
assert!((x2 - 540.0).abs() < 1.0, "{x2}");
}
#[test]
fn caret_on_an_empty_line_after_a_break_follows_alignment() {
// "BAB I", Shift+Enter: the empty line's caret sits where its alignment puts it (#4283).
let text = format!("BAB I{}", wordcraft_doc::para::LINE_BREAK);
for rtl in [false, true] {
for (align, ltr_x) in [(Align::Left, 72.0), (Align::Center, 306.0), (Align::Right, 540.0), (Align::Justify, 72.0)] {
let mut d = Document::new();
d.body = vec![wordcraft_doc::para_block(wordcraft_doc::Paragraph::with_text(&text, Default::default()))];
let at = Pos::body(0, 0);
d.format_paragraphs(&at, &at, &|p: &mut ParaProps| {
p.align = Some(align);
p.bidi = Some(rtl);
})
.unwrap();
let expected = if rtl { 612.0 - ltr_x } else { ltr_x };
let x = lay(&d).caret(&Pos::body(0, text.len())).unwrap().x;
assert!((x - expected).abs() < 1.0, "{align:?} rtl={rtl}: {x}, expected {expected}");
}
}
// An empty centred paragraph without a break was already centred.
let mut d = Document::from_text("");
d.format_paragraphs(&Pos::body(0, 0), &Pos::body(0, 0), &|p| p.align = Some(Align::Center)).unwrap();
let x = lay(&d).caret(&Pos::body(0, 0)).unwrap().x;
assert!((x - 306.0).abs() < 1.0, "{x}");
}
#[test]
fn tabs_land_on_default_stops() {
let d = Document::from_text("a\tb");