diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-30 14:49:55 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-30 14:49:55 +0100 |
| commit | bdf06c9c61c3a9e0e9104d012828583638797edc (patch) | |
| tree | d47124fe4c5f54eace49df2ed34691931d4f8e77 | |
| parent | 579dac3c91faf73866f4b9b13381393ddf7b2f9b (diff) | |
Fix auto column shrinking behaviour
| -rw-r--r-- | library/src/layout/grid.rs | 46 | ||||
| -rw-r--r-- | tests/ref/layout/grid-auto-shrink.png | bin | 0 -> 7796 bytes | |||
| -rw-r--r-- | tests/typ/layout/grid-auto-shrink.typ | 12 |
3 files changed, 37 insertions, 21 deletions
diff --git a/library/src/layout/grid.rs b/library/src/layout/grid.rs index 470b1f3b..a848a650 100644 --- a/library/src/layout/grid.rs +++ b/library/src/layout/grid.rs @@ -279,9 +279,7 @@ impl<'a> GridLayouter<'a> { // otherwise shrink auto columns. let remaining = available - auto; if remaining >= Abs::zero() { - if !fr.is_zero() { - self.grow_fractional_columns(remaining, fr); - } + self.grow_fractional_columns(remaining, fr); } else { self.shrink_auto_columns(available, count); } @@ -335,6 +333,10 @@ impl<'a> GridLayouter<'a> { /// Distribute remaining space to fractional columns. fn grow_fractional_columns(&mut self, remaining: Abs, fr: Fr) { + if fr.is_zero() { + return; + } + for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) { if let TrackSizing::Fractional(v) = col { *rcol = v.share(fr, remaining); @@ -344,30 +346,33 @@ impl<'a> GridLayouter<'a> { /// Redistribute space to auto columns so that each gets a fair share. fn shrink_auto_columns(&mut self, available: Abs, count: usize) { - // The fair share each auto column may have. - let fair = available / count as f64; - - // The number of overlarge auto columns and the space that will be - // equally redistributed to them. - let mut overlarge: usize = 0; + let mut last; + let mut fair = -Abs::inf(); let mut redistribute = available; - - // Find out the number of and space used by overlarge auto columns. - for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) { - if col == TrackSizing::Auto { - if *rcol > fair { - overlarge += 1; - } else { - redistribute -= *rcol; + let mut overlarge = count; + let mut changed = true; + + // Iteratively remove columns that don't need to be shrunk. + while changed && overlarge > 0 { + changed = false; + last = fair; + fair = redistribute / (overlarge as f64); + + for (&col, &rcol) in self.cols.iter().zip(&self.rcols) { + // Remove an auto column if it is not overlarge (rcol <= fair), + // but also hasn't already been removed (rcol > last). + if col == TrackSizing::Auto && rcol <= fair && rcol > last { + redistribute -= rcol; + overlarge -= 1; + changed = true; } } } - // Redistribute the space equally. - let share = redistribute / overlarge as f64; + // Redistribute space fairly among overlarge columns. for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) { if col == TrackSizing::Auto && *rcol > fair { - *rcol = share; + *rcol = fair; } } } @@ -465,7 +470,6 @@ impl<'a> GridLayouter<'a> { /// Layout a row with fixed height and return its frame. fn layout_single_row(&mut self, height: Abs, y: usize) -> SourceResult<Frame> { let mut output = Frame::new(Size::new(self.used.x, height)); - let mut pos = Point::zero(); for (x, &rcol) in self.rcols.iter().enumerate() { diff --git a/tests/ref/layout/grid-auto-shrink.png b/tests/ref/layout/grid-auto-shrink.png Binary files differnew file mode 100644 index 00000000..851e8b7e --- /dev/null +++ b/tests/ref/layout/grid-auto-shrink.png diff --git a/tests/typ/layout/grid-auto-shrink.typ b/tests/typ/layout/grid-auto-shrink.typ new file mode 100644 index 00000000..4d9ef0d8 --- /dev/null +++ b/tests/typ/layout/grid-auto-shrink.typ @@ -0,0 +1,12 @@ +// Test iterative auto column shrinking. + +--- +#set page(width: 210mm - 2 * 2.5cm + 2 * 10pt) +#set text(11pt) +#table( + columns: 4, + [Hello!], + [Hello there, my friend!], + [Hello there, my friends! Hi!], + [Hello there, my friends! Hi! What is going on right now?], +) |
