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 // Dummy 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() : fFontData(GetResourceAsData(kWebFontResource)) {} 29 loadFont(const char[],const char[]) const30 sk_sp<SkData> loadFont(const char[], const char[]) const override { 31 return fFontData; 32 } 33 34 private: 35 sk_sp<SkData> fFontData; 36 37 using INHERITED = skresources::ResourceProvider; 38 }; 39 40 } // namespace 41 42 class SkottieExternalPropsGM : public skiagm::GM { 43 public: 44 protected: onShortName()45 SkString onShortName() override { 46 return SkString("skottie_external_props"); 47 } 48 onISize()49 SkISize onISize() override { 50 return SkISize::Make(kSize, kSize); 51 } 52 onOnceBeforeDraw()53 void onOnceBeforeDraw() override { 54 if (auto stream = GetResourceAsStream(kSkottieResource)) { 55 fPropManager = std::make_unique<skottie_utils::CustomPropertyManager>(); 56 fAnimation = skottie::Animation::Builder() 57 .setResourceProvider(sk_make_sp<FakeWebFontProvider>()) 58 .setPropertyObserver(fPropManager->getPropertyObserver()) 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 for (size_t i = 0; i < 4; ++i) { 70 this->update_props(i); 71 auto dest = SkRect::MakeWH(kSize/2, kSize/2).makeOffset(kSize * (i & 1) / 2, 72 kSize * (i & 2) / 4); 73 fAnimation->render(canvas, &dest); 74 } 75 return DrawResult::kOk; 76 } 77 onAnimate(double nanos)78 bool onAnimate(double nanos) override { 79 if (!fAnimation) { 80 return false; 81 } 82 83 const auto duration = fAnimation->duration(); 84 fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration); 85 return true; 86 } 87 88 private: update_props(size_t i)89 void update_props(size_t i) { 90 91 SkASSERT(i < 4); 92 if (!i) { 93 return; 94 } 95 96 static constexpr struct { 97 const char* txt_string; 98 SkColor txt_color, 99 solid_color; 100 float transform_scale; 101 } gTests[] = { 102 { "update #1", SK_ColorRED , SK_ColorYELLOW, 100.f }, 103 { "update #2", SK_ColorGREEN , SK_ColorBLUE , 50.f }, 104 { "update #3", SK_ColorMAGENTA, SK_ColorCYAN , 150.f }, 105 }; 106 107 SkASSERT(i - 1 < SK_ARRAY_COUNT(gTests)); 108 const auto& tst = gTests[i - 1]; 109 110 for (const auto& prop : fPropManager->getColorProps()) { 111 SkAssertResult(fPropManager->setColor(prop, tst.solid_color)); 112 } 113 114 for (const auto& prop : fPropManager->getTransformProps()) { 115 auto t = fPropManager->getTransform(prop); 116 t.fScale = {tst.transform_scale, tst.transform_scale}; 117 SkAssertResult(fPropManager->setTransform(prop, t)); 118 } 119 120 for (const auto& prop : fPropManager->getTextProps()) { 121 auto txt = fPropManager->getText(prop); 122 txt.fText.set(tst.txt_string); 123 txt.fFillColor = tst.txt_color; 124 SkAssertResult(fPropManager->setText(prop, txt)); 125 } 126 } 127 128 static constexpr SkScalar kSize = 800; 129 130 sk_sp<skottie::Animation> fAnimation; 131 std::unique_ptr<skottie_utils::CustomPropertyManager> fPropManager; 132 133 using INHERITED = skiagm::GM; 134 }; 135 136 DEF_GM(return new SkottieExternalPropsGM;) 137