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