Compose: an empty paragraph takes its mark's character format

The line height of a paragraph without glyphs came from the paragraph style; InDesign uses the
format of the paragraph mark (the CharacterStyleRange holding its <Br/>).
This commit is contained in:
Deniz Kökden
2026-10-07 21:23:57 +02:00
parent f17397c305
commit 60712dedb2
2 changed files with 28 additions and 1 deletions
+11 -1
View File
@@ -648,6 +648,16 @@ pub fn compose(doc: &Document, story: &Story, frames: &[FrameSpec], opts: &Compo
designcraft_doc::Leading::Points(v) => v,
};
let spacing = spacing_for(&pp, base_size);
// An empty paragraph takes its height from its paragraph mark's character format.
let mark_chars = if glyphs.is_empty() {
std::borrow::Cow::Owned(doc.styles.resolve_char(&base_chars, story.char_format_at(prange.start)))
} else {
std::borrow::Cow::Borrowed(&base_chars)
};
let mark_leading = match mark_chars.leading {
designcraft_doc::Leading::Auto => mark_chars.size * pp.auto_leading,
designcraft_doc::Leading::Points(v) => v,
};
// Paragraph start options.
if force_col[pi] {
cur.next_column(&cols);
@@ -708,7 +718,7 @@ pub fn compose(doc: &Document, story: &Story, frames: &[FrameSpec], opts: &Compo
for (k, b) in breaks.iter().enumerate() {
let (s, e) = (g0 + b.start, g0 + b.end);
let line_glyphs = &glyphs[s..e.max(s)];
let (asc, desc, lead) = line_metrics(line_glyphs, &glyphs, s, base_leading, base_chars.size, db, &base_chars);
let (asc, desc, lead) = line_metrics(line_glyphs, &glyphs, s, mark_leading, mark_chars.size, db, &mark_chars);
let mut baseline = cur.next_baseline(f, col, lead, asc, &pp);
// Baseline grid.
if let Some((g_start, inc)) = f.grid
+17
View File
@@ -1027,3 +1027,20 @@ fn only_english_text_gets_english_hyphenation() {
st.format_chars(0..n, |f| f.over.language = Some("French".into()));
assert_eq!(hyphenated(&d2, sid), 0, "French isn't hyphenated with English rules");
}
#[test]
fn empty_paragraph_takes_its_marks_format() {
// Paragraph style text is 12 pt (auto leading 14.4); every character, including the empty
// paragraph's mark, is 6 pt with 8 pt leading: the empty line must advance 8, not 14.4.
let text = "One\n\nTwo";
let (mut d, sid, _) = doc_with(text, Rect::new(0.0, 0.0, 200.0, 200.0), ParaAttrs::default());
d.story_mut(sid).unwrap().format_chars(0..text.len(), |f| {
f.over.size = Some(6.0);
f.over.leading = Some(designcraft_doc::Leading::Points(8.0));
});
let cs = compose_story(&d, sid, &ComposeOptions::default());
let lines = all_lines(&cs);
assert_eq!(lines.len(), 3);
assert!((lines[1].baseline - lines[0].baseline - 8.0).abs() < 1e-6, "{} {}", lines[0].baseline, lines[1].baseline);
assert!((lines[2].baseline - lines[1].baseline - 8.0).abs() < 1e-6, "{} {}", lines[1].baseline, lines[2].baseline);
}