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