Bug 1461046 Part 2: Change ShapeUtils::ComputeInsetRect to return the inverse of a rect deflated more than its bounds can tolerate. r=dholbert
☠☠ backed out by 8c9263730393 ☠ ☠
authorBrad Werth <bwerth@mozilla.com>
Fri, 18 May 2018 17:51:19 -0700
changeset 420748 157bbc74460aa4ae7d4bba541db109fb130a3dcc
parent 420747 e990d4d07b0eda625db7bf47a2a039c463096704
child 420749 5c8648bcf6bbd7ab2ad2ba83593a2d58bc3816d5
push id34078
push usercsabou@mozilla.com
push dateFri, 01 Jun 2018 09:40:19 +0000
treeherdermozilla-central@50c379fc5536 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1461046
milestone62.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
Bug 1461046 Part 2: Change ShapeUtils::ComputeInsetRect to return the inverse of a rect deflated more than its bounds can tolerate. r=dholbert MozReview-Commit-ID: IScKyqzjMoy
layout/base/ShapeUtils.cpp
layout/base/ShapeUtils.h
--- a/layout/base/ShapeUtils.cpp
+++ b/layout/base/ShapeUtils.cpp
@@ -119,25 +119,39 @@ ShapeUtils::ComputeInsetRect(const Uniqu
                              const nsRect& aRefBox)
 {
   MOZ_ASSERT(aBasicShape->GetShapeType() == StyleBasicShapeType::Inset,
              "The basic shape must be inset()!");
 
   const nsTArray<nsStyleCoord>& coords = aBasicShape->Coordinates();
   MOZ_ASSERT(coords.Length() == 4, "wrong number of arguments");
 
-  nsMargin inset(coords[0].ComputeCoordPercentCalc(aRefBox.height),
-                 coords[1].ComputeCoordPercentCalc(aRefBox.width),
-                 coords[2].ComputeCoordPercentCalc(aRefBox.height),
-                 coords[3].ComputeCoordPercentCalc(aRefBox.width));
+  nsMargin inset(coords[0].ComputeCoordPercentCalc(aRefBox.Height()),
+                 coords[1].ComputeCoordPercentCalc(aRefBox.Width()),
+                 coords[2].ComputeCoordPercentCalc(aRefBox.Height()),
+                 coords[3].ComputeCoordPercentCalc(aRefBox.Width()));
+
+  nscoord x = aRefBox.X() + inset.left;
+  nscoord width = aRefBox.Width() - inset.LeftRight();
+  nscoord y = aRefBox.Y() + inset.top;
+  nscoord height = aRefBox.Height() - inset.TopBottom();
 
-  nsRect insetRect(aRefBox);
-  insetRect.Deflate(inset);
+  // Invert left and right, if necessary.
+  if (width < 0) {
+    width *= -1;
+    x -= width;
+  }
 
-  return insetRect;
+  // Invert top and bottom, if necessary.
+  if (height < 0) {
+    height *= -1;
+    y -= height;
+  }
+
+  return nsRect(x, y, width, height);
 }
 
 /* static */ bool
 ShapeUtils::ComputeInsetRadii(const UniquePtr<StyleBasicShape>& aBasicShape,
                               const nsRect& aInsetRect,
                               const nsRect& aRefBox,
                               nscoord aRadii[8])
 {
--- a/layout/base/ShapeUtils.h
+++ b/layout/base/ShapeUtils.h
@@ -52,17 +52,26 @@ struct ShapeUtils final
   // @param aCenter the center of the ellipse.
   // @param aRefBox the reference box of the ellipse.
   // @return The radii of the ellipse in app units. The width and height
   // represent the x-axis and y-axis radii of the ellipse.
   static nsSize ComputeEllipseRadii(
     const UniquePtr<StyleBasicShape>& aBasicShape,
     const nsPoint& aCenter, const nsRect& aRefBox);
 
-  // Compute the rect for an inset.
+  // Compute the rect for an inset. If the inset amount is larger than
+  // aRefBox itself, this will return a rect the same shape as the inverse
+  // rect that would be created by insetting aRefBox by the inset amount.
+  // This process is *not* what is called for by the current spec at
+  // https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes.
+  // The spec currently treats empty shapes, including overly-inset rects, as
+  // defining 'empty float areas' that don't affect layout. However, it is
+  // practically useful to treat empty shapes as having edges for purposes of
+  // affecting layout, and there is growing momentum for the approach we
+  // are taking here.
   // @param aRefBox the reference box of the inset.
   // @return The inset rect in app units.
   static nsRect ComputeInsetRect(
     const UniquePtr<StyleBasicShape>& aBasicShape,
     const nsRect& aRefBox);
 
   // Compute the radii for an inset.
   // @param aRefBox the reference box of the inset.