mirror of
https://github.com/typst/typst
synced 2025-08-18 00:48:34 +08:00
Compare commits
No commits in common. "af0c27cb98716ae6614120996be1c5df85da7103" and "1e3719a9ba19a9736fe05049baa90b2a7d3b0330" have entirely different histories.
af0c27cb98
...
1e3719a9ba
@ -43,8 +43,31 @@ pub struct GridLayouter<'a> {
|
||||
/// Rowspans not yet laid out because not all of their spanned rows were
|
||||
/// laid out yet.
|
||||
pub(super) rowspans: Vec<Rowspan>,
|
||||
/// Grid layout state for the current region.
|
||||
pub(super) current: Current,
|
||||
/// The initial size of the current region before we started subtracting.
|
||||
pub(super) initial: Size,
|
||||
/// The amount of repeated header rows at the start of the current region.
|
||||
/// Note that `repeating_headers` and `pending_headers` can change if we
|
||||
/// find a new header inside the region (not at the top), so this field
|
||||
/// is required to access information from the top of the region.
|
||||
///
|
||||
/// This is used for orphan prevention checks (if there are no rows other
|
||||
/// than repeated header rows upon finishing a region, we'd have an orphan).
|
||||
/// Note that non-repeated and pending repeated header rows are not included
|
||||
/// in this number and thus use a separate mechanism for orphan prevention
|
||||
/// (`lrows_orphan_shapshot` field).
|
||||
///
|
||||
/// In addition, this information is used on finish region to calculate the
|
||||
/// total height of resolved header rows at the top of the region, which is
|
||||
/// used by multi-page rowspans so they can properly skip the header rows
|
||||
/// at the top of the region during layout.
|
||||
pub(super) current_repeating_header_rows: usize,
|
||||
/// The end bound of the last repeating header at the start of the region.
|
||||
/// The last row might have disappeared due to being empty, so this is how
|
||||
/// we can become aware of that. Line layout uses this to determine when to
|
||||
/// prioritize the last lines under a header.
|
||||
///
|
||||
/// A value of zero indicates no headers were placed.
|
||||
pub(super) current_last_repeated_header_end: usize,
|
||||
/// Frames for finished regions.
|
||||
pub(super) finished: Vec<Frame>,
|
||||
/// The amount and height of header rows on each finished region.
|
||||
@ -61,46 +84,16 @@ pub struct GridLayouter<'a> {
|
||||
/// Sorted by increasing levels.
|
||||
pub(super) pending_headers: &'a [Repeatable<Header>],
|
||||
pub(super) upcoming_headers: &'a [Repeatable<Header>],
|
||||
/// The height for each repeating header that was placed in this region.
|
||||
/// Note that this includes headers not at the top of the region (pending
|
||||
/// headers), and excludes headers removed by virtue of a new, conflicting
|
||||
/// header being found.
|
||||
pub(super) repeating_header_heights: Vec<Abs>,
|
||||
/// If this is `Some`, this will receive the currently laid out row's
|
||||
/// height if it is auto or relative. This is used for header height
|
||||
/// calculation.
|
||||
/// TODO: consider refactoring this into something nicer.
|
||||
pub(super) current_row_height: Option<Abs>,
|
||||
/// The span of the grid element.
|
||||
pub(super) span: Span,
|
||||
}
|
||||
|
||||
/// Grid layout state for the current region. This should be reset or updated
|
||||
/// on each region break.
|
||||
pub(super) struct Current {
|
||||
/// The initial size of the current region before we started subtracting.
|
||||
pub(super) initial: Size,
|
||||
/// The amount of repeated header rows at the start of the current region.
|
||||
/// Thus, excludes rows from pending headers (which were placed for the
|
||||
/// first time).
|
||||
///
|
||||
/// Note that `repeating_headers` and `pending_headers` can change if we
|
||||
/// find a new header inside the region (not at the top), so this field
|
||||
/// is required to access information from the top of the region.
|
||||
///
|
||||
/// This is used for orphan prevention checks (if there are no rows other
|
||||
/// than repeated header rows upon finishing a region, we'd have orphans).
|
||||
/// Note that non-repeated and pending repeated header rows are not included
|
||||
/// in this number as they use a separate mechanism for orphan prevention
|
||||
/// (`lrows_orphan_shapshot` field).
|
||||
///
|
||||
/// In addition, this information is used on finish region to calculate the
|
||||
/// total height of resolved header rows at the top of the region, which is
|
||||
/// used by multi-page rowspans so they can properly skip the header rows
|
||||
/// at the top of the region during layout.
|
||||
pub(super) repeated_header_rows: usize,
|
||||
/// The end bound of the last repeating header at the start of the region.
|
||||
/// The last row might have disappeared due to being empty, so this is how
|
||||
/// we can become aware of that. Line layout uses this to determine when to
|
||||
/// prioritize the last lines under a header.
|
||||
///
|
||||
/// A value of zero indicates no headers were placed.
|
||||
pub(super) last_repeated_header_end: usize,
|
||||
/// Stores the length of `lrows` before a sequence of trailing rows
|
||||
/// equipped with orphan prevention were laid out. In this case, if no more
|
||||
/// rows are laid out after those rows before the region ends, the rows
|
||||
@ -108,9 +101,7 @@ pub(super) struct Current {
|
||||
/// headers will have been moved to the `pending_headers` vector and so
|
||||
/// will automatically be placed again until they fit.
|
||||
pub(super) lrows_orphan_snapshot: Option<usize>,
|
||||
/// The total simulated height for all headers currently in
|
||||
/// `repeating_headers` and `pending_headers`.
|
||||
///
|
||||
/// The simulated header height.
|
||||
/// This field is reset in `layout_header` and properly updated by
|
||||
/// `layout_auto_row` and `layout_relative_row`, and should not be read
|
||||
/// before all header rows are fully laid out. It is usually fine because
|
||||
@ -125,15 +116,11 @@ pub(super) struct Current {
|
||||
/// In particular, non-repeating headers only occupy the initial region,
|
||||
/// but disappear on new regions, so they can be ignored.
|
||||
pub(super) repeating_header_height: Abs,
|
||||
/// The height for each repeating header that was placed in this region.
|
||||
/// Note that this includes headers not at the top of the region (pending
|
||||
/// headers), and excludes headers removed by virtue of a new, conflicting
|
||||
/// header being found.
|
||||
pub(super) repeating_header_heights: Vec<Abs>,
|
||||
/// The simulated footer height for this region.
|
||||
///
|
||||
/// The simulation occurs before any rows are laid out for a region.
|
||||
pub(super) footer_height: Abs,
|
||||
/// The span of the grid element.
|
||||
pub(super) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@ -201,23 +188,21 @@ impl<'a> GridLayouter<'a> {
|
||||
lrows: vec![],
|
||||
unbreakable_rows_left: 0,
|
||||
rowspans: vec![],
|
||||
initial: regions.size,
|
||||
current_repeating_header_rows: 0,
|
||||
current_last_repeated_header_end: 0,
|
||||
finished: vec![],
|
||||
finished_header_rows: vec![],
|
||||
is_rtl: TextElem::dir_in(styles) == Dir::RTL,
|
||||
repeating_headers: vec![],
|
||||
upcoming_headers: &grid.headers,
|
||||
repeating_header_heights: vec![],
|
||||
pending_headers: Default::default(),
|
||||
lrows_orphan_snapshot: None,
|
||||
current_row_height: None,
|
||||
current: Current {
|
||||
initial: regions.size,
|
||||
repeated_header_rows: 0,
|
||||
last_repeated_header_end: 0,
|
||||
lrows_orphan_snapshot: None,
|
||||
header_height: Abs::zero(),
|
||||
repeating_header_height: Abs::zero(),
|
||||
repeating_header_heights: vec![],
|
||||
footer_height: Abs::zero(),
|
||||
},
|
||||
header_height: Abs::zero(),
|
||||
repeating_header_height: Abs::zero(),
|
||||
footer_height: Abs::zero(),
|
||||
span,
|
||||
}
|
||||
}
|
||||
@ -230,7 +215,7 @@ impl<'a> GridLayouter<'a> {
|
||||
// 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.regions.size.y -= self.footer_height;
|
||||
}
|
||||
|
||||
let mut y = 0;
|
||||
@ -359,7 +344,7 @@ impl<'a> GridLayouter<'a> {
|
||||
self.layout_relative_row(engine, disambiguator, v, y)?
|
||||
}
|
||||
Sizing::Fr(v) => {
|
||||
self.current.lrows_orphan_snapshot = None;
|
||||
self.lrows_orphan_snapshot = None;
|
||||
self.lrows.push(Row::Fr(v, y, disambiguator))
|
||||
}
|
||||
}
|
||||
@ -1109,7 +1094,7 @@ impl<'a> GridLayouter<'a> {
|
||||
target.set_max(
|
||||
region.y
|
||||
- if i > 0 {
|
||||
self.current.repeating_header_height + self.current.footer_height
|
||||
self.repeating_header_height + self.footer_height
|
||||
} else {
|
||||
Abs::zero()
|
||||
},
|
||||
@ -1340,7 +1325,7 @@ impl<'a> GridLayouter<'a> {
|
||||
&& !self.regions.size.y.fits(height)
|
||||
&& may_progress_with_offset(
|
||||
self.regions,
|
||||
self.current.header_height + self.current.footer_height,
|
||||
self.header_height + self.footer_height,
|
||||
)
|
||||
{
|
||||
self.finish_region(engine, false)?;
|
||||
@ -1474,7 +1459,7 @@ impl<'a> GridLayouter<'a> {
|
||||
fn push_row(&mut self, frame: Frame, y: usize, is_last: bool) {
|
||||
// There is now a row after the rows equipped with orphan prevention,
|
||||
// so no need to remove them anymore.
|
||||
self.current.lrows_orphan_snapshot = None;
|
||||
self.lrows_orphan_snapshot = None;
|
||||
self.regions.size.y -= frame.height();
|
||||
self.lrows.push(Row::Frame(frame, y, is_last));
|
||||
}
|
||||
@ -1485,11 +1470,11 @@ impl<'a> GridLayouter<'a> {
|
||||
engine: &mut Engine,
|
||||
last: bool,
|
||||
) -> SourceResult<()> {
|
||||
if let Some(orphan_snapshot) = self.current.lrows_orphan_snapshot.take() {
|
||||
if let Some(orphan_snapshot) = self.lrows_orphan_snapshot.take() {
|
||||
if !last {
|
||||
self.lrows.truncate(orphan_snapshot);
|
||||
self.current.repeated_header_rows =
|
||||
self.current.repeated_header_rows.min(orphan_snapshot);
|
||||
self.current_repeating_header_rows =
|
||||
self.current_repeating_header_rows.min(orphan_snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1500,13 +1485,12 @@ impl<'a> GridLayouter<'a> {
|
||||
{
|
||||
// Remove the last row in the region if it is a gutter row.
|
||||
self.lrows.pop().unwrap();
|
||||
self.current.repeated_header_rows =
|
||||
self.current.repeated_header_rows.min(self.lrows.len());
|
||||
self.current_repeating_header_rows =
|
||||
self.current_repeating_header_rows.min(self.lrows.len());
|
||||
}
|
||||
|
||||
let footer_would_be_widow = if let Some(last_header_row) = self
|
||||
.current
|
||||
.repeated_header_rows
|
||||
.current_repeating_header_rows
|
||||
.checked_sub(1)
|
||||
.and_then(|last_header_index| self.lrows.get(last_header_index))
|
||||
{
|
||||
@ -1518,21 +1502,21 @@ impl<'a> GridLayouter<'a> {
|
||||
.as_ref()
|
||||
.and_then(Repeatable::as_repeated)
|
||||
.is_none_or(|footer| footer.start != last_header_end)
|
||||
&& self.lrows.len() == self.current.repeated_header_rows
|
||||
&& self.lrows.len() == self.current_repeating_header_rows
|
||||
&& may_progress_with_offset(
|
||||
self.regions,
|
||||
// Since we're trying to find a region where to place all
|
||||
// repeating + pending headers, it makes sense to use
|
||||
// 'header_height' and include even non-repeating pending
|
||||
// headers for this check.
|
||||
self.current.header_height + self.current.footer_height,
|
||||
self.header_height + self.footer_height,
|
||||
)
|
||||
{
|
||||
// Header and footer would be alone in this region, but there are more
|
||||
// rows beyond the header and the footer. Push an empty region.
|
||||
self.lrows.clear();
|
||||
self.current.last_repeated_header_end = 0;
|
||||
self.current.repeated_header_rows = 0;
|
||||
self.current_last_repeated_header_end = 0;
|
||||
self.current_repeating_header_rows = 0;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@ -1549,7 +1533,7 @@ impl<'a> GridLayouter<'a> {
|
||||
// This header height isn't doing much as we just confirmed
|
||||
// that there are no headers in this region, but let's keep
|
||||
// it here for correctness. It will add zero anyway.
|
||||
self.current.header_height + self.current.footer_height,
|
||||
self.header_height + self.footer_height,
|
||||
)
|
||||
&& footer.start != 0
|
||||
} else {
|
||||
@ -1580,9 +1564,9 @@ impl<'a> GridLayouter<'a> {
|
||||
|
||||
// Determine the size of the grid in this region, expanding fully if
|
||||
// there are fr rows.
|
||||
let mut size = Size::new(self.width, used).min(self.current.initial);
|
||||
if fr.get() > 0.0 && self.current.initial.y.is_finite() {
|
||||
size.y = self.current.initial.y;
|
||||
let mut size = Size::new(self.width, used).min(self.initial);
|
||||
if fr.get() > 0.0 && self.initial.y.is_finite() {
|
||||
size.y = self.initial.y;
|
||||
}
|
||||
|
||||
// The frame for the region.
|
||||
@ -1604,7 +1588,7 @@ impl<'a> GridLayouter<'a> {
|
||||
};
|
||||
|
||||
let height = frame.height();
|
||||
if i < self.current.repeated_header_rows {
|
||||
if i < self.current_repeating_header_rows {
|
||||
header_row_height += height;
|
||||
}
|
||||
|
||||
@ -1704,18 +1688,18 @@ impl<'a> GridLayouter<'a> {
|
||||
output,
|
||||
rrows,
|
||||
FinishedHeaderRowInfo {
|
||||
repeated: self.current.repeated_header_rows,
|
||||
last_repeated_header_end: self.current.last_repeated_header_end,
|
||||
repeated: self.current_repeating_header_rows,
|
||||
last_repeated_header_end: self.current_last_repeated_header_end,
|
||||
height: header_row_height,
|
||||
},
|
||||
);
|
||||
|
||||
if !last {
|
||||
self.current.repeated_header_rows = 0;
|
||||
self.current.last_repeated_header_end = 0;
|
||||
self.current.header_height = Abs::zero();
|
||||
self.current.repeating_header_height = Abs::zero();
|
||||
self.current.repeating_header_heights.clear();
|
||||
self.current_repeating_header_rows = 0;
|
||||
self.current_last_repeated_header_end = 0;
|
||||
self.header_height = Abs::zero();
|
||||
self.repeating_header_height = Abs::zero();
|
||||
self.repeating_header_heights.clear();
|
||||
|
||||
let disambiguator = self.finished.len();
|
||||
if let Some(Repeatable::Repeated(footer)) = &self.grid.footer {
|
||||
@ -1726,7 +1710,7 @@ impl<'a> GridLayouter<'a> {
|
||||
// Note that header layout will only subtract this again if it has
|
||||
// to skip regions to fit headers, so there is no risk of
|
||||
// subtracting this twice.
|
||||
self.regions.size.y -= self.current.footer_height;
|
||||
self.regions.size.y -= self.footer_height;
|
||||
|
||||
if !self.repeating_headers.is_empty() || !self.pending_headers.is_empty() {
|
||||
// Add headers to the new region.
|
||||
@ -1748,14 +1732,14 @@ impl<'a> GridLayouter<'a> {
|
||||
self.finished.push(output);
|
||||
self.rrows.push(resolved_rows);
|
||||
self.regions.next();
|
||||
self.current.initial = self.regions.size;
|
||||
self.initial = self.regions.size;
|
||||
|
||||
if !self.grid.headers.is_empty() {
|
||||
self.finished_header_rows.push(header_row_info);
|
||||
}
|
||||
|
||||
// Ensure orphan prevention is handled before resolving rows.
|
||||
debug_assert!(self.current.lrows_orphan_snapshot.is_none());
|
||||
debug_assert!(self.lrows_orphan_snapshot.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,16 +142,15 @@ impl<'a> GridLayouter<'a> {
|
||||
|
||||
// Ensure upcoming rows won't see that these headers will occupy any
|
||||
// space in future regions anymore.
|
||||
for removed_height in
|
||||
self.current.repeating_header_heights.drain(first_conflicting_pos..)
|
||||
for removed_height in self.repeating_header_heights.drain(first_conflicting_pos..)
|
||||
{
|
||||
self.current.repeating_header_height -= removed_height;
|
||||
self.repeating_header_height -= removed_height;
|
||||
}
|
||||
|
||||
// Non-repeating headers stop at the pending stage for orphan
|
||||
// prevention only. Flushing pending headers, so those will no longer
|
||||
// appear in a future region.
|
||||
self.current.header_height = self.current.repeating_header_height;
|
||||
self.header_height = self.repeating_header_height;
|
||||
|
||||
// Let's try to place them at least once.
|
||||
// This might be a waste as we could generate an orphan and thus have
|
||||
@ -224,7 +223,7 @@ impl<'a> GridLayouter<'a> {
|
||||
// available size for consistency with the first region, so we
|
||||
// need to consider the footer when evaluating if skipping yet
|
||||
// another region would make a difference.
|
||||
self.current.footer_height,
|
||||
self.footer_height,
|
||||
)
|
||||
{
|
||||
// Advance regions without any output until we can place the
|
||||
@ -239,7 +238,7 @@ impl<'a> GridLayouter<'a> {
|
||||
// if 'full' changes? (Assuming height doesn't change for now...)
|
||||
skipped_region = true;
|
||||
|
||||
self.regions.size.y -= self.current.footer_height;
|
||||
self.regions.size.y -= self.footer_height;
|
||||
}
|
||||
|
||||
if let Some(Repeatable::Repeated(footer)) = &self.grid.footer {
|
||||
@ -247,11 +246,11 @@ impl<'a> GridLayouter<'a> {
|
||||
// Simulate the footer again; the region's 'full' might have
|
||||
// changed.
|
||||
// TODO: maybe this should go in the loop, a bit hacky as is...
|
||||
self.regions.size.y += self.current.footer_height;
|
||||
self.current.footer_height = self
|
||||
self.regions.size.y += self.footer_height;
|
||||
self.footer_height = self
|
||||
.simulate_footer(footer, &self.regions, engine, disambiguator)?
|
||||
.height;
|
||||
self.regions.size.y -= self.current.footer_height;
|
||||
self.regions.size.y -= self.footer_height;
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,22 +265,22 @@ impl<'a> GridLayouter<'a> {
|
||||
// within 'layout_row'.
|
||||
self.unbreakable_rows_left += repeating_header_rows + pending_header_rows;
|
||||
|
||||
self.current.last_repeated_header_end =
|
||||
self.current_last_repeated_header_end =
|
||||
self.repeating_headers.last().map(|h| h.end).unwrap_or_default();
|
||||
|
||||
// Reset the header height for this region.
|
||||
// It will be re-calculated when laying out each header row.
|
||||
self.current.header_height = Abs::zero();
|
||||
self.current.repeating_header_height = Abs::zero();
|
||||
self.current.repeating_header_heights.clear();
|
||||
self.header_height = Abs::zero();
|
||||
self.repeating_header_height = Abs::zero();
|
||||
self.repeating_header_heights.clear();
|
||||
|
||||
// Use indices to avoid double borrow. We don't mutate headers in
|
||||
// 'layout_row' so this is fine.
|
||||
let mut i = 0;
|
||||
while let Some(&header) = self.repeating_headers.get(i) {
|
||||
let header_height = self.layout_header_rows(header, engine, disambiguator)?;
|
||||
self.current.header_height += header_height;
|
||||
self.current.repeating_header_height += header_height;
|
||||
self.header_height += header_height;
|
||||
self.repeating_header_height += header_height;
|
||||
|
||||
// We assume that this vector will be sorted according
|
||||
// to increasing levels like 'repeating_headers' and
|
||||
@ -301,26 +300,26 @@ impl<'a> GridLayouter<'a> {
|
||||
// headers which have now stopped repeating. They are always at
|
||||
// the end and new pending headers respect the existing sort,
|
||||
// so the vector will remain sorted.
|
||||
self.current.repeating_header_heights.push(header_height);
|
||||
self.repeating_header_heights.push(header_height);
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
self.current.repeated_header_rows = self.lrows.len();
|
||||
self.current_repeating_header_rows = self.lrows.len();
|
||||
|
||||
if !self.pending_headers.is_empty() {
|
||||
// Restore snapshot: if pending headers placed again turn out to be
|
||||
// orphans, remove their rows again.
|
||||
self.current.lrows_orphan_snapshot = Some(self.lrows.len());
|
||||
self.lrows_orphan_snapshot = Some(self.lrows.len());
|
||||
}
|
||||
|
||||
for header in self.pending_headers {
|
||||
let header_height =
|
||||
self.layout_header_rows(header.unwrap(), engine, disambiguator)?;
|
||||
self.current.header_height += header_height;
|
||||
self.header_height += header_height;
|
||||
if matches!(header, Repeatable::Repeated(_)) {
|
||||
self.current.repeating_header_height += header_height;
|
||||
self.current.repeating_header_heights.push(header_height);
|
||||
self.repeating_header_height += header_height;
|
||||
self.repeating_header_heights.push(header_height);
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,7 +359,7 @@ impl<'a> GridLayouter<'a> {
|
||||
// 'header_height == repeating_header_height' here
|
||||
// (there won't be any pending headers at this point, other
|
||||
// than the ones we are about to place).
|
||||
self.current.header_height + self.current.footer_height,
|
||||
self.header_height + self.footer_height,
|
||||
)
|
||||
{
|
||||
// Note that, after the first region skip, the new headers will go
|
||||
@ -383,10 +382,10 @@ impl<'a> GridLayouter<'a> {
|
||||
// region, so multi-page rows and cells can effectively ignore
|
||||
// this header.
|
||||
if !short_lived {
|
||||
self.current.header_height += header_height;
|
||||
self.header_height += header_height;
|
||||
if matches!(header, Repeatable::Repeated(_)) {
|
||||
self.current.repeating_header_height += header_height;
|
||||
self.current.repeating_header_heights.push(header_height);
|
||||
self.repeating_header_height += header_height;
|
||||
self.repeating_header_heights.push(header_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -394,7 +393,7 @@ impl<'a> GridLayouter<'a> {
|
||||
// Remove new headers at the end of the region if upcoming child doesn't fit.
|
||||
// TODO: Short lived if footer comes afterwards
|
||||
if !short_lived {
|
||||
self.current.lrows_orphan_snapshot = Some(initial_row_count);
|
||||
self.lrows_orphan_snapshot = Some(initial_row_count);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -467,7 +466,7 @@ impl<'a> GridLayouter<'a> {
|
||||
// That is unnecessary at the moment as 'prepare_footers' is only
|
||||
// called at the start of the region, but what about when we can have
|
||||
// footers in the middle of the region? Let's think about this then.
|
||||
self.current.footer_height = if skipped_region {
|
||||
self.footer_height = if skipped_region {
|
||||
// Simulate the footer again; the region's 'full' might have
|
||||
// changed.
|
||||
self.simulate_footer(footer, &self.regions, engine, disambiguator)?
|
||||
@ -490,7 +489,7 @@ impl<'a> GridLayouter<'a> {
|
||||
// Ensure footer rows have their own height available.
|
||||
// Won't change much as we're creating an unbreakable row group
|
||||
// anyway, so this is mostly for correctness.
|
||||
self.regions.size.y += self.current.footer_height;
|
||||
self.regions.size.y += self.footer_height;
|
||||
|
||||
let footer_len = self.grid.rows.len() - footer.start;
|
||||
self.unbreakable_rows_left += footer_len;
|
||||
|
@ -263,7 +263,7 @@ impl GridLayouter<'_> {
|
||||
// due to orphan/widow prevention, which explains the usage of
|
||||
// 'header_height' (include non-repeating but pending headers) rather
|
||||
// than 'repeating_header_height'.
|
||||
self.current.header_height + self.current.footer_height,
|
||||
self.header_height + self.footer_height,
|
||||
)
|
||||
{
|
||||
self.finish_region(engine, false)?;
|
||||
@ -422,9 +422,7 @@ impl GridLayouter<'_> {
|
||||
let mapped_regions = self.regions.map(&mut custom_backlog, |size| {
|
||||
Size::new(
|
||||
size.x,
|
||||
size.y
|
||||
- self.current.repeating_header_height
|
||||
- self.current.footer_height,
|
||||
size.y - self.repeating_header_height - self.footer_height,
|
||||
)
|
||||
});
|
||||
|
||||
@ -537,7 +535,7 @@ impl GridLayouter<'_> {
|
||||
// and unbreakable rows in general, so there is no risk
|
||||
// of accessing an incomplete list of rows.
|
||||
let initial_header_height = self.lrows
|
||||
[..self.current.repeated_header_rows]
|
||||
[..self.current_repeating_header_rows]
|
||||
.iter()
|
||||
.map(|row| match row {
|
||||
Row::Frame(frame, _, _) => frame.height(),
|
||||
@ -545,9 +543,7 @@ impl GridLayouter<'_> {
|
||||
})
|
||||
.sum();
|
||||
|
||||
self.current.initial.y
|
||||
- initial_header_height
|
||||
- self.current.footer_height
|
||||
self.initial.y - initial_header_height - self.footer_height
|
||||
} else {
|
||||
// When measuring unbreakable auto rows, infinite
|
||||
// height is available for content to expand.
|
||||
@ -563,8 +559,7 @@ impl GridLayouter<'_> {
|
||||
// Assume only repeating headers will survive starting at
|
||||
// the next region.
|
||||
let backlog = self.regions.backlog.iter().map(|&size| {
|
||||
size - self.current.repeating_header_height
|
||||
- self.current.footer_height
|
||||
size - self.repeating_header_height - self.footer_height
|
||||
});
|
||||
|
||||
heights_up_to_current_region.chain(backlog).collect::<Vec<_>>()
|
||||
@ -579,10 +574,10 @@ impl GridLayouter<'_> {
|
||||
height = *rowspan_height;
|
||||
backlog = None;
|
||||
full = rowspan_full;
|
||||
last = self.regions.last.map(|size| {
|
||||
size - self.current.repeating_header_height
|
||||
- self.current.footer_height
|
||||
});
|
||||
last = self
|
||||
.regions
|
||||
.last
|
||||
.map(|size| size - self.repeating_header_height - self.footer_height);
|
||||
} else {
|
||||
// The rowspan started in the current region, as its vector
|
||||
// of heights in regions is currently empty.
|
||||
@ -787,8 +782,7 @@ impl GridLayouter<'_> {
|
||||
// Subtract the repeating header and footer height, since that's
|
||||
// the height we used when subtracting from the region backlog's
|
||||
// heights while measuring cells.
|
||||
simulated_regions.size.y -=
|
||||
self.current.repeating_header_height + self.current.footer_height;
|
||||
simulated_regions.size.y -= self.repeating_header_height + self.footer_height;
|
||||
}
|
||||
|
||||
if let Some(original_last_resolved_size) = last_resolved_size {
|
||||
@ -927,8 +921,8 @@ impl GridLayouter<'_> {
|
||||
// rowspan, since headers and footers are unbreakable, so
|
||||
// assuming the repeating header height and footer height
|
||||
// won't change is safe.
|
||||
self.current.repeating_header_height,
|
||||
self.current.footer_height,
|
||||
self.repeating_header_height,
|
||||
self.footer_height,
|
||||
);
|
||||
|
||||
let total_spanned_height = rowspan_simulator.simulate_rowspan_layout(
|
||||
@ -1012,7 +1006,7 @@ impl GridLayouter<'_> {
|
||||
extra_amount_to_grow -= simulated_regions.size.y.max(Abs::zero());
|
||||
simulated_regions.next();
|
||||
simulated_regions.size.y -=
|
||||
self.current.repeating_header_height + self.current.footer_height;
|
||||
self.repeating_header_height + self.footer_height;
|
||||
disambiguator += 1;
|
||||
}
|
||||
simulated_regions.size.y -= extra_amount_to_grow;
|
||||
|
Loading…
x
Reference in New Issue
Block a user