blob: e7857625c01a69e04000aa10216ec66f36cece52 [file] [log] [blame]
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +00001/*
2 * Copyright 2013 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"
10#include "include/core/SkCanvas.h"
11#include "include/core/SkColor.h"
12#include "include/core/SkColorSpace.h"
13#include "include/core/SkImage.h"
14#include "include/core/SkImageFilter.h"
15#include "include/core/SkImageInfo.h"
16#include "include/core/SkMatrix.h"
17#include "include/core/SkPaint.h"
18#include "include/core/SkRect.h"
19#include "include/core/SkRefCnt.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "include/core/SkRegion.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040021#include "include/core/SkSize.h"
22#include "include/core/SkString.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "include/core/SkSurface.h"
24#include "include/effects/SkAlphaThresholdFilter.h"
25#include "include/effects/SkImageSource.h"
26#include "include/effects/SkOffsetImageFilter.h"
27#include "include/utils/SkRandom.h"
28#include "tools/ToolUtils.h"
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000029
Ben Wagner7fde8e12019-05-01 17:28:53 -040030#include <utility>
31
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000032#define WIDTH 500
33#define HEIGHT 500
34
Robert Phillips22c57ab2016-12-19 16:51:53 -050035static void draw_rects(SkCanvas* canvas) {
senorblanco1ea67a32016-01-19 08:50:18 -080036 SkPaint rectPaint;
Robert Phillips22c57ab2016-12-19 16:51:53 -050037 rectPaint.setColor(SK_ColorBLUE);
senorblanco1ea67a32016-01-19 08:50:18 -080038 canvas->drawRect(SkRect::MakeXYWH(0, 0, WIDTH / 2, HEIGHT / 2), rectPaint);
39 rectPaint.setColor(0xBFFF0000);
40 canvas->drawRect(SkRect::MakeXYWH(WIDTH / 2, 0, WIDTH / 2, HEIGHT / 2), rectPaint);
41 rectPaint.setColor(0x3F00FF00);
42 canvas->drawRect(SkRect::MakeXYWH(0, HEIGHT / 2, WIDTH / 2, HEIGHT / 2), rectPaint);
Robert Phillips22c57ab2016-12-19 16:51:53 -050043 rectPaint.setColor(SK_ColorTRANSPARENT);
senorblanco1ea67a32016-01-19 08:50:18 -080044 canvas->drawRect(SkRect::MakeXYWH(WIDTH / 2, HEIGHT / 2, WIDTH / 2, HEIGHT / 2), rectPaint);
45}
46
Robert Phillips22c57ab2016-12-19 16:51:53 -050047static SkPaint create_filter_paint(SkImageFilter::CropRect* cropRect = nullptr) {
senorblanco1ea67a32016-01-19 08:50:18 -080048 SkIRect rects[2];
49 rects[0] = SkIRect::MakeXYWH(0, 150, WIDTH, HEIGHT - 300);
50 rects[1] = SkIRect::MakeXYWH(150, 0, WIDTH - 300, HEIGHT);
51 SkRegion region;
52 region.setRects(rects, 2);
53
54 SkPaint paint;
Robert Phillips22c57ab2016-12-19 16:51:53 -050055 sk_sp<SkImageFilter> offset(SkOffsetImageFilter::Make(25, 25, nullptr));
56 paint.setImageFilter(SkAlphaThresholdFilter::Make(region, 0.2f, 0.7f, std::move(offset), cropRect));
senorblanco1ea67a32016-01-19 08:50:18 -080057 return paint;
58}
59
Robert Phillips22c57ab2016-12-19 16:51:53 -050060class ImageAlphaThresholdGM : public skiagm::GM {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000061public:
Brian Osman01015fb2016-10-03 11:06:45 -040062 ImageAlphaThresholdGM(bool useCropRect) : fUseCropRect(useCropRect) {
Robert Phillips22c57ab2016-12-19 16:51:53 -050063 this->setBGColor(SK_ColorWHITE);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000064 }
65
66protected:
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000067
mtklein36352bf2015-03-25 18:17:31 -070068 SkString onShortName() override {
robertphillipsaf9b8c82016-04-12 11:02:25 -070069 if (fUseCropRect) {
70 return SkString("imagealphathreshold_crop");
71 }
72
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000073 return SkString("imagealphathreshold");
74 }
75
mtklein36352bf2015-03-25 18:17:31 -070076 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -070077 return SkISize::Make(WIDTH, HEIGHT);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000078 }
79
mtklein36352bf2015-03-25 18:17:31 -070080 void onDraw(SkCanvas* canvas) override {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000081 SkMatrix matrix;
82 matrix.reset();
83 matrix.setTranslate(WIDTH * .1f, HEIGHT * .1f);
commit-bot@chromium.org9109e182014-01-07 16:04:01 +000084 matrix.postScale(.8f, .8f);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000085
86 canvas->concat(matrix);
87
robertphillipsaf9b8c82016-04-12 11:02:25 -070088 SkRect r = SkRect::MakeLTRB(100, 100, WIDTH - 100, HEIGHT - 100);
89 SkImageFilter::CropRect cropRect(r);
90
91 SkPaint paint = create_filter_paint(fUseCropRect ? &cropRect : nullptr);
halcanary96fcdcc2015-08-27 07:41:13 -070092 canvas->saveLayer(nullptr, &paint);
senorblanco1ea67a32016-01-19 08:50:18 -080093 draw_rects(canvas);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000094
95 canvas->restore();
96 }
97
98private:
robertphillipsaf9b8c82016-04-12 11:02:25 -070099 bool fUseCropRect;
100
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000101 typedef GM INHERITED;
102};
103
Robert Phillips22c57ab2016-12-19 16:51:53 -0500104// Create a 'width' x 'height' SkSurface that matches the colorType of 'canvas' as
105// best we can
106static sk_sp<SkSurface> make_color_matching_surface(SkCanvas* canvas, int width, int height,
Mike Reed16178992018-02-09 17:35:29 -0500107 SkAlphaType at) {
robertphillipsaf9b8c82016-04-12 11:02:25 -0700108
Robert Phillips22c57ab2016-12-19 16:51:53 -0500109 SkColorType ct = canvas->imageInfo().colorType();
Mike Reed693fdbd2017-01-12 10:13:40 -0500110 sk_sp<SkColorSpace> cs(canvas->imageInfo().refColorSpace());
Robert Phillips22c57ab2016-12-19 16:51:53 -0500111
112 if (kUnknown_SkColorType == ct) {
113 // For backends that aren't yet color-space aware we just fallback to N32.
114 ct = kN32_SkColorType;
115 cs = nullptr;
Mike Reed16178992018-02-09 17:35:29 -0500116 } else if (SkColorTypeIsAlwaysOpaque(ct)) {
117 at = kOpaque_SkAlphaType;
Robert Phillips22c57ab2016-12-19 16:51:53 -0500118 }
119
Mike Reed16178992018-02-09 17:35:29 -0500120 SkImageInfo info = SkImageInfo::Make(width, height, ct, at, std::move(cs));
Robert Phillips22c57ab2016-12-19 16:51:53 -0500121
Mike Kleinea3f0142019-03-20 11:12:10 -0500122 return ToolUtils::makeSurface(canvas, info);
Robert Phillips22c57ab2016-12-19 16:51:53 -0500123}
124
125class ImageAlphaThresholdSurfaceGM : public skiagm::GM {
senorblanco1ea67a32016-01-19 08:50:18 -0800126public:
127 ImageAlphaThresholdSurfaceGM() {
128 this->setBGColor(0xFFFFFFFF);
129 }
130
131protected:
132 SkString onShortName() override {
133 return SkString("imagealphathreshold_surface");
134 }
135
136 SkISize onISize() override {
137 return SkISize::Make(WIDTH, HEIGHT);
138 }
139
Chris Dalton50e24d72019-02-07 16:20:09 -0700140 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
Robert Phillips22c57ab2016-12-19 16:51:53 -0500141 SkMatrix matrix;
142 matrix.reset();
143 matrix.setTranslate(WIDTH * .1f, HEIGHT * .1f);
144 matrix.postScale(.8f, .8f);
145
146 canvas->concat(matrix);
147
148 sk_sp<SkSurface> surface(make_color_matching_surface(canvas, WIDTH, HEIGHT,
149 kPremul_SkAlphaType));
Robert Phillips253b4dd2016-12-20 19:05:09 -0500150 if (!surface) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700151 *errorMsg = "make_color_matching_surface failed";
152 return DrawResult::kFail;
Robert Phillips253b4dd2016-12-20 19:05:09 -0500153 }
Robert Phillips22c57ab2016-12-19 16:51:53 -0500154
155 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
senorblanco1ea67a32016-01-19 08:50:18 -0800156 draw_rects(surface->getCanvas());
157
senorblanco1ea67a32016-01-19 08:50:18 -0800158 SkPaint paint = create_filter_paint();
159 canvas->clipRect(SkRect::MakeLTRB(100, 100, WIDTH - 100, HEIGHT - 100));
reed9ce9d672016-03-17 10:51:11 -0700160 canvas->drawImage(surface->makeImageSnapshot().get(), 0, 0, &paint);
Chris Dalton50e24d72019-02-07 16:20:09 -0700161 return DrawResult::kOk;
senorblanco1ea67a32016-01-19 08:50:18 -0800162 }
163
164private:
Robert Phillips22c57ab2016-12-19 16:51:53 -0500165 typedef skiagm::GM INHERITED;
senorblanco1ea67a32016-01-19 08:50:18 -0800166};
167
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000168//////////////////////////////////////////////////////////////////////////////
169
robertphillipsaf9b8c82016-04-12 11:02:25 -0700170DEF_GM(return new ImageAlphaThresholdGM(true);)
171DEF_GM(return new ImageAlphaThresholdGM(false);)
senorblanco1ea67a32016-01-19 08:50:18 -0800172DEF_GM(return new ImageAlphaThresholdSurfaceGM();)
Brian Osmana4aa1332017-10-19 12:54:28 -0400173
174//////////////////////////////////////////////////////////////////////////////
175
176static sk_sp<SkImage> make_img() {
177 SkBitmap bitmap;
178 bitmap.allocPixels(SkImageInfo::MakeS32(WIDTH, HEIGHT, kPremul_SkAlphaType));
179 SkCanvas canvas(bitmap);
180
181 SkPaint paint;
182 SkRect rect = SkRect::MakeWH(WIDTH, HEIGHT);
183 SkRandom rnd;
184
185 while (!rect.isEmpty()) {
186 paint.setColor(rnd.nextU() | (0xFF << 24));
187 canvas.drawRect(rect, paint);
188 rect.inset(25, 25);
189 }
190
191 return SkImage::MakeFromBitmap(bitmap);
192}
193
194DEF_SIMPLE_GM_BG(imagealphathreshold_image, canvas, WIDTH * 2, HEIGHT, SK_ColorBLACK) {
195 sk_sp<SkImage> image(make_img());
196
197 SkIRect rects[2];
198 rects[0] = SkIRect::MakeXYWH(0, 150, WIDTH, HEIGHT - 300);
199 rects[1] = SkIRect::MakeXYWH(150, 0, WIDTH - 300, HEIGHT);
200 SkRegion region;
201 region.setRects(rects, 2);
202
203 SkPaint filterPaint;
204 sk_sp<SkImageFilter> imageSource(SkImageSource::Make(image));
205 filterPaint.setImageFilter(SkAlphaThresholdFilter::Make(region, 0.2f, 0.7f,
206 std::move(imageSource)));
207
208 canvas->saveLayer(nullptr, &filterPaint);
209 canvas->restore();
210 canvas->translate(WIDTH, 0);
211 canvas->drawImage(image, 0, 0);
212}