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