Bug 1297427 - Use calculate curve origin instead of reusing center curve origin in DottedCornerFinder. r=bas, a=ritu
authorTooru Fujisawa <arai_a@mac.com>
Thu, 08 Sep 2016 10:14:14 +0900
changeset 348129 dabeb362ff124c1af9325ae34fdd43e2038556ee
parent 348128 201882b9e76226bc970f38abd2d99a0e231669a4
child 348130 0c2347afecab58733a57e88fae039df838f78c54
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas, ritu
bugs1297427
milestone50.0a2
Bug 1297427 - Use calculate curve origin instead of reusing center curve origin in DottedCornerFinder. r=bas, a=ritu
gfx/2d/BezierUtils.cpp
layout/base/DottedCornerFinder.cpp
layout/base/DottedCornerFinder.h
--- a/gfx/2d/BezierUtils.cpp
+++ b/gfx/2d/BezierUtils.cpp
@@ -324,13 +324,16 @@ CalculateDistanceToEllipticArc(const Poi
   Float B = a * b + c * d;
   Float C = a * a + c * c - 1;
 
   Float S = sqrt(B * B - A * C);
 
   Float n1 = (- B + S) / A;
   Float n2 = (- B - S) / A;
 
+  MOZ_ASSERT(n1 >= 0);
+  MOZ_ASSERT(n2 >= 0);
+
   return n1 < n2 ? n1 : n2;
 }
 
 } // namespace gfx
 } // namespace mozilla
--- a/layout/base/DottedCornerFinder.cpp
+++ b/layout/base/DottedCornerFinder.cpp
@@ -52,17 +52,18 @@ DottedCornerFinder::DottedCornerFinder(c
                                        const Point& aCn, Float aRn,
                                        const Size& aCornerDim)
  : mOuterBezier(aOuterBezier),
    mInnerBezier(aInnerBezier),
    mCorner(aCorner),
    mNormalSign((aCorner == C_TL || aCorner == C_BR) ? -1.0f : 1.0f),
    mC0(aC0), mCn(aCn),
    mR0(aR0), mRn(aRn), mMaxR(std::max(aR0, aRn)),
-   mCurveOrigin(mC0.x, mCn.y),
+   mCenterCurveOrigin(mC0.x, mCn.y),
+   mInnerCurveOrigin(mInnerBezier.mPoints[0].x, mInnerBezier.mPoints[3].y),
    mBestOverlap(0.0f),
    mHasZeroBorderWidth(false), mHasMore(true),
    mMaxCount(aCornerDim.width + aCornerDim.height),
    mType(OTHER),
    mI(0), mCount(0)
 {
   NS_ASSERTION(mR0 > 0.0f || mRn > 0.0f,
                "At least one side should have non-zero radius.");
@@ -180,18 +181,18 @@ DottedCornerFinder::Next(void)
     } else if (mCorner == C_TR) {
       phi = -M_PI / 2.0f + phi;
     } else if (mCorner == C_BR) {
       phi = M_PI / 2.0f - phi;
     } else {
       phi = M_PI / 2.0f + phi;
     }
 
-    Point C(mCurveOrigin.x + mCenterCurveR * cos(phi),
-            mCurveOrigin.y + mCenterCurveR * sin(phi));
+    Point C(mCenterCurveOrigin.x + mCenterCurveR * cos(phi),
+            mCenterCurveOrigin.y + mCenterCurveR * sin(phi));
     return DottedCornerFinder::Result(C, mR0);
   }
 
   // Find unfilled and filled circles.
   (void)FindNext(mBestOverlap);
   (void)FindNext(mBestOverlap);
   return Result(mLastC, mLastR);
 }
@@ -283,17 +284,17 @@ DottedCornerFinder::FindNext(Float overl
         // Basically this shouldn't happen.
         // If differential is 0, we cannot calculate tangent circle,
         // skip this point.
         t = (t + upper) / 2.0f;
         continue;
       }
 
       Point normal = PointRotateCCW90(Diff / DiffLength) * (-mNormalSign);
-      r = CalculateDistanceToEllipticArc(C, normal, mCurveOrigin,
+      r = CalculateDistanceToEllipticArc(C, normal, mInnerCurveOrigin,
                                          mInnerWidth, mInnerHeight);
 
       // Check overlap along arc.
       circlesDist = GetBezierLength(mCenterBezier, mLastT, t);
       expectedDist = (r + mLastR) * factor;
       if (circlesDist < expectedDist - DIST_MARGIN) {
         lower = t;
       } else if (circlesDist > expectedDist + DIST_MARGIN) {
--- a/layout/base/DottedCornerFinder.h
+++ b/layout/base/DottedCornerFinder.h
@@ -52,17 +52,19 @@ public:
   struct Result
   {
     // Center point of dot and its radius.
     Point C;
     Float r;
 
     Result(const Point& aC, Float aR)
      : C(aC), r(aR)
-    {}
+    {
+      MOZ_ASSERT(aR >= 0);
+    }
   };
 
   //                        aBorderRadiusX
   //                       aCornerDim.width
   //                     |<----------------->|
   //                     |                   | v
   //                   --+-------------___---+--
   //                   ^ |         __--      | |
@@ -184,42 +186,64 @@ private:
   //
   Point mC0;
   Point mCn;
   Float mR0;
   Float mRn;
   Float mMaxR;
 
   // Parameters for the center curve with perfect circle and the inner curve.
+  // The center curve doesn't necessarily share the origin with others.
   //
   //               ___---+
   //           __--      |
   //         _-          |
-  //       /        __---+
+  //       /        __-+ |
   //     /      __--     |
   //    |     /          |
   //   |    /        __--+--
   //  |    |       _-    | ^
   //  |    |      /      | |
   // |     |     /       | |
   // |    |     |        | |
   // |    |     |        | | mInnerHeight
   // |    |    |         | |
-  // |    |    |         | |
-  // |    |    |         | v
-  // +----+----+---------+
-  //      |    |         | mCurveOrigin
-  //      |    |<------->|
-  //      |  mInnerWidth |
-  //      |              |
-  //      |<------------>|
-  //        mCenterCurveR
+  // |    +    |         | |
+  // |         |         | v
+  // +---------+---------+
+  //           |         | mInnerCurveOrigin
+  //           |<------->|
+  //           mInnerWidth
   //
-  Point mCurveOrigin;
+  //               ___---+
+  //           __--
+  //         _-
+  //       /        __-+
+  //     /      __--   |
+  //    |     /        |
+  //   |    /        __--+
+  //  |    |       _-  |
+  //  |    |      /    |
+  // |     |     /     |
+  // |    |     |      |
+  // |    |     |      |
+  // |    |    |       |
+  // |    +--- | ------+
+  // |    |    |       | mCenterCurveOrigin
+  // +    |    +       |
+  //      |            |
+  //      |            |
+  //      |            |
+  //      |            |
+  //      |<---------->|
+  //       mCenterCurveR
+  //
+  Point mCenterCurveOrigin;
   Float mCenterCurveR;
+  Point mInnerCurveOrigin;
   Float mInnerWidth;
   Float mInnerHeight;
 
   Point mLastC;
   Float mLastR;
   Float mLastT;
 
   // Overlap between two circles.