This commit is contained in:
Brandon Thomas committed 2026-10-15 00:35:26 -04:00
commit bdda458b5b
2 files changed
+38 -2

No files matched your search

+21
View File
@@ -1622,6 +1622,27 @@ fn warichu_stacks_the_run_inside_the_line_and_closes_up() {
assert!((l.end_x - (z.x + z.adv)).abs() < 1e-3, "the line-end caret follows the close-up");
}
#[test]
fn warichu_line_spacing_from_a_document_stays_finite() {
for spacing in [1e308, -1e308, f64::INFINITY, f64::NAN] {
let mut d = Document::new(&designcraft_doc::build::NewDocument::default());
let lid = d.default_layer();
let (_, sid) = d.add_text_frame(SpreadRef::Doc(0), Rect::new(36.0, 36.0, 500.0, 200.0), lid, "ABCDEFGHZ", ParaFormat::default()).unwrap();
d.story_mut(sid).unwrap().format_chars(0..8, |f| {
f.over.warichu = Some(true);
f.over.warichu_lines = Some(16);
f.over.warichu_line_spacing = Some(spacing);
});
let cs = compose_story(&d, sid, &ComposeOptions::default());
let l = &cs.frames[0].lines[0];
assert!(
l.glyphs.iter().all(|g| g.x.is_finite() && g.y.is_finite() && g.y.abs() < 1e4),
"{spacing}: {:?}",
l.glyphs.iter().map(|g| g.y).collect::<Vec<_>>()
);
}
}
#[test]
fn warichu_break_minimum_keeps_a_short_run_on_one_line() {
let mut d = Document::new(&designcraft_doc::build::NewDocument::default());
+17 -2
View File
@@ -84,7 +84,8 @@ fn line_count(len: usize, want: usize, before: usize, after: usize) -> usize {
let before = before.max(1);
let after = after.max(1);
while n >= 2 {
if before + after + n - 2 <= len {
// The minimums come from documents and commands: on 32-bit targets their sum can overflow.
if before.saturating_add(after).saturating_add(n - 2) <= len {
return n;
}
n -= 1;
@@ -220,7 +221,9 @@ fn layout(styles: &[RunStyle], line: &mut [PlacedGlyph], members: &[usize]) -> f
let small = st.size * scale;
// 0 is the default (one small em). Any other value, including a negative one, is added to
// that em and then clamped so the rows cannot swap order.
let gap = if st.warichu_line_spacing == 0.0 { small } else { (small + st.warichu_line_spacing).max(0.0) };
// Bounded, so a hostile value can't move a row to an infinite or huge coordinate.
let spacing = if st.warichu_line_spacing.is_finite() { st.warichu_line_spacing.clamp(-16.0 * st.size, 16.0 * st.size) } else { 0.0 };
let gap = if spacing == 0.0 { small } else { (small + spacing).max(0.0) };
let mut off = 0_usize;
for (li, &c) in counts.iter().enumerate() {
let w = widths[li];
@@ -264,3 +267,15 @@ fn layout(styles: &[RunStyle], line: &mut [PlacedGlyph], members: &[usize]) -> f
}
delta
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn huge_break_minimums_keep_one_line() {
assert_eq!(line_count(10, 2, usize::MAX, 1), 1);
assert_eq!(line_count(10, 3, 1, usize::MAX), 1);
assert_eq!(line_count(10, 2, 3, 3), 2);
}
}