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