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> attachCornerPinEffect (const skjson::ArrayValue&,
40 sk_sp<sksg::RenderNode>) const;
41 sk_sp<sksg::RenderNode> attachDropShadowEffect (const skjson::ArrayValue&,
42 sk_sp<sksg::RenderNode>) const;
43 sk_sp<sksg::RenderNode> attachFillEffect (const skjson::ArrayValue&,
44 sk_sp<sksg::RenderNode>) const;
45 sk_sp<sksg::RenderNode> attachGaussianBlurEffect (const skjson::ArrayValue&,
46 sk_sp<sksg::RenderNode>) const;
47 sk_sp<sksg::RenderNode> attachGradientEffect (const skjson::ArrayValue&,
48 sk_sp<sksg::RenderNode>) const;
49 sk_sp<sksg::RenderNode> attachHueSaturationEffect (const skjson::ArrayValue&,
50 sk_sp<sksg::RenderNode>) const;
51 sk_sp<sksg::RenderNode> attachInvertEffect (const skjson::ArrayValue&,
52 sk_sp<sksg::RenderNode>) const;
53 sk_sp<sksg::RenderNode> attachEasyLevelsEffect (const skjson::ArrayValue&,
54 sk_sp<sksg::RenderNode>) const;
55 sk_sp<sksg::RenderNode> attachLinearWipeEffect (const skjson::ArrayValue&,
56 sk_sp<sksg::RenderNode>) const;
57 sk_sp<sksg::RenderNode> attachMotionTileEffect (const skjson::ArrayValue&,
58 sk_sp<sksg::RenderNode>) const;
59 sk_sp<sksg::RenderNode> attachProLevelsEffect (const skjson::ArrayValue&,
60 sk_sp<sksg::RenderNode>) const;
61 sk_sp<sksg::RenderNode> attachRadialWipeEffect (const skjson::ArrayValue&,
62 sk_sp<sksg::RenderNode>) const;
63 sk_sp<sksg::RenderNode> attachTintEffect (const skjson::ArrayValue&,
64 sk_sp<sksg::RenderNode>) const;
65 sk_sp<sksg::RenderNode> attachTransformEffect (const skjson::ArrayValue&,
66 sk_sp<sksg::RenderNode>) const;
67 sk_sp<sksg::RenderNode> attachTritoneEffect (const skjson::ArrayValue&,
68 sk_sp<sksg::RenderNode>) const;
69 sk_sp<sksg::RenderNode> attachVenetianBlindsEffect(const skjson::ArrayValue&,
70 sk_sp<sksg::RenderNode>) const;
71 sk_sp<sksg::RenderNode> attachShiftChannelsEffect (const skjson::ArrayValue&,
72 sk_sp<sksg::RenderNode>) const;
73
74 sk_sp<sksg::RenderNode> attachDropShadowStyle(const skjson::ObjectValue&,
75 sk_sp<sksg::RenderNode>) const;
76
77 EffectBuilderT findBuilder(const skjson::ObjectValue&) const;
78
79 const AnimationBuilder* fBuilder;
80 const SkSize fLayerSize;
81};
82
83// Syntactic sugar/helper.
84class EffectBinder {
85public:
86 EffectBinder(const skjson::ArrayValue& jprops,
87 const AnimationBuilder& abuilder,
88 AnimatablePropertyContainer* acontainer)
89 : fProps(jprops)
90 , fBuilder(abuilder)
91 , fContainer(acontainer) {}
92
93 template <typename T>
94 const EffectBinder& bind(size_t prop_index, T& value) const {
95 fContainer->bind(fBuilder, EffectBuilder::GetPropValue(fProps, prop_index), value);
96
97 return *this;
98 }
99
100private:
101 const skjson::ArrayValue& fProps;
102 const AnimationBuilder& fBuilder;
103 AnimatablePropertyContainer* fContainer;
104};
105
106/**
107 * Base class for mask-shader-related effects.
108 */
109class MaskShaderEffectBase : public AnimatablePropertyContainer {
110public:
111 const sk_sp<sksg::MaskShaderEffect>& node() const { return fMaskEffectNode; }
112
113protected:
114 MaskShaderEffectBase(sk_sp<sksg::RenderNode>, const SkSize&);
115
116 const SkSize& layerSize() const { return fLayerSize; }
117
118 struct MaskInfo {
119 sk_sp<SkShader> fMaskShader;
120 bool fVisible;
121 };
122 virtual MaskInfo onMakeMask() const = 0;
123
124private:
125 void onSync() final;
126
127 const sk_sp<sksg::MaskShaderEffect> fMaskEffectNode;
128 const SkSize fLayerSize;
129};
130
131} // namespace internal
132} // namespace skottie
133
134#endif // SkottieEffects_DEFINED
135