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