Bug 987077 - Correctly deal with a constant acceleration. r=jwatt, a=sledru
authorBas Schouten <bschouten@mozilla.com>
Wed, 02 Apr 2014 21:16:57 +0100
changeset 193019 cca7eb7fc75efd1100905e350cb34d25e50ef98b
parent 193018 8dc71e439d4221dfd0fcd3dc34dbd8218fb24df7
child 193020 bee1ba424663a093bceb15352f1d8bc244b605b4
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt, sledru
bugs987077
milestone30.0a2
Bug 987077 - Correctly deal with a constant acceleration. r=jwatt, a=sledru
gfx/2d/Path.cpp
--- a/gfx/2d/Path.cpp
+++ b/gfx/2d/Path.cpp
@@ -346,17 +346,17 @@ FindInflectionApproximationRange(BezierC
  * x = (-b + sqrt(b * b - 4 * a * c)) / (2 * a)
  * x = (-3 * b + sqrt(3 * b * 3 * b - 4 * a * 3 * 9 * c / 3)) / (2 * 3 * a)
  * x = 3 * (-b + sqrt(b * b - 4 * a * c)) / (2 * 3 * a)
  * x = (-b + sqrt(b * b - 4 * a * c)) / (2 * a)
  *
  * I haven't looked into whether the formulation of the quadratic formula in
  * hain has any numerical advantages over the one used below.
  */
-static inline bool
+static inline void
 FindInflectionPoints(const BezierControlPoints &aControlPoints,
                      Float *aT1, Float *aT2, uint32_t *aCount)
 {
   // Find inflection points.
   // See www.faculty.idc.ac.il/arik/quality/appendixa.html for an explanation
   // of this approach.
   Point A = aControlPoints.mCP2 - aControlPoints.mCP1;
   Point B = aControlPoints.mCP3 - (aControlPoints.mCP2 * 2) + aControlPoints.mCP1;
@@ -364,22 +364,27 @@ FindInflectionPoints(const BezierControl
 
   Float a = Float(B.x) * C.y - Float(B.y) * C.x;
   Float b = Float(A.x) * C.y - Float(A.y) * C.x;
   Float c = Float(A.x) * B.y - Float(A.y) * B.x;
 
   if (a == 0) {
     // Not a quadratic equation.
     if (b == 0) {
-      // Instead of a linear equation we have a constant.
-      return false;
+      // Instead of a linear acceleration change we have a constant
+      // acceleration change. This means the equation has no solution
+      // and there are no inflection points, unless the constant is 0.
+      // In that case the curve is a straight line, but we'll let
+      // FlattenBezierCurveSegment deal with this.
+      *aCount = 0;
+      return;
     }
     *aT1 = -c / b;
     *aCount = 1;
-    return true;
+    return;
   } else {
     Float discriminant = b * b - 4 * a * c;
 
     if (discriminant < 0) {
       // No inflection points.
       *aCount = 0;
     } else if (discriminant == 0) {
       *aCount = 1;
@@ -403,31 +408,28 @@ FindInflectionPoints(const BezierControl
       *aT2 = c / q;
       if (*aT1 > *aT2) {
         std::swap(*aT1, *aT2);
       }
       *aCount = 2;
     }
   }
 
-  return true;
+  return;
 }
 
 void
 FlattenBezier(const BezierControlPoints &aControlPoints,
               PathSink *aSink, Float aTolerance)
 {
   Float t1;
   Float t2;
   uint32_t count;
 
-  if (!FindInflectionPoints(aControlPoints, &t1, &t2, &count)) {
-    aSink->LineTo(aControlPoints.mCP4);
-    return;
-  }
+  FindInflectionPoints(aControlPoints, &t1, &t2, &count);
 
   // Check that at least one of the inflection points is inside [0..1]
   if (count == 0 || ((t1 < 0 || t1 > 1.0) && ((t2 < 0 || t2 > 1.0) || count == 1)) ) {
     FlattenBezierCurveSegment(aControlPoints, aSink, aTolerance);
     return;
   }
 
   Float t1min = t1, t1max = t1, t2min = t2, t2max = t2;