Bug 1461046 Part 2: Change ShapeUtils::ComputeInsetRect to return the inverse of a rect deflated more than its bounds can tolerate. r=dholbert
authorBrad Werth <bwerth@mozilla.com>
Fri, 18 May 2018 17:51:19 -0700
changeset 421283 3ebfdd60f59fc35e823a6e1064352cc7b39cc185
parent 421282 9619991fb38da2e0c8b20607544fff5a5878c146
child 421284 b3375f24897bf84da24d4e9391dedb235f6a6435
push id34091
push userbtara@mozilla.com
push dateTue, 05 Jun 2018 13:52:34 +0000
treeherdermozilla-central@752465b44c79 [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.