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