Fallback to moveTo when unable to find the first tangent in cubicTo

When calling cubicTo(a, b, c) and if the distance between fPrevPt and a
is too small, b is used instead of a to calculate the first tangent,
even if the distance between fPrevPt and b is too small.

In debug mode, this is causing an assertion to fail in
SkPathStroker::preJoinTo() and, in Release, the use of an
unitialized value.

The first patch set is adding a failing test.
The second one add the fix to SkPathStroker::cubicTo()

BUG=skia:2820
R=bsalomon@chromium.org, junov@chromium.org, reed@google.com, caryclark@google.com, bsalomon@google.com

Author: piotaixr@chromium.org

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

(cherry picked from commit fac4e0e83666ab59373169d6c157d3654cb479a3)

Review URL: https://codereview.chromium.org/546823002
diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp
index b138c32..1e4ae79 100644
--- a/src/core/SkStroke.cpp
+++ b/src/core/SkStroke.cpp
@@ -424,7 +424,8 @@
     bool    degenerateBC = SkPath::IsLineDegenerate(pt1, pt2);
     bool    degenerateCD = SkPath::IsLineDegenerate(pt2, pt3);
 
-    if (degenerateAB + degenerateBC + degenerateCD >= 2) {
+    if (degenerateAB + degenerateBC + degenerateCD >= 2
+            || (degenerateAB && SkPath::IsLineDegenerate(fPrevPt, pt2))) {
         this->lineTo(pt3);
         return;
     }
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index 3941ad6..0de64b0 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -64,6 +64,32 @@
     canvas->drawPath(path, paint);
 }
 
+/**
+ * In debug mode, this path was causing an assertion to fail in
+ * SkPathStroker::preJoinTo() and, in Release, the use of an unitialized value.
+ */
+static void make_path_crbugskia2820(SkPath* path, skiatest::Reporter* reporter) {
+    SkPoint orig, p1, p2, p3;
+    orig = SkPoint::Make(1.f, 1.f);
+    p1 = SkPoint::Make(1.f - SK_ScalarNearlyZero, 1.f);
+    p2 = SkPoint::Make(1.f, 1.f + SK_ScalarNearlyZero);
+    p3 = SkPoint::Make(2.f, 2.f);
+
+    path->reset();
+    path->moveTo(orig);
+    path->cubicTo(p1, p2, p3);
+    path->close();
+}
+
+static void test_path_crbugskia2820(skiatest::Reporter* reporter) {//GrContext* context) {
+    SkPath path;
+    make_path_crbugskia2820(&path, reporter);
+
+    SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
+    stroke.setStrokeStyle(2 * SK_Scalar1);
+    stroke.applyToPath(&path, path);
+}
+
 static void make_path0(SkPath* path) {
     // from  *  https://code.google.com/p/skia/issues/detail?id=1706
 
@@ -3553,4 +3579,5 @@
     PathTest_Private::TestPathTo(reporter);
     PathRefTest_Private::TestPathRef(reporter);
     test_dump(reporter);
+    test_path_crbugskia2820(reporter);
 }