Handle cubic segments in variable-width stroker

Change-Id: I51cc54e7f8b1b457a55f6cc91a9a6d3c5158d193
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330742
Reviewed-by: Tyler Denniston <tdenniston@google.com>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
diff --git a/samplecode/SampleVariableWidthStroker.cpp b/samplecode/SampleVariableWidthStroker.cpp
index 6ddbe51..ab2117a 100644
--- a/samplecode/SampleVariableWidthStroker.cpp
+++ b/samplecode/SampleVariableWidthStroker.cpp
@@ -450,17 +450,11 @@
     /** Initialize stroker state */
     void initForPath(const SkPath& path, const SkPaint& paint);
 
-    /** Strokes a line segment */
-    OffsetSegments strokeLine(const PathSegment& line,
-                              const ScalarBezCurve& varWidth,
-                              const ScalarBezCurve& varWidthInner,
-                              bool needsMove);
-
-    /** Strokes a quadratic segment */
-    OffsetSegments strokeQuad(const PathSegment& quad,
-                              const ScalarBezCurve& varWidth,
-                              const ScalarBezCurve& varWidthInner,
-                              bool needsMove);
+    /** Strokes a path segment */
+    OffsetSegments strokeSegment(const PathSegment& segment,
+                                 const ScalarBezCurve& varWidth,
+                                 const ScalarBezCurve& varWidthInner,
+                                 bool needsMove);
 
     /**
      * Strokes the given segment using the given distance function.
@@ -578,10 +572,9 @@
         // Stroke the current segment
         switch (segment.fVerb) {
             case SkPath::kLine_Verb:
-                offsetSegs = strokeLine(segment, partVarWidth, partVarWidthInner, firstSegment);
-                break;
             case SkPath::kQuad_Verb:
-                offsetSegs = strokeQuad(segment, partVarWidth, partVarWidthInner, firstSegment);
+            case SkPath::kCubic_Verb:
+                offsetSegs = strokeSegment(segment, partVarWidth, partVarWidthInner, firstSegment);
                 break;
             case SkPath::kMove_Verb:
                 // Don't care about multiple contours currently
@@ -630,25 +623,15 @@
     return fOuter;
 }
 
-SkVarWidthStroker::OffsetSegments SkVarWidthStroker::strokeLine(const PathSegment& line,
-                                                                const ScalarBezCurve& varWidth,
-                                                                const ScalarBezCurve& varWidthInner,
-                                                                bool needsMove) {
+SkVarWidthStroker::OffsetSegments SkVarWidthStroker::strokeSegment(
+        const PathSegment& segment,
+        const ScalarBezCurve& varWidth,
+        const ScalarBezCurve& varWidthInner,
+        bool needsMove) {
     viz::outerErr.reset(nullptr);
 
-    std::vector<PathSegment> outer = strokeSegment(line, varWidth);
-    std::vector<PathSegment> inner = strokeSegment(line, varWidthInner);
-    return {inner, outer};
-}
-
-SkVarWidthStroker::OffsetSegments SkVarWidthStroker::strokeQuad(const PathSegment& quad,
-                                                                const ScalarBezCurve& varWidth,
-                                                                const ScalarBezCurve& varWidthInner,
-                                                                bool needsMove) {
-    viz::outerErr.reset(nullptr);
-
-    std::vector<PathSegment> outer = strokeSegment(quad, varWidth);
-    std::vector<PathSegment> inner = strokeSegment(quad, varWidthInner);
+    std::vector<PathSegment> outer = strokeSegment(segment, varWidth);
+    std::vector<PathSegment> inner = strokeSegment(segment, varWidthInner);
     return {inner, outer};
 }
 
@@ -1014,6 +997,18 @@
             }
             return rotate90(tangent);
         }
+        case SkPath::kCubic_Verb: {
+            SkPoint tangent;
+            SkEvalCubicAt(seg.fPoints.data(), t, nullptr, &tangent, nullptr);
+            if (!tangent.normalize()) {
+                SkDebugf("Failed to normalize cubic tangent\n");
+                SkASSERT(false);
+            }
+            if (tangentOut) {
+                *tangentOut = tangent;
+            }
+            return rotate90(tangent);
+        }
         default:
             SkDebugf("Unhandled verb for unit normal %d\n", seg.fVerb);
             SkASSERT(false);