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