blob: 60b62ff0ebc2da5fe94b97fdf3f7b5ded34bffd1 [file] [log] [blame]
robertphillipsf5ac9722015-04-14 08:19:01 -07001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
Ben Wagnerd1701ba2019-04-30 13:44:26 -04009#include "include/core/SkCanvas.h"
10#include "include/core/SkColor.h"
Mike Reed6dbeac52021-01-13 13:14:23 -050011#include "include/core/SkImage.h"
Ben Wagnerd1701ba2019-04-30 13:44:26 -040012#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"
Mike Reed18aeb572021-01-19 17:58:25 -050017#include "include/core/SkSurface.h"
robertphillipsf5ac9722015-04-14 08:19:01 -070018
19namespace skiagm {
20
21// This GM exercises HighQuality anisotropic filtering.
22class AnisotropicGM : public GM {
23public:
Mike Reedf3ac2af2021-02-05 12:55:38 -050024 AnisotropicGM() : fSampling(SkCubicResampler::Mitchell()) {
Mike Kleind46dce32018-08-16 10:17:03 -040025 this->setBGColor(0xFFCCCCCC);
robertphillipsf5ac9722015-04-14 08:19:01 -070026 }
27
28protected:
29
30 SkString onShortName() override { return SkString("anisotropic_hq"); }
31
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
38 void onOnceBeforeDraw() override {
mtkleindbfd7ab2016-09-01 11:24:54 -070039 constexpr int kNumLines = 100;
40 constexpr SkScalar kAngleStep = 360.0f / kNumLines;
41 constexpr int kInnerOffset = 10;
robertphillipsf5ac9722015-04-14 08:19:01 -070042
Mike Reed18aeb572021-01-19 17:58:25 -050043 auto info = SkImageInfo::MakeN32(kImageSize, kImageSize, kOpaque_SkAlphaType);
44 auto surf = SkSurface::MakeRaster(info);
45 auto canvas = surf->getCanvas();
robertphillipsf5ac9722015-04-14 08:19:01 -070046
Mike Reed18aeb572021-01-19 17:58:25 -050047 canvas->clear(SK_ColorWHITE);
robertphillipsf5ac9722015-04-14 08:19:01 -070048
49 SkPaint p;
50 p.setAntiAlias(true);
51
52 SkScalar angle = 0.0f, sin, cos;
53
Mike Reed18aeb572021-01-19 17:58:25 -050054 canvas->translate(kImageSize/2.0f, kImageSize/2.0f);
robertphillipsf5ac9722015-04-14 08:19:01 -070055 for (int i = 0; i < kNumLines; ++i, angle += kAngleStep) {
Brian Osman4428f2c2019-04-02 10:59:28 -040056 sin = SkScalarSin(angle);
57 cos = SkScalarCos(angle);
Mike Reed18aeb572021-01-19 17:58:25 -050058 canvas->drawLine(cos * kInnerOffset, sin * kInnerOffset,
59 cos * kImageSize/2, sin * kImageSize/2, p);
robertphillipsf5ac9722015-04-14 08:19:01 -070060 }
Mike Reed18aeb572021-01-19 17:58:25 -050061 fImage = surf->makeImageSnapshot();
robertphillipsf5ac9722015-04-14 08:19:01 -070062 }
63
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));
Mike Reed34c56a52021-01-22 15:26:41 -050067 canvas->drawImageRect(fImage, r, fSampling);
robertphillipsf5ac9722015-04-14 08:19:01 -070068 }
69
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 };
halcanary9d524f22016-03-29 09:03:52 -070072
robertphillipsf5ac9722015-04-14 08:19:01 -070073 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) {
Mike Reed18aeb572021-01-19 17:58:25 -050077 int height = SkScalarFloorToInt(fImage->height() * gScales[i]);
robertphillipsf5ac9722015-04-14 08:19:01 -070078
79 int yOff;
80 if (i <= (int)SK_ARRAY_COUNT(gScales)/2) {
Mike Reed18aeb572021-01-19 17:58:25 -050081 yOff = kSpacer + i * (fImage->height() + kSpacer);
robertphillipsf5ac9722015-04-14 08:19:01 -070082 } else {
83 // Position the more highly squashed images with their less squashed counterparts
Mike Reed18aeb572021-01-19 17:58:25 -050084 yOff = (SK_ARRAY_COUNT(gScales) - i) * (fImage->height() + kSpacer) - height;
robertphillipsf5ac9722015-04-14 08:19:01 -070085 }
86
Mike Reed18aeb572021-01-19 17:58:25 -050087 this->draw(canvas, kSpacer, yOff, fImage->width(), height);
robertphillipsf5ac9722015-04-14 08:19:01 -070088 }
89
90 // Minimize horizontally
91 for (int i = 0; i < (int)SK_ARRAY_COUNT(gScales); ++i) {
Mike Reed18aeb572021-01-19 17:58:25 -050092 int width = SkScalarFloorToInt(fImage->width() * gScales[i]);
robertphillipsf5ac9722015-04-14 08:19:01 -070093
94 int xOff, yOff;
95 if (i <= (int)SK_ARRAY_COUNT(gScales)/2) {
Mike Reed18aeb572021-01-19 17:58:25 -050096 xOff = fImage->width() + 2*kSpacer;
97 yOff = kSpacer + i * (fImage->height() + kSpacer);
robertphillipsf5ac9722015-04-14 08:19:01 -070098 } else {
99 // Position the more highly squashed images with their less squashed counterparts
Mike Reed18aeb572021-01-19 17:58:25 -0500100 xOff = fImage->width() + 2*kSpacer + fImage->width() - width;
101 yOff = kSpacer + (SK_ARRAY_COUNT(gScales) - i - 1) * (fImage->height() + kSpacer);
robertphillipsf5ac9722015-04-14 08:19:01 -0700102 }
103
Mike Reed18aeb572021-01-19 17:58:25 -0500104 this->draw(canvas, xOff, yOff, width, fImage->height());
robertphillipsf5ac9722015-04-14 08:19:01 -0700105 }
106 }
107
108private:
Brian Salomon9fa47cc2021-10-08 18:48:26 -0400109 inline static constexpr int kImageSize = 256;
110 inline static constexpr int kSpacer = 10;
111 inline static constexpr int kNumVertImages = 5;
robertphillipsf5ac9722015-04-14 08:19:01 -0700112
Mike Reed18aeb572021-01-19 17:58:25 -0500113 sk_sp<SkImage> fImage;
114 SkSamplingOptions fSampling;
robertphillipsf5ac9722015-04-14 08:19:01 -0700115
John Stiles7571f9e2020-09-02 22:42:33 -0400116 using INHERITED = GM;
robertphillipsf5ac9722015-04-14 08:19:01 -0700117};
118
119//////////////////////////////////////////////////////////////////////////////
120
halcanary385fe4d2015-08-26 13:07:48 -0700121DEF_GM(return new AnisotropicGM;)
John Stilesa6841be2020-08-06 14:11:56 -0400122} // namespace skiagm