• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 SkSGTransform_DEFINED
9 #define SkSGTransform_DEFINED
10 
11 #include "modules/sksg/include/SkSGEffectNode.h"
12 
13 #include "include/core/SkMatrix.h"
14 #include "include/core/SkMatrix44.h"
15 
16 namespace sksg {
17 
18 /**
19  * Transformations base class.
20  */
21 class Transform : public Node {
22 public:
23     // Compose T' = A x B
24     static sk_sp<Transform> MakeConcat(sk_sp<Transform> a, sk_sp<Transform> b);
25 
26     // T' = Inv(T)
27     static sk_sp<Transform> MakeInverse(sk_sp<Transform> t);
28 
29 protected:
30     Transform();
31 
32     virtual bool is44() const = 0;
33 
34     virtual SkMatrix   asMatrix  () const = 0;
35     virtual SkMatrix44 asMatrix44() const = 0;
36 
37 private:
38     friend class TransformPriv;
39 
40     using INHERITED = Node;
41 };
42 
43 /**
44  * Concrete, matrix-backed Transform.
45  *
46  * Supported instantiations: SkMatrix, SkMatrix44.
47  *
48  * Sample use:
49  *
50  *   auto m33 = Matrix<SkMatrix>::Make(SkMatrix::I());
51  *   ...
52  *   m33->setMatrix(SkMatrix::MakeTrans(10, 10));
53  *
54  */
55 template <typename T>
56 class Matrix final : public Transform {
57 public:
58     template <typename = std::enable_if<std::is_same<T, SkMatrix  >::value ||
59                                         std::is_same<T, SkMatrix44>::value>>
Make(const T & m)60     static sk_sp<Matrix> Make(const T& m) { return sk_sp<Matrix>(new Matrix(m)); }
61 
SG_ATTRIBUTE(Matrix,T,fMatrix)62     SG_ATTRIBUTE(Matrix, T, fMatrix)
63 
64 protected:
65     explicit Matrix(const T& m) : fMatrix(m) {}
66 
onRevalidate(InvalidationController *,const SkMatrix &)67     SkRect onRevalidate(InvalidationController*, const SkMatrix&) override {
68         return SkRect::MakeEmpty();
69     }
70 
is44()71     bool is44() const override { return std::is_same<T, SkMatrix44>::value; }
72 
asMatrix()73     SkMatrix   asMatrix  () const override { return fMatrix; }
asMatrix44()74     SkMatrix44 asMatrix44() const override { return fMatrix; }
75 
76 private:
77     T fMatrix;
78 
79     using INHERITED = Transform;
80 };
81 
82 /**
83  * Concrete Effect node, binding a Transform to a RenderNode.
84  */
85 class TransformEffect final : public EffectNode {
86 public:
Make(sk_sp<RenderNode> child,sk_sp<Transform> transform)87     static sk_sp<TransformEffect> Make(sk_sp<RenderNode> child, sk_sp<Transform> transform) {
88         return child && transform
89             ? sk_sp<TransformEffect>(new TransformEffect(std::move(child), std::move(transform)))
90             : nullptr;
91     }
92 
Make(sk_sp<RenderNode> child,const SkMatrix & m)93     static sk_sp<TransformEffect> Make(sk_sp<RenderNode> child, const SkMatrix& m) {
94         return Make(std::move(child), Matrix<SkMatrix>::Make(m));
95     }
96 
97     ~TransformEffect() override;
98 
getTransform()99     const sk_sp<Transform>& getTransform() const { return fTransform; }
100 
101 protected:
102     void onRender(SkCanvas*, const RenderContext*) const override;
103     const RenderNode* onNodeAt(const SkPoint&)     const override;
104 
105     SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
106 
107 private:
108     TransformEffect(sk_sp<RenderNode>, sk_sp<Transform>);
109 
110     const sk_sp<Transform> fTransform;
111 
112     typedef EffectNode INHERITED;
113 };
114 
115 } // namespace sksg
116 
117 #endif // SkSGTransform_DEFINED
118