Reland of more zero-length changes for svg compatibility (patchset #1 id:1 of https://codereview.chromium.org/1334543002/ )

Reason for revert:
DEPS should be fixed now

Original issue's description:
> Revert of more zero-length changes for svg compatibility (patchset #6 id:100001 of https://codereview.chromium.org/1330623003/ )
>
> Reason for revert:
> breaks DEPS
>
> Original issue's description:
> > more zero-length changes for svg compatibility
> >
> > If a path contains a moveTo followed by a line or curve,
> > even if the line or curve has no length, SVG expects
> > the end caps to draw if the cap style is round or square.
> >
> > Fredrik Söderquist attached a patch to the chrome bug
> > (slightly modified here) that fixes layout test failures
> > resulting from deleting special-case code in SVG
> > dealing with zero-length path segments.
> >
> > R=reed@google.com,fs@opera.com
> > BUG=22974
> >
> > Committed: https://skia.googlesource.com/skia/+/62fb1ba1786863e545c89839b5706ad5151cec15
>
> TBR=fs@opera.com,reed@google.com
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=22974
>
> Committed: https://skia.googlesource.com/skia/+/5ca4fa3846067a47e88d35ace895df3ebe3ec2a5

TBR=fs@opera.com,reed@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=22974

Review URL: https://codereview.chromium.org/1314833004
diff --git a/gm/strokes.cpp b/gm/strokes.cpp
index 57517a0..e74d35f 100644
--- a/gm/strokes.cpp
+++ b/gm/strokes.cpp
@@ -84,12 +84,16 @@
  */
 class ZeroLenStrokesGM : public skiagm::GM {
     SkPath fMoveHfPath, fMoveZfPath, fDashedfPath, fRefPath[4];
+    SkPath fCubicPath, fQuadPath, fLinePath;
 protected:
     void onOnceBeforeDraw() override {
 
         SkAssertResult(SkParsePath::FromSVGString("M0,0h0M10,0h0M20,0h0", &fMoveHfPath));
         SkAssertResult(SkParsePath::FromSVGString("M0,0zM10,0zM20,0z", &fMoveZfPath));
         SkAssertResult(SkParsePath::FromSVGString("M0,0h25", &fDashedfPath));
+        SkAssertResult(SkParsePath::FromSVGString("M 0 0 C 0 0 0 0 0 0", &fCubicPath));
+        SkAssertResult(SkParsePath::FromSVGString("M 0 0 Q 0 0 0 0", &fQuadPath));
+        SkAssertResult(SkParsePath::FromSVGString("M 0 0 L 0 0", &fLinePath));
 
         for (int i = 0; i < 3; ++i) {
             fRefPath[0].addCircle(i * 10.f, 0, 5);
@@ -140,6 +144,12 @@
             canvas->translate(0, 30);
             fillPaint.setAlpha(127);
             canvas->drawPath(fRefPath[1 + i * 2], fillPaint);
+            canvas->translate(0, 30);
+            canvas->drawPath(fCubicPath, strokePaint);
+            canvas->translate(0, 30);
+            canvas->drawPath(fQuadPath, strokePaint);
+            canvas->translate(0, 30);
+            canvas->drawPath(fLinePath, strokePaint);
             canvas->restore();
         }
     }
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 7043ec3..3a28956 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -2124,8 +2124,8 @@
     if (r.width() <= 0 && r.height() <= 0) {
         if (path.isInverseFillType()) {
             this->internalDrawPaint(paint);
+            return;
         }
-        return;
     }
 
     LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds)
diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp
index 1689f97..522a000 100644
--- a/src/core/SkStroke.cpp
+++ b/src/core/SkStroke.cpp
@@ -619,6 +619,10 @@
     SkPoint reduction;
     ReductionType reductionType = CheckConicLinear(conic, &reduction);
     if (kPoint_ReductionType == reductionType) {
+        /* If the stroke consists of a moveTo followed by a degenerate curve, treat it
+            as if it were followed by a zero-length line. Lines without length
+            can have square and round end caps. */
+        this->lineTo(pt2);
         return;
     }
     if (kLine_ReductionType == reductionType) {
@@ -653,6 +657,10 @@
     SkPoint reduction;
     ReductionType reductionType = CheckQuadLinear(quad, &reduction);
     if (kPoint_ReductionType == reductionType) {
+        /* If the stroke consists of a moveTo followed by a degenerate curve, treat it
+            as if it were followed by a zero-length line. Lines without length
+            can have square and round end caps. */
+        this->lineTo(pt2);
         return;
     }
     if (kLine_ReductionType == reductionType) {
@@ -1168,6 +1176,10 @@
     const SkPoint* tangentPt;
     ReductionType reductionType = CheckCubicLinear(cubic, reduction, &tangentPt);
     if (kPoint_ReductionType == reductionType) {
+        /* If the stroke consists of a moveTo followed by a degenerate curve, treat it
+            as if it were followed by a zero-length line. Lines without length
+            can have square and round end caps. */
+        this->lineTo(pt3);
         return;
     }
     if (kLine_ReductionType == reductionType) {
diff --git a/tests/EmptyPathTest.cpp b/tests/EmptyPathTest.cpp
index c4f011a..060ef8d 100644
--- a/tests/EmptyPathTest.cpp
+++ b/tests/EmptyPathTest.cpp
@@ -54,7 +54,13 @@
     }
 }
 
-static void iter_paint(skiatest::Reporter* reporter, const SkPath& path, bool shouldDraw) {
+enum DrawCaps {
+    kDontDrawCaps,
+    kDrawCaps
+};
+
+static void iter_paint(skiatest::Reporter* reporter, const SkPath& path, bool shouldDraw,
+                       DrawCaps drawCaps) {
     static const SkPaint::Cap gCaps[] = {
         SkPaint::kButt_Cap,
         SkPaint::kRound_Cap,
@@ -73,6 +79,11 @@
     for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
         for (size_t join = 0; join < SK_ARRAY_COUNT(gJoins); ++join) {
             for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
+                if (drawCaps && SkPaint::kButt_Cap != gCaps[cap]
+                        && SkPaint::kFill_Style != gStyles[style]) {
+                    continue;
+                }
+
                 SkPaint paint;
                 paint.setStrokeWidth(SkIntToScalar(10));
 
@@ -127,10 +138,14 @@
             if (doClose) {
                 path.close();
             }
+            /* zero length segments and close following moves draw round and square caps */
+            bool allowCaps = make_L == gMakeProc[i] || make_Q == gMakeProc[i]
+                    || make_C == gMakeProc[i] || make_MZM == gMakeProc[i];
+            allowCaps |= SkToBool(doClose);
             for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
                 path.setFillType(gFills[fill]);
                 bool shouldDraw = path.isInverseFillType();
-                iter_paint(reporter, path, shouldDraw);
+                iter_paint(reporter, path, shouldDraw, allowCaps ? kDrawCaps : kDontDrawCaps);
             }
         }
     }