Home | History | Annotate | Download | only in include
      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