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 #ifndef SkottieEffects_DEFINED
9 #define SkottieEffects_DEFINED
10 
11 #include "modules/skottie/src/Composition.h"
12 #include "modules/skottie/src/SkottiePriv.h"
13 #include "modules/skottie/src/animator/Animator.h"
14 
15 class SkMaskFilter;
16 
17 namespace sksg {
18 class MaskShaderEffect;
19 } // namespace sksg
20 
21 namespace skottie {
22 namespace internal {
23 
24 class EffectBuilder final : public SkNoncopyable {
25 public:
26     EffectBuilder(const AnimationBuilder*, const SkSize&, CompositionBuilder*);
27 
28     sk_sp<sksg::RenderNode> attachEffects(const skjson::ArrayValue&,
29                                           sk_sp<sksg::RenderNode>) const;
30 
31     sk_sp<sksg::RenderNode> attachStyles(const skjson::ArrayValue&,
32                                          sk_sp<sksg::RenderNode>) const;
33 
34     static const skjson::Value& GetPropValue(const skjson::ArrayValue& jprops, size_t prop_index);
35 
getLayerBuilder(int layer_index)36     LayerBuilder* getLayerBuilder(int layer_index) const {
37         return fCompBuilder->layerBuilder(layer_index);
38     }
39 
40 private:
41     using EffectBuilderT = sk_sp<sksg::RenderNode>(EffectBuilder::*)(const skjson::ArrayValue&,
42                                                                      sk_sp<sksg::RenderNode>) const;
43 
44     sk_sp<sksg::RenderNode> attachBlackAndWhiteEffect     (const skjson::ArrayValue&,
45                                                            sk_sp<sksg::RenderNode>) const;
46     sk_sp<sksg::RenderNode> attachBrightnessContrastEffect(const skjson::ArrayValue&,
47                                                            sk_sp<sksg::RenderNode>) const;
48     sk_sp<sksg::RenderNode> attachCornerPinEffect         (const skjson::ArrayValue&,
49                                                             sk_sp<sksg::RenderNode>) const;
50     sk_sp<sksg::RenderNode> attachDisplacementMapEffect   (const skjson::ArrayValue&,
51                                                            sk_sp<sksg::RenderNode>) const;
52     sk_sp<sksg::RenderNode> attachDropShadowEffect        (const skjson::ArrayValue&,
53                                                            sk_sp<sksg::RenderNode>) const;
54     sk_sp<sksg::RenderNode> attachFillEffect              (const skjson::ArrayValue&,
55                                                            sk_sp<sksg::RenderNode>) const;
56     sk_sp<sksg::RenderNode> attachFractalNoiseEffect      (const skjson::ArrayValue&,
57                                                            sk_sp<sksg::RenderNode>) const;
58     sk_sp<sksg::RenderNode> attachGaussianBlurEffect      (const skjson::ArrayValue&,
59                                                            sk_sp<sksg::RenderNode>) const;
60     sk_sp<sksg::RenderNode> attachGradientEffect          (const skjson::ArrayValue&,
61                                                            sk_sp<sksg::RenderNode>) const;
62     sk_sp<sksg::RenderNode> attachHueSaturationEffect     (const skjson::ArrayValue&,
63                                                            sk_sp<sksg::RenderNode>) const;
64     sk_sp<sksg::RenderNode> attachInvertEffect            (const skjson::ArrayValue&,
65                                                            sk_sp<sksg::RenderNode>) const;
66     sk_sp<sksg::RenderNode> attachEasyLevelsEffect        (const skjson::ArrayValue&,
67                                                            sk_sp<sksg::RenderNode>) const;
68     sk_sp<sksg::RenderNode> attachLinearWipeEffect        (const skjson::ArrayValue&,
69                                                            sk_sp<sksg::RenderNode>) const;
70     sk_sp<sksg::RenderNode> attachMotionTileEffect        (const skjson::ArrayValue&,
71                                                            sk_sp<sksg::RenderNode>) const;
72     sk_sp<sksg::RenderNode> attachProLevelsEffect         (const skjson::ArrayValue&,
73                                                            sk_sp<sksg::RenderNode>) const;
74     sk_sp<sksg::RenderNode> attachRadialWipeEffect        (const skjson::ArrayValue&,
75                                                            sk_sp<sksg::RenderNode>) const;
76     sk_sp<sksg::RenderNode> attachShiftChannelsEffect     (const skjson::ArrayValue&,
77                                                            sk_sp<sksg::RenderNode>) const;
78     sk_sp<sksg::RenderNode> attachSphereEffect            (const skjson::ArrayValue&,
79                                                            sk_sp<sksg::RenderNode>) const;
80     sk_sp<sksg::RenderNode> attachThresholdEffect         (const skjson::ArrayValue&,
81                                                            sk_sp<sksg::RenderNode>) const;
82     sk_sp<sksg::RenderNode> attachTintEffect              (const skjson::ArrayValue&,
83                                                            sk_sp<sksg::RenderNode>) const;
84     sk_sp<sksg::RenderNode> attachTransformEffect         (const skjson::ArrayValue&,
85                                                            sk_sp<sksg::RenderNode>) const;
86     sk_sp<sksg::RenderNode> attachTritoneEffect           (const skjson::ArrayValue&,
87                                                            sk_sp<sksg::RenderNode>) const;
88     sk_sp<sksg::RenderNode> attachVenetianBlindsEffect    (const skjson::ArrayValue&,
89                                                            sk_sp<sksg::RenderNode>) const;
90 
91     sk_sp<sksg::RenderNode> attachDropShadowStyle(const skjson::ObjectValue&,
92                                                   sk_sp<sksg::RenderNode>) const;
93     sk_sp<sksg::RenderNode> attachInnerShadowStyle(const skjson::ObjectValue&,
94                                                    sk_sp<sksg::RenderNode>) const;
95     sk_sp<sksg::RenderNode> attachInnerGlowStyle(const skjson::ObjectValue&,
96                                                  sk_sp<sksg::RenderNode>) const;
97     sk_sp<sksg::RenderNode> attachOuterGlowStyle(const skjson::ObjectValue&,
98                                                  sk_sp<sksg::RenderNode>) const;
99 
100     EffectBuilderT findBuilder(const skjson::ObjectValue&) const;
101 
102     const AnimationBuilder* fBuilder;
103     CompositionBuilder*     fCompBuilder;
104     const SkSize            fLayerSize;
105 };
106 
107 // Syntactic sugar/helper.
108 class EffectBinder {
109 public:
EffectBinder(const skjson::ArrayValue & jprops,const AnimationBuilder & abuilder,AnimatablePropertyContainer * acontainer)110     EffectBinder(const skjson::ArrayValue& jprops,
111                  const AnimationBuilder& abuilder,
112                  AnimatablePropertyContainer* acontainer)
113         : fProps(jprops)
114         , fBuilder(abuilder)
115         , fContainer(acontainer) {}
116 
117     template <typename T>
bind(size_t prop_index,T & value)118     const EffectBinder& bind(size_t prop_index, T& value) const {
119         fContainer->bind(fBuilder, EffectBuilder::GetPropValue(fProps, prop_index), value);
120 
121         return *this;
122     }
123 
124 private:
125     const skjson::ArrayValue&    fProps;
126     const AnimationBuilder&      fBuilder;
127     AnimatablePropertyContainer* fContainer;
128 };
129 
130 /**
131  * Base class for mask-shader-related effects.
132  */
133 class MaskShaderEffectBase : public AnimatablePropertyContainer {
134 public:
node()135     const sk_sp<sksg::MaskShaderEffect>& node() const { return fMaskEffectNode; }
136 
137 protected:
138     MaskShaderEffectBase(sk_sp<sksg::RenderNode>, const SkSize&);
139 
layerSize()140     const SkSize& layerSize() const { return  fLayerSize; }
141 
142     struct MaskInfo {
143         sk_sp<SkShader> fMaskShader;
144         bool            fVisible;
145     };
146     virtual MaskInfo onMakeMask() const = 0;
147 
148 private:
149     void onSync() final;
150 
151     const sk_sp<sksg::MaskShaderEffect> fMaskEffectNode;
152     const SkSize                        fLayerSize;
153 };
154 
155 } // namespace internal
156 } // namespace skottie
157 
158 #endif // SkottieEffects_DEFINED
159