summaryrefslogtreecommitdiff
path: root/library/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/src')
-rw-r--r--library/src/layout/grid.rs81
1 files changed, 49 insertions, 32 deletions
diff --git a/library/src/layout/grid.rs b/library/src/layout/grid.rs
index 63183e1d..acfee8a2 100644
--- a/library/src/layout/grid.rs
+++ b/library/src/layout/grid.rs
@@ -450,33 +450,15 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
/// Layout a row with automatic height. Such a row may break across multiple
/// regions.
fn layout_auto_row(&mut self, y: usize) -> SourceResult<()> {
- let mut resolved: Vec<Abs> = vec![];
- let mut skip = false;
-
- // Determine the size for each region of the row.
- for (x, &rcol) in self.rcols.iter().enumerate() {
- if let Some(cell) = self.cell(x, y) {
- let mut pod = self.regions;
- pod.size.x = rcol;
-
- let frames = cell.measure(self.vt, self.styles, pod)?.into_frames();
- if let [first, rest @ ..] = frames.as_slice() {
- skip |=
- first.is_empty() && rest.iter().any(|frame| !frame.is_empty());
- }
-
- // For each region, we want to know the maximum height any
- // column requires.
- let mut sizes = frames.iter().map(|frame| frame.height());
- for (target, size) in resolved.iter_mut().zip(&mut sizes) {
- target.set_max(size);
- }
-
- // New heights are maximal by virtue of being new. Note that
- // this extend only uses the rest of the sizes iterator.
- resolved.extend(sizes);
+ // Determine the size for each region of the row. If the first region
+ // ends up empty for some column, skip the region and remeasure.
+ let mut resolved = match self.measure_auto_row(y, true)? {
+ Some(resolved) => resolved,
+ None => {
+ self.finish_region()?;
+ self.measure_auto_row(y, false)?.unwrap()
}
- }
+ };
// Nothing to layout.
if resolved.is_empty() {
@@ -490,12 +472,6 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
return Ok(());
}
- // Skip the first region if it's empty for some cell.
- if skip && !self.regions.in_last() {
- self.finish_region()?;
- resolved.remove(0);
- }
-
// Expand all but the last region.
// Skip the first region if the space is eaten up by an fr row.
let len = resolved.len();
@@ -521,6 +497,47 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
Ok(())
}
+ /// Measure the regions sizes of an auto row. The option is always `Some(_)`
+ /// if `can_skip` is false.
+ fn measure_auto_row(
+ &mut self,
+ y: usize,
+ can_skip: bool,
+ ) -> SourceResult<Option<Vec<Abs>>> {
+ let mut resolved: Vec<Abs> = vec![];
+
+ for (x, &rcol) in self.rcols.iter().enumerate() {
+ if let Some(cell) = self.cell(x, y) {
+ let mut pod = self.regions;
+ pod.size.x = rcol;
+
+ let frames = cell.measure(self.vt, self.styles, pod)?.into_frames();
+
+ // Skip the first region if one cell in it is empty. Then,
+ // remeasure.
+ if let [first, rest @ ..] = frames.as_slice() {
+ if can_skip
+ && first.is_empty()
+ && rest.iter().any(|frame| !frame.is_empty())
+ {
+ return Ok(None);
+ }
+ }
+
+ let mut sizes = frames.iter().map(|frame| frame.height());
+ for (target, size) in resolved.iter_mut().zip(&mut sizes) {
+ target.set_max(size);
+ }
+
+ // New heights are maximal by virtue of being new. Note that
+ // this extend only uses the rest of the sizes iterator.
+ resolved.extend(sizes);
+ }
+ }
+
+ Ok(Some(resolved))
+ }
+
/// Layout a row with relative height. Such a row cannot break across
/// multiple regions, but it may force a region break.
fn layout_relative_row(&mut self, v: Rel<Length>, y: usize) -> SourceResult<()> {