1 /* 2 * Copyright 2018 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 "include/core/SkCanvas.h" 9 #include "include/core/SkColorFilter.h" 10 #include "include/core/SkColorPriv.h" 11 #include "include/core/SkFont.h" 12 #include "include/core/SkImage.h" 13 #include "include/core/SkTime.h" 14 #include "include/core/SkTypeface.h" 15 #include "include/utils/SkRandom.h" 16 #include "samplecode/Sample.h" 17 #include "tools/timer/Timer.h" 18 19 // Create an animation of a bunch of letters that rotate in place. This is intended to stress 20 // the glyph atlas and test that we don't see corruption or bad slowdowns. 21 class FlutterAnimateView : public Sample { 22 public: FlutterAnimateView()23 FlutterAnimateView() : fCurrTime(0), fResetTime(0) {} 24 25 protected: onOnceBeforeDraw()26 void onOnceBeforeDraw() override { 27 fTypeface = SkTypeface::MakeFromFile("/skimages/samplefont.ttf"); 28 initChars(); 29 } 30 name()31 SkString name() override { return SkString("FlutterAnimate"); } 32 onDrawContent(SkCanvas * canvas)33 void onDrawContent(SkCanvas* canvas) override { 34 SkFont font(fTypeface, 50); 35 SkPaint paint; 36 37 // rough center of each glyph 38 static constexpr auto kMidX = 35; 39 static constexpr auto kMidY = 50; 40 41 canvas->clear(SK_ColorWHITE); 42 for (int i = 0; i < kNumChars; ++i) { 43 canvas->save(); 44 double rot = SkScalarInterp(fChars[i].fStartRotation, fChars[i].fEndRotation, 45 fCurrTime/kDuration); 46 canvas->translate(fChars[i].fPosition.fX + kMidX, fChars[i].fPosition.fY - kMidY); 47 canvas->rotate(SkRadiansToDegrees(rot)); 48 canvas->translate(-35,+50); 49 canvas->drawString(fChars[i].fChar, 0, 0, font, paint); 50 canvas->restore(); 51 } 52 } 53 onAnimate(double nanos)54 bool onAnimate(double nanos) override { 55 fCurrTime = 1e-9 * nanos - fResetTime; 56 if (fCurrTime > kDuration) { 57 this->initChars(); 58 fResetTime = 1e-9 * nanos; 59 fCurrTime = 0; 60 } 61 62 return true; 63 } 64 65 private: initChars()66 void initChars() { 67 for (int i = 0; i < kNumChars; ++i) { 68 char c = fRand.nextULessThan(26) + 65; 69 fChars[i].fChar[0] = c; 70 fChars[i].fChar[1] = '\0'; 71 fChars[i].fPosition = SkPoint::Make(fRand.nextF()*748 + 10, fRand.nextF()*1004 + 10); 72 fChars[i].fStartRotation = fRand.nextF(); 73 fChars[i].fEndRotation = fRand.nextF() * 20 - 10; 74 } 75 } 76 77 inline static constexpr double kDuration = 5.0; 78 double fCurrTime; 79 double fResetTime; 80 SkRandom fRand; 81 82 struct AnimatedChar { 83 char fChar[2]; 84 SkPoint fPosition; 85 SkScalar fStartRotation; 86 SkScalar fEndRotation; 87 }; 88 sk_sp<SkTypeface> fTypeface; 89 inline static constexpr int kNumChars = 40; 90 AnimatedChar fChars[kNumChars]; 91 92 using INHERITED = Sample; 93 }; 94 95 ////////////////////////////////////////////////////////////////////////////// 96 97 DEF_SAMPLE( return new FlutterAnimateView(); ) 98