diff --git a/crates/typst-layout/src/grid/layouter.rs b/crates/typst-layout/src/grid/layouter.rs index 8a6e1fc34..42fe38dbe 100644 --- a/crates/typst-layout/src/grid/layouter.rs +++ b/crates/typst-layout/src/grid/layouter.rs @@ -274,13 +274,14 @@ impl<'a> GridLayouter<'a> { pub fn layout(mut self, engine: &mut Engine) -> SourceResult { self.measure_columns(engine)?; - if let Some(footer) = self.grid.footer.as_ref().and_then(Repeatable::as_repeated) - { - // Ensure rows in the first region will be aware of the possible - // presence of the footer. - self.prepare_footer(footer, engine, 0)?; - self.regions.size.y -= self.current.footer_height; - self.current.initial_after_repeats = self.regions.size.y; + if let Some(footer) = &self.grid.footer { + if footer.repeated { + // Ensure rows in the first region will be aware of the + // possible presence of the footer. + self.prepare_footer(footer, engine, 0)?; + self.regions.size.y -= self.current.footer_height; + self.current.initial_after_repeats = self.regions.size.y; + } } let mut y = 0; @@ -297,10 +298,8 @@ impl<'a> GridLayouter<'a> { } } - if let Some(footer) = - self.grid.footer.as_ref().and_then(Repeatable::as_repeated) - { - if y >= footer.start { + if let Some(footer) = &self.grid.footer { + if footer.repeated && y >= footer.start { if y == footer.start { self.layout_footer(footer, engine, self.finished.len())?; self.flush_orphans(); @@ -1573,9 +1572,7 @@ impl<'a> GridLayouter<'a> { let mut laid_out_footer_start = None; if !footer_would_be_widow { - if let Some(footer) = - self.grid.footer.as_ref().and_then(Repeatable::as_repeated) - { + if let Some(footer) = &self.grid.footer { // Don't layout the footer if it would be alone with the header // in the page (hence the widow check), and don't layout it // twice (check below). @@ -1583,7 +1580,9 @@ impl<'a> GridLayouter<'a> { // TODO(subfooters): this check can be replaced by a vector of // repeating footers in the future, and/or some "pending // footers" vector for footers we're about to place. - if self.current.lrows.iter().all(|row| row.index() < footer.start) { + if footer.repeated + && self.current.lrows.iter().all(|row| row.index() < footer.start) + { laid_out_footer_start = Some(footer.start); self.layout_footer(footer, engine, self.finished.len())?; } diff --git a/crates/typst-layout/src/grid/repeated.rs b/crates/typst-layout/src/grid/repeated.rs index 61ef6988d..8db33df5e 100644 --- a/crates/typst-layout/src/grid/repeated.rs +++ b/crates/typst-layout/src/grid/repeated.rs @@ -1,3 +1,5 @@ +use std::ops::Deref; + use typst_library::diag::SourceResult; use typst_library::engine::Engine; use typst_library::layout::grid::resolve::{Footer, Header, Repeatable}; @@ -205,7 +207,7 @@ impl<'a> GridLayouter<'a> { self.repeating_headers .iter() .copied() - .chain(self.pending_headers.iter().map(Repeatable::unwrap)), + .chain(self.pending_headers.iter().map(Repeatable::deref)), &self.regions, engine, disambiguator, @@ -254,7 +256,7 @@ impl<'a> GridLayouter<'a> { total_header_row_count(self.repeating_headers.iter().copied()); let pending_header_rows = - total_header_row_count(self.pending_headers.iter().map(Repeatable::unwrap)); + total_header_row_count(self.pending_headers.iter().map(Repeatable::deref)); // Group of headers is unbreakable. // Thus, no risk of 'finish_region' being recursively called from @@ -326,7 +328,7 @@ impl<'a> GridLayouter<'a> { has_non_repeated_pending_header = true; } let header_height = - self.layout_header_rows(header.unwrap(), engine, disambiguator, false)?; + self.layout_header_rows(header, engine, disambiguator, false)?; if header.repeated { self.current.repeating_header_height += header_height; self.current.repeating_header_heights.push(header_height); @@ -364,7 +366,7 @@ impl<'a> GridLayouter<'a> { // for upcoming regions, we will have to consider repeating headers as // well. let header_height = self.simulate_header_height( - headers.iter().map(Repeatable::unwrap), + headers.iter().map(Repeatable::deref), &self.regions, engine, 0, @@ -398,11 +400,10 @@ impl<'a> GridLayouter<'a> { let mut at_top = self.regions.size.y == self.current.initial_after_repeats; self.unbreakable_rows_left += - total_header_row_count(headers.iter().map(Repeatable::unwrap)); + total_header_row_count(headers.iter().map(Repeatable::deref)); for header in headers { - let header_height = - self.layout_header_rows(header.unwrap(), engine, 0, false)?; + let header_height = self.layout_header_rows(header, engine, 0, false)?; // Only store this header height if it is actually going to // become a pending header. Otherwise, pretend it's not a diff --git a/crates/typst-library/src/layout/grid/resolve.rs b/crates/typst-library/src/layout/grid/resolve.rs index d6a67d12c..baf6b7383 100644 --- a/crates/typst-library/src/layout/grid/resolve.rs +++ b/crates/typst-library/src/layout/grid/resolve.rs @@ -1,5 +1,5 @@ use std::num::{NonZeroU32, NonZeroUsize}; -use std::ops::{Deref, Range}; +use std::ops::{Deref, DerefMut, Range}; use std::sync::Arc; use ecow::eco_format; @@ -485,21 +485,13 @@ impl Deref for Repeatable { } } -impl Repeatable { - /// Gets the value inside this repeatable, regardless of whether - /// it repeats. - #[inline] - pub fn unwrap(&self) -> &T { - &self.inner - } - - /// Gets the value inside this repeatable, regardless of whether - /// it repeats (mutably). - #[inline] - pub fn unwrap_mut(&mut self) -> &mut T { +impl DerefMut for Repeatable { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } +} +impl Repeatable { /// Returns `Some` if the value is repeated, `None` otherwise. #[inline] pub fn as_repeated(&self) -> Option<&T> { @@ -1606,7 +1598,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> { conflicts }) { - conflicting_header.unwrap_mut().short_lived = true; + conflicting_header.short_lived = true; } headers.push(Repeatable { inner: data, repeated: row_group.repeat }); @@ -1825,7 +1817,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> { consecutive_header_start = h.range.start; at_the_end }) { - header_at_the_end.unwrap_mut().short_lived = true; + header_at_the_end.short_lived = true; } // Repeat the gutter below a header (hence why we don't @@ -1833,8 +1825,6 @@ impl<'x> CellGridResolver<'_, '_, 'x> { // Don't do this if there are no rows under the header. if has_gutter { for header in &mut *headers { - let header = header.unwrap_mut(); - // Index of first y is doubled, as each row before it // receives a gutter row below. header.range.start *= 2;