mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Fix floating point errors in table layout (#33098)
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
parent
fb22dfb373
commit
3b8c638a84
1 changed files with 30 additions and 2 deletions
|
@ -890,17 +890,45 @@ impl<'a> TableLayout<'a> {
|
|||
}
|
||||
|
||||
let bounds = |sum_a, sum_b| self.assignable_width > sum_a && self.assignable_width < sum_b;
|
||||
|
||||
let blend = |a: &[Au], sum_a: Au, b: &[Au], sum_b: Au| {
|
||||
// First convert the Au units to f32 in order to do floating point division.
|
||||
let weight_a =
|
||||
(self.assignable_width - sum_b).to_f32_px() / (sum_a - sum_b).to_f32_px();
|
||||
let weight_b = 1.0 - weight_a;
|
||||
a.iter()
|
||||
|
||||
let mut sum_accounting_for_floating_point_inaccuracy = Au::new(0);
|
||||
let mut widths: Vec<Au> = a
|
||||
.iter()
|
||||
.zip(b.iter())
|
||||
.map(|(guess_a, guess_b)| {
|
||||
(guess_a.scale_by(weight_a)) + (guess_b.scale_by(weight_b))
|
||||
})
|
||||
.collect()
|
||||
.inspect(|&column_width| {
|
||||
sum_accounting_for_floating_point_inaccuracy += column_width;
|
||||
})
|
||||
.collect();
|
||||
|
||||
if sum_accounting_for_floating_point_inaccuracy != self.assignable_width {
|
||||
// The computations above can introduce floating-point imprecisions.
|
||||
// Since these errors are very small (+-1Au), it's fine to simply adjust
|
||||
// the first column such that the total width matches the assignable width
|
||||
let difference =
|
||||
self.assignable_width - sum_accounting_for_floating_point_inaccuracy;
|
||||
|
||||
debug_assert!(
|
||||
difference.abs() <= Au::new(widths.len() as i32),
|
||||
"A deviation of more than one Au per column is unlikely to be caused by float imprecision"
|
||||
);
|
||||
|
||||
// We checked if the table was empty at the top of the function, so there
|
||||
// always is a first column
|
||||
widths[0] += difference;
|
||||
}
|
||||
|
||||
debug_assert!(widths.iter().sum::<Au>() == self.assignable_width);
|
||||
|
||||
widths
|
||||
};
|
||||
|
||||
if bounds(min_content_sizes_sum, min_content_percentage_sizing_sum) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue