[skotty,sksg] Initial gradient support

TBR=
Change-Id: I61e4d46ac14660f4c9ea757be2278e4098131a6b
Reviewed-on: https://skia-review.googlesource.com/94121
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/experimental/sksg/paint/SkSGGradient.cpp b/experimental/sksg/paint/SkSGGradient.cpp
new file mode 100644
index 0000000..98e7f39
--- /dev/null
+++ b/experimental/sksg/paint/SkSGGradient.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkSGGradient.h"
+
+#include "SkGradientShader.h"
+#include "SkPaint.h"
+
+namespace sksg {
+
+void Gradient::onApplyToPaint(SkPaint* paint) const {
+    if (fColorStops.empty()) {
+        paint->setShader(nullptr);
+        return;
+    }
+
+    std::vector<SkColor>  colors;
+    std::vector<SkScalar> positions;
+    colors.reserve(fColorStops.size());
+    positions.reserve(fColorStops.size());
+
+    SkScalar position = 0;
+    for (const auto& stop : fColorStops) {
+        colors.push_back(stop.fColor);
+        position = SkTPin(stop.fPosition, position, 1.0f);
+        positions.push_back(position);
+    }
+
+    // TODO: detect even stop distributions, pass null for positions.
+    paint->setShader(this->onMakeShader(colors, positions));
+}
+
+sk_sp<SkShader> LinearGradient::onMakeShader(const std::vector<SkColor>& colors,
+                                             const std::vector<SkScalar>& positions) const {
+    SkASSERT(colors.size() == positions.size());
+
+    const SkPoint pts[] = { fStartPoint, fEndPoint };
+    return SkGradientShader::MakeLinear(pts, colors.data(), positions.data(), colors.size(),
+                                        this->getTileMode());
+}
+
+sk_sp<SkShader> RadialGradient::onMakeShader(const std::vector<SkColor>& colors,
+                                             const std::vector<SkScalar>& positions) const {
+    SkASSERT(colors.size() == positions.size());
+
+    return (fStartRadius <= 0 && fStartCenter == fEndCenter)
+        ? SkGradientShader::MakeRadial(fEndCenter, fEndRadius,
+                                       colors.data(), positions.data(), colors.size(),
+                                       this->getTileMode())
+        : SkGradientShader::MakeTwoPointConical(fStartCenter, fStartRadius,
+                                                fEndCenter, fEndRadius,
+                                                colors.data(), positions.data(), colors.size(),
+                                                this->getTileMode());
+}
+
+} //namespace sksg