Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkottieUtils.cpp
Go to the documentation of this file.
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
9
10#include "include/core/SkData.h"
11#include "include/core/SkRect.h"
12#include "include/core/SkSize.h"
16
17#include <cstring>
18#include <utility>
19
20class SkCanvas;
21
22namespace skottie_utils {
23
25public:
26 explicit PropertyInterceptor(CustomPropertyManager* mgr) : fMgr(mgr) {}
27
28 void onColorProperty(const char node_name[],
30 const auto key = fMgr->acceptKey(node_name, ".Color");
31 if (!key.empty()) {
32 fMgr->fColorMap[key].push_back(c());
33 }
34 }
35
36 void onOpacityProperty(const char node_name[],
38 const auto key = fMgr->acceptKey(node_name, ".Opacity");
39 if (!key.empty()) {
40 fMgr->fOpacityMap[key].push_back(o());
41 }
42 }
43
44 void onTransformProperty(const char node_name[],
46 const auto key = fMgr->acceptKey(node_name, ".Transform");
47 if (!key.empty()) {
48 fMgr->fTransformMap[key].push_back(t());
49 }
50 }
51
52 void onTextProperty(const char node_name[],
54 const auto key = fMgr->acceptKey(node_name, ".Text");
55 if (!key.empty()) {
56 fMgr->fTextMap[key].push_back(t());
57 }
58 }
59
60 void onEnterNode(const char node_name[], PropertyObserver::NodeType node_type) override {
61 if (node_name == nullptr) {
62 return;
63 }
64 fMgr->fCurrentNode =
65 fMgr->fCurrentNode.empty() ? node_name : fMgr->fCurrentNode + "." + node_name;
66 }
67
68 void onLeavingNode(const char node_name[], PropertyObserver::NodeType node_type) override {
69 if (node_name == nullptr) {
70 return;
71 }
72 auto length = strlen(node_name);
73 fMgr->fCurrentNode =
74 fMgr->fCurrentNode.length() > length
75 ? fMgr->fCurrentNode.substr(
76 0, fMgr->fCurrentNode.length() - strlen(node_name) - 1)
77 : "";
78 }
79
80private:
82};
83
85public:
86 explicit MarkerInterceptor(CustomPropertyManager* mgr) : fMgr(mgr) {}
87
88 void onMarker(const char name[], float t0, float t1) override {
89 // collect all markers
90 fMgr->fMarkers.push_back({ std::string(name), t0, t1 });
91 }
92
93private:
95};
96
98 : fMode(mode)
99 , fPrefix(prefix ? prefix : "$")
100 , fPropertyInterceptor(sk_make_sp<PropertyInterceptor>(this))
101 , fMarkerInterceptor(sk_make_sp<MarkerInterceptor>(this)) {}
102
104
105std::string CustomPropertyManager::acceptKey(const char* name, const char* suffix) const {
106 if (!SkStrStartsWith(name, fPrefix.c_str())) {
107 return std::string();
108 }
109
110 return fMode == Mode::kCollapseProperties
111 ? std::string(name)
112 : fCurrentNode + suffix;
113}
114
118
122
123template <typename T>
124std::vector<CustomPropertyManager::PropKey>
125CustomPropertyManager::getProps(const PropMap<T>& container) const {
126 std::vector<PropKey> props;
127
128 for (const auto& prop_list : container) {
129 SkASSERT(!prop_list.second.empty());
130 props.push_back(prop_list.first);
131 }
132
133 return props;
134}
135
136template <typename V, typename T>
137V CustomPropertyManager::get(const PropKey& key, const PropMap<T>& container) const {
138 auto prop_group = container.find(key);
139
140 return prop_group == container.end()
141 ? V()
142 : prop_group->second.front()->get();
143}
144
145template <typename T>
146std::unique_ptr<T> CustomPropertyManager::getHandle(const PropKey& key,
147 size_t index,
148 const PropMap<T>& container) const {
149 auto prop_group = container.find(key);
150
151 if (prop_group == container.end() || index >= prop_group->second.size()) {
152 return nullptr;
153 }
154
155 return std::make_unique<T>(*prop_group->second[index]);
156}
157
158template <typename V, typename T>
159bool CustomPropertyManager::set(const PropKey& key, const V& val, const PropMap<T>& container) {
160 auto prop_group = container.find(key);
161
162 if (prop_group == container.end()) {
163 return false;
164 }
165
166 for (auto& handle : prop_group->second) {
167 handle->set(val);
168 }
169
170 return true;
171}
172
173std::vector<CustomPropertyManager::PropKey>
175 return this->getProps(fColorMap);
176}
177
179 return this->get<skottie::ColorPropertyValue>(key, fColorMap);
180}
181
182std::unique_ptr<skottie::ColorPropertyHandle>
184 return this->getHandle(key, index, fColorMap);
185}
186
188 return this->set(key, c, fColorMap);
189}
190
191std::vector<CustomPropertyManager::PropKey>
193 return this->getProps(fOpacityMap);
194}
195
197 return this->get<skottie::OpacityPropertyValue>(key, fOpacityMap);
198}
199
200std::unique_ptr<skottie::OpacityPropertyHandle>
202 return this->getHandle(key, index, fOpacityMap);
203}
204
206 return this->set(key, o, fOpacityMap);
207}
208
209std::vector<CustomPropertyManager::PropKey>
211 return this->getProps(fTransformMap);
212}
213
215 return this->get<skottie::TransformPropertyValue>(key, fTransformMap);
216}
217
218std::unique_ptr<skottie::TransformPropertyHandle>
220 return this->getHandle(key, index, fTransformMap);
221}
222
225 return this->set(key, t, fTransformMap);
226}
227
228std::vector<CustomPropertyManager::PropKey>
230 return this->getProps(fTextMap);
231}
232
234 return this->get<skottie::TextPropertyValue>(key, fTextMap);
235}
236
237std::unique_ptr<skottie::TextPropertyHandle>
239 return this->getHandle(key, index, fTextMap);
240}
241
243 return this->set(key, o, fTextMap);
244}
245
246namespace {
247
248class ExternalAnimationLayer final : public skottie::ExternalLayer {
249public:
250 ExternalAnimationLayer(sk_sp<skottie::Animation> anim, const SkSize& size)
251 : fAnimation(std::move(anim))
252 , fSize(size) {}
253
254private:
255 void render(SkCanvas* canvas, double t) override {
256 fAnimation->seekFrameTime(t);
257
258 // The main animation will layer-isolate if needed - we don't want the nested animation
259 // to override that decision.
261 const auto dst_rect = SkRect::MakeSize(fSize);
262 fAnimation->render(canvas, &dst_rect, flags);
263 }
264
265 const sk_sp<skottie::Animation> fAnimation;
266 const SkSize fSize;
267};
268
269} // namespace
270
273 const char prefixp[])
274 : fResourceProvider(std::move(rprovider))
275 , fPrefix(prefixp) {}
276
278
280 const char[], const char name[], const SkSize& size) {
281 if (0 != strncmp(name, fPrefix.c_str(), fPrefix.size())) {
282 return nullptr;
283 }
284
285 auto data = fResourceProvider->load("", name + fPrefix.size());
286 if (!data) {
287 return nullptr;
288 }
289
290 auto anim = skottie::Animation::Builder()
292 .setResourceProvider(fResourceProvider)
293 .make(static_cast<const char*>(data->data()), data->size());
294
295 return anim ? sk_make_sp<ExternalAnimationLayer>(std::move(anim), size)
296 : nullptr;
297}
298
299} // namespace skottie_utils
static sk_sp< SkImage > render(const SkPicture &p)
#define SkASSERT(cond)
Definition SkAssert.h:116
sk_sp< T > sk_make_sp(Args &&... args)
Definition SkRefCnt.h:371
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
static bool SkStrStartsWith(const char string[], const char prefixStr[])
Definition SkString.h:26
size_t size() const
Definition SkString.h:131
const char * c_str() const
Definition SkString.h:133
Builder & setResourceProvider(sk_sp< ResourceProvider >)
Definition Skottie.cpp:309
Builder & setPrecompInterceptor(sk_sp< PrecompInterceptor >)
Definition Skottie.cpp:334
sk_sp< Animation > make(SkStream *)
Definition Skottie.cpp:349
void seekFrameTime(double t, sksg::InvalidationController *=nullptr)
Definition Skottie.cpp:530
void render(SkCanvas *canvas, const SkRect *dst=nullptr) const
Definition Skottie.cpp:482
std::function< std::unique_ptr< T >()> LazyHandle
void onMarker(const char name[], float t0, float t1) override
void onTextProperty(const char node_name[], const LazyHandle< skottie::TextPropertyHandle > &t) override
void onTransformProperty(const char node_name[], const LazyHandle< skottie::TransformPropertyHandle > &t) override
void onOpacityProperty(const char node_name[], const LazyHandle< skottie::OpacityPropertyHandle > &o) override
void onLeavingNode(const char node_name[], PropertyObserver::NodeType node_type) override
void onColorProperty(const char node_name[], const LazyHandle< skottie::ColorPropertyHandle > &c) override
void onEnterNode(const char node_name[], PropertyObserver::NodeType node_type) override
sk_sp< skottie::MarkerObserver > getMarkerObserver() const
bool setOpacity(const PropKey &, const skottie::OpacityPropertyValue &)
skottie::ColorPropertyValue getColor(const PropKey &) const
bool setTransform(const PropKey &, const skottie::TransformPropertyValue &)
std::unique_ptr< skottie::OpacityPropertyHandle > getOpacityHandle(const PropKey &, size_t) const
bool setColor(const PropKey &, const skottie::ColorPropertyValue &)
bool setText(const PropKey &, const skottie::TextPropertyValue &)
std::vector< PropKey > getColorProps() const
std::unique_ptr< skottie::TextPropertyHandle > getTextHandle(const PropKey &, size_t index) const
skottie::TransformPropertyValue getTransform(const PropKey &) const
std::unique_ptr< skottie::TransformPropertyHandle > getTransformHandle(const PropKey &, size_t) const
std::unique_ptr< skottie::ColorPropertyHandle > getColorHandle(const PropKey &, size_t) const
std::vector< PropKey > getTextProps() const
skottie::TextPropertyValue getText(const PropKey &) const
std::vector< PropKey > getOpacityProps() const
sk_sp< skottie::PropertyObserver > getPropertyObserver() const
std::vector< PropKey > getTransformProps() const
CustomPropertyManager(Mode=Mode::kNamespacedProperties, const char *prefix=nullptr)
skottie::OpacityPropertyValue getOpacity(const PropKey &) const
sk_sp< skottie::ExternalLayer > onLoadPrecomp(const char[], const char[], const SkSize &) override
ExternalAnimationPrecompInterceptor(sk_sp< skresources::ResourceProvider >, const char prefix[])
virtual sk_sp< SkData > load(const char[], const char[]) const
FlutterSemanticsFlag flags
const char * name
Definition fuchsia.cc:50
size_t length
T __attribute__((ext_vector_type(N))) V
float OpacityPropertyValue
SkColor ColorPropertyValue
Definition ref_ptr.h:256
#define V(name)
Definition raw_object.h:124
static constexpr SkRect MakeSize(const SkSize &size)
Definition SkRect.h:633
SkBlendMode fMode
Definition xfermodes.cpp:52