mirror of
https://github.com/typst/typst
synced 2025-05-19 11:35:27 +08:00
create lrows orphan snapshot
- Indicate some rows at the end cannot be orphans
This commit is contained in:
parent
f81560af47
commit
40bc08291d
@ -92,6 +92,13 @@ pub struct GridLayouter<'a> {
|
|||||||
/// calculation.
|
/// calculation.
|
||||||
/// TODO: consider refactoring this into something nicer.
|
/// TODO: consider refactoring this into something nicer.
|
||||||
pub(super) current_row_height: Option<Abs>,
|
pub(super) current_row_height: Option<Abs>,
|
||||||
|
/// 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
|
||||||
|
/// will be removed. For new headers in particular, which use this, those
|
||||||
|
/// 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 simulated header height.
|
/// The simulated header height.
|
||||||
/// This field is reset in `layout_header` and properly updated by
|
/// This field is reset in `layout_header` and properly updated by
|
||||||
/// `layout_auto_row` and `layout_relative_row`, and should not be read
|
/// `layout_auto_row` and `layout_relative_row`, and should not be read
|
||||||
@ -190,6 +197,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
upcoming_headers: &grid.headers,
|
upcoming_headers: &grid.headers,
|
||||||
repeating_header_heights: vec![],
|
repeating_header_heights: vec![],
|
||||||
pending_headers: Default::default(),
|
pending_headers: Default::default(),
|
||||||
|
lrows_orphan_snapshot: None,
|
||||||
current_row_height: None,
|
current_row_height: None,
|
||||||
header_height: Abs::zero(),
|
header_height: Abs::zero(),
|
||||||
repeating_header_height: Abs::zero(),
|
repeating_header_height: Abs::zero(),
|
||||||
@ -334,7 +342,10 @@ impl<'a> GridLayouter<'a> {
|
|||||||
Sizing::Rel(v) => {
|
Sizing::Rel(v) => {
|
||||||
self.layout_relative_row(engine, disambiguator, v, y)?
|
self.layout_relative_row(engine, disambiguator, v, y)?
|
||||||
}
|
}
|
||||||
Sizing::Fr(v) => self.lrows.push(Row::Fr(v, y, disambiguator)),
|
Sizing::Fr(v) => {
|
||||||
|
self.lrows_orphan_snapshot = None;
|
||||||
|
self.lrows.push(Row::Fr(v, y, disambiguator))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1445,6 +1456,9 @@ impl<'a> GridLayouter<'a> {
|
|||||||
/// will be pushed for this particular row. It can be `false` for rows
|
/// will be pushed for this particular row. It can be `false` for rows
|
||||||
/// spanning multiple regions.
|
/// spanning multiple regions.
|
||||||
fn push_row(&mut self, frame: Frame, y: usize, is_last: bool) {
|
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.lrows_orphan_snapshot = None;
|
||||||
self.regions.size.y -= frame.height();
|
self.regions.size.y -= frame.height();
|
||||||
self.lrows.push(Row::Frame(frame, y, is_last));
|
self.lrows.push(Row::Frame(frame, y, is_last));
|
||||||
}
|
}
|
||||||
@ -1455,6 +1469,15 @@ impl<'a> GridLayouter<'a> {
|
|||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
last: bool,
|
last: bool,
|
||||||
) -> SourceResult<()> {
|
) -> SourceResult<()> {
|
||||||
|
if let Some(orphan_snapshot) = self.lrows_orphan_snapshot.take() {
|
||||||
|
if !last {
|
||||||
|
self.lrows.truncate(orphan_snapshot);
|
||||||
|
self.current_header_rows = self.current_header_rows.min(orphan_snapshot);
|
||||||
|
self.current_repeating_header_rows =
|
||||||
|
self.current_repeating_header_rows.min(orphan_snapshot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self
|
if self
|
||||||
.lrows
|
.lrows
|
||||||
.last()
|
.last()
|
||||||
@ -1462,13 +1485,9 @@ impl<'a> GridLayouter<'a> {
|
|||||||
{
|
{
|
||||||
// Remove the last row in the region if it is a gutter row.
|
// Remove the last row in the region if it is a gutter row.
|
||||||
self.lrows.pop().unwrap();
|
self.lrows.pop().unwrap();
|
||||||
|
self.current_header_rows = self.current_header_rows.min(self.lrows.len());
|
||||||
if self.lrows.len() == self.current_header_rows {
|
self.current_repeating_header_rows =
|
||||||
if self.current_header_rows == self.current_repeating_header_rows {
|
self.current_repeating_header_rows.min(self.lrows.len());
|
||||||
self.current_repeating_header_rows -= 1;
|
|
||||||
}
|
|
||||||
self.current_header_rows -= 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let footer_would_be_widow = if let Some(last_header_row) = self
|
let footer_would_be_widow = if let Some(last_header_row) = self
|
||||||
@ -1727,6 +1746,9 @@ impl<'a> GridLayouter<'a> {
|
|||||||
if !self.grid.headers.is_empty() {
|
if !self.grid.headers.is_empty() {
|
||||||
self.finished_header_rows.push(header_row_info);
|
self.finished_header_rows.push(header_row_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure orphan prevention is handled before resolving rows.
|
||||||
|
debug_assert!(self.lrows_orphan_snapshot.is_none());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user