• 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/gm.h"
9 #include "include/core/SkColor.h"
10 #include "include/core/SkStream.h"
11 #include "include/utils/SkAnimCodecPlayer.h"
12 #include "modules/skottie/include/Skottie.h"
13 #include "modules/skottie/include/SkottieProperty.h"
14 #include "modules/skottie/utils/SkottieUtils.h"
15 #include "modules/skresources/include/SkResources.h"
16 #include "tools/Resources.h"
17 
18 #include <cmath>
19 #include <vector>
20 
21 namespace {
22 
23 static constexpr char kWebFontResource[] = "fonts/Roboto-Regular.ttf";
24 static constexpr char kSkottieResource[] = "skottie/skottie_sample_webfont.json";
25 
26 // Mock web font loader which serves a single local font (checked in under resources/).
27 class FakeWebFontProvider final : public skresources::ResourceProvider {
28 public:
FakeWebFontProvider()29     FakeWebFontProvider()
30         : fTypeface(SkTypeface::MakeFromData(GetResourceAsData(kWebFontResource))) {}
31 
loadTypeface(const char[],const char[]) const32     sk_sp<SkTypeface> loadTypeface(const char[], const char[]) const override {
33         return fTypeface;
34     }
35 
36 private:
37     sk_sp<SkTypeface> fTypeface;
38 
39     using INHERITED = skresources::ResourceProvider;
40 };
41 
42 } // namespace
43 
44 class SkottieWebFontGM : public skiagm::GM {
45 public:
46 protected:
onShortName()47     SkString onShortName() override {
48         return SkString("skottie_webfont");
49     }
50 
onISize()51     SkISize onISize() override {
52         return SkISize::Make(kSize, kSize);
53     }
54 
onOnceBeforeDraw()55     void onOnceBeforeDraw() override {
56         if (auto stream = GetResourceAsStream(kSkottieResource)) {
57             fAnimation = skottie::Animation::Builder()
58                             .setResourceProvider(sk_make_sp<FakeWebFontProvider>())
59                             .make(stream.get());
60         }
61     }
62 
onDraw(SkCanvas * canvas,SkString * errorMsg)63     DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
64         if (!fAnimation) {
65             *errorMsg = "No animation";
66             return DrawResult::kFail;
67         }
68 
69         auto dest = SkRect::MakeWH(kSize, kSize);
70         fAnimation->render(canvas, &dest);
71         return DrawResult::kOk;
72     }
73 
onAnimate(double nanos)74     bool onAnimate(double nanos) override {
75         if (!fAnimation) {
76             return false;
77         }
78 
79         const auto duration = fAnimation->duration();
80         fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
81         return true;
82     }
83 
84 private:
85     inline static constexpr SkScalar kSize = 800;
86 
87     sk_sp<skottie::Animation> fAnimation;
88 
89     using INHERITED = skiagm::GM;
90 };
91 
92 DEF_GM(return new SkottieWebFontGM;)
93 
94 class SkottieColorizeGM : public skiagm::GM {
95 public:
SkottieColorizeGM(const char * name,const char * resource)96     SkottieColorizeGM(const char* name, const char* resource)
97         : fName(name)
98         , fResource(resource)
99     {}
100 
101 protected:
onShortName()102     SkString onShortName() override {
103         return SkStringPrintf("skottie_colorize_%s", fName);
104     }
105 
onISize()106     SkISize onISize() override {
107         return SkISize::Make(kSize, kSize);
108     }
109 
onOnceBeforeDraw()110     void onOnceBeforeDraw() override {
111         if (auto stream = GetResourceAsStream(fResource)) {
112             fPropManager = std::make_unique<skottie_utils::CustomPropertyManager>();
113             fAnimation   = skottie::Animation::Builder()
114                               .setPropertyObserver(fPropManager->getPropertyObserver())
115                               .make(stream.get());
116             fColorProps  = fPropManager->getColorProps();
117             fTextProps   = fPropManager->getTextProps();
118         }
119     }
120 
onDraw(SkCanvas * canvas,SkString * errorMsg)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 
onAnimate(double nanos)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 
onChar(SkUnichar uni)142     bool onChar(SkUnichar uni) override {
143         static constexpr SkColor kColors[] = {
144             SK_ColorBLACK,
145             SK_ColorRED,
146             SK_ColorGREEN,
147             SK_ColorYELLOW,
148             SK_ColorCYAN,
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 
167 private:
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 
182 DEF_GM(return new SkottieColorizeGM("color", "skottie/skottie_sample_search.json");)
183 DEF_GM(return new SkottieColorizeGM("text" , "skottie/skottie-text-animator-5.json");)
184 
185 class SkottieMultiFrameGM : public skiagm::GM {
186 public:
187 protected:
onShortName()188     SkString onShortName() override {
189         return SkString("skottie_multiframe");
190     }
191 
onISize()192     SkISize onISize() override {
193         return SkISize::Make(kSize, kSize);
194     }
195 
onOnceBeforeDraw()196     void onOnceBeforeDraw() override {
197         if (auto stream = GetResourceAsStream("skottie/skottie_sample_multiframe.json")) {
198             fAnimation = skottie::Animation::Builder()
199                             .setResourceProvider(sk_make_sp<MultiFrameResourceProvider>())
200                             .make(stream.get());
201             fAnimation->seek(0);
202         }
203     }
204 
onDraw(SkCanvas * canvas,SkString * errorMsg)205     DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
206         if (!fAnimation) {
207             *errorMsg = "No animation";
208             return DrawResult::kFail;
209         }
210 
211         auto dest = SkRect::MakeWH(kSize, kSize);
212         fAnimation->render(canvas, &dest);
213         return DrawResult::kOk;
214     }
215 
onAnimate(double nanos)216     bool onAnimate(double nanos) override {
217         if (!fAnimation) {
218             return false;
219         }
220 
221         const auto duration = fAnimation->duration();
222         fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
223         return true;
224     }
225 
226 private:
227     class MultiFrameResourceProvider final : public skresources::ResourceProvider {
228     public:
loadImageAsset(const char[],const char[],const char[]) const229         sk_sp<skresources::ImageAsset> loadImageAsset(const char[], const char[],
230                                                       const char[]) const override {
231             return skresources::MultiFrameImageAsset::Make(
232                         GetResourceAsData("images/flightAnim.gif"));
233         }
234     };
235 
236     inline static constexpr SkScalar kSize = 800;
237 
238     sk_sp<skottie::Animation> fAnimation;
239 
240     using INHERITED = skiagm::GM;
241 };
242 
243 DEF_GM(return new SkottieMultiFrameGM;)
244