diff --git a/crates/engine/src/cmd.rs b/crates/engine/src/cmd.rs index c005082d6..597649cb0 100644 --- a/crates/engine/src/cmd.rs +++ b/crates/engine/src/cmd.rs @@ -439,9 +439,7 @@ pub fn xfrm_of(doc: &deckcraft_model::Presentation, sel: &crate::Selection, shap let t = if t.is_normalized() { t } else { - let mut n = t.clone(); - n.normalize(); - normalized = n; + normalized = t.normalized(); &normalized }; let drawn: f64 = table_drawn_heights(doc, sel, t).iter().sum(); diff --git a/crates/model/src/table.rs b/crates/model/src/table.rs index be9a0fe49..9ff39697e 100644 --- a/crates/model/src/table.rs +++ b/crates/model/src/table.rs @@ -322,6 +322,16 @@ impl Table { let n = self.cols.len(); n <= MAX_CELLS && self.rows.len() <= (MAX_CELLS / n.max(1)).max(1) && self.rows.iter().all(|r| r.cells.len() == n) } + /// What [`Table::normalize`] would leave of this table, cloning only the rows and cells that + /// survive (an oversized table is not copied whole first). + pub fn normalized(&self) -> Table { + let n = self.cols.len().min(MAX_CELLS); + let keep = (MAX_CELLS / n.max(1)).max(1); + let rows = self.rows.iter().take(keep).map(|r| Row { height: r.height, cells: r.cells.iter().take(n).cloned().collect() }).collect(); + let mut t = Table { cols: self.cols[..n].to_vec(), rows, background: self.background.clone(), style: self.style.clone(), ..*self }; + t.normalize(); + t + } /// Make every row have exactly `cols.len()` cells (repair after loading). A grid over /// [`MAX_CELLS`] loses its last rows (and columns) first, so a file naming many rows and many /// columns but few cells cannot make this allocate their product. @@ -575,6 +585,11 @@ mod tests { let mut t = Table { cols: vec![1.0; MAX_CELLS + 5], rows: vec![Row::default(); 3], ..Default::default() }; t.normalize(); assert_eq!((t.cols.len(), t.rows.len()), (MAX_CELLS, 1)); + // `normalized` leaves what `normalize` does. + let wide = Table { cols: vec![10.0; 1000], rows: vec![Row { height: 1.0, cells: vec![Cell::new("x"); 1500] }; 150], ..Default::default() }; + let mut n = wide.clone(); + n.normalize(); + assert_eq!(wide.normalized(), n); // A normal table is untouched. let mut t = Table::new(4, 4, 400.0, 30.0); t.normalize();