mirror of
https://github.com/typst/typst
synced 2025-07-03 18:52:52 +08:00
use may_progress_with_repeats for rowspans
This commit is contained in:
parent
915743e6e8
commit
3cbbcaa734
@ -1793,16 +1793,3 @@ pub(super) fn points(
|
|||||||
offset
|
offset
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the first region of a sequence of regions is not the last usable
|
|
||||||
/// region, assuming that the last region will always be occupied by some
|
|
||||||
/// specific offset height, even after calling `.next()`, due to some
|
|
||||||
/// additional logic which adds content automatically on each region turn (in
|
|
||||||
/// our case, headers).
|
|
||||||
pub(super) fn may_progress_with_offset(regions: Regions<'_>, offset: Abs) -> bool {
|
|
||||||
// Use 'approx_eq' as float addition and subtraction are not associative.
|
|
||||||
!regions.backlog.is_empty()
|
|
||||||
|| regions
|
|
||||||
.last
|
|
||||||
.is_some_and(|height| !(regions.size.y + offset).approx_eq(height))
|
|
||||||
}
|
|
||||||
|
@ -4,7 +4,7 @@ use typst_library::foundations::Resolve;
|
|||||||
use typst_library::layout::grid::resolve::Repeatable;
|
use typst_library::layout::grid::resolve::Repeatable;
|
||||||
use typst_library::layout::{Abs, Axes, Frame, Point, Region, Regions, Size, Sizing};
|
use typst_library::layout::{Abs, Axes, Frame, Point, Region, Regions, Size, Sizing};
|
||||||
|
|
||||||
use super::layouter::{may_progress_with_offset, points, Row};
|
use super::layouter::{points, Row};
|
||||||
use super::{layout_cell, Cell, GridLayouter};
|
use super::{layout_cell, Cell, GridLayouter};
|
||||||
|
|
||||||
/// All information needed to layout a single rowspan.
|
/// All information needed to layout a single rowspan.
|
||||||
@ -258,14 +258,7 @@ impl GridLayouter<'_> {
|
|||||||
|
|
||||||
// Skip to fitting region.
|
// Skip to fitting region.
|
||||||
while !self.regions.size.y.fits(row_group.height)
|
while !self.regions.size.y.fits(row_group.height)
|
||||||
&& may_progress_with_offset(
|
&& self.may_progress_with_repeats()
|
||||||
self.regions,
|
|
||||||
// Use 'repeating_header_height' (ignoring the height of
|
|
||||||
// non-repeated headers) to allow skipping if the
|
|
||||||
// non-repeated header is too large. It will become an
|
|
||||||
// orphan, but when there is no space left, anything goes.
|
|
||||||
self.current.repeating_header_height + self.current.footer_height,
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
self.finish_region(engine, false)?;
|
self.finish_region(engine, false)?;
|
||||||
}
|
}
|
||||||
@ -931,6 +924,8 @@ impl GridLayouter<'_> {
|
|||||||
// won't change is safe.
|
// won't change is safe.
|
||||||
self.current.repeating_header_height,
|
self.current.repeating_header_height,
|
||||||
self.current.footer_height,
|
self.current.footer_height,
|
||||||
|
self.current.could_progress_at_top,
|
||||||
|
self.current.initial_after_repeats,
|
||||||
);
|
);
|
||||||
|
|
||||||
let total_spanned_height = rowspan_simulator.simulate_rowspan_layout(
|
let total_spanned_height = rowspan_simulator.simulate_rowspan_layout(
|
||||||
@ -1031,10 +1026,17 @@ struct RowspanSimulator<'a> {
|
|||||||
finished: usize,
|
finished: usize,
|
||||||
/// The state of regions during the simulation.
|
/// The state of regions during the simulation.
|
||||||
regions: Regions<'a>,
|
regions: Regions<'a>,
|
||||||
/// The height of the header in the currently simulated region.
|
/// The total height of headers in the currently simulated region.
|
||||||
header_height: Abs,
|
header_height: Abs,
|
||||||
/// The height of the footer in the currently simulated region.
|
/// The total height of footers in the currently simulated region.
|
||||||
footer_height: Abs,
|
footer_height: Abs,
|
||||||
|
/// Whether `self.regions.may_progress()` was `true` at the top of the
|
||||||
|
/// region, indicating we can progress anywhere in the current region,
|
||||||
|
/// even right after a repeated header.
|
||||||
|
could_progress_at_top: bool,
|
||||||
|
/// Available height after laying out repeated headers at the top of the
|
||||||
|
/// currently simulated region.
|
||||||
|
initial_after_repeats: Abs,
|
||||||
/// The total spanned height so far in the simulation.
|
/// The total spanned height so far in the simulation.
|
||||||
total_spanned_height: Abs,
|
total_spanned_height: Abs,
|
||||||
/// Height of the latest spanned gutter row in the simulation.
|
/// Height of the latest spanned gutter row in the simulation.
|
||||||
@ -1050,12 +1052,16 @@ impl<'a> RowspanSimulator<'a> {
|
|||||||
regions: Regions<'a>,
|
regions: Regions<'a>,
|
||||||
header_height: Abs,
|
header_height: Abs,
|
||||||
footer_height: Abs,
|
footer_height: Abs,
|
||||||
|
could_progress_at_top: bool,
|
||||||
|
initial_after_repeats: Abs,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
finished,
|
finished,
|
||||||
regions,
|
regions,
|
||||||
header_height,
|
header_height,
|
||||||
footer_height,
|
footer_height,
|
||||||
|
could_progress_at_top,
|
||||||
|
initial_after_repeats,
|
||||||
total_spanned_height: Abs::zero(),
|
total_spanned_height: Abs::zero(),
|
||||||
latest_spanned_gutter_height: Abs::zero(),
|
latest_spanned_gutter_height: Abs::zero(),
|
||||||
}
|
}
|
||||||
@ -1104,10 +1110,7 @@ impl<'a> RowspanSimulator<'a> {
|
|||||||
0,
|
0,
|
||||||
)?;
|
)?;
|
||||||
while !self.regions.size.y.fits(row_group.height)
|
while !self.regions.size.y.fits(row_group.height)
|
||||||
&& may_progress_with_offset(
|
&& self.may_progress_with_repeats()
|
||||||
self.regions,
|
|
||||||
self.header_height + self.footer_height,
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
self.finish_region(layouter, engine)?;
|
self.finish_region(layouter, engine)?;
|
||||||
}
|
}
|
||||||
@ -1129,10 +1132,7 @@ impl<'a> RowspanSimulator<'a> {
|
|||||||
let mut skipped_region = false;
|
let mut skipped_region = false;
|
||||||
while unbreakable_rows_left == 0
|
while unbreakable_rows_left == 0
|
||||||
&& !self.regions.size.y.fits(height)
|
&& !self.regions.size.y.fits(height)
|
||||||
&& may_progress_with_offset(
|
&& self.may_progress_with_repeats()
|
||||||
self.regions,
|
|
||||||
self.header_height + self.footer_height,
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
self.finish_region(layouter, engine)?;
|
self.finish_region(layouter, engine)?;
|
||||||
|
|
||||||
@ -1252,6 +1252,7 @@ impl<'a> RowspanSimulator<'a> {
|
|||||||
// header or footer (as an invariant, any rowspans spanning any header
|
// header or footer (as an invariant, any rowspans spanning any header
|
||||||
// or footer rows are fully contained within that header's or footer's rows).
|
// or footer rows are fully contained within that header's or footer's rows).
|
||||||
self.regions.size.y -= self.header_height + self.footer_height;
|
self.regions.size.y -= self.header_height + self.footer_height;
|
||||||
|
self.initial_after_repeats = self.regions.size.y;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1268,8 +1269,17 @@ impl<'a> RowspanSimulator<'a> {
|
|||||||
self.regions.next();
|
self.regions.next();
|
||||||
self.finished += 1;
|
self.finished += 1;
|
||||||
|
|
||||||
|
self.could_progress_at_top = self.regions.may_progress();
|
||||||
self.simulate_header_footer_layout(layouter, engine)
|
self.simulate_header_footer_layout(layouter, engine)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Similar to [`GridLayouter::may_progress_with_repeats`] but for rowspan
|
||||||
|
/// simulation.
|
||||||
|
fn may_progress_with_repeats(&self) -> bool {
|
||||||
|
self.could_progress_at_top
|
||||||
|
|| self.regions.last.is_some()
|
||||||
|
&& self.regions.size.y != self.initial_after_repeats
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtracts some size from the end of a vector of sizes.
|
/// Subtracts some size from the end of a vector of sizes.
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 437 B After Width: | Height: | Size: 491 B |
Loading…
x
Reference in New Issue
Block a user