mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-25 10:46:50 -06:00
Text: the paragraph mark's size counts in its line's auto leading
The paragraph mark is a character of its paragraph's last line, so its leading (auto: its size times the auto leading percentage) takes part in the line's largest-leading rule. It doesn't change the line's ascent or descent. Earlier lines of the paragraph are unaffected.
This commit is contained in:
@@ -768,6 +768,18 @@ fn compose_with_db(doc: &Document, story: &Story, frames: &[FrameSpec], opts: &C
|
||||
designcraft_doc::Leading::Auto => base_size * pp.auto_leading,
|
||||
designcraft_doc::Leading::Points(v) => v,
|
||||
};
|
||||
// The paragraph mark is a character of the last line: its leading counts there like any
|
||||
// other character's. It doesn't set the line's ascent or descent. A hidden or deleted
|
||||
// mark takes no room.
|
||||
let mark_leading = story.text.get(prange.end..).filter(|t| t.starts_with('\n')).and_then(|_| {
|
||||
let props = doc.styles.resolve_char(&base_chars, story.format_after(prange.end));
|
||||
let hidden = props.change == designcraft_doc::ChangeMark::Deleted
|
||||
|| (!props.conditions.is_empty() && props.conditions.iter().all(|c| sub.hidden_conditions.contains(c)));
|
||||
(!hidden).then_some(match props.leading {
|
||||
designcraft_doc::Leading::Auto => props.size * pp.auto_leading,
|
||||
designcraft_doc::Leading::Points(v) => v,
|
||||
})
|
||||
});
|
||||
let spacing = spacing_for(&pp, base_size);
|
||||
// A paragraph set across the columns moves on to the next frame where others move on to
|
||||
// the next column.
|
||||
@@ -914,6 +926,10 @@ fn compose_with_db(doc: &Document, story: &Story, frames: &[FrameSpec], opts: &C
|
||||
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 lead = match mark_leading {
|
||||
Some(m) if k + 1 == breaks.len() => lead.max(m),
|
||||
_ => lead,
|
||||
};
|
||||
let reference = cjk_line_reference(line_glyphs);
|
||||
let mut baseline = cur.next_baseline(f, col, lead, asc, &pp);
|
||||
if cur.last_baseline.is_some() {
|
||||
|
||||
@@ -2771,3 +2771,22 @@ fn empty_paragraphs_get_no_bullet_or_number() {
|
||||
assert_eq!(list_labels(&cs, LABEL_CHARS), ["1.", "", "2.", ""], "list `{name}`");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn paragraph_mark_size_counts_in_its_line_auto_leading() {
|
||||
let gaps = |mark_size: f64| {
|
||||
let (mut d, sid, _) = doc_with("One\nTwo\nThree", Rect::new(36.0, 36.0, 300.0, 300.0), ParaAttrs::default());
|
||||
d.story_mut(sid).unwrap().format_chars(7..8, |f| f.over.size = Some(mark_size));
|
||||
let cs = compose_story(&d, sid, &ComposeOptions::default());
|
||||
let b: Vec<f64> = all_lines(&cs).iter().map(|l| l.baseline).collect();
|
||||
assert_eq!(b.len(), 3);
|
||||
(b[1] - b[0], b[2] - b[1])
|
||||
};
|
||||
// A 12 pt line ending in a 14 pt return: 14 × 120% above it, the next line unchanged.
|
||||
let (above, below) = gaps(14.0);
|
||||
assert!((above - 16.8).abs() < 1e-6, "{above}");
|
||||
assert!((below - 14.4).abs() < 1e-6, "{below}");
|
||||
let (above, below) = gaps(12.0);
|
||||
assert!((above - 14.4).abs() < 1e-6, "{above}");
|
||||
assert!((below - 14.4).abs() < 1e-6, "{below}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user