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
13class SkM44;
14class SkMatrix;
15
16namespace sksg {
17
18/**
19 * Transformations base class.
20 */
21class Transform : public Node {
22public:
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
29protected:
30 Transform();
31
32 virtual bool is44() const = 0;
33
34 virtual SkMatrix asMatrix() const = 0;
35 virtual SkM44 asM44 () const = 0;
36
37private:
38 friend class TransformPriv;
39
40 using INHERITED = Node;
41};
42
43/**
44 * Concrete, matrix-backed Transform.
45 *
46 * Supported instantiations: SkMatrix, SkM44.
47 *
48 * Sample use:
49 *
50 * auto m33 = Matrix<SkMatrix>::Make(SkMatrix::I());
51 * ...
52 * m33->setMatrix(SkMatrix::MakeTrans(10, 10));
53 *
54 */
55template <typename T>
56class Matrix final : public Transform {
57public:
58 template <typename = std::enable_if<std::is_same<T, SkMatrix>::value ||
59 std::is_same<T, SkM44 >::value>>
60 static sk_sp<Matrix> Make(const T& m) { return sk_sp<Matrix>(new Matrix(m)); }
61
62 SG_ATTRIBUTE(Matrix, T, fMatrix)
63
64protected:
65 explicit Matrix(const T& m) : fMatrix(m) {}
66
67 SkRect onRevalidate(InvalidationController*, const SkMatrix&) override {
68 return SkRect::MakeEmpty();
69 }
70
71 bool is44() const override { return std::is_same<T, SkM44>::value; }
72
73 SkMatrix asMatrix() const override;
74 SkM44 asM44 () const override;
75
76private:
77 T fMatrix;
78
79 using INHERITED = Transform;
80};
81
82/**
83 * Concrete Effect node, binding a Transform to a RenderNode.
84 */
85class TransformEffect final : public EffectNode {
86public:
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
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
99 const sk_sp<Transform>& getTransform() const { return fTransform; }
100
101protected:
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
107private:
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