• 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/utils/SkAnimCodecPlayer.h"
11 #include "modules/skottie/include/Skottie.h"
12 #include "modules/skottie/include/SkottieProperty.h"
13 #include "modules/skottie/utils/SkottieUtils.h"
14 #include "modules/skresources/include/SkResources.h"
15 #include "tools/Resources.h"
16 
17 #include <cmath>
18 #include <vector>
19 
20 namespace {
21 
22 static constexpr char kWebFontResource[] = "fonts/Roboto-Regular.ttf";
23 static constexpr char kSkottieResource[] = "skottie/skottie_sample_webfont.json";
24 
25 // Mock web font loader which serves a single local font (checked in under resources/).
26 class FakeWebFontProvider final : public skresources::ResourceProvider {
27 public:
FakeWebFontProvider()28     FakeWebFontProvider()
29         : fTypeface(SkTypeface::MakeFromData(GetResourceAsData(kWebFontResource))) {}
30 
loadTypeface(const char[],const char[]) const31     sk_sp<SkTypeface> loadTypeface(const char[], const char[]) const override {
32         return fTypeface;
33     }
34 
35 private:
36     sk_sp<SkTypeface> fTypeface;
37 
38     using INHERITED = skresources::ResourceProvider;
39 };
40 
41 } // namespace
42 
43 class SkottieWebFontGM : public skiagm::GM {
44 public:
45 protected:
onShortName()46     SkString onShortName() override {
47         return SkString("skottie_webfont");
48     }
49 
onISize()50     SkISize onISize() override {
51         return SkISize::Make(kSize, kSize);
52     }
53 
onOnceBeforeDraw()54     void onOnceBeforeDraw() override {
55         if (auto stream = GetResourceAsStream(kSkottieResource)) {
56             fAnimation = skottie::Animation::Builder()
57                             .setResourceProvider(sk_make_sp<FakeWebFontProvider>())
58                             .make(stream.get());
59         }
60     }
61 
onDraw(SkCanvas * canvas,SkString * errorMsg)62     DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
63         if (!fAnimation) {
64             *errorMsg = "No animation";
65             return DrawResult::kFail;
66         }
67 
68         auto dest = SkRect::MakeWH(kSize, kSize);
69         fAnimation->render(canvas, &dest);
70         return DrawResult::kOk;
71     }
72 
onAnimate(double nanos)73     bool onAnimate(double nanos) override {
74         if (!fAnimation) {
75             return false;
76         }
77 
78         const auto duration = fAnimation->duration();
79         fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
80         return true;
81     }
82 
83 private:
84     inline static constexpr SkScalar kSize = 800;
85 
86     sk_sp<skottie::Animation> fAnimation;
87 
88     using INHERITED = skiagm::GM;
89 };
90 
91 DEF_GM(return new SkottieWebFontGM;)
92 
93 class SkottieColorizeGM : public skiagm::GM {
94 public:
SkottieColorizeGM(const char * name,const char * resource)95     SkottieColorizeGM(const char* name, const char* resource)
96         : fName(name)
97         , fResource(resource)
98     {}
99 
100 protected:
onShortName()101     SkString onShortName() override {
102         return SkStringPrintf("skottie_colorize_%s", fName);
103     }
104 
onISize()105     SkISize onISize() override {
106         return SkISize::Make(kSize, kSize);
107     }
108 
onOnceBeforeDraw()109     void onOnceBeforeDraw() override {
110         if (auto stream = GetResourceAsStream(fResource)) {
111             fPropManager = std::make_unique<skottie_utils::CustomPropertyManager>();
112             fAnimation   = skottie::Animation::Builder()
113                               .setPropertyObserver(fPropManager->getPropertyObserver())
114                               .make(stream.get());
115             fColorProps  = fPropManager->getColorProps();
116             fTextProps   = fPropManager->getTextProps();
117         }
118     }
119 
onDraw(SkCanvas * canvas,SkString * errorMsg)120     DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
121         if (!fAnimation) {
122             *errorMsg = "No animation";
123             return DrawResult::kFail;
124         }
125 
126         auto dest = SkRect::MakeWH(kSize, kSize);
127         fAnimation->render(canvas, &dest);
128         return DrawResult::kOk;
129     }
130 
onAnimate(double nanos)131     bool onAnimate(double nanos) override {
132         if (!fAnimation) {
133             return false;
134         }
135 
136         const auto duration = fAnimation->duration();
137         fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
138         return true;
139     }
140 
onChar(SkUnichar uni)141     bool onChar(SkUnichar uni) override {
142         static constexpr SkColor kColors[] = {
143             SK_ColorBLACK,
144             SK_ColorRED,
145             SK_ColorGREEN,
146             SK_ColorYELLOW,
147             SK_ColorCYAN,
148         };
149 
150         if (uni == 'c') {
151             fColorIndex = (fColorIndex + 1) % SK_ARRAY_COUNT(kColors);
152             for (const auto& prop : fColorProps) {
153                 fPropManager->setColor(prop, kColors[fColorIndex]);
154             }
155             for (const auto& prop : fTextProps) {
156                 auto txtval = fPropManager->getText(prop);
157                 txtval.fFillColor = kColors[fColorIndex];
158                 fPropManager->setText(prop, txtval);
159             }
160             return true;
161         }
162 
163         return false;
164     }
165 
166 private:
167     inline static constexpr SkScalar kSize = 800;
168 
169     const char*                                                fName;
170     const char*                                                fResource;
171 
172     sk_sp<skottie::Animation>                                  fAnimation;
173     std::unique_ptr<skottie_utils::CustomPropertyManager>      fPropManager;
174     std::vector<skottie_utils::CustomPropertyManager::PropKey> fColorProps,
175                                                                fTextProps;
176     size_t                                                     fColorIndex = 0;
177 
178     using INHERITED = skiagm::GM;
179 };
180 
181 DEF_GM(return new SkottieColorizeGM("color", "skottie/skottie_sample_search.json");)
182 DEF_GM(return new SkottieColorizeGM("text" , "skottie/skottie-text-animator-5.json");)
183 
184 class SkottieMultiFrameGM : public skiagm::GM {
185 public:
186 protected:
onShortName()187     SkString onShortName() override {
188         return SkString("skottie_multiframe");
189     }
190 
onISize()191     SkISize onISize() override {
192         return SkISize::Make(kSize, kSize);
193     }
194 
onOnceBeforeDraw()195     void onOnceBeforeDraw() override {
196         if (auto stream = GetResourceAsStream("skottie/skottie_sample_multiframe.json")) {
197             fAnimation = skottie::Animation::Builder()
198                             .setResourceProvider(sk_make_sp<MultiFrameResourceProvider>())
199                             .make(stream.get());
200             fAnimation->seek(0);
201         }
202     }
203 
onDraw(SkCanvas * canvas,SkString * errorMsg)204     DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
205         if (!fAnimation) {
206             *errorMsg = "No animation";
207             return DrawResult::kFail;
208         }
209 
210         auto dest = SkRect::MakeWH(kSize, kSize);
211         fAnimation->render(canvas, &dest);
212         return DrawResult::kOk;
213     }
214 
onAnimate(double nanos)215     bool onAnimate(double nanos) override {
216         if (!fAnimation) {
217             return false;
218         }
219 
220         const auto duration = fAnimation->duration();
221         fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
222         return true;
223     }
224 
225 private:
226     class MultiFrameResourceProvider final : public skresources::ResourceProvider {
227     public:
loadImageAsset(const char[],const char[],const char[]) const228         sk_sp<skresources::ImageAsset> loadImageAsset(const char[], const char[],
229                                                       const char[]) const override {
230             return skresources::MultiFrameImageAsset::Make(
231                         GetResourceAsData("images/flightAnim.gif"));
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 
242 DEF_GM(return new SkottieMultiFrameGM;)
243