#3692: autofit counts the grid's columns once

Finding 3: column_content called Table::cols (a walk of every row) for each spanning cell, and there can be one in every row. Hoisted out of the loop; the end is also added with saturating_add.

Test: autofit_tables_with_a_spanning_cell_in_every_row_lay_out_in_linear_time.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Martin Ball
2026-10-26 00:19:16 +00:00
co-authored by Claude Opus 5.5
parent 4d027de402
commit 629711582f
2 changed files with 21 additions and 1 deletions
+3 -1
View File
@@ -1144,8 +1144,10 @@ fn column_content(ctx: &mut Ctx, t: &Table, style: Option<&TableStyleProps>, dep
}
spanning.extend(row_gaps(row, g).map(|(g, span, w)| (g, span, (w, w))));
}
// The grid's width once: counting it walks every row, and there can be a spanning cell in each.
let ncols = t.cols();
for (g, span, need) in spanning {
let Some(cs) = cols.get_mut(g..(g + span).min(t.cols())) else { continue };
let Some(cs) = cols.get_mut(g..g.saturating_add(span).min(ncols)) else { continue };
let n = cs.len().max(1) as f32;
let (have_lo, have_hi) = cs.iter().fold((0.0, 0.0), |(l, h), c| (l + c.0, h + c.1));
for c in cs {
+18
View File
@@ -92,3 +92,21 @@ fn line_carets_match_x_of() {
}
}
/// Finding 3: autofitting a table counted its grid's columns again for every spanning cell.
#[test]
fn autofit_tables_with_a_spanning_cell_in_every_row_lay_out_in_linear_time() {
let doc = |n: usize| {
let mut t = Table::new(n, 3, 468.0);
for row in &mut t.rows {
row.cells.truncate(2);
if let Some(c) = row.cells.first_mut() {
c.props.span = 2;
}
}
let mut d = Document::from_text("x");
d.insert_block(StoryRef::Body, &Path::top(0), Block::Table(t)).unwrap();
d
};
assert_linear("spanning cells", layout_time_ratio(doc, 400, &LayoutOptions::default()));
}