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 "gm.h" 9 #include "sk_tool_utils.h" 10 11 namespace skiagm { 12 13 // This GM exercises HighQuality anisotropic filtering. 14 class AnisotropicGM : public GM { 15 public: AnisotropicGM()16 AnisotropicGM() : fFilterQuality(kHigh_SkFilterQuality) { 17 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); 18 } 19 20 protected: 21 onShortName()22 SkString onShortName() override { return SkString("anisotropic_hq"); } 23 onISize()24 SkISize onISize() override { 25 return SkISize::Make(2*kImageSize + 3*kSpacer, 26 kNumVertImages*kImageSize + (kNumVertImages+1)*kSpacer); 27 } 28 29 // Create an image consisting of lines radiating from its center onOnceBeforeDraw()30 void onOnceBeforeDraw() override { 31 constexpr int kNumLines = 100; 32 constexpr SkScalar kAngleStep = 360.0f / kNumLines; 33 constexpr int kInnerOffset = 10; 34 35 fBM.allocN32Pixels(kImageSize, kImageSize, true); 36 37 SkCanvas canvas(fBM); 38 39 canvas.clear(SK_ColorWHITE); 40 41 SkPaint p; 42 p.setAntiAlias(true); 43 44 SkScalar angle = 0.0f, sin, cos; 45 46 canvas.translate(kImageSize/2.0f, kImageSize/2.0f); 47 for (int i = 0; i < kNumLines; ++i, angle += kAngleStep) { 48 sin = SkScalarSinCos(angle, &cos); 49 canvas.drawLine(cos * kInnerOffset, sin * kInnerOffset, 50 cos * kImageSize/2, sin * kImageSize/2, p); 51 } 52 } 53 draw(SkCanvas * canvas,int x,int y,int xSize,int ySize)54 void draw(SkCanvas* canvas, int x, int y, int xSize, int ySize) { 55 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y), 56 SkIntToScalar(xSize), SkIntToScalar(ySize)); 57 SkPaint p; 58 p.setFilterQuality(fFilterQuality); 59 canvas->drawBitmapRect(fBM, r, &p); 60 } 61 onDraw(SkCanvas * canvas)62 void onDraw(SkCanvas* canvas) override { 63 SkScalar gScales[] = { 0.9f, 0.8f, 0.75f, 0.6f, 0.5f, 0.4f, 0.25f, 0.2f, 0.1f }; 64 65 SkASSERT(kNumVertImages-1 == (int)SK_ARRAY_COUNT(gScales)/2); 66 67 // Minimize vertically 68 for (int i = 0; i < (int)SK_ARRAY_COUNT(gScales); ++i) { 69 int height = SkScalarFloorToInt(fBM.height() * gScales[i]); 70 71 int yOff; 72 if (i <= (int)SK_ARRAY_COUNT(gScales)/2) { 73 yOff = kSpacer + i * (fBM.height() + kSpacer); 74 } else { 75 // Position the more highly squashed images with their less squashed counterparts 76 yOff = (SK_ARRAY_COUNT(gScales) - i) * (fBM.height() + kSpacer) - height; 77 } 78 79 this->draw(canvas, kSpacer, yOff, fBM.width(), height); 80 } 81 82 // Minimize horizontally 83 for (int i = 0; i < (int)SK_ARRAY_COUNT(gScales); ++i) { 84 int width = SkScalarFloorToInt(fBM.width() * gScales[i]); 85 86 int xOff, yOff; 87 if (i <= (int)SK_ARRAY_COUNT(gScales)/2) { 88 xOff = fBM.width() + 2*kSpacer; 89 yOff = kSpacer + i * (fBM.height() + kSpacer); 90 } else { 91 // Position the more highly squashed images with their less squashed counterparts 92 xOff = fBM.width() + 2*kSpacer + fBM.width() - width; 93 yOff = kSpacer + (SK_ARRAY_COUNT(gScales) - i - 1) * (fBM.height() + kSpacer); 94 } 95 96 this->draw(canvas, xOff, yOff, width, fBM.height()); 97 } 98 } 99 100 private: 101 static constexpr int kImageSize = 256; 102 static constexpr int kSpacer = 10; 103 static constexpr int kNumVertImages = 5; 104 105 SkBitmap fBM; 106 SkFilterQuality fFilterQuality; 107 108 typedef GM INHERITED; 109 }; 110 111 ////////////////////////////////////////////////////////////////////////////// 112 113 DEF_GM(return new AnisotropicGM;) 114 } 115