servo: Merge #18448 - stylo: Round down when computing viewport units (from Manishearth:viewport-round); r=emilio
authorManish Goregaokar <manishearth@gmail.com>
Mon, 11 Sep 2017 16:28:14 -0500
changeset 429658 7bf510328045e8ea7b39f955ba2cb606b1f71c00
parent 429657 7dd4be007d1389ad90285d1a6d606d24973e82f8
child 429659 4247bc5eed01240d4943f981d3c19e45cca67ebb
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #18448 - stylo: Round down when computing viewport units (from Manishearth:viewport-round); r=emilio r=emilio https://bugzilla.mozilla.org/show_bug.cgi?id=1396045 Source-Repo: https://github.com/servo/servo Source-Revision: a3a3f4bf4fa27e34855c76c69d95c338499f605d
servo/components/style/values/specified/length.rs
--- a/servo/components/style/values/specified/length.rs
+++ b/servo/components/style/values/specified/length.rs
@@ -193,33 +193,31 @@ impl ToCss for ViewportPercentageLength 
             ViewportPercentageLength::Vmax(length) => serialize_dimension(length, "vmax", dest)
         }
     }
 }
 
 impl ViewportPercentageLength {
     /// Computes the given viewport-relative length for the given viewport size.
     pub fn to_computed_value(&self, viewport_size: Size2D<Au>) -> Au {
-        macro_rules! to_unit {
-            ($viewport_dimension:expr) => {
-                $viewport_dimension.to_f32_px() / 100.0
-            }
-        }
-
-        let value = match *self {
+        let (factor, length) = match *self {
             ViewportPercentageLength::Vw(length) =>
-                length * to_unit!(viewport_size.width),
+                (length, viewport_size.width),
             ViewportPercentageLength::Vh(length) =>
-                length * to_unit!(viewport_size.height),
+                (length, viewport_size.height),
             ViewportPercentageLength::Vmin(length) =>
-                length * to_unit!(cmp::min(viewport_size.width, viewport_size.height)),
+                (length, cmp::min(viewport_size.width, viewport_size.height)),
             ViewportPercentageLength::Vmax(length) =>
-                length * to_unit!(cmp::max(viewport_size.width, viewport_size.height)),
+                (length, cmp::max(viewport_size.width, viewport_size.height)),
         };
-        Au::from_f32_px(value)
+
+        // See bug 989802. We truncate so that adding multiple viewport units
+        // that add up to 100 does not overflow due to rounding differences
+        let trunc_scaled = ((length.0 as f64) * factor as f64 / 100.).trunc();
+        Au::from_f64_au(trunc_scaled)
     }
 }
 
 /// HTML5 "character width", as defined in HTML5 ยง 14.5.4.
 #[derive(Clone, Copy, Debug, PartialEq)]
 #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct CharacterWidth(pub i32);