mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
G4: the Character panel counts a final empty paragraph
each_paragraph_run skipped the empty paragraph after a closing line break, so a selected object whose last paragraph's Auto Leading differed showed one Leading instead of a mixed (blank) field. With no range, that paragraph now counts with the style of the run before it. Covered by leading_field_counts_the_final_empty_paragraph. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014gCpjL3yUhaH3jRp7ksufh
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Opus 5.5
parent
2cf37aea2f
commit
58977acf6d
@@ -115,13 +115,17 @@ fn shared_styles<T: PartialEq>(
|
||||
|
||||
/// `f` of the paragraph and style of each piece of `t`'s runs that lies in one paragraph (a
|
||||
/// paragraph's closing line break belongs to it): the pieces within bytes `a..b`, or with no
|
||||
/// range every run's, empty ones included.
|
||||
/// range every run's, empty ones included. With no range, a final empty paragraph (the text ends
|
||||
/// in a line break) counts too, with the style of the run before it, as the caret there types.
|
||||
fn each_paragraph_run<'a>(
|
||||
t: &'a vectorcraft_doc::TextObject,
|
||||
range: Option<(usize, usize)>,
|
||||
mut f: impl FnMut(&'a vectorcraft_doc::ParaStyle, &'a CharStyle),
|
||||
) {
|
||||
let (mut end, mut para) = (0, 0);
|
||||
// The style of the last character and whether it is a line break: the paragraph after it has
|
||||
// no characters of its own.
|
||||
let mut last: Option<(&'a CharStyle, bool)> = None;
|
||||
for r in &t.runs {
|
||||
if r.text.is_empty() {
|
||||
if range.is_none_or(|(a, b)| a < end && end < b) {
|
||||
@@ -136,8 +140,14 @@ fn each_paragraph_run<'a>(
|
||||
f(t.para_at(para), &r.style);
|
||||
}
|
||||
para += usize::from(piece.ends_with('\n'));
|
||||
last = Some((&r.style, piece.ends_with('\n')));
|
||||
}
|
||||
}
|
||||
if range.is_none()
|
||||
&& let Some((style, true)) = last
|
||||
{
|
||||
f(t.para_at(para), style);
|
||||
}
|
||||
}
|
||||
|
||||
/// The value a run of styles share so far ([`shared`]).
|
||||
@@ -942,6 +952,19 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// A final empty paragraph counts: with the object selected, its Auto Leading differing from
|
||||
/// the paragraph before it shows Leading as mixed.
|
||||
#[test]
|
||||
fn leading_field_counts_the_final_empty_paragraph() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run("file.new", json!({"width": 300, "height": 200})).unwrap();
|
||||
let id = app.run("text.create", json!({"x": 20, "y": 50, "text": "One\n", "size": 10})).unwrap()["id"].clone();
|
||||
app.run("select.set", json!({"ids": [id]})).unwrap();
|
||||
assert!((shared_leading(&app).unwrap() - 12.0).abs() < 1e-9);
|
||||
app.run("text.setFormat", json!({"autoLeading": 200, "start": 4, "end": 4})).unwrap();
|
||||
assert_eq!(shared_leading(&app), None, "the empty last paragraph differs");
|
||||
}
|
||||
|
||||
/// Auto leading shows the leading the paragraph's Justification › Auto Leading sets.
|
||||
#[test]
|
||||
fn leading_field_shows_the_paragraph_auto_leading() {
|
||||
|
||||
Reference in New Issue
Block a user