• Home
  • 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/gm.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkColorFilter.h"
13 #include "include/core/SkImage.h"
14 #include "include/core/SkImageFilter.h"
15 #include "include/core/SkPaint.h"
16 #include "include/core/SkPoint.h"
17 #include "include/core/SkPoint3.h"
18 #include "include/core/SkRect.h"
19 #include "include/core/SkRefCnt.h"
20 #include "include/core/SkScalar.h"
21 #include "include/core/SkShader.h"
22 #include "include/core/SkSurface.h"
23 #include "include/core/SkTileMode.h"
24 #include "include/effects/SkGradientShader.h"
25 #include "include/effects/SkImageFilters.h"
26 
27 #include <utility>
28 
29 namespace {
30 
31 sk_sp<SkImage> make_checkerboard();
32 sk_sp<SkImage> make_gradient_circle(int width, int height);
33 void draw(SkCanvas*, sk_sp<SkImage>, const SkIRect&, sk_sp<SkImageFilter>);
34 
35 }  // namespace
36 
37 ///////////////////////////////////////////////////////////////////////////////
38 
39 DEF_SIMPLE_GM(imagefilterscropexpand, canvas, 730, 650) {
40     SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 44, 44);
41 
42     sk_sp<SkImage> gradientCircle(make_gradient_circle(64, 64));
43     auto checkerboard = make_checkerboard();
44 
45     sk_sp<SkImageFilter> gradientCircleSource(SkImageFilters::Image(std::move(gradientCircle)));
46     sk_sp<SkImageFilter> noopCropped(SkImageFilters::Offset(0, 0, nullptr, &cropRect));
47     // This color matrix saturates the green component but only partly increases the opacity.
48     // For the opaque checkerboard, the opacity boost doesn't matter but it does impact the
49     // area outside the checkerboard.
50     float matrix[20] = { 1, 0, 0, 0, 0,
51                          0, 1, 0, 0, 1,
52                          0, 0, 1, 0, 0,
53                          0, 0, 0, 1, 32.0f/255 };
54     sk_sp<SkColorFilter> cfAlphaTrans(SkColorFilters::Matrix(matrix));
55 
56     SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
57     SkScalar MARGIN = SkIntToScalar(12);
58 
59     SkPoint3 pointLocation = SkPoint3::Make(0, 0, SkIntToScalar(10));
60     SkScalar kd = SkIntToScalar(2);
61     SkScalar surfaceScale = SkIntToScalar(1);
62     SkIRect bounds;
63     r.roundOut(&bounds);
64 
65     SkPaint paint;
66     canvas->translate(MARGIN, MARGIN);
67     for (int outset = -15; outset <= 20; outset += 5) {
68         canvas->save();
69         SkIRect bigRect = cropRect;
70         bigRect.outset(outset, outset);
71 
72         draw(canvas, checkerboard, bigRect,
73              SkImageFilters::ColorFilter(cfAlphaTrans, noopCropped,  &bigRect));
74 
75         draw(canvas, checkerboard, bigRect,
76              SkImageFilters::Blur(0.3f, 0.3f,  noopCropped, &bigRect));
77 
78         draw(canvas, checkerboard, bigRect,
79              SkImageFilters::Blur(8.0f, 8.0f,  noopCropped, &bigRect));
80 
81         draw(canvas, checkerboard, bigRect,
82              SkImageFilters::Dilate(2, 2, noopCropped, &bigRect));
83 
84         draw(canvas, checkerboard, bigRect,
85              SkImageFilters::Erode(2, 2, noopCropped, &bigRect));
86 
87         draw(canvas, checkerboard, bigRect,
88              SkImageFilters::DropShadow(10, 10, 3, 3, SK_ColorBLUE, noopCropped, &bigRect));
89 
90         draw(canvas, checkerboard, bigRect,
91              SkImageFilters::DisplacementMap(SkColorChannel::kR, SkColorChannel::kR, 12,
92                                              gradientCircleSource, noopCropped, &bigRect));
93 
94         draw(canvas, checkerboard, bigRect,
95              SkImageFilters::Offset(SkIntToScalar(-8), SkIntToScalar(16), noopCropped, &bigRect));
96 
97         draw(canvas, checkerboard, bigRect,
98              SkImageFilters::PointLitDiffuse(pointLocation, SK_ColorWHITE, surfaceScale, kd,
99                                              noopCropped, &bigRect));
100 
101         canvas->restore();
102         canvas->translate(0, SkIntToScalar(80));
103     }
104 }
105 
106 namespace {
make_checkerboard()107     sk_sp<SkImage> make_checkerboard() {
108         auto surf = SkSurface::MakeRasterN32Premul(64, 64);
109         auto canvas = surf->getCanvas();
110         canvas->clear(0xFFFF0000);
111         SkPaint darkPaint;
112         darkPaint.setColor(0xFF404040);
113         SkPaint lightPaint;
114         lightPaint.setColor(0xFFA0A0A0);
115         for (int y = 8; y < 48; y += 16) {
116             for (int x = 8; x < 48; x += 16) {
117                 canvas->save();
118                 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
119                 canvas->drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
120                 canvas->drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
121                 canvas->drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
122                 canvas->drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
123                 canvas->restore();
124             }
125         }
126         return surf->makeImageSnapshot();
127     }
128 
make_gradient_circle(int width,int height)129     sk_sp<SkImage> make_gradient_circle(int width, int height) {
130         SkScalar x = SkIntToScalar(width / 2);
131         SkScalar y = SkIntToScalar(height / 2);
132         SkScalar radius = std::min(x, y) * 0.8f;
133         auto surface(SkSurface::MakeRasterN32Premul(width, height));
134         SkCanvas* canvas = surface->getCanvas();
135         canvas->clear(0x00000000);
136         SkColor colors[2];
137         colors[0] = SK_ColorWHITE;
138         colors[1] = SK_ColorBLACK;
139         SkPaint paint;
140         paint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(x, y), radius, colors, nullptr,
141                                                      2, SkTileMode::kClamp));
142         canvas->drawCircle(x, y, radius, paint);
143 
144         return surface->makeImageSnapshot();
145     }
146 
draw(SkCanvas * canvas,sk_sp<SkImage> image,const SkIRect & layerRect,sk_sp<SkImageFilter> filter)147     void draw(SkCanvas* canvas, sk_sp<SkImage> image, const SkIRect& layerRect,
148                      sk_sp<SkImageFilter> filter) {
149         // Convert SkIRect to SkRect since that's what saveLayer and drawRect need
150         SkRect rect = SkRect::Make(layerRect);
151 
152         SkPaint paint;
153         paint.setImageFilter(std::move(filter));
154         canvas->saveLayer(&rect, &paint);
155         canvas->drawImage(image, 0, 0);
156         canvas->restore();
157 
158         SkPaint strokePaint;
159         strokePaint.setColor(0xFFFF0000);
160         strokePaint.setStyle(SkPaint::kStroke_Style);
161         canvas->drawRect(rect, strokePaint);
162 
163         canvas->translate(SkIntToScalar(80), 0);
164     }
165 }  // namespace
166