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