Bug 1461046 Part 1: Change EllipseShapeInfo to tolerate empty circles/ellipses and treat them as singular points/lines (possibly expanded by shape-margin). r=dholbert
authorBrad Werth <bwerth@mozilla.com>
Fri, 18 May 2018 17:13:22 -0700
changeset 420699 e990d4d07b0eda625db7bf47a2a039c463096704
parent 420698 9d570f91ea5a273fb2a38a0b40d90d00b9cbbbc6
child 420700 157bbc74460aa4ae7d4bba541db109fb130a3dcc
push id64710
push userbwerth@mozilla.com
push dateThu, 31 May 2018 20:31:28 +0000
treeherderautoland@f5990eb1eb0d [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 1: Change EllipseShapeInfo to tolerate empty circles/ellipses and treat them as singular points/lines (possibly expanded by shape-margin). r=dholbert MozReview-Commit-ID: 69VQiRjhtqA
layout/generic/nsFloatManager.cpp
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -725,17 +725,20 @@ public:
                     const nscoord aBEnd) const override;
   nscoord BStart() const override {
     return mCenter.y - mRadii.height - mShapeMargin;
   }
   nscoord BEnd() const override {
     return mCenter.y + mRadii.height + mShapeMargin;
   }
   bool IsEmpty() const override {
-    return mRadii.IsEmpty();
+    // An EllipseShapeInfo is never empty, because an ellipse or circle with
+    // a zero radius acts like a point, and an ellipse with one zero radius
+    // acts like a line.
+    return false;
   }
 
   void Translate(nscoord aLineLeft, nscoord aBlockStart) override
   {
     mCenter.MoveBy(aLineLeft, aBlockStart);
 
     for (nsRect& interval : mIntervals) {
       interval.MoveBy(aLineLeft, aBlockStart);
@@ -861,38 +864,46 @@ nsFloatManager::EllipseShapeInfo::Ellips
     bool bIsInExpandedRegion(b < bExpand);
     nscoord bInAppUnits = (b - bExpand) * aAppUnitsPerDevPixel;
     bool bIsMoreThanEllipseBEnd(bInAppUnits > mRadii.height);
 
     // Find the i intercept of the ellipse edge for this block row, and
     // adjust it to compensate for the expansion of the inline dimension.
     // If we're in the expanded region, or if we're using a b that's more
     // than the bEnd of the ellipse, the intercept is nscoord_MIN.
-    const int32_t iIntercept = (bIsInExpandedRegion ||
-                                bIsMoreThanEllipseBEnd) ? nscoord_MIN :
+    // We have one other special case to consider: when the ellipse has no
+    // height. In that case we treat the bInAppUnits == 0 case as
+    // intercepting at the width of the ellipse. All other cases solve
+    // the intersection mathematically.
+    const int32_t iIntercept =
+      (bIsInExpandedRegion || bIsMoreThanEllipseBEnd) ? nscoord_MIN :
       iExpand + NSAppUnitsToIntPixels(
-        XInterceptAtY(bInAppUnits, mRadii.width, mRadii.height),
+        (!!mRadii.height || bInAppUnits) ?
+        XInterceptAtY(bInAppUnits, mRadii.width, mRadii.height) :
+        mRadii.width,
         aAppUnitsPerDevPixel);
 
     // Set iMax in preparation for this block row.
     int32_t iMax = iIntercept;
 
     for (uint32_t i = 0; i < iSize; ++i) {
       const uint32_t index = i + b * iSize;
       MOZ_ASSERT(index < (iSize * bSize),
                  "Our distance field index should be in-bounds.");
 
       // Handle our three cases, in order.
       if (i < iExpand ||
           bIsInExpandedRegion) {
         // Case 1: Expanded reqion pixel.
         df[index] = MAX_MARGIN_5X;
       } else if ((int32_t)i <= iIntercept) {
-        // Case 2: Pixel within the ellipse.
-        df[index] = 0;
+        // Case 2: Pixel within the ellipse, or just outside the edge of it.
+        // Having a positive height indicates that there's an area we can
+        // be inside of.
+        df[index] = (!!mRadii.height) ? 0 : 5;
       } else {
         // Case 3: Other pixel.
 
         // Backward-looking neighborhood distance from target pixel X
         // with chamfer 5-7-11 looks like:
         //
         // +--+--+--+
         // |  |11|  |