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