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     using INHERITED = GM;
119 };
120 
121 //////////////////////////////////////////////////////////////////////////////
122 
123 DEF_GM(return new AnisotropicGM;)
124 }  // namespace skiagm
125