simplify Repeatable, keep only deref

This commit is contained in:
PgBiel 2025-06-10 02:54:07 -03:00
parent 75a4cfb2e4
commit 8cde2d4f17
3 changed files with 29 additions and 39 deletions

View File

@ -274,13 +274,14 @@ impl<'a> GridLayouter<'a> {
pub fn layout(mut self, engine: &mut Engine) -> SourceResult<Fragment> {
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())?;
}

View File

@ -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

View File

@ -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<T> Deref for Repeatable<T> {
}
}
impl<T> Repeatable<T> {
/// 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<T> DerefMut for Repeatable<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<T> Repeatable<T> {
/// 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;