xref: /aosp_15_r20/external/skia/modules/skottie/gm/ExternalProperties.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2017 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontMgr.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skottie/include/Skottie.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skottie/include/SkottieProperty.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skottie/utils/SkottieUtils.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skresources/include/SkResources.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skshaper/include/SkShaper_factory.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skshaper/utils/FactoryHelpers.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "tools/Resources.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker #include <cmath>
22*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
23*c8dee2aaSAndroid Build Coastguard Worker 
24*c8dee2aaSAndroid Build Coastguard Worker namespace {
25*c8dee2aaSAndroid Build Coastguard Worker 
26*c8dee2aaSAndroid Build Coastguard Worker static constexpr char kWebFontResource[] = "fonts/Roboto-Regular.ttf";
27*c8dee2aaSAndroid Build Coastguard Worker static constexpr char kSkottieResource[] = "skottie/skottie_sample_webfont.json";
28*c8dee2aaSAndroid Build Coastguard Worker 
29*c8dee2aaSAndroid Build Coastguard Worker // Mock web font loader which serves a single local font (checked in under resources/).
30*c8dee2aaSAndroid Build Coastguard Worker class FakeWebFontProvider final : public skresources::ResourceProvider {
31*c8dee2aaSAndroid Build Coastguard Worker public:
FakeWebFontProvider()32*c8dee2aaSAndroid Build Coastguard Worker     FakeWebFontProvider() : fTypeface(ToolUtils::CreateTypefaceFromResource(kWebFontResource)) {}
33*c8dee2aaSAndroid Build Coastguard Worker 
loadTypeface(const char[],const char[]) const34*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkTypeface> loadTypeface(const char[], const char[]) const override {
35*c8dee2aaSAndroid Build Coastguard Worker         return fTypeface;
36*c8dee2aaSAndroid Build Coastguard Worker     }
37*c8dee2aaSAndroid Build Coastguard Worker 
38*c8dee2aaSAndroid Build Coastguard Worker private:
39*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkTypeface> fTypeface;
40*c8dee2aaSAndroid Build Coastguard Worker 
41*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = skresources::ResourceProvider;
42*c8dee2aaSAndroid Build Coastguard Worker };
43*c8dee2aaSAndroid Build Coastguard Worker 
44*c8dee2aaSAndroid Build Coastguard Worker } // namespace
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker class SkottieExternalPropsGM : public skiagm::GM {
47*c8dee2aaSAndroid Build Coastguard Worker public:
48*c8dee2aaSAndroid Build Coastguard Worker protected:
getName() const49*c8dee2aaSAndroid Build Coastguard Worker     SkString getName() const override { return SkString("skottie_external_props"); }
50*c8dee2aaSAndroid Build Coastguard Worker 
getISize()51*c8dee2aaSAndroid Build Coastguard Worker     SkISize getISize() override { return SkISize::Make(kSize, kSize); }
52*c8dee2aaSAndroid Build Coastguard Worker 
onOnceBeforeDraw()53*c8dee2aaSAndroid Build Coastguard Worker     void onOnceBeforeDraw() override {
54*c8dee2aaSAndroid Build Coastguard Worker         if (auto stream = GetResourceAsStream(kSkottieResource)) {
55*c8dee2aaSAndroid Build Coastguard Worker             fPropManager = std::make_unique<skottie_utils::CustomPropertyManager>();
56*c8dee2aaSAndroid Build Coastguard Worker             fAnimation = skottie::Animation::Builder()
57*c8dee2aaSAndroid Build Coastguard Worker                             .setFontManager(ToolUtils::TestFontMgr())
58*c8dee2aaSAndroid Build Coastguard Worker                             .setResourceProvider(sk_make_sp<FakeWebFontProvider>())
59*c8dee2aaSAndroid Build Coastguard Worker                             .setPropertyObserver(fPropManager->getPropertyObserver())
60*c8dee2aaSAndroid Build Coastguard Worker                             .setTextShapingFactory(SkShapers::BestAvailable())
61*c8dee2aaSAndroid Build Coastguard Worker                             .make(stream.get());
62*c8dee2aaSAndroid Build Coastguard Worker         }
63*c8dee2aaSAndroid Build Coastguard Worker     }
64*c8dee2aaSAndroid Build Coastguard Worker 
onDraw(SkCanvas * canvas,SkString * errorMsg)65*c8dee2aaSAndroid Build Coastguard Worker     DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
66*c8dee2aaSAndroid Build Coastguard Worker         if (!fAnimation) {
67*c8dee2aaSAndroid Build Coastguard Worker             *errorMsg = "No animation";
68*c8dee2aaSAndroid Build Coastguard Worker             return DrawResult::kFail;
69*c8dee2aaSAndroid Build Coastguard Worker         }
70*c8dee2aaSAndroid Build Coastguard Worker 
71*c8dee2aaSAndroid Build Coastguard Worker         for (size_t i = 0; i < 4; ++i) {
72*c8dee2aaSAndroid Build Coastguard Worker             this->update_props(i);
73*c8dee2aaSAndroid Build Coastguard Worker             auto dest = SkRect::MakeWH(kSize/2, kSize/2).makeOffset(kSize * (i & 1) / 2,
74*c8dee2aaSAndroid Build Coastguard Worker                                                                     kSize * (i & 2) / 4);
75*c8dee2aaSAndroid Build Coastguard Worker             fAnimation->render(canvas, &dest);
76*c8dee2aaSAndroid Build Coastguard Worker         }
77*c8dee2aaSAndroid Build Coastguard Worker         return DrawResult::kOk;
78*c8dee2aaSAndroid Build Coastguard Worker     }
79*c8dee2aaSAndroid Build Coastguard Worker 
onAnimate(double nanos)80*c8dee2aaSAndroid Build Coastguard Worker     bool onAnimate(double nanos) override {
81*c8dee2aaSAndroid Build Coastguard Worker         if (!fAnimation) {
82*c8dee2aaSAndroid Build Coastguard Worker             return false;
83*c8dee2aaSAndroid Build Coastguard Worker         }
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker         const auto duration = fAnimation->duration();
86*c8dee2aaSAndroid Build Coastguard Worker         fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
87*c8dee2aaSAndroid Build Coastguard Worker         return true;
88*c8dee2aaSAndroid Build Coastguard Worker     }
89*c8dee2aaSAndroid Build Coastguard Worker 
90*c8dee2aaSAndroid Build Coastguard Worker private:
update_props(size_t i)91*c8dee2aaSAndroid Build Coastguard Worker     void update_props(size_t i) {
92*c8dee2aaSAndroid Build Coastguard Worker 
93*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(i < 4);
94*c8dee2aaSAndroid Build Coastguard Worker         if (!i) {
95*c8dee2aaSAndroid Build Coastguard Worker             return;
96*c8dee2aaSAndroid Build Coastguard Worker         }
97*c8dee2aaSAndroid Build Coastguard Worker 
98*c8dee2aaSAndroid Build Coastguard Worker         static constexpr struct {
99*c8dee2aaSAndroid Build Coastguard Worker             const char* txt_string;
100*c8dee2aaSAndroid Build Coastguard Worker             SkColor     txt_color,
101*c8dee2aaSAndroid Build Coastguard Worker                         solid_color;
102*c8dee2aaSAndroid Build Coastguard Worker             float       transform_scale;
103*c8dee2aaSAndroid Build Coastguard Worker         } gTests[] = {
104*c8dee2aaSAndroid Build Coastguard Worker             { "update #1", SK_ColorRED    , SK_ColorYELLOW, 100.f },
105*c8dee2aaSAndroid Build Coastguard Worker             { "update #2", SK_ColorGREEN  , SK_ColorBLUE  ,  50.f },
106*c8dee2aaSAndroid Build Coastguard Worker             { "update #3", SK_ColorMAGENTA, SK_ColorCYAN  , 150.f },
107*c8dee2aaSAndroid Build Coastguard Worker         };
108*c8dee2aaSAndroid Build Coastguard Worker 
109*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(i - 1 < std::size(gTests));
110*c8dee2aaSAndroid Build Coastguard Worker         const auto& tst = gTests[i - 1];
111*c8dee2aaSAndroid Build Coastguard Worker 
112*c8dee2aaSAndroid Build Coastguard Worker         for (const auto& prop : fPropManager->getColorProps()) {
113*c8dee2aaSAndroid Build Coastguard Worker             SkAssertResult(fPropManager->setColor(prop, tst.solid_color));
114*c8dee2aaSAndroid Build Coastguard Worker         }
115*c8dee2aaSAndroid Build Coastguard Worker 
116*c8dee2aaSAndroid Build Coastguard Worker         for (const auto& prop : fPropManager->getTransformProps()) {
117*c8dee2aaSAndroid Build Coastguard Worker             auto t = fPropManager->getTransform(prop);
118*c8dee2aaSAndroid Build Coastguard Worker             t.fScale = {tst.transform_scale, tst.transform_scale};
119*c8dee2aaSAndroid Build Coastguard Worker             SkAssertResult(fPropManager->setTransform(prop, t));
120*c8dee2aaSAndroid Build Coastguard Worker         }
121*c8dee2aaSAndroid Build Coastguard Worker 
122*c8dee2aaSAndroid Build Coastguard Worker         for (const auto& prop : fPropManager->getTextProps()) {
123*c8dee2aaSAndroid Build Coastguard Worker             auto txt = fPropManager->getText(prop);
124*c8dee2aaSAndroid Build Coastguard Worker             txt.fText.set(tst.txt_string);
125*c8dee2aaSAndroid Build Coastguard Worker             txt.fFillColor = tst.txt_color;
126*c8dee2aaSAndroid Build Coastguard Worker             SkAssertResult(fPropManager->setText(prop, txt));
127*c8dee2aaSAndroid Build Coastguard Worker         }
128*c8dee2aaSAndroid Build Coastguard Worker     }
129*c8dee2aaSAndroid Build Coastguard Worker 
130*c8dee2aaSAndroid Build Coastguard Worker     inline static constexpr SkScalar kSize = 800;
131*c8dee2aaSAndroid Build Coastguard Worker 
132*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<skottie::Animation>                             fAnimation;
133*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<skottie_utils::CustomPropertyManager> fPropManager;
134*c8dee2aaSAndroid Build Coastguard Worker 
135*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = skiagm::GM;
136*c8dee2aaSAndroid Build Coastguard Worker };
137*c8dee2aaSAndroid Build Coastguard Worker 
138*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new SkottieExternalPropsGM;)
139