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 SkottieAdapter_DEFINED
9 #define SkottieAdapter_DEFINED
10 
11 #include "SkPoint.h"
12 #include "SkRefCnt.h"
13 #include "SkSize.h"
14 #include "SkottieValue.h"
15 
16 namespace sksg {
17 
18 class Color;
19 class Draw;
20 class Gradient;
21 class Group;
22 class LinearGradient;
23 template <typename>
24 class Matrix;
25 class Path;
26 class RadialGradient;
27 class RenderNode;
28 class RRect;
29 class TextBlob;
30 class TransformEffect;
31 class TrimEffect;
32 
33 };
34 
35 namespace skottie {
36 
37 #define ADAPTER_PROPERTY(p_name, p_type, p_default) \
38     const p_type& get##p_name() const {             \
39         return f##p_name;                           \
40     }                                               \
41     void set##p_name(const p_type& p) {             \
42         if (p == f##p_name) return;                 \
43         f##p_name = p;                              \
44         this->apply();                              \
45     }                                               \
46   private:                                          \
47     p_type f##p_name = p_default;                   \
48   public:
49 
50 class RRectAdapter final : public SkNVRefCnt<RRectAdapter> {
51 public:
52     explicit RRectAdapter(sk_sp<sksg::RRect>);
53     ~RRectAdapter();
54 
55     ADAPTER_PROPERTY(Position, SkPoint , SkPoint::Make(0, 0))
56     ADAPTER_PROPERTY(Size    , SkSize  ,  SkSize::Make(0, 0))
57     ADAPTER_PROPERTY(Radius  , SkSize  ,  SkSize::Make(0, 0))
58 
59 private:
60     void apply();
61 
62     sk_sp<sksg::RRect> fRRectNode;
63 };
64 
65 class PolyStarAdapter final : public SkNVRefCnt<PolyStarAdapter> {
66 public:
67     enum class Type {
68         kStar, kPoly,
69     };
70 
71     PolyStarAdapter(sk_sp<sksg::Path>, Type);
72     ~PolyStarAdapter();
73 
74     ADAPTER_PROPERTY(Position      , SkPoint , SkPoint::Make(0, 0))
75     ADAPTER_PROPERTY(PointCount    , SkScalar, 0)
76     ADAPTER_PROPERTY(InnerRadius   , SkScalar, 0)
77     ADAPTER_PROPERTY(OuterRadius   , SkScalar, 0)
78     ADAPTER_PROPERTY(InnerRoundness, SkScalar, 0)
79     ADAPTER_PROPERTY(OuterRoundness, SkScalar, 0)
80     ADAPTER_PROPERTY(Rotation      , SkScalar, 0)
81 
82 private:
83     void apply();
84 
85     sk_sp<sksg::Path> fPathNode;
86     Type              fType;
87 };
88 
89 class TransformAdapter2D final : public SkNVRefCnt<TransformAdapter2D> {
90 public:
91     explicit TransformAdapter2D(sk_sp<sksg::Matrix<SkMatrix>>);
92     ~TransformAdapter2D();
93 
94     ADAPTER_PROPERTY(AnchorPoint, SkPoint , SkPoint::Make(0, 0))
95     ADAPTER_PROPERTY(Position   , SkPoint , SkPoint::Make(0, 0))
96     ADAPTER_PROPERTY(Scale      , SkVector, SkPoint::Make(100, 100))
97     ADAPTER_PROPERTY(Rotation   , SkScalar, 0)
98     ADAPTER_PROPERTY(Skew       , SkScalar, 0)
99     ADAPTER_PROPERTY(SkewAxis   , SkScalar, 0)
100 
101     SkMatrix totalMatrix() const;
102 
103 private:
104     void apply();
105 
106     sk_sp<sksg::Matrix<SkMatrix>> fMatrixNode;
107 };
108 
109 class TransformAdapter3D final : public SkNVRefCnt<TransformAdapter3D> {
110 public:
111     explicit TransformAdapter3D(sk_sp<sksg::Matrix<SkMatrix44>>);
112     ~TransformAdapter3D();
113 
114     struct Vec3 {
115         float fX, fY, fZ;
116 
117         explicit Vec3(const VectorValue&);
118 
119         bool operator==(const Vec3& other) const {
120             return fX == other.fX && fY == other.fY && fZ == other.fZ;
121         }
122         bool operator!=(const Vec3& other) const { return !(*this == other); }
123     };
124 
125     ADAPTER_PROPERTY(AnchorPoint, Vec3, Vec3({  0,   0,   0}))
126     ADAPTER_PROPERTY(Position   , Vec3, Vec3({  0,   0,   0}))
127     ADAPTER_PROPERTY(Rotation   , Vec3, Vec3({  0,   0,   0}))
128     ADAPTER_PROPERTY(Scale      , Vec3, Vec3({100, 100, 100}))
129 
130     SkMatrix44 totalMatrix() const;
131 
132 private:
133     void apply();
134 
135     sk_sp<sksg::Matrix<SkMatrix44>> fMatrixNode;
136 };
137 
138 class RepeaterAdapter final : public SkNVRefCnt<RepeaterAdapter> {
139 public:
140     enum class Composite { kAbove, kBelow };
141 
142     RepeaterAdapter(sk_sp<sksg::RenderNode>, Composite);
143     ~RepeaterAdapter();
144 
145     // Repeater props
146     ADAPTER_PROPERTY(Count       , SkScalar, 0)
147     ADAPTER_PROPERTY(Offset      , SkScalar, 0)
148 
149     // Transform props
150     ADAPTER_PROPERTY(AnchorPoint , SkPoint , SkPoint::Make(0, 0))
151     ADAPTER_PROPERTY(Position    , SkPoint , SkPoint::Make(0, 0))
152     ADAPTER_PROPERTY(Scale       , SkVector, SkPoint::Make(100, 100))
153     ADAPTER_PROPERTY(Rotation    , SkScalar, 0)
154     ADAPTER_PROPERTY(StartOpacity, SkScalar, 100)
155     ADAPTER_PROPERTY(EndOpacity  , SkScalar, 100)
156 
root()157     const sk_sp<sksg::Group>& root() const { return fRoot; }
158 
159 private:
160     void apply();
161 
162     const sk_sp<sksg::RenderNode> fRepeaterNode;
163     const Composite               fComposite;
164 
165     sk_sp<sksg::Group>            fRoot;
166 };
167 
168 class GradientAdapter : public SkRefCnt {
169 public:
170     ADAPTER_PROPERTY(StartPoint, SkPoint        , SkPoint::Make(0, 0)   )
171     ADAPTER_PROPERTY(EndPoint  , SkPoint        , SkPoint::Make(0, 0)   )
172     ADAPTER_PROPERTY(ColorStops, VectorValue    , VectorValue()         )
173 
174 protected:
175     GradientAdapter(sk_sp<sksg::Gradient>, size_t stopCount);
176 
startPoint()177     const SkPoint& startPoint() const { return fStartPoint; }
endPoint()178     const SkPoint& endPoint()   const { return fEndPoint;   }
179 
180     sk_sp<sksg::Gradient> fGradient;
181     size_t                fStopCount;
182 
183     virtual void onApply() = 0;
184 
185 private:
186     void apply();
187 };
188 
189 class LinearGradientAdapter final : public GradientAdapter {
190 public:
191     LinearGradientAdapter(sk_sp<sksg::LinearGradient>, size_t stopCount);
192 
193 private:
194     void onApply() override;
195 
196     using INHERITED = GradientAdapter;
197 };
198 
199 class RadialGradientAdapter final : public GradientAdapter {
200 public:
201     RadialGradientAdapter(sk_sp<sksg::RadialGradient>, size_t stopCount);
202 
203 private:
204     void onApply() override;
205 
206     using INHERITED = GradientAdapter;
207 };
208 
209 class TrimEffectAdapter final : public SkNVRefCnt<TrimEffectAdapter> {
210 public:
211     explicit TrimEffectAdapter(sk_sp<sksg::TrimEffect>);
212     ~TrimEffectAdapter();
213 
214     ADAPTER_PROPERTY(Start , SkScalar,   0)
215     ADAPTER_PROPERTY(End   , SkScalar, 100)
216     ADAPTER_PROPERTY(Offset, SkScalar,   0)
217 
218 private:
219     void apply();
220 
221     sk_sp<sksg::TrimEffect> fTrimEffect;
222 };
223 
224 class TextAdapter final : public SkNVRefCnt<TextAdapter> {
225 public:
226     explicit TextAdapter(sk_sp<sksg::Group> root);
227     ~TextAdapter();
228 
ADAPTER_PROPERTY(Text,TextValue,TextValue ())229     ADAPTER_PROPERTY(Text, TextValue, TextValue())
230 
231     const sk_sp<sksg::Group>& root() const { return fRoot; }
232 
233 private:
234     void apply();
235     sk_sp<SkTextBlob> makeBlob() const;
236 
237     sk_sp<sksg::Group>     fRoot;
238     sk_sp<sksg::TextBlob>  fTextNode;
239     sk_sp<sksg::Color>     fFillColor,
240                            fStrokeColor;
241     sk_sp<sksg::Draw>      fFillNode,
242                            fStrokeNode;
243 
244     bool                   fHadFill   : 1, //  - state cached from the prev apply()
245                            fHadStroke : 1; //  /
246 };
247 
248 #undef ADAPTER_PROPERTY
249 
250 } // namespace skottie
251 
252 #endif // SkottieAdapter_DEFINED
253