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