1 /*
2  * Copyright 2018 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkSGGradient_DEFINED
9 #define SkSGGradient_DEFINED
10 
11 #include "SkSGPaintNode.h"
12 
13 #include "SkColor.h"
14 #include "SkPoint.h"
15 #include "SkScalar.h"
16 #include "SkShader.h"
17 
18 #include <vector>
19 
20 namespace sksg {
21 
22 /**
23  * Gradient base class.
24  */
25 class Gradient : public PaintNode {
26 public:
27     struct ColorStop {
28         SkScalar fPosition;
29         SkColor  fColor;
30 
31         bool operator==(const ColorStop& other) const {
32             return fPosition == other.fPosition && fColor == other.fColor;
33         }
34     };
35 
36     SG_ATTRIBUTE(ColorStops, std::vector<ColorStop>, fColorStops)
37     SG_ATTRIBUTE(TileMode  , SkShader::TileMode    , fTileMode  )
38 
39 protected:
40     void onApplyToPaint(SkPaint*) const final;
41 
42     virtual sk_sp<SkShader> onMakeShader(const std::vector<SkColor>& colors,
43                                          const std::vector<SkScalar>& positions) const = 0;
44 
45 protected:
46     Gradient() = default;
47 
48 private:
49     std::vector<ColorStop> fColorStops;
50     SkShader::TileMode     fTileMode = SkShader::kClamp_TileMode;
51 
52     using INHERITED = PaintNode;
53 };
54 
55 class LinearGradient final : public Gradient {
56 public:
Make()57     static sk_sp<LinearGradient> Make() {
58         return sk_sp<LinearGradient>(new LinearGradient());
59     }
60 
61     SG_ATTRIBUTE(StartPoint, SkPoint, fStartPoint)
62     SG_ATTRIBUTE(EndPoint  , SkPoint, fEndPoint  )
63 
64 protected:
65     sk_sp<SkShader> onMakeShader(const std::vector<SkColor>& colors,
66                                  const std::vector<SkScalar>& positions) const override;
67 
68 private:
69     LinearGradient() = default;
70 
71     SkPoint fStartPoint = SkPoint::Make(0, 0),
72             fEndPoint   = SkPoint::Make(0, 0);
73 
74     using INHERITED = Gradient;
75 };
76 
77 class RadialGradient final : public Gradient {
78 public:
Make()79     static sk_sp<RadialGradient> Make() {
80         return sk_sp<RadialGradient>(new RadialGradient());
81     }
82 
83     SG_ATTRIBUTE(StartCenter, SkPoint , fStartCenter)
84     SG_ATTRIBUTE(EndCenter  , SkPoint , fEndCenter  )
85     SG_ATTRIBUTE(StartRadius, SkScalar, fStartRadius)
86     SG_ATTRIBUTE(EndRadius  , SkScalar, fEndRadius  )
87 
88 protected:
89     sk_sp<SkShader> onMakeShader(const std::vector<SkColor>& colors,
90                                  const std::vector<SkScalar>& positions) const override;
91 
92 private:
93     RadialGradient() = default;
94 
95     SkPoint  fStartCenter = SkPoint::Make(0, 0),
96              fEndCenter   = SkPoint::Make(0, 0);
97     SkScalar fStartRadius = 0,
98              fEndRadius   = 0;
99 
100     using INHERITED = Gradient;
101 };
102 
103 } // namespace sksg
104 
105 #endif // SkSGGradient_DEFINED
106