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