Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkottieGM.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 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#include "gm/gm.h"
20#include "tools/Resources.h"
22
23#include <cmath>
24#include <vector>
25
26namespace {
27
28static constexpr char kWebFontResource[] = "fonts/Roboto-Regular.ttf";
29static constexpr char kSkottieResource[] = "skottie/skottie_sample_webfont.json";
30
31// Mock web font loader which serves a single local font (checked in under resources/).
32class FakeWebFontProvider final : public skresources::ResourceProvider {
33public:
34 FakeWebFontProvider() : fTypeface(ToolUtils::CreateTypefaceFromResource(kWebFontResource)) {}
35
36 sk_sp<SkTypeface> loadTypeface(const char[], const char[]) const override {
37 return fTypeface;
38 }
39
40private:
41 sk_sp<SkTypeface> fTypeface;
42
44};
45
46} // namespace
47
49public:
50protected:
51 SkString getName() const override { return SkString("skottie_webfont"); }
52
53 SkISize getISize() override { return SkISize::Make(kSize, kSize); }
54
55 void onOnceBeforeDraw() override {
56 if (auto stream = GetResourceAsStream(kSkottieResource)) {
57 fAnimation = skottie::Animation::Builder()
59 .setResourceProvider(sk_make_sp<FakeWebFontProvider>())
61 .make(stream.get());
62 }
63 }
64
65 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
66 if (!fAnimation) {
67 *errorMsg = "No animation";
68 return DrawResult::kFail;
69 }
70
71 auto dest = SkRect::MakeWH(kSize, kSize);
72 fAnimation->render(canvas, &dest);
73 return DrawResult::kOk;
74 }
75
76 bool onAnimate(double nanos) override {
77 if (!fAnimation) {
78 return false;
79 }
80
81 const auto duration = fAnimation->duration();
82 fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
83 return true;
84 }
85
86private:
87 inline static constexpr SkScalar kSize = 800;
88
90
91 using INHERITED = skiagm::GM;
92};
93
94DEF_GM(return new SkottieWebFontGM;)
95
96class SkottieColorizeGM : public skiagm::GM {
97public:
98 SkottieColorizeGM(const char* name, const char* resource)
99 : fName(name)
100 , fResource(resource)
101 {}
102
103protected:
104 SkString getName() const override { return SkStringPrintf("skottie_colorize_%s", fName); }
105
106 SkISize getISize() override { return SkISize::Make(kSize, kSize); }
107
108 void onOnceBeforeDraw() override {
109 if (auto stream = GetResourceAsStream(fResource)) {
110 fPropManager = std::make_unique<skottie_utils::CustomPropertyManager>();
111 fAnimation = skottie::Animation::Builder()
113 .setPropertyObserver(fPropManager->getPropertyObserver())
115 .make(stream.get());
116 fColorProps = fPropManager->getColorProps();
117 fTextProps = fPropManager->getTextProps();
118 }
119 }
120
121 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
122 if (!fAnimation) {
123 *errorMsg = "No animation";
124 return DrawResult::kFail;
125 }
126
127 auto dest = SkRect::MakeWH(kSize, kSize);
128 fAnimation->render(canvas, &dest);
129 return DrawResult::kOk;
130 }
131
132 bool onAnimate(double nanos) override {
133 if (!fAnimation) {
134 return false;
135 }
136
137 const auto duration = fAnimation->duration();
138 fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
139 return true;
140 }
141
142 bool onChar(SkUnichar uni) override {
143 static constexpr SkColor kColors[] = {
149 };
150
151 if (uni == 'c') {
152 fColorIndex = (fColorIndex + 1) % std::size(kColors);
153 for (const auto& prop : fColorProps) {
154 fPropManager->setColor(prop, kColors[fColorIndex]);
155 }
156 for (const auto& prop : fTextProps) {
157 auto txtval = fPropManager->getText(prop);
158 txtval.fFillColor = kColors[fColorIndex];
159 fPropManager->setText(prop, txtval);
160 }
161 return true;
162 }
163
164 return false;
165 }
166
167private:
168 inline static constexpr SkScalar kSize = 800;
169
170 const char* fName;
171 const char* fResource;
172
173 sk_sp<skottie::Animation> fAnimation;
174 std::unique_ptr<skottie_utils::CustomPropertyManager> fPropManager;
175 std::vector<skottie_utils::CustomPropertyManager::PropKey> fColorProps,
176 fTextProps;
177 size_t fColorIndex = 0;
178
179 using INHERITED = skiagm::GM;
180};
181
182DEF_GM(return new SkottieColorizeGM("color", "skottie/skottie_sample_search.json");)
183DEF_GM(return new SkottieColorizeGM("text" , "skottie/skottie-text-animator-5.json");)
184
185class SkottieMultiFrameGM : public skiagm::GM {
186public:
187protected:
188 SkString getName() const override { return SkString("skottie_multiframe"); }
189
190 SkISize getISize() override { return SkISize::Make(kSize, kSize); }
191
192 void onOnceBeforeDraw() override {
193 if (auto stream = GetResourceAsStream("skottie/skottie_sample_multiframe.json")) {
194 fAnimation = skottie::Animation::Builder()
195 .setResourceProvider(sk_make_sp<MultiFrameResourceProvider>())
196 .make(stream.get());
197 fAnimation->seek(0);
198 }
199 }
200
201 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
202 if (!fAnimation) {
203 *errorMsg = "No animation";
204 return DrawResult::kFail;
205 }
206
207 auto dest = SkRect::MakeWH(kSize, kSize);
208 fAnimation->render(canvas, &dest);
209 return DrawResult::kOk;
210 }
211
212 bool onAnimate(double nanos) override {
213 if (!fAnimation) {
214 return false;
215 }
216
217 const auto duration = fAnimation->duration();
218 fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
219 return true;
220 }
221
222private:
223 class MultiFrameResourceProvider final : public skresources::ResourceProvider {
224 public:
225 sk_sp<skresources::ImageAsset> loadImageAsset(const char[], const char[],
226 const char[]) const override {
227 sk_sp<SkData> data = GetResourceAsData("images/flightAnim.gif");
228 SkASSERT(data);
229 std::unique_ptr<SkCodec> codec = SkGifDecoder::Decode(data, nullptr);
230 SkASSERT(codec);
231 return skresources::MultiFrameImageAsset::Make(std::move(codec));
232 }
233 };
234
235 inline static constexpr SkScalar kSize = 800;
236
237 sk_sp<skottie::Animation> fAnimation;
238
239 using INHERITED = skiagm::GM;
240};
241
242DEF_GM(return new SkottieMultiFrameGM;)
const char * fName
std::unique_ptr< SkStreamAsset > GetResourceAsStream(const char *resource, bool useFileStream)
Definition Resources.cpp:31
sk_sp< SkData > GetResourceAsData(const char *resource)
Definition Resources.cpp:42
#define SkASSERT(cond)
Definition SkAssert.h:116
constexpr SkColor SK_ColorYELLOW
Definition SkColor.h:139
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorCYAN
Definition SkColor.h:143
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
#define INHERITED(method,...)
SK_API SkString static SkString SkStringPrintf()
Definition SkString.h:287
int32_t SkUnichar
Definition SkTypes.h:175
DrawResult onDraw(SkCanvas *canvas, SkString *errorMsg) override
void onOnceBeforeDraw() override
SkISize getISize() override
SkString getName() const override
bool onAnimate(double nanos) override
bool onChar(SkUnichar uni) override
SkISize getISize() override
bool onAnimate(double nanos) override
void onOnceBeforeDraw() override
DrawResult onDraw(SkCanvas *canvas, SkString *errorMsg) override
SkISize getISize() override
Definition SkottieGM.cpp:53
bool onAnimate(double nanos) override
Definition SkottieGM.cpp:76
void onOnceBeforeDraw() override
Definition SkottieGM.cpp:55
DrawResult onDraw(SkCanvas *canvas, SkString *errorMsg) override
Definition SkottieGM.cpp:65
SkString getName() const override
Definition SkottieGM.cpp:51
Builder & setPropertyObserver(sk_sp< PropertyObserver >)
Definition Skottie.cpp:319
Builder & setResourceProvider(sk_sp< ResourceProvider >)
Definition Skottie.cpp:309
Builder & setFontManager(sk_sp< SkFontMgr >)
Definition Skottie.cpp:314
sk_sp< Animation > make(SkStream *)
Definition Skottie.cpp:349
Builder & setTextShapingFactory(sk_sp< SkShapers::Factory >)
Definition Skottie.cpp:344
double duration() const
Definition Skottie.h:268
void render(SkCanvas *canvas, const SkRect *dst=nullptr) const
Definition Skottie.cpp:482
void seek(SkScalar t, sksg::InvalidationController *ic=nullptr)
Definition Skottie.h:244
static sk_sp< MultiFrameImageAsset > Make(sk_sp< SkData >, ImageDecodeStrategy=ImageDecodeStrategy::kLazyDecode)
virtual sk_sp< ImageAsset > loadImageAsset(const char[], const char[], const char[]) const
virtual sk_sp< SkTypeface > loadTypeface(const char[], const char[]) const
static constexpr int kSize
double duration
Definition examples.cpp:30
float SkScalar
Definition extension.cpp:12
const char * name
Definition fuchsia.cc:50
#define DEF_GM(CODE)
Definition gm.h:40
SK_API std::unique_ptr< SkCodec > Decode(std::unique_ptr< SkStream >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
sk_sp< Factory > BestAvailable()
sk_sp< SkTypeface > CreateTypefaceFromResource(const char *resource, int ttcIndex)
sk_sp< SkFontMgr > TestFontMgr()
DrawResult
Definition gm.h:104
static SkScalar prop(SkScalar radius, SkScalar newSize, SkScalar oldSize)
Definition rrect.cpp:83
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609