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