Bug 960245 - Deal with the final possibility for degeneracies in FindInflectionApproximationRange. r=jrmuizel, a=lsblakk
authorBas Schouten <bschouten@mozilla.com>
Thu, 16 Jan 2014 21:39:19 +0100
changeset 175860 c61a1dd23ef233480bcf240cf406869291bf3ac6
parent 175859 6b861c14640bd080b479409e866347ec00de5b3e
child 175861 b7599feb2fd98bd13139e709055f91fc3054febc
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, lsblakk
bugs960245
milestone28.0a2
Bug 960245 - Deal with the final possibility for degeneracies in FindInflectionApproximationRange. r=jrmuizel, a=lsblakk
gfx/2d/Path.cpp
--- a/gfx/2d/Path.cpp
+++ b/gfx/2d/Path.cpp
@@ -262,25 +262,34 @@ FindInflectionApproximationRange(BezierC
                                  Float *aMin, Float *aMax, Float aT,
                                  Float aTolerance)
 {
     SplitBezier(aControlPoints, nullptr, &aControlPoints, aT);
 
     Point cp21 = aControlPoints.mCP2 - aControlPoints.mCP1;
     Point cp41 = aControlPoints.mCP4 - aControlPoints.mCP1;
 
-    if (!cp21.x && !cp21.y) {
+    if (cp21.x == 0 && cp21.y == 0) {
       // In this case s3 becomes lim[n->0] (cp41.x * n) / n - (cp41.y * n) / n = cp41.x - cp41.y.
       *aMin = aT - pow(aTolerance / (cp41.x - cp41.y), Float(1. / 3.));
       *aMax = aT + pow(aTolerance / (cp41.x - cp41.y), Float(1. / 3.));;
       return;
     }
 
     Float s3 = (cp41.x * cp21.y - cp41.y * cp21.x) / hypotf(cp21.x, cp21.y);
 
+    if (s3 == 0) {
+      // This means within the precision we have it can be approximated
+      // infinitely by a linear segment. Deal with this by specifying the
+      // approximation range as extending beyond the entire curve.
+      *aMin = -1.0f;
+      *aMax = 2.0f;
+      return;
+    }
+
     Float tf = pow(abs(aTolerance / s3), Float(1. / 3.));
 
     *aMin = aT - tf * (1 - aT);
     *aMax = aT + tf * (1 - aT);
 }
 
 /* Find the inflection points of a bezier curve. Will return false if the
  * curve is degenerate in such a way that it is best approximated by a straight
@@ -463,17 +472,17 @@ FlattenBezier(const BezierControlPoints 
       aSink->LineTo(nextCPs.mCP1);
     } else if (t2min > 0 && t1max > 0) {
       SplitBezier(aControlPoints, nullptr, &nextCPs, t1max);
 
       // Find a control points describing the portion of the curve between t1max and t2min.
       Float t2mina = (t2min - t1max) / (1 - t1max);
       SplitBezier(nextCPs, &prevCPs, &nextCPs, t2mina);
       FlattenBezierCurveSegment(prevCPs, aSink, aTolerance);
-    } else {
+    } else if (t2min > 0) {
       // We have nothing interesting before t2min, find that bit and flatten it.
       SplitBezier(aControlPoints, &prevCPs, &nextCPs, t2min);
       FlattenBezierCurveSegment(prevCPs, aSink, aTolerance);
     }
     if (t2max < 1.0) {
       // Flatten the portion of the curve after t2max
       SplitBezier(aControlPoints, nullptr, &nextCPs, t2max);