From bdf06c9c61c3a9e0e9104d012828583638797edc Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 30 Nov 2022 14:49:55 +0100 Subject: [PATCH] Fix auto column shrinking behaviour --- library/src/layout/grid.rs | 44 ++++++++++++++------------ tests/ref/layout/grid-auto-shrink.png | Bin 0 -> 7796 bytes tests/typ/layout/grid-auto-shrink.typ | 12 +++++++ 3 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 tests/ref/layout/grid-auto-shrink.png create mode 100644 tests/typ/layout/grid-auto-shrink.typ diff --git a/library/src/layout/grid.rs b/library/src/layout/grid.rs index 470b1f3bb..a848a650d 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; + let mut overlarge = count; + let mut changed = true; - // 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; + // 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 { 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 new file mode 100644 index 0000000000000000000000000000000000000000..851e8b7eeef97e058f9529f2778db34a1513bd8b GIT binary patch literal 7796 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 literal 0 HcmV?d00001 diff --git a/tests/typ/layout/grid-auto-shrink.typ b/tests/typ/layout/grid-auto-shrink.typ new file mode 100644 index 000000000..4d9ef0d81 --- /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?], +)