mirrored from https://skia.googlesource.com/skia
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
Skottie.h
292 lines (242 loc) · 9.18 KB
/
Skottie.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef Skottie_DEFINED
#define Skottie_DEFINED
#include "include/core/SkFontMgr.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "modules/skottie/include/ExternalLayer.h"
#include "modules/skottie/include/SkottieProperty.h"
#include "modules/skresources/include/SkResources.h"
#include <memory>
#include <vector>
class SkCanvas;
struct SkRect;
class SkStream;
namespace skjson { class ObjectValue; }
namespace sksg {
class InvalidationController;
class Scene;
} // namespace sksg
namespace skottie {
namespace internal { class Animator; }
using ImageAsset = skresources::ImageAsset;
using ResourceProvider = skresources::ResourceProvider;
/**
* A Logger subclass can be used to receive Animation::Builder parsing errors and warnings.
*/
class SK_API Logger : public SkRefCnt {
public:
enum class Level {
kWarning,
kError,
};
virtual void log(Level, const char message[], const char* json = nullptr);
};
// Evaluates AE expressions.
template <class T>
class SK_API ExpressionEvaluator : public SkRefCnt {
public:
// Evaluate the expression at the current time.
virtual T evaluate(float t) = 0;
};
/**
* Creates ExpressionEvaluators to evaluate AE expressions and return the results.
*/
class SK_API ExpressionManager : public SkRefCnt {
public:
virtual sk_sp<ExpressionEvaluator<float>> createNumberExpressionEvaluator(
const char expression[]) = 0;
virtual sk_sp<ExpressionEvaluator<SkString>> createStringExpressionEvaluator(
const char expression[]) = 0;
virtual sk_sp<ExpressionEvaluator<std::vector<float>>> createArrayExpressionEvaluator(
const char expression[]) = 0;
};
/**
* Interface for receiving AE composition markers at Animation build time.
*/
class SK_API MarkerObserver : public SkRefCnt {
public:
// t0,t1 are in the Animation::seek() domain.
virtual void onMarker(const char name[], float t0, float t1) = 0;
};
class SK_API Animation : public SkNVRefCnt<Animation> {
public:
class SK_API Builder final {
public:
enum Flags : uint32_t {
kDeferImageLoading = 0x01, // Normally, all static image frames are resolved at
// load time via ImageAsset::getFrame(0). With this flag,
// frames are only resolved when needed, at seek() time.
kPreferEmbeddedFonts = 0x02, // Attempt to use the embedded fonts (glyph paths,
// normally used as fallback) over native Skia typefaces.
};
explicit Builder(uint32_t flags = 0);
~Builder();
struct Stats {
float fTotalLoadTimeMS = 0, // Total animation instantiation time.
fJsonParseTimeMS = 0, // Time spent building a JSON DOM.
fSceneParseTimeMS = 0; // Time spent constructing the animation scene graph.
size_t fJsonSize = 0, // Input JSON size.
fAnimatorCount = 0; // Number of dynamically animated properties.
};
/**
* Returns various animation build stats.
*
* @return Stats (see above).
*/
const Stats& getStats() const { return fStats; }
/**
* Specify a loader for external resources (images, etc.).
*/
Builder& setResourceProvider(sk_sp<ResourceProvider>);
/**
* Specify a font manager for loading animation fonts.
*/
Builder& setFontManager(sk_sp<SkFontMgr>);
/**
* Specify a PropertyObserver to receive callbacks during parsing.
*
* See SkottieProperty.h for more details.
*
*/
Builder& setPropertyObserver(sk_sp<PropertyObserver>);
/**
* Register a Logger with this builder.
*/
Builder& setLogger(sk_sp<Logger>);
/**
* Register a MarkerObserver with this builder.
*/
Builder& setMarkerObserver(sk_sp<MarkerObserver>);
/**
* Register a precomp layer interceptor.
* This allows substituting precomp layers with custom/externally managed content.
*/
Builder& setPrecompInterceptor(sk_sp<PrecompInterceptor>);
/**
* Registers an ExpressionManager to evaluate AE expressions.
* If unspecified, expressions in the animation JSON will be ignored.
*/
Builder& setExpressionManager(sk_sp<ExpressionManager>);
/**
* Animation factories.
*/
sk_sp<Animation> make(SkStream*);
sk_sp<Animation> make(const char* data, size_t length);
sk_sp<Animation> makeFromFile(const char path[]);
private:
const uint32_t fFlags;
sk_sp<ResourceProvider> fResourceProvider;
sk_sp<SkFontMgr> fFontMgr;
sk_sp<PropertyObserver> fPropertyObserver;
sk_sp<Logger> fLogger;
sk_sp<MarkerObserver > fMarkerObserver;
sk_sp<PrecompInterceptor> fPrecompInterceptor;
sk_sp<ExpressionManager> fExpressionManager;
Stats fStats;
};
/**
* Animation factories.
*
* Use the Builder helper above for more options/control.
*/
static sk_sp<Animation> Make(const char* data, size_t length);
static sk_sp<Animation> Make(SkStream*);
static sk_sp<Animation> MakeFromFile(const char path[]);
~Animation();
enum RenderFlag : uint32_t {
// When rendering into a known transparent buffer, clients can pass
// this flag to avoid some unnecessary compositing overhead for
// animations using layer blend modes.
kSkipTopLevelIsolation = 0x01,
// By default, content is clipped to the intrinsic animation
// bounds (as determined by its size). If this flag is set,
// then the animation can draw outside of the bounds.
kDisableTopLevelClipping = 0x02,
};
using RenderFlags = uint32_t;
/**
* Draws the current animation frame.
*
* It is undefined behavior to call render() on a newly created Animation
* before specifying an initial frame via one of the seek() variants.
*
* @param canvas destination canvas
* @param dst optional destination rect
* @param flags optional RenderFlags
*/
void render(SkCanvas* canvas, const SkRect* dst = nullptr) const;
void render(SkCanvas* canvas, const SkRect* dst, RenderFlags) const;
/**
* [Deprecated: use one of the other versions.]
*
* Updates the animation state for |t|.
*
* @param t normalized [0..1] frame selector (0 -> first frame, 1 -> final frame)
* @param ic optional invalidation controller (dirty region tracking)
*
*/
void seek(SkScalar t, sksg::InvalidationController* ic = nullptr) {
this->seekFrameTime(t * this->duration(), ic);
}
/**
* Update the animation state to match |t|, specified as a frame index
* i.e. relative to duration() * fps().
*
* Fractional values are allowed and meaningful - e.g.
*
* 0.0 -> first frame
* 1.0 -> second frame
* 0.5 -> halfway between first and second frame
*/
void seekFrame(double t, sksg::InvalidationController* ic = nullptr);
/** Update the animation state to match t, specifed in frame time
* i.e. relative to duration().
*/
void seekFrameTime(double t, sksg::InvalidationController* = nullptr);
/**
* Returns the animation duration in seconds.
*/
double duration() const { return fDuration; }
/**
* Returns the animation frame rate (frames / second).
*/
double fps() const { return fFPS; }
/**
* Animation in point, in frame index units.
*/
double inPoint() const { return fInPoint; }
/**
* Animation out point, in frame index units.
*/
double outPoint() const { return fOutPoint; }
const SkString& version() const { return fVersion; }
const SkSize& size() const { return fSize; }
private:
enum Flags : uint32_t {
kRequiresTopLevelIsolation = 1 << 0, // Needs to draw into a layer due to layer blending.
};
Animation(std::unique_ptr<sksg::Scene>,
std::vector<sk_sp<internal::Animator>>&&,
SkString ver, const SkSize& size,
double inPoint, double outPoint, double duration, double fps, uint32_t flags);
const std::unique_ptr<sksg::Scene> fScene;
const std::vector<sk_sp<internal::Animator>> fAnimators;
const SkString fVersion;
const SkSize fSize;
const double fInPoint,
fOutPoint,
fDuration,
fFPS;
const uint32_t fFlags;
using INHERITED = SkNVRefCnt<Animation>;
};
} // namespace skottie
#endif // Skottie_DEFINED