mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-07 03:01:32 +00:00
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:
1 parent
75fc50fb77
commit
0802b4fe70
2 files changed
+34
-1
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in new issue
Block a user