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::Translate(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 using INHERITED = EffectNode; 113}; 114 115} // namespace sksg 116 117#endif // SkSGTransform_DEFINED 118