• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.h"
9 #include "Resources.h"
10 #include "SkAnimCodecPlayer.h"
11 #include "SkAnimTimer.h"
12 #include "SkColor.h"
13 #include "SkMakeUnique.h"
14 #include "Skottie.h"
15 #include "SkottieProperty.h"
16 #include "SkottieUtils.h"
17 
18 #include <cmath>
19 #include <vector>
20 
21 using namespace skottie;
22 
23 namespace {
24 
25 static constexpr char kWebFontResource[] = "fonts/Roboto-Regular.ttf";
26 static constexpr char kSkottieResource[] = "skottie/skottie_sample_webfont.json";
27 
28 // Dummy web font loader which serves a single local font (checked in under resources/).
29 class FakeWebFontProvider final : public ResourceProvider {
30 public:
FakeWebFontProvider()31     FakeWebFontProvider() : fFontData(GetResourceAsData(kWebFontResource)) {}
32 
loadFont(const char[],const char[]) const33     sk_sp<SkData> loadFont(const char[], const char[]) const override {
34         return fFontData;
35     }
36 
37 private:
38     sk_sp<SkData> fFontData;
39 
40     using INHERITED = ResourceProvider;
41 };
42 
43 } // namespace
44 
45 class SkottieWebFontGM : public skiagm::GM {
46 public:
47 protected:
onShortName()48     SkString onShortName() override {
49         return SkString("skottie_webfont");
50     }
51 
onISize()52     SkISize onISize() override {
53         return SkISize::Make(kSize, kSize);
54     }
55 
onOnceBeforeDraw()56     void onOnceBeforeDraw() override {
57         if (auto stream = GetResourceAsStream(kSkottieResource)) {
58             fAnimation = Animation::Builder()
59                             .setResourceProvider(sk_make_sp<FakeWebFontProvider>())
60                             .make(stream.get());
61         }
62     }
63 
onDraw(SkCanvas * canvas)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 
onAnimate(const SkAnimTimer & timer)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 
83 private:
84     static constexpr SkScalar kSize = 800;
85 
86     sk_sp<Animation> fAnimation;
87 
88     using INHERITED = skiagm::GM;
89 };
90 
91 DEF_GM(return new SkottieWebFontGM;)
92 
93 using namespace skottie_utils;
94 
95 class SkottieColorizeGM : public skiagm::GM {
96 protected:
onShortName()97     SkString onShortName() override {
98         return SkString("skottie_colorize");
99     }
100 
onISize()101     SkISize onISize() override {
102         return SkISize::Make(kSize, kSize);
103     }
104 
onOnceBeforeDraw()105     void onOnceBeforeDraw() override {
106         if (auto stream = GetResourceAsStream("skottie/skottie_sample_search.json")) {
107             fPropManager = skstd::make_unique<CustomPropertyManager>();
108             fAnimation   = Animation::Builder()
109                               .setPropertyObserver(fPropManager->getPropertyObserver())
110                               .make(stream.get());
111             fColors      = fPropManager->getColorProps();
112         }
113     }
114 
onDraw(SkCanvas * canvas)115     void onDraw(SkCanvas* canvas) override {
116         if (!fAnimation) {
117             return;
118         }
119 
120         auto dest = SkRect::MakeWH(kSize, kSize);
121         fAnimation->render(canvas, &dest);
122     }
123 
onAnimate(const SkAnimTimer & timer)124     bool onAnimate(const SkAnimTimer& timer) override {
125         if (!fAnimation) {
126             return false;
127         }
128 
129         const auto duration = fAnimation->duration();
130         fAnimation->seek(std::fmod(timer.secs(), duration) / duration);
131         return true;
132     }
133 
onHandleKey(SkUnichar uni)134     bool onHandleKey(SkUnichar uni) override {
135         static constexpr SkColor kColors[] = {
136             SK_ColorBLACK,
137             SK_ColorRED,
138             SK_ColorGREEN,
139             SK_ColorYELLOW,
140             SK_ColorCYAN,
141         };
142 
143         if (uni == 'c') {
144             fColorIndex = (fColorIndex + 1) % SK_ARRAY_COUNT(kColors);
145             for (const auto& prop : fColors) {
146                 fPropManager->setColor(prop, kColors[fColorIndex]);
147             }
148             return true;
149         }
150 
151         return false;
152     }
153 
154 private:
155     static constexpr SkScalar kSize = 800;
156 
157     sk_sp<Animation>                            fAnimation;
158     std::unique_ptr<CustomPropertyManager>      fPropManager;
159     std::vector<CustomPropertyManager::PropKey> fColors;
160     size_t                                      fColorIndex = 0;
161 
162     using INHERITED = skiagm::GM;
163 };
164 
165 DEF_GM(return new SkottieColorizeGM;)
166 
167 class SkottieMultiFrameGM : public skiagm::GM {
168 public:
169 protected:
onShortName()170     SkString onShortName() override {
171         return SkString("skottie_multiframe");
172     }
173 
onISize()174     SkISize onISize() override {
175         return SkISize::Make(kSize, kSize);
176     }
177 
onOnceBeforeDraw()178     void onOnceBeforeDraw() override {
179         if (auto stream = GetResourceAsStream("skottie/skottie_sample_multiframe.json")) {
180             fAnimation = Animation::Builder()
181                             .setResourceProvider(sk_make_sp<MultiFrameResourceProvider>())
182                             .make(stream.get());
183         }
184     }
185 
onDraw(SkCanvas * canvas)186     void onDraw(SkCanvas* canvas) override {
187         if (!fAnimation) {
188             return;
189         }
190 
191         auto dest = SkRect::MakeWH(kSize, kSize);
192         fAnimation->render(canvas, &dest);
193     }
194 
onAnimate(const SkAnimTimer & timer)195     bool onAnimate(const SkAnimTimer& timer) override {
196         if (!fAnimation) {
197             return false;
198         }
199 
200         const auto duration = fAnimation->duration();
201         fAnimation->seek(std::fmod(timer.secs(), duration) / duration);
202         return true;
203     }
204 
205 private:
206     class MultiFrameResourceProvider final : public skottie::ResourceProvider {
207     public:
loadImageAsset(const char[],const char[]) const208         sk_sp<ImageAsset> loadImageAsset(const char[], const char[]) const override {
209             return skottie_utils::MultiFrameImageAsset::Make(
210                         GetResourceAsData("images/flightAnim.gif"));
211         }
212     };
213 
214     static constexpr SkScalar kSize = 800;
215 
216     sk_sp<Animation> fAnimation;
217 
218     using INHERITED = skiagm::GM;
219 };
220 
221 DEF_GM(return new SkottieMultiFrameGM;)
222