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 "gm.h"
9 #include "SkCanvas.h"
10 #include "SkColorFilter.h"
11 #include "SkColorPriv.h"
12 #include "SkShader.h"
13 
14 #include "SkBlurImageFilter.h"
15 #include "SkColorMatrixFilter.h"
16 #include "SkDisplacementMapEffect.h"
17 #include "SkDropShadowImageFilter.h"
18 #include "SkGradientShader.h"
19 #include "SkImageSource.h"
20 #include "SkMorphologyImageFilter.h"
21 #include "SkColorFilterImageFilter.h"
22 #include "SkLightingImageFilter.h"
23 #include "SkMergeImageFilter.h"
24 #include "SkOffsetImageFilter.h"
25 #include "SkPoint3.h"
26 #include "SkSurface.h"
27 
28 ///////////////////////////////////////////////////////////////////////////////
29 
30 class ImageFiltersCropExpandGM : public skiagm::GM {
31 public:
ImageFiltersCropExpandGM()32     ImageFiltersCropExpandGM () {}
33 
34 protected:
35 
onShortName()36     SkString onShortName() override {
37         return SkString("imagefilterscropexpand");
38     }
39 
onISize()40     SkISize onISize() override { return SkISize::Make(730, 650); }
41 
onDraw(SkCanvas * canvas)42     void onDraw(SkCanvas* canvas) override {
43         SkAutoTUnref<SkColorFilter> cf(
44             SkColorFilter::CreateModeFilter(SK_ColorBLUE, SkXfermode::kSrcIn_Mode));
45         SkImageFilter::CropRect cropRect(
46             SkRect::Make(SkIRect::MakeXYWH(10, 10, 44, 44)),
47             SkImageFilter::CropRect::kHasAll_CropEdge);
48 
49         SkAutoTUnref<SkImage> gradientCircle(MakeGradientCircle(64, 64));
50         SkBitmap checkerboard;
51         MakeCheckerboard(&checkerboard);
52 
53         SkAutoTUnref<SkImageFilter> gradientCircleSource(
54             SkImageSource::Create(gradientCircle));
55         SkAutoTUnref<SkImageFilter> noopCropped(
56             SkOffsetImageFilter::Create(0, 0, nullptr, &cropRect));
57         SkScalar sk255 = SkIntToScalar(255);
58         SkScalar matrix[20] = { 1, 0, 0, 0, 0,
59                                 0, 1, 0, 0, sk255,
60                                 0, 0, 1, 0, 0,
61                                 0, 0, 0, 0, sk255 };
62         SkAutoTUnref<SkColorFilter> cfAlphaTrans(SkColorMatrixFilter::Create(matrix));
63 
64         SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
65         SkScalar MARGIN = SkIntToScalar(12);
66 
67         SkPoint3 pointLocation = SkPoint3::Make(0, 0, SkIntToScalar(10));
68         SkScalar kd = SkIntToScalar(2);
69         SkScalar surfaceScale = SkIntToScalar(1);
70         SkIRect bounds;
71         r.roundOut(&bounds);
72 
73         SkPaint paint;
74         canvas->translate(MARGIN, MARGIN);
75         for (int outset = -15; outset <= 20; outset += 5) {
76             canvas->save();
77             SkRect rect = cropRect.rect();
78             rect.outset(SkIntToScalar(outset),
79                         SkIntToScalar(outset));
80             SkImageFilter::CropRect bigRect(rect, SkImageFilter::CropRect::kHasAll_CropEdge);
81 
82             Draw(canvas, checkerboard, rect, SkColorFilterImageFilter::Create(
83                 cfAlphaTrans, noopCropped.get(), &bigRect));
84 
85             Draw(canvas, checkerboard, rect, SkBlurImageFilter::Create(
86                 0.3f, 0.3f, noopCropped.get(), &bigRect));
87 
88             Draw(canvas, checkerboard, rect, SkBlurImageFilter::Create(
89                 8.0f, 8.0f, noopCropped.get(), &bigRect));
90 
91             Draw(canvas, checkerboard, rect, SkDilateImageFilter::Create(
92                 2, 2, noopCropped.get(), &bigRect));
93 
94             Draw(canvas, checkerboard, rect, SkErodeImageFilter::Create(
95                 2, 2, noopCropped.get(), &bigRect));
96 
97             Draw(canvas, checkerboard, rect, SkDropShadowImageFilter::Create(
98                 SkIntToScalar(10), SkIntToScalar(10), SkIntToScalar(3), SkIntToScalar(3),
99                 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
100                 noopCropped.get(), &bigRect));
101 
102             Draw(canvas, checkerboard, rect, SkDisplacementMapEffect::Create(
103                 SkDisplacementMapEffect::kR_ChannelSelectorType,
104                 SkDisplacementMapEffect::kR_ChannelSelectorType,
105                 SkIntToScalar(12),
106                 gradientCircleSource.get(),
107                 noopCropped.get(),
108                 &bigRect));
109 
110             Draw(canvas, checkerboard, rect, SkOffsetImageFilter::Create(
111                 SkIntToScalar(-8), SkIntToScalar(16), noopCropped.get(), &bigRect));
112 
113             Draw(canvas, checkerboard, rect,
114                 SkLightingImageFilter::CreatePointLitDiffuse(pointLocation, SK_ColorWHITE,
115                 surfaceScale, kd, noopCropped.get(), &bigRect));
116 
117             canvas->restore();
118             canvas->translate(0, SkIntToScalar(80));
119         }
120     }
121 
122 private:
MakeCheckerboard(SkBitmap * bitmap)123     static void MakeCheckerboard(SkBitmap* bitmap) {
124         bitmap->allocN32Pixels(64, 64);
125         SkCanvas canvas(*bitmap);
126         canvas.clear(0xFFFF0000);
127         SkPaint darkPaint;
128         darkPaint.setColor(sk_tool_utils::color_to_565(0xFF404040));
129         SkPaint lightPaint;
130         lightPaint.setColor(sk_tool_utils::color_to_565(0xFFA0A0A0));
131         for (int y = 8; y < 48; y += 16) {
132             for (int x = 8; x < 48; x += 16) {
133                 canvas.save();
134                 canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
135                 canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
136                 canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
137                 canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
138                 canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
139                 canvas.restore();
140             }
141         }
142     }
143 
MakeGradientCircle(int width,int height)144     static SkImage* MakeGradientCircle(int width, int height) {
145         SkScalar x = SkIntToScalar(width / 2);
146         SkScalar y = SkIntToScalar(height / 2);
147         SkScalar radius = SkMinScalar(x, y) * 0.8f;
148         SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(width, height));
149         SkCanvas* canvas = surface->getCanvas();
150         canvas->clear(0x00000000);
151         SkColor colors[2];
152         colors[0] = SK_ColorWHITE;
153         colors[1] = SK_ColorBLACK;
154         SkAutoTUnref<SkShader> shader(
155             SkGradientShader::CreateRadial(SkPoint::Make(x, y), radius, colors, nullptr, 2,
156                                            SkShader::kClamp_TileMode)
157         );
158         SkPaint paint;
159         paint.setShader(shader);
160         canvas->drawCircle(x, y, radius, paint);
161 
162         return surface->newImageSnapshot();
163     }
164 
Draw(SkCanvas * canvas,const SkBitmap & bitmap,const SkRect & rect,SkImageFilter * filter)165     static void Draw(SkCanvas* canvas, const SkBitmap& bitmap, const SkRect& rect, SkImageFilter* filter) {
166         SkPaint paint;
167         paint.setImageFilter(filter)->unref();
168         canvas->saveLayer(&rect, &paint);
169         canvas->drawBitmap(bitmap, 0, 0);
170         canvas->restore();
171 
172         SkPaint strokePaint;
173         strokePaint.setColor(0xFFFF0000);
174         strokePaint.setStyle(SkPaint::kStroke_Style);
175         canvas->drawRect(rect, strokePaint);
176 
177         canvas->translate(SkIntToScalar(80), 0);
178     }
179 
180     typedef GM INHERITED;
181 };
182 
183 ///////////////////////////////////////////////////////////////////////////////
184 
185 DEF_GM( return new ImageFiltersCropExpandGM; )
186