Fix yet another convexicator issue
authorrobertphillips <robertphillips@google.com>
Mon, 17 Nov 2014 20:11:42 +0000 (12:11 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 17 Nov 2014 20:11:42 +0000 (12:11 -0800)
This CL fixes the case where a bad initial vector (i.e., nearly zero) managed to short circuit all of the convexicator's logic. The initial bad vector would become the last vector and then never get displaced.

The history of this is:

https://codereview.chromium.org/298973004/
Switched the convexicator to not advance the last vector when the cross product wasn't significant

https://codereview.chromium.org/573763002/
Fixed a bug (crbug.com/412640) wherein a zero area path was being incorrectly categorized as convex b.c. opposite but equal vectors were not signaling concavity.

BUG=433683

Review URL: https://codereview.chromium.org/727283003

src/core/SkPath.cpp
tests/PathTest.cpp

index 5288b85db37e3ed4e6d5e68532975032ef7374d5..25fd058d20468feec4cf99d514cbad6fe4dcc4e8 100644 (file)
@@ -2242,7 +2242,7 @@ struct Convexicator {
             ++fPtCount;
         } else {
             SkVector vec = pt - fCurrPt;
-            if (vec.fX || vec.fY) {
+            if (!SkScalarNearlyZero(vec.lengthSqd(), SK_ScalarNearlyZero*SK_ScalarNearlyZero)) {
                 fLastPt = fCurrPt;
                 fCurrPt = pt;
                 if (++fPtCount == 2) {
index 94b91d261be37a3396f184f28202de836dfbb26b..78cba5ba00a4d2510ddf75ed8a39dad60c0d2591 100644 (file)
@@ -1206,6 +1206,20 @@ static void test_convexity2(skiatest::Reporter* reporter) {
     degenerateConcave.lineTo(41.446522f, 376.25f);
     check_convexity(reporter, degenerateConcave, SkPath::kConcave_Convexity);
     check_direction(reporter, degenerateConcave, SkPath::kUnknown_Direction);
+
+    // http://crbug.com/433683
+    SkPath badFirstVector;
+    badFirstVector.moveTo(501.087708f, 319.610352f);
+    badFirstVector.lineTo(501.087708f, 319.610352f);
+    badFirstVector.cubicTo(501.087677f, 319.610321f, 449.271606f, 258.078674f, 395.084564f, 198.711182f);
+    badFirstVector.cubicTo(358.967072f, 159.140717f, 321.910553f, 120.650436f, 298.442322f, 101.955399f);
+    badFirstVector.lineTo(301.557678f, 98.044601f);
+    badFirstVector.cubicTo(325.283844f, 116.945084f, 362.615204f, 155.720825f, 398.777557f, 195.340454f);
+    badFirstVector.cubicTo(453.031860f, 254.781662f, 504.912262f, 316.389618f, 504.912292f, 316.389648f);
+    badFirstVector.lineTo(504.912292f, 316.389648f);
+    badFirstVector.lineTo(501.087708f, 319.610352f);
+    badFirstVector.close();
+    check_convexity(reporter, badFirstVector, SkPath::kConcave_Convexity);
 }
 
 static void check_convex_bounds(skiatest::Reporter* reporter, const SkPath& p,