• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 namespace {
29 
30 void make_checkerboard(SkBitmap* bitmap);
31 sk_sp<SkImage> make_gradient_circle(int width, int height);
32 void draw(SkCanvas* canvas, const SkBitmap& bitmap, const SkRect& rect,
33                  sk_sp<SkImageFilter> filter);
34 
35 };
36 
37 ///////////////////////////////////////////////////////////////////////////////
38 
39 DEF_SIMPLE_GM(imagefilterscropexpand, canvas, 730, 650) {
40     SkImageFilter::CropRect cropRect(
41         SkRect::Make(SkIRect::MakeXYWH(10, 10, 44, 44)),
42         SkImageFilter::CropRect::kHasAll_CropEdge);
43 
44     sk_sp<SkImage> gradientCircle(make_gradient_circle(64, 64));
45     SkBitmap checkerboard;
46     make_checkerboard(&checkerboard);
47 
48     sk_sp<SkImageFilter> gradientCircleSource(SkImageSource::Make(std::move(gradientCircle)));
49     sk_sp<SkImageFilter> noopCropped(SkOffsetImageFilter::Make(0, 0, nullptr, &cropRect));
50     // This color matrix saturates the green component but only partly increases the opacity.
51     // For the opaque checkerboard, the opacity boost doesn't matter but it does impact the
52     // area outside the checkerboard.
53     SkScalar matrix[20] = { 1, 0, 0, 0, 0,
54                             0, 1, 0, 0, 255,
55                             0, 0, 1, 0, 0,
56                             0, 0, 0, 1, 32 };
57     sk_sp<SkColorFilter> cfAlphaTrans(SkColorFilter::MakeMatrixFilterRowMajor255(matrix));
58 
59     SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
60     SkScalar MARGIN = SkIntToScalar(12);
61 
62     SkPoint3 pointLocation = SkPoint3::Make(0, 0, SkIntToScalar(10));
63     SkScalar kd = SkIntToScalar(2);
64     SkScalar surfaceScale = SkIntToScalar(1);
65     SkIRect bounds;
66     r.roundOut(&bounds);
67 
68     SkPaint paint;
69     canvas->translate(MARGIN, MARGIN);
70     for (int outset = -15; outset <= 20; outset += 5) {
71         canvas->save();
72         SkRect rect = cropRect.rect();
73         rect.outset(SkIntToScalar(outset),
74                     SkIntToScalar(outset));
75         SkImageFilter::CropRect bigRect(rect, SkImageFilter::CropRect::kHasAll_CropEdge);
76 
77         draw(canvas, checkerboard, rect, SkColorFilterImageFilter::Make(cfAlphaTrans,
78                                                                         noopCropped,
79                                                                         &bigRect));
80 
81         draw(canvas, checkerboard, rect, SkBlurImageFilter::Make(0.3f, 0.3f,
82                                                                  noopCropped,
83                                                                  &bigRect));
84 
85         draw(canvas, checkerboard, rect, SkBlurImageFilter::Make(8.0f, 8.0f,
86                                                                  noopCropped,
87                                                                  &bigRect));
88 
89         draw(canvas, checkerboard, rect, SkDilateImageFilter::Make(2, 2,
90                                                                    noopCropped,
91                                                                    &bigRect));
92 
93         draw(canvas, checkerboard, rect, SkErodeImageFilter::Make(2, 2,
94                                                                   noopCropped,
95                                                                   &bigRect));
96 
97         draw(canvas, checkerboard, rect,
98              SkDropShadowImageFilter::Make(
99                                 SkIntToScalar(10),
100                                 SkIntToScalar(10),
101                                 SkIntToScalar(3),
102                                 SkIntToScalar(3),
103                                 SK_ColorBLUE,
104                                 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
105                                 noopCropped,
106                                 &bigRect));
107 
108         draw(canvas, checkerboard, rect,
109              SkDisplacementMapEffect::Make(SkDisplacementMapEffect::kR_ChannelSelectorType,
110                                            SkDisplacementMapEffect::kR_ChannelSelectorType,
111                                            SkIntToScalar(12),
112                                            gradientCircleSource,
113                                            noopCropped,
114                                            &bigRect));
115 
116         draw(canvas, checkerboard, rect,
117              SkOffsetImageFilter::Make(SkIntToScalar(-8), SkIntToScalar(16),
118                                        noopCropped,
119                                        &bigRect));
120 
121         draw(canvas, checkerboard, rect,
122              SkLightingImageFilter::MakePointLitDiffuse(pointLocation,
123                                                         SK_ColorWHITE,
124                                                         surfaceScale,
125                                                         kd,
126                                                         noopCropped,
127                                                         &bigRect));
128 
129         canvas->restore();
130         canvas->translate(0, SkIntToScalar(80));
131     }
132 }
133 
134 namespace {
make_checkerboard(SkBitmap * bitmap)135     void make_checkerboard(SkBitmap* bitmap) {
136         bitmap->allocN32Pixels(64, 64);
137         SkCanvas canvas(*bitmap);
138         canvas.clear(0xFFFF0000);
139         SkPaint darkPaint;
140         darkPaint.setColor(0xFF404040);
141         SkPaint lightPaint;
142         lightPaint.setColor(0xFFA0A0A0);
143         for (int y = 8; y < 48; y += 16) {
144             for (int x = 8; x < 48; x += 16) {
145                 canvas.save();
146                 canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
147                 canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
148                 canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
149                 canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
150                 canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
151                 canvas.restore();
152             }
153         }
154     }
155 
make_gradient_circle(int width,int height)156     sk_sp<SkImage> make_gradient_circle(int width, int height) {
157         SkScalar x = SkIntToScalar(width / 2);
158         SkScalar y = SkIntToScalar(height / 2);
159         SkScalar radius = SkMinScalar(x, y) * 0.8f;
160         auto surface(SkSurface::MakeRasterN32Premul(width, height));
161         SkCanvas* canvas = surface->getCanvas();
162         canvas->clear(0x00000000);
163         SkColor colors[2];
164         colors[0] = SK_ColorWHITE;
165         colors[1] = SK_ColorBLACK;
166         SkPaint paint;
167         paint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(x, y), radius, colors, nullptr,
168                                                      2, SkShader::kClamp_TileMode));
169         canvas->drawCircle(x, y, radius, paint);
170 
171         return surface->makeImageSnapshot();
172     }
173 
draw(SkCanvas * canvas,const SkBitmap & bitmap,const SkRect & rect,sk_sp<SkImageFilter> filter)174     void draw(SkCanvas* canvas, const SkBitmap& bitmap, const SkRect& rect,
175                      sk_sp<SkImageFilter> filter) {
176         SkPaint paint;
177         paint.setImageFilter(std::move(filter));
178         canvas->saveLayer(&rect, &paint);
179         canvas->drawBitmap(bitmap, 0, 0);
180         canvas->restore();
181 
182         SkPaint strokePaint;
183         strokePaint.setColor(0xFFFF0000);
184         strokePaint.setStyle(SkPaint::kStroke_Style);
185         canvas->drawRect(rect, strokePaint);
186 
187         canvas->translate(SkIntToScalar(80), 0);
188     }
189 };
190