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