1/*
2 * Copyright 2014 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 "SkBlurImageFilter.h"
9#include "SkColor.h"
10#include "SkDisplacementMapEffect.h"
11#include "SkDropShadowImageFilter.h"
12#include "SkGradientShader.h"
13#include "SkImage.h"
14#include "SkImageSource.h"
15#include "SkLightingImageFilter.h"
16#include "SkMorphologyImageFilter.h"
17#include "SkOffsetImageFilter.h"
18#include "SkPaintImageFilter.h"
19#include "SkPerlinNoiseShader.h"
20#include "SkPoint3.h"
21#include "SkScalar.h"
22#include "SkSurface.h"
23#include "gm.h"
24#include "sk_tool_utils.h"
25
26#define RESIZE_FACTOR SkIntToScalar(4)
27
28static sk_sp<SkImage> make_gradient_circle(int width, int height) {
29    SkScalar x = SkIntToScalar(width / 2);
30    SkScalar y = SkIntToScalar(height / 2);
31    SkScalar radius = SkMinScalar(x, y) * 4 / 5;
32    sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(width, height));
33    SkCanvas* canvas = surface->getCanvas();
34    canvas->clear(0x00000000);
35    SkColor colors[2];
36    colors[0] = SK_ColorWHITE;
37    colors[1] = SK_ColorBLACK;
38    SkPaint paint;
39    paint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(x, y), radius, colors, nullptr,
40        2, SkShader::kClamp_TileMode));
41    canvas->drawCircle(x, y, radius, paint);
42
43    return surface->makeImageSnapshot();
44}
45
46
47namespace skiagm {
48
49class ImageFiltersScaledGM : public GM {
50public:
51    ImageFiltersScaledGM() {
52        this->setBGColor(0x00000000);
53    }
54
55protected:
56
57    SkString onShortName() override {
58        return SkString("imagefiltersscaled");
59    }
60
61    SkISize onISize() override {
62        return SkISize::Make(1428, 500);
63    }
64
65    void onOnceBeforeDraw() override {
66        fCheckerboard = SkImage::MakeFromBitmap(
67            sk_tool_utils::create_checkerboard_bitmap(64, 64, 0xFFA0A0A0, 0xFF404040, 8));
68        fGradientCircle = make_gradient_circle(64, 64);
69    }
70
71    void onDraw(SkCanvas* canvas) override {
72        canvas->clear(SK_ColorBLACK);
73
74        sk_sp<SkImageFilter> gradient(SkImageSource::Make(fGradientCircle));
75        sk_sp<SkImageFilter> checkerboard(SkImageSource::Make(fCheckerboard));
76
77        SkPaint noisePaint;
78        noisePaint.setShader(SkPerlinNoiseShader::MakeFractalNoise(SkDoubleToScalar(0.1),
79                                                                   SkDoubleToScalar(0.05), 1, 0));
80
81        SkPoint3 pointLocation = SkPoint3::Make(0, 0, SkIntToScalar(10));
82        SkPoint3 spotLocation = SkPoint3::Make(SkIntToScalar(-10),
83                                               SkIntToScalar(-10),
84                                               SkIntToScalar(20));
85        SkPoint3 spotTarget = SkPoint3::Make(SkIntToScalar(40), SkIntToScalar(40), 0);
86        SkScalar spotExponent = SK_Scalar1;
87        SkScalar cutoffAngle = SkIntToScalar(15);
88        SkScalar kd = SkIntToScalar(2);
89        SkScalar surfaceScale = SkIntToScalar(1);
90        SkColor white(0xFFFFFFFF);
91        SkMatrix resizeMatrix;
92        resizeMatrix.setScale(RESIZE_FACTOR, RESIZE_FACTOR);
93
94        sk_sp<SkImageFilter> filters[] = {
95            SkBlurImageFilter::Make(SkIntToScalar(4), SkIntToScalar(4), nullptr),
96            SkDropShadowImageFilter::Make(
97                                    SkIntToScalar(5), SkIntToScalar(10),
98                                    SkIntToScalar(3), SkIntToScalar(3), SK_ColorYELLOW,
99                                    SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
100                                    nullptr),
101            SkDisplacementMapEffect::Make(SkDisplacementMapEffect::kR_ChannelSelectorType,
102                                          SkDisplacementMapEffect::kR_ChannelSelectorType,
103                                          SkIntToScalar(12),
104                                          std::move(gradient),
105                                          checkerboard),
106            SkDilateImageFilter::Make(1, 1, checkerboard),
107            SkErodeImageFilter::Make(1, 1, checkerboard),
108            SkOffsetImageFilter::Make(SkIntToScalar(32), 0, nullptr),
109            SkImageFilter::MakeMatrixFilter(resizeMatrix, kNone_SkFilterQuality, nullptr),
110            SkPaintImageFilter::Make(noisePaint),
111            SkLightingImageFilter::MakePointLitDiffuse(pointLocation, white, surfaceScale, kd,
112                                                       nullptr),
113            SkLightingImageFilter::MakeSpotLitDiffuse(spotLocation, spotTarget, spotExponent,
114                                                      cutoffAngle, white, surfaceScale, kd,
115                                                      nullptr),
116        };
117
118        SkVector scales[] = {
119            SkVector::Make(SkScalarInvert(2), SkScalarInvert(2)),
120            SkVector::Make(SkIntToScalar(1), SkIntToScalar(1)),
121            SkVector::Make(SkIntToScalar(1), SkIntToScalar(2)),
122            SkVector::Make(SkIntToScalar(2), SkIntToScalar(1)),
123            SkVector::Make(SkIntToScalar(2), SkIntToScalar(2)),
124        };
125
126        SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
127        SkScalar margin = SkIntToScalar(16);
128        SkRect bounds = r;
129        bounds.outset(margin, margin);
130
131        for (size_t j = 0; j < SK_ARRAY_COUNT(scales); ++j) {
132            canvas->save();
133            for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
134                SkPaint paint;
135                paint.setColor(SK_ColorBLUE);
136                paint.setImageFilter(filters[i]);
137                paint.setAntiAlias(true);
138                canvas->save();
139                canvas->scale(scales[j].fX, scales[j].fY);
140                canvas->clipRect(r);
141                if (5 == i) {
142                    canvas->translate(SkIntToScalar(-32), 0);
143                } else if (6 == i) {
144                    canvas->scale(SkScalarInvert(RESIZE_FACTOR),
145                                  SkScalarInvert(RESIZE_FACTOR));
146                }
147                canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint);
148                canvas->restore();
149                canvas->translate(r.width() * scales[j].fX + margin, 0);
150            }
151            canvas->restore();
152            canvas->translate(0, r.height() * scales[j].fY + margin);
153        }
154    }
155
156private:
157    sk_sp<SkImage> fCheckerboard, fGradientCircle;
158
159    typedef GM INHERITED;
160};
161
162//////////////////////////////////////////////////////////////////////////////
163
164DEF_GM(return new ImageFiltersScaledGM;)
165}
166