blob: 18cddb639dcef563eb37a53f5fcc5c3db8e3000a [file] [log] [blame]
senorblanco@chromium.org11825292014-03-14 17:44:41 +00001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -04009#include "include/core/SkBitmap.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkCanvas.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040011#include "include/core/SkColor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkColorFilter.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040013#include "include/core/SkImage.h"
14#include "include/core/SkImageFilter.h"
15#include "include/core/SkPaint.h"
16#include "include/core/SkPoint.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "include/core/SkPoint3.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040018#include "include/core/SkRect.h"
19#include "include/core/SkRefCnt.h"
20#include "include/core/SkScalar.h"
21#include "include/core/SkShader.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050022#include "include/core/SkSurface.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040023#include "include/core/SkTileMode.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "include/effects/SkGradientShader.h"
Michael Ludwig898bbfa2019-08-02 15:21:23 -040025#include "include/effects/SkImageFilters.h"
senorblanco@chromium.org11825292014-03-14 17:44:41 +000026
Ben Wagner7fde8e12019-05-01 17:28:53 -040027#include <utility>
28
Stephen White930f69e2017-01-12 17:15:50 -050029namespace {
30
31void make_checkerboard(SkBitmap* bitmap);
32sk_sp<SkImage> make_gradient_circle(int width, int height);
Michael Ludwigbf8439d2019-08-05 10:24:49 -040033void draw(SkCanvas* canvas, const SkBitmap& bitmap, const SkIRect& rect,
Stephen White930f69e2017-01-12 17:15:50 -050034 sk_sp<SkImageFilter> filter);
35
36};
37
senorblanco@chromium.org11825292014-03-14 17:44:41 +000038///////////////////////////////////////////////////////////////////////////////
39
Stephen White930f69e2017-01-12 17:15:50 -050040DEF_SIMPLE_GM(imagefilterscropexpand, canvas, 730, 650) {
Michael Ludwig898bbfa2019-08-02 15:21:23 -040041 SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 44, 44);
senorblanco@chromium.org11825292014-03-14 17:44:41 +000042
Stephen White930f69e2017-01-12 17:15:50 -050043 sk_sp<SkImage> gradientCircle(make_gradient_circle(64, 64));
44 SkBitmap checkerboard;
45 make_checkerboard(&checkerboard);
senorblanco@chromium.org11825292014-03-14 17:44:41 +000046
Michael Ludwig898bbfa2019-08-02 15:21:23 -040047 sk_sp<SkImageFilter> gradientCircleSource(SkImageFilters::Image(std::move(gradientCircle)));
48 sk_sp<SkImageFilter> noopCropped(SkImageFilters::Offset(0, 0, nullptr, &cropRect));
Stephen White930f69e2017-01-12 17:15:50 -050049 // 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.
Mike Reede869a1e2019-04-30 12:18:54 -040052 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));
senorblanco@chromium.org11825292014-03-14 17:44:41 +000057
Stephen White930f69e2017-01-12 17:15:50 -050058 SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
59 SkScalar MARGIN = SkIntToScalar(12);
senorblanco@chromium.org11825292014-03-14 17:44:41 +000060
Stephen White930f69e2017-01-12 17:15:50 -050061 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);
fmalita5598b632015-09-15 11:26:13 -070066
Stephen White930f69e2017-01-12 17:15:50 -050067 SkPaint paint;
68 canvas->translate(MARGIN, MARGIN);
69 for (int outset = -15; outset <= 20; outset += 5) {
70 canvas->save();
Michael Ludwig898bbfa2019-08-02 15:21:23 -040071 SkIRect bigRect = cropRect;
72 bigRect.outset(outset, outset);
fmalita5598b632015-09-15 11:26:13 -070073
Michael Ludwigbf8439d2019-08-05 10:24:49 -040074 draw(canvas, checkerboard, bigRect,
75 SkImageFilters::ColorFilter(cfAlphaTrans, noopCropped, &bigRect));
fmalita5598b632015-09-15 11:26:13 -070076
Michael Ludwigbf8439d2019-08-05 10:24:49 -040077 draw(canvas, checkerboard, bigRect,
78 SkImageFilters::Blur(0.3f, 0.3f, noopCropped, &bigRect));
fmalita5598b632015-09-15 11:26:13 -070079
Michael Ludwigbf8439d2019-08-05 10:24:49 -040080 draw(canvas, checkerboard, bigRect,
81 SkImageFilters::Blur(8.0f, 8.0f, noopCropped, &bigRect));
fmalita5598b632015-09-15 11:26:13 -070082
Michael Ludwigbf8439d2019-08-05 10:24:49 -040083 draw(canvas, checkerboard, bigRect,
84 SkImageFilters::Dilate(2, 2, noopCropped, &bigRect));
fmalita5598b632015-09-15 11:26:13 -070085
Michael Ludwigbf8439d2019-08-05 10:24:49 -040086 draw(canvas, checkerboard, bigRect,
87 SkImageFilters::Erode(2, 2, noopCropped, &bigRect));
senorblanco84f0e742016-02-16 13:26:56 -080088
Michael Ludwigbf8439d2019-08-05 10:24:49 -040089 draw(canvas, checkerboard, bigRect,
Michael Ludwig898bbfa2019-08-02 15:21:23 -040090 SkImageFilters::DropShadow(10, 10, 3, 3, SK_ColorBLUE, noopCropped, &bigRect));
robertphillips51a315e2016-03-31 09:05:49 -070091
Michael Ludwigbf8439d2019-08-05 10:24:49 -040092 draw(canvas, checkerboard, bigRect,
Michael Ludwig898bbfa2019-08-02 15:21:23 -040093 SkImageFilters::DisplacementMap(SkColorChannel::kR, SkColorChannel::kR, 12,
94 gradientCircleSource, noopCropped, &bigRect));
robertphillips51a315e2016-03-31 09:05:49 -070095
Michael Ludwigbf8439d2019-08-05 10:24:49 -040096 draw(canvas, checkerboard, bigRect,
Michael Ludwig898bbfa2019-08-02 15:21:23 -040097 SkImageFilters::Offset(SkIntToScalar(-8), SkIntToScalar(16), noopCropped, &bigRect));
fmalita5598b632015-09-15 11:26:13 -070098
Michael Ludwigbf8439d2019-08-05 10:24:49 -040099 draw(canvas, checkerboard, bigRect,
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400100 SkImageFilters::PointLitDiffuse(pointLocation, SK_ColorWHITE, surfaceScale, kd,
101 noopCropped, &bigRect));
Stephen White930f69e2017-01-12 17:15:50 -0500102
103 canvas->restore();
104 canvas->translate(0, SkIntToScalar(80));
fmalita5598b632015-09-15 11:26:13 -0700105 }
Stephen White930f69e2017-01-12 17:15:50 -0500106}
fmalita5598b632015-09-15 11:26:13 -0700107
Stephen White930f69e2017-01-12 17:15:50 -0500108namespace {
109 void make_checkerboard(SkBitmap* bitmap) {
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000110 bitmap->allocN32Pixels(64, 64);
111 SkCanvas canvas(*bitmap);
112 canvas.clear(0xFFFF0000);
113 SkPaint darkPaint;
Mike Kleind46dce32018-08-16 10:17:03 -0400114 darkPaint.setColor(0xFF404040);
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000115 SkPaint lightPaint;
Mike Kleind46dce32018-08-16 10:17:03 -0400116 lightPaint.setColor(0xFFA0A0A0);
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000117 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
Stephen White930f69e2017-01-12 17:15:50 -0500130 sk_sp<SkImage> make_gradient_circle(int width, int height) {
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000131 SkScalar x = SkIntToScalar(width / 2);
132 SkScalar y = SkIntToScalar(height / 2);
Brian Osman116b33e2020-02-05 13:34:09 -0500133 SkScalar radius = std::min(x, y) * 0.8f;
reede8f30622016-03-23 18:59:25 -0700134 auto surface(SkSurface::MakeRasterN32Premul(width, height));
fmalita5598b632015-09-15 11:26:13 -0700135 SkCanvas* canvas = surface->getCanvas();
136 canvas->clear(0x00000000);
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000137 SkColor colors[2];
138 colors[0] = SK_ColorWHITE;
139 colors[1] = SK_ColorBLACK;
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000140 SkPaint paint;
reed1a9b9642016-03-13 14:13:58 -0700141 paint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(x, y), radius, colors, nullptr,
Mike Reedfae8fce2019-04-03 10:27:45 -0400142 2, SkTileMode::kClamp));
fmalita5598b632015-09-15 11:26:13 -0700143 canvas->drawCircle(x, y, radius, paint);
144
reed9ce9d672016-03-17 10:51:11 -0700145 return surface->makeImageSnapshot();
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000146 }
147
Michael Ludwigbf8439d2019-08-05 10:24:49 -0400148 void draw(SkCanvas* canvas, const SkBitmap& bitmap, const SkIRect& layerRect,
robertphillips51a315e2016-03-31 09:05:49 -0700149 sk_sp<SkImageFilter> filter) {
Michael Ludwigbf8439d2019-08-05 10:24:49 -0400150 // Convert SkIRect to SkRect since that's what saveLayer and drawRect need
151 SkRect rect = SkRect::Make(layerRect);
152
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000153 SkPaint paint;
robertphillips51a315e2016-03-31 09:05:49 -0700154 paint.setImageFilter(std::move(filter));
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000155 canvas->saveLayer(&rect, &paint);
156 canvas->drawBitmap(bitmap, 0, 0);
157 canvas->restore();
skia.committer@gmail.comf0f9f5f2014-03-15 03:02:32 +0000158
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000159 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 }
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000166};