blob: 040b8b32a705d1f27cac8a1ac60d4420d5eadb81 [file] [log] [blame]
Florin Malita26870722018-09-20 14:35:30 -04001/*
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.h"
9#include "Resources.h"
Florin Malita62c6bd92018-10-03 14:39:56 -040010#include "SkAnimCodecPlayer.h"
Florin Malita26870722018-09-20 14:35:30 -040011#include "SkAnimTimer.h"
Florin Malita17282da2018-09-25 13:10:12 -040012#include "SkColor.h"
Florin Malita62c6bd92018-10-03 14:39:56 -040013#include "SkMakeUnique.h"
Florin Malita26870722018-09-20 14:35:30 -040014#include "Skottie.h"
Florin Malita17282da2018-09-25 13:10:12 -040015#include "SkottieProperty.h"
Florin Malitaa8316552018-11-09 16:19:44 -050016#include "SkottieUtils.h"
Florin Malita26870722018-09-20 14:35:30 -040017
18#include <cmath>
Florin Malita17282da2018-09-25 13:10:12 -040019#include <vector>
20
21using namespace skottie;
Florin Malita26870722018-09-20 14:35:30 -040022
23namespace {
24
25static constexpr char kWebFontResource[] = "fonts/Roboto-Regular.ttf";
26static constexpr char kSkottieResource[] = "skottie/skottie_sample_webfont.json";
27
28// Dummy web font loader which serves a single local font (checked in under resources/).
Florin Malita17282da2018-09-25 13:10:12 -040029class FakeWebFontProvider final : public ResourceProvider {
Florin Malita26870722018-09-20 14:35:30 -040030public:
31 FakeWebFontProvider() : fFontData(GetResourceAsData(kWebFontResource)) {}
32
Florin Malita97b150e2018-09-27 10:59:52 -040033 sk_sp<SkData> loadFont(const char[], const char[]) const override {
Florin Malita26870722018-09-20 14:35:30 -040034 return fFontData;
35 }
36
37private:
38 sk_sp<SkData> fFontData;
39
Florin Malita17282da2018-09-25 13:10:12 -040040 using INHERITED = ResourceProvider;
Florin Malita26870722018-09-20 14:35:30 -040041};
42
43} // namespace
44
45class SkottieWebFontGM : public skiagm::GM {
46public:
47protected:
48 SkString onShortName() override {
49 return SkString("skottie_webfont");
50 }
51
52 SkISize onISize() override {
53 return SkISize::Make(kSize, kSize);
54 }
55
56 void onOnceBeforeDraw() override {
57 if (auto stream = GetResourceAsStream(kSkottieResource)) {
Florin Malita17282da2018-09-25 13:10:12 -040058 fAnimation = Animation::Builder()
Florin Malita26870722018-09-20 14:35:30 -040059 .setResourceProvider(sk_make_sp<FakeWebFontProvider>())
60 .make(stream.get());
61 }
62 }
63
64 void onDraw(SkCanvas* canvas) override {
65 if (!fAnimation) {
66 return;
67 }
68
69 auto dest = SkRect::MakeWH(kSize, kSize);
70 fAnimation->render(canvas, &dest);
71 }
72
73 bool onAnimate(const SkAnimTimer& timer) override {
74 if (!fAnimation) {
75 return false;
76 }
77
78 const auto duration = fAnimation->duration();
79 fAnimation->seek(std::fmod(timer.secs(), duration) / duration);
80 return true;
81 }
82
83private:
84 static constexpr SkScalar kSize = 800;
85
Florin Malita17282da2018-09-25 13:10:12 -040086 sk_sp<Animation> fAnimation;
Florin Malita26870722018-09-20 14:35:30 -040087
88 using INHERITED = skiagm::GM;
89};
90
91DEF_GM(return new SkottieWebFontGM;)
Florin Malita17282da2018-09-25 13:10:12 -040092
93class SkottieColorizeGM : public skiagm::GM {
Florin Malita17282da2018-09-25 13:10:12 -040094protected:
95 SkString onShortName() override {
96 return SkString("skottie_colorize");
97 }
98
99 SkISize onISize() override {
100 return SkISize::Make(kSize, kSize);
101 }
102
103 void onOnceBeforeDraw() override {
104 if (auto stream = GetResourceAsStream("skottie/skottie_sample_search.json")) {
105 fColorizer = sk_make_sp<Colorizer>();
106 fAnimation = Animation::Builder()
107 .setPropertyObserver(fColorizer)
108 .make(stream.get());
109 }
110 }
111
112 void onDraw(SkCanvas* canvas) override {
113 if (!fAnimation) {
114 return;
115 }
116
117 auto dest = SkRect::MakeWH(kSize, kSize);
118 fAnimation->render(canvas, &dest);
119 }
120
121 bool onAnimate(const SkAnimTimer& timer) override {
122 if (!fAnimation) {
123 return false;
124 }
125
126 const auto duration = fAnimation->duration();
127 fAnimation->seek(std::fmod(timer.secs(), duration) / duration);
128 return true;
129 }
130
Florin Malita17282da2018-09-25 13:10:12 -0400131 bool onHandleKey(SkUnichar uni) override {
132 static constexpr SkColor kColors[] = {
133 SK_ColorBLACK,
134 SK_ColorRED,
135 SK_ColorGREEN,
136 SK_ColorYELLOW,
137 SK_ColorCYAN,
138 };
139
140 if (uni == 'c') {
141 fColorIndex = (fColorIndex + 1) % SK_ARRAY_COUNT(kColors);
142 fColorizer->colorize(kColors[fColorIndex]);
143 return true;
144 }
145
146 return false;
147 }
148
149private:
150 class Colorizer final : public PropertyObserver {
151 public:
152 void onColorProperty(const char node_name[],
153 const PropertyObserver::LazyHandle<ColorPropertyHandle>& lh) override {
154 fColorHandles.push_back(lh());
155 }
156
157 void colorize(SkColor c) {
158 for (const auto& handle : fColorHandles) {
159 handle->setColor(c);
160 }
161 }
162
163 private:
164 std::vector<std::unique_ptr<skottie::ColorPropertyHandle>> fColorHandles;
165 };
166
167 static constexpr SkScalar kSize = 800;
168
169 sk_sp<Animation> fAnimation;
170 sk_sp<Colorizer> fColorizer;
171 size_t fColorIndex = 0;
172
173 using INHERITED = skiagm::GM;
174};
175
176DEF_GM(return new SkottieColorizeGM;)
Florin Malita62c6bd92018-10-03 14:39:56 -0400177
178class SkottieMultiFrameGM : public skiagm::GM {
179public:
180protected:
181 SkString onShortName() override {
182 return SkString("skottie_multiframe");
183 }
184
185 SkISize onISize() override {
186 return SkISize::Make(kSize, kSize);
187 }
188
189 void onOnceBeforeDraw() override {
190 if (auto stream = GetResourceAsStream("skottie/skottie_sample_multiframe.json")) {
191 fAnimation = Animation::Builder()
192 .setResourceProvider(sk_make_sp<MultiFrameResourceProvider>())
193 .make(stream.get());
194 }
195 }
196
197 void onDraw(SkCanvas* canvas) override {
198 if (!fAnimation) {
199 return;
200 }
201
202 auto dest = SkRect::MakeWH(kSize, kSize);
203 fAnimation->render(canvas, &dest);
204 }
205
206 bool onAnimate(const SkAnimTimer& timer) override {
207 if (!fAnimation) {
208 return false;
209 }
210
211 const auto duration = fAnimation->duration();
212 fAnimation->seek(std::fmod(timer.secs(), duration) / duration);
213 return true;
214 }
215
216private:
Florin Malita62c6bd92018-10-03 14:39:56 -0400217 class MultiFrameResourceProvider final : public skottie::ResourceProvider {
218 public:
219 sk_sp<ImageAsset> loadImageAsset(const char[], const char[]) const override {
Florin Malitaa8316552018-11-09 16:19:44 -0500220 return skottie_utils::MultiFrameImageAsset::Make(
221 GetResourceAsData("images/flightAnim.gif"));
Florin Malita62c6bd92018-10-03 14:39:56 -0400222 }
223 };
224
225 static constexpr SkScalar kSize = 800;
226
227 sk_sp<Animation> fAnimation;
228
229 using INHERITED = skiagm::GM;
230};
231
232DEF_GM(return new SkottieMultiFrameGM;)