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