Bug 1461046 Part 2: Change ShapeUtils::ComputeInsetRect to return the inverse of a rect deflated more than its bounds can tolerate.
MozReview-Commit-ID: IScKyqzjMoy
--- 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.