1 /*
2  * Copyright 2019 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/Adapter.h"
11 #include "modules/skottie/src/SkottieValue.h"
12 #include "modules/sksg/include/SkSGColorFilter.h"
13 #include "modules/sksg/include/SkSGPaint.h"
14 #include "src/utils/SkJSON.h"
15 
16 namespace skottie {
17 namespace internal {
18 
19 namespace  {
20 
21 class TritoneAdapter final : public AnimatablePropertyContainer {
22 public:
Make(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer,const AnimationBuilder & abuilder)23     static sk_sp<TritoneAdapter> Make(const skjson::ArrayValue& jprops,
24                                       sk_sp<sksg::RenderNode> layer,
25                                       const AnimationBuilder& abuilder) {
26         return sk_sp<TritoneAdapter>(new TritoneAdapter(jprops, std::move(layer), abuilder));
27     }
28 
node() const29     const auto& node() const { return fCF; }
30 
31 private:
TritoneAdapter(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer,const AnimationBuilder & abuilder)32     TritoneAdapter(const skjson::ArrayValue& jprops,
33                    sk_sp<sksg::RenderNode> layer,
34                    const AnimationBuilder& abuilder)
35         : fLoColorNode(sksg::Color::Make(SK_ColorBLACK))
36         , fMiColorNode(sksg::Color::Make(SK_ColorBLACK))
37         , fHiColorNode(sksg::Color::Make(SK_ColorBLACK))
38         , fCF(sksg::GradientColorFilter::Make(std::move(layer),
39                                               { fLoColorNode, fMiColorNode, fHiColorNode })) {
40         enum : size_t {
41                 kHiColor_Index = 0,
42                 kMiColor_Index = 1,
43                 kLoColor_Index = 2,
44             kBlendAmount_Index = 3,
45         };
46 
47         EffectBinder(jprops, abuilder, this)
48             .bind(    kHiColor_Index, fHiColor)
49             .bind(    kMiColor_Index, fMiColor)
50             .bind(    kLoColor_Index, fLoColor)
51             .bind(kBlendAmount_Index, fWeight );
52     }
53 
onSync()54     void onSync() override {
55         fLoColorNode->setColor(fLoColor);
56         fMiColorNode->setColor(fMiColor);
57         fHiColorNode->setColor(fHiColor);
58 
59         // 100-based, inverted
60         fCF->setWeight((100 - fWeight) / 100);
61     }
62 
63     const sk_sp<sksg::Color> fLoColorNode,
64                              fMiColorNode,
65                              fHiColorNode;
66     const sk_sp<sksg::GradientColorFilter> fCF;
67 
68     VectorValue fLoColor,
69                 fMiColor,
70                 fHiColor;
71     ScalarValue fWeight = 0;
72 };
73 
74 } // namespace
75 
attachTritoneEffect(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer) const76 sk_sp<sksg::RenderNode> EffectBuilder::attachTritoneEffect(const skjson::ArrayValue& jprops,
77                                                            sk_sp<sksg::RenderNode> layer) const {
78     return fBuilder->attachDiscardableAdapter<TritoneAdapter>(jprops, std::move(layer), *fBuilder);
79 }
80 
81 } // namespace internal
82 } // namespace skottie
83