1 /*
2 * Copyright 2021 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/SkColorData.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/base/SkVx.h"
16 #include "src/core/SkSwizzlePriv.h"
17 #include "src/utils/SkJSON.h"
18
19 namespace skottie::internal {
20
21 namespace {
22
23 class CCTonerAdapter final : public DiscardableAdapterBase<CCTonerAdapter,
24 sksg::GradientColorFilter> {
25 public:
CCTonerAdapter(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer,const AnimationBuilder & abuilder,std::vector<sk_sp<sksg::Color>> colorNodes)26 CCTonerAdapter(const skjson::ArrayValue& jprops,
27 sk_sp<sksg::RenderNode> layer,
28 const AnimationBuilder& abuilder,
29 std::vector<sk_sp<sksg::Color>> colorNodes)
30 : INHERITED(sksg::GradientColorFilter::Make(std::move(layer), colorNodes))
31 , fColorNodes(std::move(colorNodes))
32 {
33 enum : size_t {
34 kTone_Index = 0,
35 kHiColor_Index = 1,
36 kBrightColor_Index = 2,
37 kMidColor_Index = 3,
38 kDarkColor_Index = 4,
39 kShadowColor_Index = 5,
40 kBlendAmount_Index = 6,
41 };
42
43
44 EffectBinder(jprops, abuilder, this)
45 .bind( kTone_Index, fTone)
46 .bind( kHiColor_Index, fHighlights)
47 .bind(kBrightColor_Index, fBrights)
48 .bind( kMidColor_Index, fMidtones)
49 .bind( kDarkColor_Index, fDarktones)
50 .bind(kShadowColor_Index, fShadows);
51
52 }
53 private:
lerpColor(SkColor c0,SkColor c1,float t)54 static SkColor lerpColor(SkColor c0, SkColor c1, float t) {
55 const auto c0_4f = Sk4f_fromL32(c0),
56 c1_4f = Sk4f_fromL32(c1),
57 c_4f = c0_4f + (c1_4f - c0_4f) * t;
58
59 return Sk4f_toL32(c_4f);
60 }
61
onSync()62 void onSync() override {
63 switch (SkScalarRoundToInt(fTone)) {
64 // duotone
65 case 1: fColorNodes.at(0)->setColor(fShadows);
66 fColorNodes.at(1)->setColor(lerpColor(fShadows, fHighlights, 0.25));
67 fColorNodes.at(2)->setColor(lerpColor(fShadows, fHighlights, 0.5));
68 fColorNodes.at(3)->setColor(lerpColor(fShadows, fHighlights, 0.75));
69 fColorNodes.at(4)->setColor(fHighlights);
70 break;
71 // tritone
72 case 2: fColorNodes.at(0)->setColor(fShadows);
73 fColorNodes.at(1)->setColor(lerpColor(fShadows, fMidtones, 0.5));
74 fColorNodes.at(2)->setColor(fMidtones);
75 fColorNodes.at(3)->setColor(lerpColor(fMidtones, fHighlights, 0.5));
76 fColorNodes.at(4)->setColor(fHighlights);
77 break;
78 // pentone
79 case 3: fColorNodes.at(0)->setColor(fShadows);
80 fColorNodes.at(1)->setColor(fDarktones);
81 fColorNodes.at(2)->setColor(fMidtones);
82 fColorNodes.at(3)->setColor(fBrights);
83 fColorNodes.at(4)->setColor(fHighlights);
84 break;
85 // solid
86 default: fColorNodes.at(0)->setColor(fMidtones);
87 fColorNodes.at(1)->setColor(fMidtones);
88 fColorNodes.at(2)->setColor(fMidtones);
89 fColorNodes.at(3)->setColor(fMidtones);
90 fColorNodes.at(4)->setColor(fMidtones);
91 break;
92 }
93
94 this->node()->setWeight((100-fBlend)/100);
95 }
96
97
98 const std::vector<sk_sp<sksg::Color>> fColorNodes;
99
100 ScalarValue fTone = 0;
101 VectorValue fHighlights,
102 fBrights,
103 fMidtones,
104 fDarktones,
105 fShadows;
106 ScalarValue fBlend = 0;
107
108 using INHERITED = DiscardableAdapterBase<CCTonerAdapter, sksg::GradientColorFilter>;
109 };
110
111 } // namespace
112
attachCCTonerEffect(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer) const113 sk_sp<sksg::RenderNode> EffectBuilder::attachCCTonerEffect(const skjson::ArrayValue& jprops,
114 sk_sp<sksg::RenderNode> layer) const {
115 std::vector<sk_sp<sksg::Color>> colorNodes = {
116 sksg::Color::Make(SK_ColorRED),
117 sksg::Color::Make(SK_ColorRED),
118 sksg::Color::Make(SK_ColorRED),
119 sksg::Color::Make(SK_ColorRED),
120 sksg::Color::Make(SK_ColorRED)
121 };
122 return fBuilder->attachDiscardableAdapter<CCTonerAdapter>(jprops,
123 std::move(layer),
124 *fBuilder,
125 std::move(colorNodes));
126 }
127
128 } // namespace skottie::internal
129