Bug 1297427 - Use calculate curve origin instead of reusing center curve origin in DottedCornerFinder. r=bas
authorTooru Fujisawa <arai_a@mac.com>
Thu, 08 Sep 2016 10:14:14 +0900
changeset 354456 c39042e6ec52f3ff6d7bc5401fc5c4b42bed570b
parent 354455 a8df6215f6c00747bebccb0bcc7acb87378e347b
child 354457 b31b1d10f122657179b894d8ceaedcdb99399073
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs1297427
milestone51.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 1297427 - Use calculate curve origin instead of reusing center curve origin in DottedCornerFinder. r=bas
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.