1 /*
2 * Copyright 2020 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 SkRive_DEFINED
9 #define SkRive_DEFINED
10
11 #include "include/core/SkBlendMode.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkM44.h"
14 #include "include/core/SkPaint.h"
15 #include "include/core/SkPathTypes.h"
16 #include "include/core/SkRefCnt.h"
17 #include "include/core/SkString.h"
18
19 #include <memory>
20 #include <type_traits>
21 #include <vector>
22
23 class SkCanvas;
24 class SkPaint;
25 class SkStreamAsset;
26
27 namespace skrive {
28
29 #define ACTOR_ATTR(attr_name, attr_type, attr_default) \
30 private: \
31 attr_type f##attr_name = attr_default; \
32 public: \
33 const attr_type& get##attr_name() const { return f##attr_name; } \
34 void set##attr_name(const attr_type& v) { \
35 if (f##attr_name == v) return; \
36 f##attr_name = v; \
37 this->invalidate(); \
38 } \
39 void set##attr_name(attr_type&& v) { \
40 if (f##attr_name == v) return; \
41 f##attr_name = std::move(v); \
42 this->invalidate(); \
43 }
44
45 class Node;
46
47 class Component : public SkRefCnt {
48 public:
ACTOR_ATTR(Name,SkString,SkString ())49 ACTOR_ATTR(Name, SkString, SkString())
50
51 template <typename T>
52 std::enable_if_t<std::is_base_of<Component, T>::value, bool>
53 is() const {
54 if constexpr(std::is_same<Component, T>::value) {
55 return true;
56 } else {
57 return is_base_of<T>(fType);
58 }
59 }
60
61 template <typename T>
62 operator const T*() const {
63 return this->is<T>() ? reinterpret_cast<const T*>(this) : nullptr;
64 }
65
66 template <typename T>
67 operator T*() {
68 return this->is<T>() ? reinterpret_cast<T*>(this) : nullptr;
69 }
70
71 void revalidate();
72
73 // probably not the right place
render(SkCanvas * canvas)74 void render(SkCanvas* canvas) const {
75 this->onRender(canvas);
76 }
77
78 protected:
79 enum class Type : uint32_t {
80 kNode,
81 kShape,
82 kColorPaint,
83 kEllipse,
84 kRectangle,
85 };
86
Component(Type t)87 explicit Component(Type t) : fType(t) {}
88
89 void invalidate();
90
hasInval()91 bool hasInval() const { return fDirty; }
92
93 virtual void onRevalidate() = 0;
94 virtual void onRender(SkCanvas*) const;
95
96 private:
97 friend class Node; // parent access
98
99 template <typename T>
100 static constexpr bool is_base_of(Type t);
101
102 const Type fType;
103
104 Node* fParent = nullptr;
105 bool fDirty = true;
106 };
107
108 class TransformableComponent : public Component {
109 public:
110 ACTOR_ATTR(Translation , SkV2 , SkV2({0, 0}))
111 ACTOR_ATTR(Scale , SkV2 , SkV2({1, 1}))
112 ACTOR_ATTR(Rotation , float, 0 )
113 ACTOR_ATTR(Opacity , float, 1 )
114
115 protected:
TransformableComponent(Type t)116 explicit TransformableComponent(Type t) : INHERITED(t) {}
117
118 class ScopedTransformContext final {
119 public:
120 ScopedTransformContext(const TransformableComponent*, SkCanvas*);
121 ~ScopedTransformContext();
122
123 private:
124 SkCanvas* fCanvas;
125 const int fRestoreCount;
126 };
127
128 private:
129 using INHERITED = Component;
130 };
131
132 class Node : public TransformableComponent {
133 public:
Node()134 Node() : INHERITED(Type::kNode) {}
135
136 ACTOR_ATTR(CollapsedVisibility, bool , false )
137
138 void addChild(sk_sp<Component>);
139
children()140 const std::vector<sk_sp<Component>>& children() const { return fChildren; }
141
142 protected:
Node(Type t)143 explicit Node(Type t) : INHERITED(t) {}
144
145 void onRevalidate() override;
146
147 void onRender(SkCanvas*) const override;
148
149 private:
150 std::vector<sk_sp<Component>> fChildren;
151
152 using INHERITED = TransformableComponent;
153 };
154
155 class Paint : public Component {
156 public:
157 ACTOR_ATTR(Opacity , float , 1 )
158 ACTOR_ATTR(FillRule , SkPathFillType, SkPathFillType::kWinding )
159 ACTOR_ATTR(StrokeWidth, float , 1 )
160 ACTOR_ATTR(StrokeCap , SkPaint::Cap , SkPaint::Cap::kButt_Cap )
161 ACTOR_ATTR(StrokeJoin , SkPaint::Join , SkPaint::Join::kMiter_Join)
162
163 enum class StrokeTrim : uint8_t { kOff, kSequential, kSynced };
ACTOR_ATTR(StrokeTrim,StrokeTrim,StrokeTrim::kOff)164 ACTOR_ATTR(StrokeTrim , StrokeTrim, StrokeTrim::kOff)
165 ACTOR_ATTR(StrokeTrimStart , float , 0)
166 ACTOR_ATTR(StrokeTrimEnd , float , 0)
167 ACTOR_ATTR(StrokeTrimOffset, float , 0)
168
169 void apply(SkPaint* paint) const {
170 this->onApply(paint);
171 }
172
style()173 SkPaint::Style style() const { return fStyle; }
174
175 protected:
Paint(Type t,SkPaint::Style style)176 Paint(Type t, SkPaint::Style style) : INHERITED(t), fStyle(style) {}
177
178 virtual void onApply(SkPaint*) const;
179
180 private:
181 const SkPaint::Style fStyle;
182
183 using INHERITED = Component;
184 };
185
186 class ColorPaint final : public Paint {
187 public:
ColorPaint(SkPaint::Style style)188 explicit ColorPaint(SkPaint::Style style) : INHERITED(Type::kColorPaint, style) {}
189
190 ACTOR_ATTR(Color, SkColor4f, SkColors::kBlack)
191
192 private:
193 void onRevalidate() override;
194
195 void onApply(SkPaint*) const override;
196
197 using INHERITED = Paint;
198 };
199
200 class Geometry : public Node {
201 public:
draw(SkCanvas * canvas,const SkPaint & paint,SkPathFillType ftype)202 void draw(SkCanvas* canvas, const SkPaint& paint, SkPathFillType ftype) const {
203 return this->onDraw(canvas, paint, ftype);
204 }
205
206 protected:
Geometry(Type t)207 explicit Geometry(Type t) : INHERITED(t) {}
208
209 virtual void onDraw(SkCanvas*, const SkPaint&, SkPathFillType) const = 0;
210
211 private:
212 using INHERITED = Node;
213 };
214
215 class Ellipse final : public Geometry {
216 public:
Ellipse()217 Ellipse() : INHERITED(Type::kEllipse) {}
218
219 ACTOR_ATTR(Width , float, 0)
220 ACTOR_ATTR(Height, float, 0)
221
222 private:
223 void onRevalidate() override;
224 void onDraw(SkCanvas*, const SkPaint&, SkPathFillType) const override;
225
226 using INHERITED = Geometry;
227 };
228
229 class Rectangle final : public Geometry {
230 public:
Rectangle()231 Rectangle() : INHERITED(Type::kRectangle) {}
232
233 ACTOR_ATTR(Width , float, 0)
234 ACTOR_ATTR(Height, float, 0)
235 ACTOR_ATTR(Radius, float, 0)
236
237 private:
238 void onRevalidate() override;
239 void onDraw(SkCanvas*, const SkPaint&, SkPathFillType) const override;
240
241 using INHERITED = Geometry;
242 };
243
244 class Drawable : public Node {
245 public:
246 ACTOR_ATTR(DrawOrder, size_t , 0 )
ACTOR_ATTR(BlendMode,SkBlendMode,SkBlendMode::kSrcOver)247 ACTOR_ATTR(BlendMode, SkBlendMode, SkBlendMode::kSrcOver)
248 ACTOR_ATTR(IsHidden , bool , false )
249
250 protected:
251 explicit Drawable(Type t) : INHERITED(t) {}
252
253 private:
254 using INHERITED = Node;
255 };
256
257 class Shape final : public Drawable {
258 public:
Shape()259 Shape() : INHERITED(Type::kShape) {}
260
261 ACTOR_ATTR(TransformAffectsStroke, bool, true)
262
263 private:
264 void onRevalidate() override;
265 void onRender(SkCanvas*) const override;
266
267 // cached on revalidation
268 // tracked separately due to paint order (all fills before strokes)
269 std::vector<const Paint*> fFills,
270 fStrokes;
271
272 std::vector<const Geometry*> fGeometries;
273
274 using INHERITED = Drawable;
275 };
276
277 template <typename T>
is_base_of(Type t)278 constexpr bool Component::is_base_of(Type t) {
279 if (t == Type::kNode ) return std::is_base_of<T, Node >::value;
280 if (t == Type::kShape ) return std::is_base_of<T, Shape >::value;
281 if (t == Type::kColorPaint) return std::is_base_of<T, ColorPaint>::value;
282 if (t == Type::kEllipse ) return std::is_base_of<T, Ellipse >::value;
283 if (t == Type::kRectangle ) return std::is_base_of<T, Rectangle >::value;
284
285 return false;
286 }
287
288 class Artboard final : public SkRefCnt {
289 public:
290 ACTOR_ATTR(Root , sk_sp<Node>, nullptr )
291 ACTOR_ATTR(Name , SkString , SkString() )
292 ACTOR_ATTR(Color , SkColor4f , SkColors::kBlack)
293 ACTOR_ATTR(Size , SkV2 , SkV2({0,0}) )
294 ACTOR_ATTR(Origin , SkV2 , SkV2({0,0}) )
295 ACTOR_ATTR(Translation , SkV2 , SkV2({0,0}) )
296 ACTOR_ATTR(ClipContents, bool , false )
297
298 void render(SkCanvas*) const;
299
300 private:
invalidate()301 void invalidate() {}
302 };
303
304 class SK_API SkRive final : public SkNVRefCnt<SkRive> {
305 public:
306 class Builder final {
307 public:
308 sk_sp<SkRive> make(std::unique_ptr<SkStreamAsset>);
309 };
310
artboards()311 const std::vector<sk_sp<Artboard>>& artboards() const { return fArtboards; }
artboards()312 std::vector<sk_sp<Artboard>>& artboards() { return fArtboards; }
313
314 private:
315 std::vector<sk_sp<Artboard>> fArtboards;
316 };
317
318 } // namespace skrive
319
320 #endif // SkRive_DEFINED
321