1 /* 2 * Copyright 2018 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 SkottieUtils_DEFINED 9 #define SkottieUtils_DEFINED 10 11 #include "include/core/SkColor.h" 12 #include "include/core/SkString.h" 13 #include "include/private/SkTHash.h" 14 #include "modules/skottie/include/Skottie.h" 15 #include "modules/skottie/include/SkottieProperty.h" 16 17 #include <memory> 18 #include <string> 19 #include <unordered_map> 20 #include <vector> 21 22 class SkAnimCodecPlayer; 23 class SkData; 24 class SkImage; 25 26 namespace skottie_utils { 27 28 class MultiFrameImageAsset final : public skottie::ImageAsset { 29 public: 30 /** 31 * By default, images are decoded on-the-fly, at rasterization time. 32 * Large images may cause jank as decoding is expensive (and can thrash internal caches). 33 * 34 * Pass |predecode| true to force-decode all images upfront, at the cost of potentially more RAM 35 * and slower animation build times. 36 */ 37 static sk_sp<MultiFrameImageAsset> Make(sk_sp<SkData>, bool predecode = false); 38 39 bool isMultiFrame() override; 40 41 sk_sp<SkImage> getFrame(float t) override; 42 43 private: 44 explicit MultiFrameImageAsset(std::unique_ptr<SkAnimCodecPlayer>, bool predecode); 45 46 std::unique_ptr<SkAnimCodecPlayer> fPlayer; 47 bool fPreDecode; 48 49 using INHERITED = skottie::ImageAsset; 50 }; 51 52 class FileResourceProvider final : public skottie::ResourceProvider { 53 public: 54 static sk_sp<FileResourceProvider> Make(SkString base_dir); 55 56 sk_sp<SkData> load(const char resource_path[], const char resource_name[]) const override; 57 58 sk_sp<skottie::ImageAsset> loadImageAsset(const char[], const char[], 59 const char[]) const override; 60 61 private: 62 explicit FileResourceProvider(SkString); 63 64 const SkString fDir; 65 66 using INHERITED = skottie::ResourceProvider; 67 }; 68 69 /** 70 * CustomPropertyManager implements a property management scheme where color/opacity/transform 71 * attributes are grouped and manipulated by name (one-to-many mapping). 72 * 73 * - setters apply the value to all properties in a named group 74 * 75 * - getters return all the managed property groups, and the first value within each of them 76 * (unchecked assumption: all properties within the same group have the same value) 77 * 78 * Attach to an Animation::Builder using the utility methods below to intercept properties and 79 * markers at build time. 80 */ 81 class CustomPropertyManager final { 82 public: 83 CustomPropertyManager(); 84 ~CustomPropertyManager(); 85 86 using PropKey = std::string; 87 88 std::vector<PropKey> getColorProps() const; 89 skottie::ColorPropertyValue getColor(const PropKey&) const; 90 bool setColor(const PropKey&, const skottie::ColorPropertyValue&); 91 92 std::vector<PropKey> getOpacityProps() const; 93 skottie::OpacityPropertyValue getOpacity(const PropKey&) const; 94 bool setOpacity(const PropKey&, const skottie::OpacityPropertyValue&); 95 96 std::vector<PropKey> getTransformProps() const; 97 skottie::TransformPropertyValue getTransform(const PropKey&) const; 98 bool setTransform(const PropKey&, const skottie::TransformPropertyValue&); 99 100 struct MarkerInfo { 101 std::string name; 102 float t0, t1; 103 }; markers()104 const std::vector<MarkerInfo>& markers() const { return fMarkers; } 105 106 // Returns a property observer to be attached to an animation builder. 107 sk_sp<skottie::PropertyObserver> getPropertyObserver() const; 108 109 // Returns a marker observer to be attached to an animation builder. 110 sk_sp<skottie::MarkerObserver> getMarkerObserver() const; 111 112 private: 113 class PropertyInterceptor; 114 class MarkerInterceptor; 115 acceptKey(const char * name)116 static std::string acceptKey(const char* name) { 117 static constexpr char kPrefix = '$'; 118 119 return (name[0] == kPrefix && name[1] != '\0') 120 ? std::string(name + 1) 121 : std::string(); 122 } 123 124 sk_sp<PropertyInterceptor> fPropertyInterceptor; 125 sk_sp<MarkerInterceptor> fMarkerInterceptor; 126 127 template <typename T> 128 using PropGroup = std::vector<std::unique_ptr<T>>; 129 130 template <typename T> 131 using PropMap = std::unordered_map<PropKey, PropGroup<T>>; 132 133 template <typename T> 134 std::vector<PropKey> getProps(const PropMap<T>& container) const; 135 136 template <typename V, typename T> 137 V get(const PropKey&, const PropMap<T>& container) const; 138 139 template <typename V, typename T> 140 bool set(const PropKey&, const V&, const PropMap<T>& container); 141 142 PropMap<skottie::ColorPropertyHandle> fColorMap; 143 PropMap<skottie::OpacityPropertyHandle> fOpacityMap; 144 PropMap<skottie::TransformPropertyHandle> fTransformMap; 145 std::vector<MarkerInfo> fMarkers; 146 }; 147 148 } // namespace skottie_utils 149 150 #endif // SkottieUtils_DEFINED 151