1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 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 "src/utils/SkUTF.h" 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci#if SK_SUPPORT_GPU 20cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 21cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 22cb93a386Sopenharmony_ci#endif 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ciSkRandom gRand; 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_cistatic void DrawTheText(SkCanvas* canvas, const char text[], size_t length, SkScalar x, SkScalar y, 27cb93a386Sopenharmony_ci const SkFont& font, const SkPaint& paint) { 28cb93a386Sopenharmony_ci SkFont f(font); 29cb93a386Sopenharmony_ci f.setSubpixel(true); 30cb93a386Sopenharmony_ci canvas->drawSimpleText(text, length, SkTextEncoding::kUTF8, x, y, f, paint); 31cb93a386Sopenharmony_ci} 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci// This sample demonstrates the cache behavior of bitmap vs. distance field text 34cb93a386Sopenharmony_ci// It renders variously sized text with an animated scale and rotation. 35cb93a386Sopenharmony_ci// Specifically one should: 36cb93a386Sopenharmony_ci// use 'D' to toggle between bitmap and distance field fonts 37cb93a386Sopenharmony_ci// use '2' to toggle between scaling the image by 2x 38cb93a386Sopenharmony_ci// -- this feature boosts the rendering out of the small point-size 39cb93a386Sopenharmony_ci// SDF-text special case (which falls back to bitmap fonts for small points) 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ciclass AnimatedTextView : public Sample { 42cb93a386Sopenharmony_ci float fScale = 1; 43cb93a386Sopenharmony_ci float fScaleInc = 0.1f; 44cb93a386Sopenharmony_ci float fRotation = 0; 45cb93a386Sopenharmony_ci int fSizeScale = 1; 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci SkString name() override { return SkString("AnimatedText"); } 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci bool onChar(SkUnichar uni) override { 50cb93a386Sopenharmony_ci if ('2' == uni) { 51cb93a386Sopenharmony_ci if (fSizeScale == 2) { 52cb93a386Sopenharmony_ci fSizeScale = 1; 53cb93a386Sopenharmony_ci } else { 54cb93a386Sopenharmony_ci fSizeScale = 2; 55cb93a386Sopenharmony_ci } 56cb93a386Sopenharmony_ci return true; 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci return false; 59cb93a386Sopenharmony_ci } 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci void onDrawContent(SkCanvas* canvas) override { 62cb93a386Sopenharmony_ci SkFont font(SkTypeface::MakeFromFile("/skimages/samplefont.ttf")); 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci SkPaint paint; 65cb93a386Sopenharmony_ci paint.setAntiAlias(true); 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ci canvas->save(); 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci#if SK_SUPPORT_GPU 70cb93a386Sopenharmony_ci auto direct = GrAsDirectContext(canvas->recordingContext()); 71cb93a386Sopenharmony_ci if (direct) { 72cb93a386Sopenharmony_ci SkSamplingOptions sampling(SkFilterMode::kLinear, SkMipmapMode::kNearest); 73cb93a386Sopenharmony_ci sk_sp<SkImage> image = direct->priv().testingOnly_getFontAtlasImage( 74cb93a386Sopenharmony_ci GrMaskFormat::kA8_GrMaskFormat); 75cb93a386Sopenharmony_ci const SkRect rect = SkRect::MakeXYWH(512.0f, 10.0f, 512.0f, 512.0f); 76cb93a386Sopenharmony_ci canvas->drawImageRect(image.get(), rect, rect, sampling, &paint, 77cb93a386Sopenharmony_ci SkCanvas::kFast_SrcRectConstraint); 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci#endif 80cb93a386Sopenharmony_ci canvas->translate(180, 180); 81cb93a386Sopenharmony_ci canvas->rotate(fRotation); 82cb93a386Sopenharmony_ci canvas->scale(fScale, fScale); 83cb93a386Sopenharmony_ci canvas->translate(-180, -180); 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci const char* text = "Hamburgefons"; 86cb93a386Sopenharmony_ci size_t length = strlen(text); 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_ci SkScalar y = SkIntToScalar(0); 89cb93a386Sopenharmony_ci for (int i = 12; i <= 26; i++) { 90cb93a386Sopenharmony_ci font.setSize(SkIntToScalar(i*fSizeScale)); 91cb93a386Sopenharmony_ci y += font.getSpacing(); 92cb93a386Sopenharmony_ci DrawTheText(canvas, text, length, SkIntToScalar(110), y, font, paint); 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci canvas->restore(); 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci font.setSize(16); 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci bool onAnimate(double nanos) override { 100cb93a386Sopenharmony_ci // TODO: use nanos 101cb93a386Sopenharmony_ci // We add noise to the scale and rotation animations to 102cb93a386Sopenharmony_ci // keep the font atlas from falling into a steady state 103cb93a386Sopenharmony_ci fRotation += (1.0f + gRand.nextRangeF(-0.1f, 0.1f)); 104cb93a386Sopenharmony_ci fScale += (fScaleInc + gRand.nextRangeF(-0.025f, 0.025f)); 105cb93a386Sopenharmony_ci if (fScale >= 2.0f) { 106cb93a386Sopenharmony_ci fScaleInc = -0.1f; 107cb93a386Sopenharmony_ci } else if (fScale <= 1.0f) { 108cb93a386Sopenharmony_ci fScaleInc = 0.1f; 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci return true; 111cb93a386Sopenharmony_ci } 112cb93a386Sopenharmony_ci}; 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ciDEF_SAMPLE( return new AnimatedTextView(); ) 115