Fix auto column shrinking behaviour

This commit is contained in:
Laurenz 2022-11-30 14:49:55 +01:00
parent 579dac3c91
commit bdf06c9c61
3 changed files with 36 additions and 20 deletions

View File

@ -279,9 +279,7 @@ impl<'a> GridLayouter<'a> {
// otherwise shrink auto columns. // otherwise shrink auto columns.
let remaining = available - auto; let remaining = available - auto;
if remaining >= Abs::zero() { if remaining >= Abs::zero() {
if !fr.is_zero() { self.grow_fractional_columns(remaining, fr);
self.grow_fractional_columns(remaining, fr);
}
} else { } else {
self.shrink_auto_columns(available, count); self.shrink_auto_columns(available, count);
} }
@ -335,6 +333,10 @@ impl<'a> GridLayouter<'a> {
/// Distribute remaining space to fractional columns. /// Distribute remaining space to fractional columns.
fn grow_fractional_columns(&mut self, remaining: Abs, fr: Fr) { 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) { for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) {
if let TrackSizing::Fractional(v) = col { if let TrackSizing::Fractional(v) = col {
*rcol = v.share(fr, remaining); *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. /// Redistribute space to auto columns so that each gets a fair share.
fn shrink_auto_columns(&mut self, available: Abs, count: usize) { fn shrink_auto_columns(&mut self, available: Abs, count: usize) {
// The fair share each auto column may have. let mut last;
let fair = available / count as f64; let mut fair = -Abs::inf();
// The number of overlarge auto columns and the space that will be
// equally redistributed to them.
let mut overlarge: usize = 0;
let mut redistribute = available; let mut redistribute = available;
let mut overlarge = count;
let mut changed = true;
// Find out the number of and space used by overlarge auto columns. // Iteratively remove columns that don't need to be shrunk.
for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) { while changed && overlarge > 0 {
if col == TrackSizing::Auto { changed = false;
if *rcol > fair { last = fair;
overlarge += 1; fair = redistribute / (overlarge as f64);
} else {
redistribute -= *rcol; 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. // Redistribute space fairly among overlarge columns.
let share = redistribute / overlarge as f64;
for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) { for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) {
if col == TrackSizing::Auto && *rcol > fair { 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. /// Layout a row with fixed height and return its frame.
fn layout_single_row(&mut self, height: Abs, y: usize) -> SourceResult<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 output = Frame::new(Size::new(self.used.x, height));
let mut pos = Point::zero(); let mut pos = Point::zero();
for (x, &rcol) in self.rcols.iter().enumerate() { for (x, &rcol) in self.rcols.iter().enumerate() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -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?],
)