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
20namespace 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 */
34class CustomPropertyManager final {
35public:
36 CustomPropertyManager();
37 ~CustomPropertyManager();
38
39 using PropKey = std::string;
40
41 std::vector<PropKey> getColorProps() const;
42 skottie::ColorPropertyValue getColor(const PropKey&) const;
43 bool setColor(const PropKey&, const skottie::ColorPropertyValue&);
44
45 std::vector<PropKey> getOpacityProps() const;
46 skottie::OpacityPropertyValue getOpacity(const PropKey&) const;
47 bool setOpacity(const PropKey&, const skottie::OpacityPropertyValue&);
48
49 std::vector<PropKey> getTransformProps() const;
50 skottie::TransformPropertyValue getTransform(const PropKey&) const;
51 bool setTransform(const PropKey&, const skottie::TransformPropertyValue&);
52
53 std::vector<PropKey> getTextProps() const;
54 skottie::TextPropertyValue getText(const PropKey&) const;
55 bool setText(const PropKey&, const skottie::TextPropertyValue&);
56
57 struct MarkerInfo {
58 std::string name;
59 float t0, t1;
60 };
61 const std::vector<MarkerInfo>& markers() const { return fMarkers; }
62
63 // Returns a property observer to be attached to an animation builder.
64 sk_sp<skottie::PropertyObserver> getPropertyObserver() const;
65
66 // Returns a marker observer to be attached to an animation builder.
67 sk_sp<skottie::MarkerObserver> getMarkerObserver() const;
68
69private:
70 class PropertyInterceptor;
71 class MarkerInterceptor;
72
73 static std::string AcceptKey(const char* name) {
74 static constexpr char kPrefix = '$';
75
76 return (name[0] == kPrefix && name[1] != '\0')
77 ? std::string(name + 1)
78 : std::string();
79 }
80
81 sk_sp<PropertyInterceptor> fPropertyInterceptor;
82 sk_sp<MarkerInterceptor> fMarkerInterceptor;
83
84 template <typename T>
85 using PropGroup = std::vector<std::unique_ptr<T>>;
86
87 template <typename T>
88 using PropMap = std::unordered_map<PropKey, PropGroup<T>>;
89
90 template <typename T>
91 std::vector<PropKey> getProps(const PropMap<T>& container) const;
92
93 template <typename V, typename T>
94 V get(const PropKey&, const PropMap<T>& container) const;
95
96 template <typename V, typename T>
97 bool set(const PropKey&, const V&, const PropMap<T>& container);
98
99 PropMap<skottie::ColorPropertyHandle> fColorMap;
100 PropMap<skottie::OpacityPropertyHandle> fOpacityMap;
101 PropMap<skottie::TransformPropertyHandle> fTransformMap;
102 PropMap<skottie::TextPropertyHandle> fTextMap;
103 std::vector<MarkerInfo> fMarkers;
104 std::string fCurrentNode;
105};
106
107/**
108 * A sample PrecompInterceptor implementation.
109 *
110 * Attempts to substitute all precomp layers matching the given pattern (name prefix)
111 * with external Lottie animations.
112 */
113class ExternalAnimationPrecompInterceptor final : public skottie::PrecompInterceptor {
114public:
115 ExternalAnimationPrecompInterceptor(sk_sp<skresources::ResourceProvider>, const char prefix[]);
116 ~ExternalAnimationPrecompInterceptor() override;
117
118private:
119 sk_sp<skottie::ExternalLayer> onLoadPrecomp(const char[], const char[], const SkSize&) override;
120
121 const sk_sp<skresources::ResourceProvider> fResourceProvider;
122 const SkString fPrefix;
123};
124
125
126} // namespace skottie_utils
127
128#endif // SkottieUtils_DEFINED
129