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