1 /*
2 * Copyright 2020 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 #include "include/core/SkMatrix.h"
9 #include "include/core/SkPoint.h"
10 #include "include/core/SkRefCnt.h"
11 #include "include/core/SkSize.h"
12 #include "modules/skottie/src/SkottiePriv.h"
13 #include "modules/skottie/src/SkottieValue.h"
14 #include "modules/skottie/src/animator/Animator.h"
15 #include "modules/skottie/src/effects/Effects.h"
16 #include "modules/sksg/include/SkSGRenderNode.h"
17 #include "modules/sksg/include/SkSGTransform.h"
18
19 #include <array>
20 #include <cstddef>
21 #include <utility>
22
23 namespace skjson {
24 class ArrayValue;
25 }
26
27 namespace skottie::internal {
28
29 namespace {
30
31 class CornerPinAdapter final : public AnimatablePropertyContainer {
32 public:
Make(const skjson::ArrayValue & jprops,const AnimationBuilder & abuilder,const SkSize & layer_size)33 static sk_sp<CornerPinAdapter> Make(const skjson::ArrayValue& jprops,
34 const AnimationBuilder& abuilder,
35 const SkSize& layer_size) {
36 return sk_sp<CornerPinAdapter>(new CornerPinAdapter(jprops, abuilder, layer_size));
37 }
38
node() const39 auto& node() const { return fMatrixNode; }
40
41 private:
CornerPinAdapter(const skjson::ArrayValue & jprops,const AnimationBuilder & abuilder,const SkSize & layer_size)42 CornerPinAdapter(const skjson::ArrayValue& jprops,
43 const AnimationBuilder& abuilder,
44 const SkSize& layer_size)
45 : fMatrixNode(sksg::Matrix<SkMatrix>::Make(SkMatrix::I()))
46 , fLayerSize(layer_size) {
47 enum : size_t {
48 kUpperLeft_Index = 0,
49 kUpperRight_Index = 1,
50 kLowerLeft_Index = 2,
51 kLowerRight_Index = 3,
52 };
53
54 EffectBinder(jprops, abuilder, this)
55 .bind( kUpperLeft_Index, fUL)
56 .bind(kUpperRight_Index, fUR)
57 .bind( kLowerLeft_Index, fLL)
58 .bind(kLowerRight_Index, fLR);
59 }
60
onSync()61 void onSync() override {
62 const SkPoint src[] = {{ 0, 0},
63 {fLayerSize.width(), 0},
64 {fLayerSize.width(), fLayerSize.height()},
65 { 0, fLayerSize.height()}},
66
67 dst[] = {{ fUL.x, fUL.y},
68 { fUR.x, fUR.y},
69 { fLR.x, fLR.y},
70 { fLL.x, fLL.y}};
71 static_assert(std::size(src) == std::size(dst));
72
73 SkMatrix m;
74 if (m.setPolyToPoly(src, dst, std::size(src))) {
75 fMatrixNode->setMatrix(m);
76 }
77 }
78
79 const sk_sp<sksg::Matrix<SkMatrix>> fMatrixNode;
80 const SkSize fLayerSize;
81
82 Vec2Value fUL,
83 fLL,
84 fUR,
85 fLR;
86 };
87
88 } // namespace
89
attachCornerPinEffect(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer) const90 sk_sp<sksg::RenderNode> EffectBuilder::attachCornerPinEffect(const skjson::ArrayValue& jprops,
91 sk_sp<sksg::RenderNode> layer) const {
92 sk_sp<sksg::Matrix<SkMatrix>> matrix_node =
93 fBuilder->attachDiscardableAdapter<CornerPinAdapter>(jprops, *fBuilder, fLayerSize);
94
95 return sksg::TransformEffect::Make(std::move(layer), std::move(matrix_node));
96 }
97
98 } // namespace skottie::internal
99