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 "include/private/SkTPin.h"
11 #include "modules/skottie/src/Adapter.h"
12 #include "modules/skottie/src/SkottieValue.h"
13 #include "modules/sksg/include/SkSGColorFilter.h"
14 #include "modules/sksg/include/SkSGPaint.h"
15 #include "src/utils/SkJSON.h"
16 
17 namespace skottie {
18 namespace internal {
19 
20 namespace  {
21 
22 class FillAdapter final : public AnimatablePropertyContainer {
23 public:
Make(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer,const AnimationBuilder & abuilder)24     static sk_sp<FillAdapter> Make(const skjson::ArrayValue& jprops,
25                                    sk_sp<sksg::RenderNode> layer,
26                                    const AnimationBuilder& abuilder) {
27         return sk_sp<FillAdapter>(new FillAdapter(jprops, std::move(layer), abuilder));
28     }
29 
node() const30     const auto& node() const { return fFilterNode; }
31 
32 private:
FillAdapter(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer,const AnimationBuilder & abuilder)33     FillAdapter(const skjson::ArrayValue& jprops,
34                 sk_sp<sksg::RenderNode> layer,
35                 const AnimationBuilder& abuilder)
36         : fColorNode(sksg::Color::Make(SK_ColorBLACK))
37         , fFilterNode(sksg::ModeColorFilter::Make(std::move(layer),
38                                                   fColorNode,
39                                                   SkBlendMode::kSrcIn)) {
40         enum : size_t {
41          // kFillMask_Index = 0,
42          // kAllMasks_Index = 1,
43                kColor_Index = 2,
44          //   kInvert_Index = 3,
45          // kHFeather_Index = 4,
46          // kVFeather_Index = 5,
47              kOpacity_Index = 6,
48         };
49 
50         EffectBinder(jprops, abuilder, this)
51             .bind(  kColor_Index, fColor  )
52             .bind(kOpacity_Index, fOpacity);
53 
54         abuilder.dispatchColorProperty(fColorNode);
55     }
56 
onSync()57     void onSync() override {
58         const auto c = static_cast<SkColor>(fColor);
59         const auto a =
60                 sk_float_round2int_no_saturate(SkColorGetA(c) * SkTPin(fOpacity, 0.0f, 1.0f));
61         fColorNode->setColor(SkColorSetA(c, a));
62     }
63 
64     const sk_sp<sksg::Color>           fColorNode;
65     const sk_sp<sksg::ModeColorFilter> fFilterNode;
66 
67     VectorValue fColor;
68     ScalarValue fOpacity = 1;
69 };
70 
71 } // namespace
72 
attachFillEffect(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer) const73 sk_sp<sksg::RenderNode> EffectBuilder::attachFillEffect(const skjson::ArrayValue& jprops,
74                                                         sk_sp<sksg::RenderNode> layer) const {
75     return fBuilder->attachDiscardableAdapter<FillAdapter>(jprops, std::move(layer), *fBuilder);
76 }
77 
78 } // namespace internal
79 } // namespace skottie
80