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/SkRefCnt.h" 12 #include "include/core/SkString.h" 13 #include "modules/skottie/include/ExternalLayer.h" 14 #include "modules/skottie/include/SkottieProperty.h" 15 16 #include <cstddef> 17 #include <memory> 18 #include <string> 19 #include <unordered_map> 20 #include <vector> 21 22 struct SkSize; 23 24 namespace skottie { 25 class MarkerObserver; 26 } 27 28 namespace skresources { 29 class ResourceProvider; 30 } 31 32 namespace skottie_utils { 33 34 /** 35 * CustomPropertyManager implements a property management scheme where color/opacity/transform 36 * attributes are grouped and manipulated by name (one-to-many mapping). 37 * 38 * - setters apply the value to all properties in a named group 39 * 40 * - getters return all the managed property groups, and the first value within each of them 41 * (unchecked assumption: all properties within the same group have the same value) 42 * 43 * Attach to an Animation::Builder using the utility methods below to intercept properties and 44 * markers at build time. 45 */ 46 class CustomPropertyManager final { 47 public: 48 enum class Mode { 49 kCollapseProperties, // keys ignore the ancestor chain and are 50 // grouped based on the local node name 51 kNamespacedProperties, // keys include the ancestor node names (no grouping) 52 }; 53 54 explicit CustomPropertyManager(Mode = Mode::kNamespacedProperties, 55 const char* prefix = nullptr); 56 ~CustomPropertyManager(); 57 58 using PropKey = std::string; 59 60 std::vector<PropKey> getColorProps() const; 61 skottie::ColorPropertyValue getColor(const PropKey&) const; 62 std::unique_ptr<skottie::ColorPropertyHandle> getColorHandle(const PropKey&, size_t) const; 63 bool setColor(const PropKey&, const skottie::ColorPropertyValue&); 64 65 std::vector<PropKey> getOpacityProps() const; 66 skottie::OpacityPropertyValue getOpacity(const PropKey&) const; 67 std::unique_ptr<skottie::OpacityPropertyHandle> getOpacityHandle(const PropKey&, size_t) const; 68 bool setOpacity(const PropKey&, const skottie::OpacityPropertyValue&); 69 70 std::vector<PropKey> getTransformProps() const; 71 skottie::TransformPropertyValue getTransform(const PropKey&) const; 72 std::unique_ptr<skottie::TransformPropertyHandle> getTransformHandle(const PropKey&, 73 size_t) const; 74 bool setTransform(const PropKey&, const skottie::TransformPropertyValue&); 75 76 std::vector<PropKey> getTextProps() const; 77 skottie::TextPropertyValue getText(const PropKey&) const; 78 std::unique_ptr<skottie::TextPropertyHandle> getTextHandle(const PropKey&, size_t index) const; 79 bool setText(const PropKey&, const skottie::TextPropertyValue&); 80 81 struct MarkerInfo { 82 std::string name; 83 float t0, t1; 84 }; markers()85 const std::vector<MarkerInfo>& markers() const { return fMarkers; } 86 87 // Returns a property observer to be attached to an animation builder. 88 sk_sp<skottie::PropertyObserver> getPropertyObserver() const; 89 90 // Returns a marker observer to be attached to an animation builder. 91 sk_sp<skottie::MarkerObserver> getMarkerObserver() const; 92 93 private: 94 class PropertyInterceptor; 95 class MarkerInterceptor; 96 97 std::string acceptKey(const char*, const char*) const; 98 99 template <typename T> 100 using PropGroup = std::vector<std::unique_ptr<T>>; 101 102 template <typename T> 103 using PropMap = std::unordered_map<PropKey, PropGroup<T>>; 104 105 template <typename T> 106 std::vector<PropKey> getProps(const PropMap<T>& container) const; 107 108 template <typename V, typename T> 109 V get(const PropKey&, const PropMap<T>& container) const; 110 111 template <typename T> 112 std::unique_ptr<T> getHandle(const PropKey&, size_t, const PropMap<T>& container) const; 113 114 template <typename V, typename T> 115 bool set(const PropKey&, const V&, const PropMap<T>& container); 116 117 const Mode fMode; 118 const SkString fPrefix; 119 120 sk_sp<PropertyInterceptor> fPropertyInterceptor; 121 sk_sp<MarkerInterceptor> fMarkerInterceptor; 122 123 PropMap<skottie::ColorPropertyHandle> fColorMap; 124 PropMap<skottie::OpacityPropertyHandle> fOpacityMap; 125 PropMap<skottie::TransformPropertyHandle> fTransformMap; 126 PropMap<skottie::TextPropertyHandle> fTextMap; 127 std::vector<MarkerInfo> fMarkers; 128 std::string fCurrentNode; 129 }; 130 131 /** 132 * A sample PrecompInterceptor implementation. 133 * 134 * Attempts to substitute all precomp layers matching the given pattern (name prefix) 135 * with external Lottie animations. 136 */ 137 class ExternalAnimationPrecompInterceptor final : public skottie::PrecompInterceptor { 138 public: 139 ExternalAnimationPrecompInterceptor(sk_sp<skresources::ResourceProvider>, const char prefix[]); 140 ~ExternalAnimationPrecompInterceptor() override; 141 142 private: 143 sk_sp<skottie::ExternalLayer> onLoadPrecomp(const char[], const char[], const SkSize&) override; 144 145 const sk_sp<skresources::ResourceProvider> fResourceProvider; 146 const SkString fPrefix; 147 }; 148 149 } // namespace skottie_utils 150 151 #endif // SkottieUtils_DEFINED 152