Home | History | Annotate | Download | only in include
      1 /*
      2  * Copyright 2017 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 Skottie_DEFINED
      9 #define Skottie_DEFINED
     10 
     11 #include "SkFontMgr.h"
     12 #include "SkRefCnt.h"
     13 #include "SkSize.h"
     14 #include "SkString.h"
     15 #include "SkTypes.h"
     16 
     17 #include <memory>
     18 
     19 class SkCanvas;
     20 class SkData;
     21 class SkImage;
     22 struct SkRect;
     23 class SkStream;
     24 
     25 namespace skjson { class ObjectValue; }
     26 
     27 namespace sksg { class Scene;  }
     28 
     29 namespace skottie {
     30 
     31 class PropertyObserver;
     32 
     33 /**
     34  * Image asset proxy interface.
     35  */
     36 class SK_API ImageAsset : public SkRefCnt {
     37 public:
     38     /**
     39      * Returns true if the image asset is animated.
     40      */
     41     virtual bool isMultiFrame() = 0;
     42 
     43     /**
     44      * Returns the SkImage for a given frame.
     45      *
     46      * If the image asset is static, getImage() is only called once, at animation load time.
     47      * Otherwise, this gets invoked every time the animation time is adjusted (on every seek).
     48      *
     49      * Embedders should cache and serve the same SkImage whenever possible, for efficiency.
     50      *
     51      * @param t   Frame time code, in seconds, relative to the image layer timeline origin
     52      *            (in-point).
     53      */
     54     virtual sk_sp<SkImage> getFrame(float t) = 0;
     55 };
     56 
     57 /**
     58  * ResourceProvider allows Skottie embedders to control loading of external
     59  * Skottie resources -- e.g. images, fonts, nested animations.
     60  */
     61 class SK_API ResourceProvider : public SkRefCnt {
     62 public:
     63     /**
     64      * Load a generic resource (currently only nested animations) specified by |path| + |name|,
     65      * and return as an SkData.
     66      */
     67     virtual sk_sp<SkData> load(const char resource_path[],
     68                                const char resource_name[]) const;
     69 
     70     /**
     71      * Load an image asset specified by |path| + |name|, and returns the corresponding
     72      * ImageAsset proxy.
     73      */
     74     virtual sk_sp<ImageAsset> loadImageAsset(const char resource_path[],
     75                                              const char resource_name[]) const;
     76 
     77     /**
     78      * Load an external font and return as SkData.
     79      *
     80      * @param name  font name    ("fName" Lottie property)
     81      * @param url   web font URL ("fPath" Lottie property)
     82      *
     83      * -- Note --
     84      *
     85      *   This mechanism assumes monolithic fonts (single data blob).  Some web font providers may
     86      *   serve multiple font blobs, segmented for various unicode ranges, depending on user agent
     87      *   capabilities (woff, woff2).  In that case, the embedder would need to advertise no user
     88      *   agent capabilities when fetching the URL, in order to receive full font data.
     89      */
     90     virtual sk_sp<SkData> loadFont(const char name[], const char url[]) const;
     91 };
     92 
     93 /**
     94  * A Logger subclass can be used to receive Animation::Builder parsing errors and warnings.
     95  */
     96 class SK_API Logger : public SkRefCnt {
     97 public:
     98     enum class Level {
     99         kWarning,
    100         kError,
    101     };
    102 
    103     virtual void log(Level, const char message[], const char* json = nullptr);
    104 };
    105 
    106 /**
    107  * Interface for receiving AE composition markers at Animation build time.
    108  */
    109 class SK_API MarkerObserver : public SkRefCnt {
    110 public:
    111     // t0,t1 are in the Animation::seek() domain.
    112     virtual void onMarker(const char name[], float t0, float t1) = 0;
    113 };
    114 
    115 class SK_API Animation : public SkNVRefCnt<Animation> {
    116 public:
    117 
    118     class Builder final {
    119     public:
    120         Builder();
    121         ~Builder();
    122 
    123         struct Stats {
    124             float  fTotalLoadTimeMS  = 0, // Total animation instantiation time.
    125                    fJsonParseTimeMS  = 0, // Time spent building a JSON DOM.
    126                    fSceneParseTimeMS = 0; // Time spent constructing the animation scene graph.
    127             size_t fJsonSize         = 0, // Input JSON size.
    128                    fAnimatorCount    = 0; // Number of dynamically animated properties.
    129         };
    130 
    131         /**
    132          * Returns various animation build stats.
    133          *
    134          * @return Stats (see above).
    135          */
    136         const Stats& getStats() const { return fStats; }
    137 
    138         /**
    139          * Specify a loader for external resources (images, etc.).
    140          */
    141         Builder& setResourceProvider(sk_sp<ResourceProvider>);
    142 
    143         /**
    144          * Specify a font manager for loading animation fonts.
    145          */
    146         Builder& setFontManager(sk_sp<SkFontMgr>);
    147 
    148         /**
    149          * Specify a PropertyObserver to receive callbacks during parsing.
    150          *
    151          * See SkottieProperty.h for more details.
    152          *
    153          */
    154         Builder& setPropertyObserver(sk_sp<PropertyObserver>);
    155 
    156         /**
    157          * Register a Logger with this builder.
    158          */
    159         Builder& setLogger(sk_sp<Logger>);
    160 
    161         /**
    162          * Register a MarkerObserver with this builder.
    163          */
    164         Builder& setMarkerObserver(sk_sp<MarkerObserver>);
    165 
    166         /**
    167          * Animation factories.
    168          */
    169         sk_sp<Animation> make(SkStream*);
    170         sk_sp<Animation> make(const char* data, size_t length);
    171         sk_sp<Animation> makeFromFile(const char path[]);
    172 
    173     private:
    174         sk_sp<ResourceProvider> fResourceProvider;
    175         sk_sp<SkFontMgr>        fFontMgr;
    176         sk_sp<PropertyObserver> fPropertyObserver;
    177         sk_sp<Logger>           fLogger;
    178         sk_sp<MarkerObserver>   fMarkerObserver;
    179         Stats                   fStats;
    180     };
    181 
    182     /**
    183      * Animation factories.
    184      *
    185      * Use the Builder helper above for more options/control.
    186      */
    187     static sk_sp<Animation> Make(const char* data, size_t length);
    188     static sk_sp<Animation> Make(SkStream*);
    189     static sk_sp<Animation> MakeFromFile(const char path[]);
    190 
    191     ~Animation();
    192 
    193     enum RenderFlag : uint32_t {
    194         // When rendering into a known transparent buffer, clients can pass
    195         // this flag to avoid some unnecessary compositing overhead for
    196         // animations using layer blend modes.
    197         kSkipTopLevelIsolation = 0x01,
    198     };
    199     using RenderFlags = uint32_t;
    200 
    201     /**
    202      * Draws the current animation frame.
    203      *
    204      * @param canvas   destination canvas
    205      * @param dst      optional destination rect
    206      * @param flags    optional RenderFlags
    207      */
    208     void render(SkCanvas* canvas, const SkRect* dst = nullptr) const;
    209     void render(SkCanvas* canvas, const SkRect* dst, RenderFlags) const;
    210 
    211     /**
    212      * Updates the animation state for |t|.
    213      *
    214      * @param t   normalized [0..1] frame selector (0 -> first frame, 1 -> final frame)
    215      *
    216      */
    217     void seek(SkScalar t);
    218 
    219     /**
    220      * Returns the animation duration in seconds.
    221      */
    222     SkScalar duration() const { return fDuration; }
    223 
    224     const SkString& version() const { return fVersion;   }
    225     const SkSize&      size() const { return fSize;      }
    226 
    227     void setShowInval(bool show);
    228 
    229 private:
    230     enum Flags : uint32_t {
    231         kRequiresTopLevelIsolation = 1 << 0, // Needs to draw into a layer due to layer blending.
    232     };
    233 
    234     Animation(std::unique_ptr<sksg::Scene>, SkString ver, const SkSize& size,
    235               SkScalar inPoint, SkScalar outPoint, SkScalar duration, uint32_t flags = 0);
    236 
    237     std::unique_ptr<sksg::Scene> fScene;
    238     const SkString               fVersion;
    239     const SkSize                 fSize;
    240     const SkScalar               fInPoint,
    241                                  fOutPoint,
    242                                  fDuration;
    243     const uint32_t               fFlags;
    244 
    245     typedef SkNVRefCnt<Animation> INHERITED;
    246 };
    247 
    248 } // namespace skottie
    249 
    250 #endif // Skottie_DEFINED
    251