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