xref: /aosp_15_r20/external/skia/modules/skottie/src/effects/CornerPinEffect.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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