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 421160 9619991fb38da2e0c8b20607544fff5a5878c146
parent 421159 a8c5ef43a3c9d4881de947ff8dbfb1da1d399b80
child 421161 3ebfdd60f59fc35e823a6e1064352cc7b39cc185
push id64818
push userbwerth@mozilla.com
push dateMon, 04 Jun 2018 17:18:30 +0000
treeherderautoland@bd46d28842ff [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|  |