/* * Copyright 2017 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkSGTransform_DEFINED #define SkSGTransform_DEFINED #include "SkSGEffectNode.h" #include "SkMatrix.h" #include "SkMatrix44.h" namespace sksg { /** * Transformations base class. */ class Transform : public Node { public: // Compose T = A x B static sk_sp<Transform> MakeConcat(sk_sp<Transform> a, sk_sp<Transform> b); protected: Transform(); virtual bool is44() const = 0; virtual SkMatrix asMatrix () const = 0; virtual SkMatrix44 asMatrix44() const = 0; private: friend class TransformPriv; using INHERITED = Node; }; /** * Concrete, matrix-backed Transform. * * Supported instantiations: SkMatrix, SkMatrix44. * * Sample use: * * auto m33 = Matrix<SkMatrix>::Make(SkMatrix::I()); * ... * m33->setMatrix(SkMatrix::MakeTrans(10, 10)); * */ template <typename T> class Matrix final : public Transform { public: template <typename = std::enable_if<std::is_same<T, SkMatrix >::value || std::is_same<T, SkMatrix44>::value>> static sk_sp<Matrix> Make(const T& m) { return sk_sp<Matrix>(new Matrix(m)); } SG_ATTRIBUTE(Matrix, T, fMatrix) protected: explicit Matrix(const T& m) : fMatrix(m) {} SkRect onRevalidate(InvalidationController*, const SkMatrix&) override { return SkRect::MakeEmpty(); } bool is44() const override { return std::is_same<T, SkMatrix44>::value; } SkMatrix asMatrix () const override { return fMatrix; } SkMatrix44 asMatrix44() const override { return fMatrix; } private: T fMatrix; using INHERITED = Transform; }; /** * Concrete Effect node, binding a Transform to a RenderNode. */ class TransformEffect final : public EffectNode { public: static sk_sp<TransformEffect> Make(sk_sp<RenderNode> child, sk_sp<Transform> transform) { return child && transform ? sk_sp<TransformEffect>(new TransformEffect(std::move(child), std::move(transform))) : nullptr; } static sk_sp<TransformEffect> Make(sk_sp<RenderNode> child, const SkMatrix& m) { return Make(std::move(child), Matrix<SkMatrix>::Make(m)); } ~TransformEffect() override; const sk_sp<Transform>& getTransform() const { return fTransform; } protected: void onRender(SkCanvas*, const RenderContext*) const override; const RenderNode* onNodeAt(const SkPoint&) const override; SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; private: TransformEffect(sk_sp<RenderNode>, sk_sp<Transform>); const sk_sp<Transform> fTransform; typedef EffectNode INHERITED; }; } // namespace sksg #endif // SkSGTransform_DEFINED