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