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