blob: d8408da6eb41ded2418f6439731c7173eb7ec6ef [file] [log] [blame]
Florin Malita4aa44412017-12-19 12:21:02 -05001/*
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"
Florin Malita919e2092019-01-09 15:37:57 -050014#include "SkMatrix44.h"
Florin Malita4aa44412017-12-19 12:21:02 -050015
16namespace sksg {
17
18/**
Florin Malita919e2092019-01-09 15:37:57 -050019 * Transformations base class.
Florin Malita18eafd92018-01-04 21:11:55 -050020 */
Florin Malita919e2092019-01-09 15:37:57 -050021class Transform : public Node {
Florin Malita18eafd92018-01-04 21:11:55 -050022public:
Florin Malita919e2092019-01-09 15:37:57 -050023 // Compose T = A x B
24 static sk_sp<Transform> MakeConcat(sk_sp<Transform> a, sk_sp<Transform> b);
25
Florin Malita919e2092019-01-09 15:37:57 -050026protected:
27 Transform();
28
Florin Malita13c1b962019-01-10 14:44:59 -050029 virtual bool is44() const = 0;
30
Florin Malitadf0e1af2019-01-10 11:27:13 -050031 virtual SkMatrix asMatrix () const = 0;
32 virtual SkMatrix44 asMatrix44() const = 0;
33
Florin Malita919e2092019-01-09 15:37:57 -050034private:
Florin Malitadf0e1af2019-01-10 11:27:13 -050035 friend class TransformPriv;
36
Florin Malita919e2092019-01-09 15:37:57 -050037 using INHERITED = Node;
38};
39
40/**
Florin Malita760a0522019-01-10 15:24:15 -050041 * 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 *
Florin Malita919e2092019-01-09 15:37:57 -050051 */
Florin Malita760a0522019-01-10 15:24:15 -050052template <typename T>
Florin Malita919e2092019-01-09 15:37:57 -050053class Matrix final : public Transform {
54public:
Florin Malita760a0522019-01-10 15:24:15 -050055 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)); }
Florin Malita18eafd92018-01-04 21:11:55 -050058
Florin Malita760a0522019-01-10 15:24:15 -050059 SG_ATTRIBUTE(Matrix, T, fMatrix)
Florin Malita18eafd92018-01-04 21:11:55 -050060
Florin Malita18eafd92018-01-04 21:11:55 -050061protected:
Florin Malita760a0522019-01-10 15:24:15 -050062 explicit Matrix(const T& m) : fMatrix(m) {}
Florin Malita18eafd92018-01-04 21:11:55 -050063
Florin Malita760a0522019-01-10 15:24:15 -050064 SkRect onRevalidate(InvalidationController*, const SkMatrix&) override {
65 return SkRect::MakeEmpty();
66 }
Florin Malita18eafd92018-01-04 21:11:55 -050067
Florin Malita760a0522019-01-10 15:24:15 -050068 bool is44() const override { return std::is_same<T, SkMatrix44>::value; }
Florin Malita13c1b962019-01-10 14:44:59 -050069
Florin Malita760a0522019-01-10 15:24:15 -050070 SkMatrix asMatrix () const override { return fMatrix; }
71 SkMatrix44 asMatrix44() const override { return fMatrix; }
Florin Malitadf0e1af2019-01-10 11:27:13 -050072
Florin Malita18eafd92018-01-04 21:11:55 -050073private:
Florin Malita760a0522019-01-10 15:24:15 -050074 T fMatrix;
Florin Malita919e2092019-01-09 15:37:57 -050075
76 using INHERITED = Transform;
77};
78
79/**
80 * Concrete Effect node, binding a Transform to a RenderNode.
81 */
82class TransformEffect final : public EffectNode {
83public:
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)))
Florin Malita18eafd92018-01-04 21:11:55 -050087 : nullptr;
Florin Malita4aa44412017-12-19 12:21:02 -050088 }
89
Florin Malita919e2092019-01-09 15:37:57 -050090 static sk_sp<TransformEffect> Make(sk_sp<RenderNode> child, const SkMatrix& m) {
Florin Malita760a0522019-01-10 15:24:15 -050091 return Make(std::move(child), Matrix<SkMatrix>::Make(m));
Florin Malita18eafd92018-01-04 21:11:55 -050092 }
93
Florin Malita919e2092019-01-09 15:37:57 -050094 ~TransformEffect() override;
Florin Malita18eafd92018-01-04 21:11:55 -050095
Florin Malita919e2092019-01-09 15:37:57 -050096 const sk_sp<Transform>& getTransform() const { return fTransform; }
Florin Malita4aa44412017-12-19 12:21:02 -050097
98protected:
Florin Malitac0132ff2018-08-09 07:40:01 -040099 void onRender(SkCanvas*, const RenderContext*) const override;
Florin Malitaeb46bd82019-02-12 09:33:21 -0500100 const RenderNode* onNodeAt(const SkPoint&) const override;
Florin Malita4aa44412017-12-19 12:21:02 -0500101
Florin Malitac14f1442018-01-05 11:32:31 -0500102 SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
Florin Malita4aa44412017-12-19 12:21:02 -0500103
104private:
Florin Malita919e2092019-01-09 15:37:57 -0500105 TransformEffect(sk_sp<RenderNode>, sk_sp<Transform>);
Florin Malita16d0ad02018-01-19 15:07:29 -0500106
Florin Malita919e2092019-01-09 15:37:57 -0500107 const sk_sp<Transform> fTransform;
Florin Malita4aa44412017-12-19 12:21:02 -0500108
109 typedef EffectNode INHERITED;
110};
111
112} // namespace sksg
113
114#endif // SkSGTransform_DEFINED