Bug 1068603: Extend FlattenBezier to handle case where full path can be approximated by a linear segment. r=Bas
authorDaniel Holbert <dholbert@cs.stanford.edu>
Fri, 02 Jan 2015 14:46:53 -0800
changeset 247749 b9458d466161337046f71d4b6687a8fd47643736
parent 247748 fe2187ec388c581d0ed6dc1db77d096d1263227e
child 247750 ab9cdbcd083de4753d1c03c834dd161f27a4bf7d
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs1068603
milestone37.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 1068603: Extend FlattenBezier to handle case where full path can be approximated by a linear segment. r=Bas
dom/svg/test/test_pathLength.html
gfx/2d/Path.cpp
--- a/dom/svg/test/test_pathLength.html
+++ b/dom/svg/test/test_pathLength.html
@@ -9,38 +9,44 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1024926">Mozilla Bug 1024926</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   <svg width="100%" height="1" id="svg">
-    <path id="path" d="M50,100l0,0l0,-50l100,0l86.3325,122.665z"></path>
+    <path id="path_lines" d="M50,100l0,0l0,-50l100,0l86.3325,122.665z"></path>
+    <path id="path_straight_curve" d="M0,0 C100,0 150,0 200,0" />
   </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
   SimpleTest.waitForExplicitFinish();
 
-  var path = document.getElementById("path");
-
+  // Test a closed path with a series of lines.
+  var path = document.getElementById("path_lines");
   is(path.getTotalLength(), 500, "Unexpected path length");
 
+  // Test a path that's been shortened via the DOM.
   for (var i = 0; i < 2; i++) {
       path.pathSegList.removeItem(path.pathSegList.numberOfItems - 1);
   }
-
   is(path.getTotalLength(), 150, "Unexpected path length");
 
+  // Test a path that's been shortened to be empty, via the DOM.
   while (path.pathSegList.numberOfItems > 0) {
       path.pathSegList.removeItem(0);
   }
+  is(path.getTotalLength(), 0, "Unexpected path length");
 
-  is(path.getTotalLength(), 0, "Unexpected path length");
+  // Test a path with a curve command ("C") that is really a straight line.
+  path = document.getElementById("path_straight_curve");
+  is(path.getTotalLength(), 200, "Unexpected path length, for straight line " +
+                                 "generated by 'C' command");
 
   SimpleTest.finish();
 
 </script>
 </pre>
 </body>
 </html>
--- a/gfx/2d/Path.cpp
+++ b/gfx/2d/Path.cpp
@@ -454,16 +454,22 @@ FlattenBezier(const BezierControlPoints 
   if (count > 1 && t2 >= 0 && t2 < 1.0) {
     FindInflectionApproximationRange(aControlPoints, &t2min, &t2max, t2, aTolerance);
   }
   BezierControlPoints nextCPs = aControlPoints;
   BezierControlPoints prevCPs;
 
   // Process ranges. [t1min, t1max] and [t2min, t2max] are approximated by line
   // segments.
+  if (count == 1 && t1min <= 0 && t1max >= 1.0) {
+    // The whole range can be approximated by a line segment.
+    aSink->LineTo(aControlPoints.mCP4);
+    return;
+  }
+
   if (t1min > 0) {
     // Flatten the Bezier up until the first inflection point's approximation
     // point.
     SplitBezier(aControlPoints, &prevCPs,
                 &remainingCP, t1min);
     FlattenBezierCurveSegment(prevCPs, aSink, aTolerance);
   }
   if (t1max >= 0 && t1max < 1.0 && (count == 1 || t2min > t1max)) {