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