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/SkottieValue.h"
11#include "modules/sksg/include/SkSGColorFilter.h"
12#include "modules/sksg/include/SkSGPaint.h"
13#include "src/utils/SkJSON.h"
14
15namespace skottie {
16namespace internal {
17
18namespace  {
19
20class TintAdapter final : public AnimatablePropertyContainer {
21public:
22    static sk_sp<TintAdapter> Make(const skjson::ArrayValue& jprops,
23                                   sk_sp<sksg::RenderNode> layer,
24                                   const AnimationBuilder& abuilder) {
25        return sk_sp<TintAdapter>(new TintAdapter(jprops, std::move(layer), abuilder));
26    }
27
28    const auto& node() const { return fFilterNode; }
29
30private:
31    TintAdapter(const skjson::ArrayValue& jprops,
32                sk_sp<sksg::RenderNode> layer,
33                const AnimationBuilder& abuilder)
34        : fColorNode0(sksg::Color::Make(SK_ColorBLACK))
35        , fColorNode1(sksg::Color::Make(SK_ColorBLACK))
36        , fFilterNode(sksg::GradientColorFilter::Make(std::move(layer), fColorNode0, fColorNode1)) {
37
38        enum : size_t {
39            kMapBlackTo_Index = 0,
40            kMapWhiteTo_Index = 1,
41            kAmount_Index     = 2,
42            // kOpacity_Index    = 3, // currently unused (not exported)
43
44            kMax_Index        = kAmount_Index,
45        };
46
47        EffectBinder(jprops, abuilder, this)
48            .bind(kMapBlackTo_Index, fMapBlackTo)
49            .bind(kMapWhiteTo_Index, fMapWhiteTo)
50            .bind(    kAmount_Index, fAmount    );
51    }
52
53    void onSync() override {
54        fColorNode0->setColor(fMapBlackTo);
55        fColorNode1->setColor(fMapWhiteTo);
56
57        fFilterNode->setWeight(fAmount / 100); // 100-based
58    }
59
60    const sk_sp<sksg::Color>               fColorNode0,
61                                           fColorNode1;
62    const sk_sp<sksg::GradientColorFilter> fFilterNode;
63
64    VectorValue fMapBlackTo,
65                fMapWhiteTo;
66    ScalarValue fAmount = 0;
67};
68
69} // namespace
70
71sk_sp<sksg::RenderNode> EffectBuilder::attachTintEffect(const skjson::ArrayValue& jprops,
72                                                        sk_sp<sksg::RenderNode> layer) const {
73    return fBuilder->attachDiscardableAdapter<TintAdapter>(jprops, std::move(layer), *fBuilder);
74}
75
76} // namespace internal
77} // namespace skottie
78