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