Bug 972703 - Clamp massive transformed overflow areas to the middle of the representable range instead of the start. r=roc
☠☠ backed out by 89b9078be02a ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Mon, 17 Feb 2014 11:25:36 +1300
changeset 169442 ef3d90780478ee8f8a0282231d794d55c4744497
parent 169441 34c95e93767196340493e759da5d49e83886ecc8
child 169443 89b9078be02af6485b8d035281abe9a8fda69c7b
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersroc
bugs972703
milestone30.0a1
Bug 972703 - Clamp massive transformed overflow areas to the middle of the representable range instead of the start. r=roc
layout/base/nsLayoutUtils.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1634,36 +1634,55 @@ nsLayoutUtils::ChangeMatrixBasis(const g
   return result; 
 }
 
 /**
  * Given a gfxFloat, constrains its value to be between nscoord_MIN and nscoord_MAX.
  *
  * @param aVal The value to constrain (in/out)
  */
-static void ConstrainToCoordValues(gfxFloat &aVal)
+static void ConstrainToCoordValues(gfxFloat& aVal)
 {
   if (aVal <= nscoord_MIN)
     aVal = nscoord_MIN;
   else if (aVal >= nscoord_MAX)
     aVal = nscoord_MAX;
 }
 
+static void ConstrainToCoordValues(gfxFloat& aStart, gfxFloat& aSize)
+{
+  MOZ_ASSERT(aSize >= 0);
+  gfxFloat max = aStart + aSize;
+
+  // Clamp the end points to within nscoord range
+  ConstrainToCoordValues(aStart);
+  ConstrainToCoordValues(max);
+
+  aSize = max - aStart;
+  // If the width if still greater than the max nscoord, then bring both
+  // endpoints in by the same amount until it fits.
+  if (aSize > nscoord_MAX) {
+    gfxFloat excess = aSize - nscoord_MAX;
+    excess /= 2;
+
+    aStart += excess;
+    aSize = nscoord_MAX;
+  }
+}
+
 nsRect
 nsLayoutUtils::RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor)
 {
   /* Get a new gfxRect whose units are app units by scaling by the specified factor. */
   gfxRect scaledRect = aRect;
   scaledRect.ScaleRoundOut(aFactor);
 
   /* We now need to constrain our results to the max and min values for coords. */
-  ConstrainToCoordValues(scaledRect.x);
-  ConstrainToCoordValues(scaledRect.y);
-  ConstrainToCoordValues(scaledRect.width);
-  ConstrainToCoordValues(scaledRect.height);
+  ConstrainToCoordValues(scaledRect.x, scaledRect.width);
+  ConstrainToCoordValues(scaledRect.y, scaledRect.height);
 
   /* Now typecast everything back.  This is guaranteed to be safe. */
   return nsRect(nscoord(scaledRect.X()), nscoord(scaledRect.Y()),
                 nscoord(scaledRect.Width()), nscoord(scaledRect.Height()));
 }
 
 
 nsRegion