blob: b7792bc10a363e78c9e1b1b423bbe39c4c340e17 [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/SkBlurImageFilter.h"
25#include "include/effects/SkColorFilterImageFilter.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050026#include "include/effects/SkDisplacementMapEffect.h"
27#include "include/effects/SkDropShadowImageFilter.h"
28#include "include/effects/SkGradientShader.h"
29#include "include/effects/SkImageSource.h"
30#include "include/effects/SkLightingImageFilter.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050031#include "include/effects/SkMorphologyImageFilter.h"
32#include "include/effects/SkOffsetImageFilter.h"
senorblanco@chromium.org11825292014-03-14 17:44:41 +000033
Ben Wagner7fde8e12019-05-01 17:28:53 -040034#include <utility>
35
Stephen White930f69e2017-01-12 17:15:50 -050036namespace {
37
38void make_checkerboard(SkBitmap* bitmap);
39sk_sp<SkImage> make_gradient_circle(int width, int height);
40void draw(SkCanvas* canvas, const SkBitmap& bitmap, const SkRect& rect,
41 sk_sp<SkImageFilter> filter);
42
43};
44
senorblanco@chromium.org11825292014-03-14 17:44:41 +000045///////////////////////////////////////////////////////////////////////////////
46
Stephen White930f69e2017-01-12 17:15:50 -050047DEF_SIMPLE_GM(imagefilterscropexpand, canvas, 730, 650) {
48 SkImageFilter::CropRect cropRect(
49 SkRect::Make(SkIRect::MakeXYWH(10, 10, 44, 44)),
50 SkImageFilter::CropRect::kHasAll_CropEdge);
senorblanco@chromium.org11825292014-03-14 17:44:41 +000051
Stephen White930f69e2017-01-12 17:15:50 -050052 sk_sp<SkImage> gradientCircle(make_gradient_circle(64, 64));
53 SkBitmap checkerboard;
54 make_checkerboard(&checkerboard);
senorblanco@chromium.org11825292014-03-14 17:44:41 +000055
Stephen White930f69e2017-01-12 17:15:50 -050056 sk_sp<SkImageFilter> gradientCircleSource(SkImageSource::Make(std::move(gradientCircle)));
57 sk_sp<SkImageFilter> noopCropped(SkOffsetImageFilter::Make(0, 0, nullptr, &cropRect));
58 // This color matrix saturates the green component but only partly increases the opacity.
59 // For the opaque checkerboard, the opacity boost doesn't matter but it does impact the
60 // area outside the checkerboard.
Mike Reede869a1e2019-04-30 12:18:54 -040061 float matrix[20] = { 1, 0, 0, 0, 0,
62 0, 1, 0, 0, 1,
63 0, 0, 1, 0, 0,
64 0, 0, 0, 1, 32.0f/255 };
65 sk_sp<SkColorFilter> cfAlphaTrans(SkColorFilters::Matrix(matrix));
senorblanco@chromium.org11825292014-03-14 17:44:41 +000066
Stephen White930f69e2017-01-12 17:15:50 -050067 SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
68 SkScalar MARGIN = SkIntToScalar(12);
senorblanco@chromium.org11825292014-03-14 17:44:41 +000069
Stephen White930f69e2017-01-12 17:15:50 -050070 SkPoint3 pointLocation = SkPoint3::Make(0, 0, SkIntToScalar(10));
71 SkScalar kd = SkIntToScalar(2);
72 SkScalar surfaceScale = SkIntToScalar(1);
73 SkIRect bounds;
74 r.roundOut(&bounds);
fmalita5598b632015-09-15 11:26:13 -070075
Stephen White930f69e2017-01-12 17:15:50 -050076 SkPaint paint;
77 canvas->translate(MARGIN, MARGIN);
78 for (int outset = -15; outset <= 20; outset += 5) {
79 canvas->save();
80 SkRect rect = cropRect.rect();
81 rect.outset(SkIntToScalar(outset),
82 SkIntToScalar(outset));
83 SkImageFilter::CropRect bigRect(rect, SkImageFilter::CropRect::kHasAll_CropEdge);
fmalita5598b632015-09-15 11:26:13 -070084
Stephen White930f69e2017-01-12 17:15:50 -050085 draw(canvas, checkerboard, rect, SkColorFilterImageFilter::Make(cfAlphaTrans,
86 noopCropped,
87 &bigRect));
fmalita5598b632015-09-15 11:26:13 -070088
Stephen White930f69e2017-01-12 17:15:50 -050089 draw(canvas, checkerboard, rect, SkBlurImageFilter::Make(0.3f, 0.3f,
90 noopCropped,
91 &bigRect));
fmalita5598b632015-09-15 11:26:13 -070092
Stephen White930f69e2017-01-12 17:15:50 -050093 draw(canvas, checkerboard, rect, SkBlurImageFilter::Make(8.0f, 8.0f,
94 noopCropped,
95 &bigRect));
fmalita5598b632015-09-15 11:26:13 -070096
Stephen White930f69e2017-01-12 17:15:50 -050097 draw(canvas, checkerboard, rect, SkDilateImageFilter::Make(2, 2,
98 noopCropped,
99 &bigRect));
fmalita5598b632015-09-15 11:26:13 -0700100
Stephen White930f69e2017-01-12 17:15:50 -0500101 draw(canvas, checkerboard, rect, SkErodeImageFilter::Make(2, 2,
102 noopCropped,
103 &bigRect));
senorblanco84f0e742016-02-16 13:26:56 -0800104
Stephen White930f69e2017-01-12 17:15:50 -0500105 draw(canvas, checkerboard, rect,
106 SkDropShadowImageFilter::Make(
107 SkIntToScalar(10),
108 SkIntToScalar(10),
109 SkIntToScalar(3),
110 SkIntToScalar(3),
111 SK_ColorBLUE,
112 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
113 noopCropped,
114 &bigRect));
robertphillips51a315e2016-03-31 09:05:49 -0700115
Stephen White930f69e2017-01-12 17:15:50 -0500116 draw(canvas, checkerboard, rect,
117 SkDisplacementMapEffect::Make(SkDisplacementMapEffect::kR_ChannelSelectorType,
118 SkDisplacementMapEffect::kR_ChannelSelectorType,
119 SkIntToScalar(12),
120 gradientCircleSource,
robertphillips51a315e2016-03-31 09:05:49 -0700121 noopCropped,
122 &bigRect));
123
Stephen White930f69e2017-01-12 17:15:50 -0500124 draw(canvas, checkerboard, rect,
125 SkOffsetImageFilter::Make(SkIntToScalar(-8), SkIntToScalar(16),
126 noopCropped,
127 &bigRect));
fmalita5598b632015-09-15 11:26:13 -0700128
Stephen White930f69e2017-01-12 17:15:50 -0500129 draw(canvas, checkerboard, rect,
130 SkLightingImageFilter::MakePointLitDiffuse(pointLocation,
131 SK_ColorWHITE,
132 surfaceScale,
133 kd,
134 noopCropped,
135 &bigRect));
136
137 canvas->restore();
138 canvas->translate(0, SkIntToScalar(80));
fmalita5598b632015-09-15 11:26:13 -0700139 }
Stephen White930f69e2017-01-12 17:15:50 -0500140}
fmalita5598b632015-09-15 11:26:13 -0700141
Stephen White930f69e2017-01-12 17:15:50 -0500142namespace {
143 void make_checkerboard(SkBitmap* bitmap) {
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000144 bitmap->allocN32Pixels(64, 64);
145 SkCanvas canvas(*bitmap);
146 canvas.clear(0xFFFF0000);
147 SkPaint darkPaint;
Mike Kleind46dce32018-08-16 10:17:03 -0400148 darkPaint.setColor(0xFF404040);
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000149 SkPaint lightPaint;
Mike Kleind46dce32018-08-16 10:17:03 -0400150 lightPaint.setColor(0xFFA0A0A0);
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000151 for (int y = 8; y < 48; y += 16) {
152 for (int x = 8; x < 48; x += 16) {
153 canvas.save();
154 canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
155 canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
156 canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
157 canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
158 canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
159 canvas.restore();
160 }
161 }
162 }
163
Stephen White930f69e2017-01-12 17:15:50 -0500164 sk_sp<SkImage> make_gradient_circle(int width, int height) {
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000165 SkScalar x = SkIntToScalar(width / 2);
166 SkScalar y = SkIntToScalar(height / 2);
167 SkScalar radius = SkMinScalar(x, y) * 0.8f;
reede8f30622016-03-23 18:59:25 -0700168 auto surface(SkSurface::MakeRasterN32Premul(width, height));
fmalita5598b632015-09-15 11:26:13 -0700169 SkCanvas* canvas = surface->getCanvas();
170 canvas->clear(0x00000000);
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000171 SkColor colors[2];
172 colors[0] = SK_ColorWHITE;
173 colors[1] = SK_ColorBLACK;
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000174 SkPaint paint;
reed1a9b9642016-03-13 14:13:58 -0700175 paint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(x, y), radius, colors, nullptr,
Mike Reedfae8fce2019-04-03 10:27:45 -0400176 2, SkTileMode::kClamp));
fmalita5598b632015-09-15 11:26:13 -0700177 canvas->drawCircle(x, y, radius, paint);
178
reed9ce9d672016-03-17 10:51:11 -0700179 return surface->makeImageSnapshot();
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000180 }
181
Stephen White930f69e2017-01-12 17:15:50 -0500182 void draw(SkCanvas* canvas, const SkBitmap& bitmap, const SkRect& rect,
robertphillips51a315e2016-03-31 09:05:49 -0700183 sk_sp<SkImageFilter> filter) {
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000184 SkPaint paint;
robertphillips51a315e2016-03-31 09:05:49 -0700185 paint.setImageFilter(std::move(filter));
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000186 canvas->saveLayer(&rect, &paint);
187 canvas->drawBitmap(bitmap, 0, 0);
188 canvas->restore();
skia.committer@gmail.comf0f9f5f2014-03-15 03:02:32 +0000189
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000190 SkPaint strokePaint;
191 strokePaint.setColor(0xFFFF0000);
192 strokePaint.setStyle(SkPaint::kStroke_Style);
193 canvas->drawRect(rect, strokePaint);
194
195 canvas->translate(SkIntToScalar(80), 0);
196 }
senorblanco@chromium.org11825292014-03-14 17:44:41 +0000197};