blob: e5787ee342b7b340f0724802e8606e5959d7d7c8 [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"
Michael Ludwig898bbfa2019-08-02 15:21:23 -040024#include "include/effects/SkImageFilters.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "include/utils/SkRandom.h"
26#include "tools/ToolUtils.h"
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000027
Ben Wagner7fde8e12019-05-01 17:28:53 -040028#include <utility>
29
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000030#define WIDTH 500
31#define HEIGHT 500
32
Robert Phillips22c57ab2016-12-19 16:51:53 -050033static void draw_rects(SkCanvas* canvas) {
senorblanco1ea67a32016-01-19 08:50:18 -080034 SkPaint rectPaint;
Robert Phillips22c57ab2016-12-19 16:51:53 -050035 rectPaint.setColor(SK_ColorBLUE);
senorblanco1ea67a32016-01-19 08:50:18 -080036 canvas->drawRect(SkRect::MakeXYWH(0, 0, WIDTH / 2, HEIGHT / 2), rectPaint);
37 rectPaint.setColor(0xBFFF0000);
38 canvas->drawRect(SkRect::MakeXYWH(WIDTH / 2, 0, WIDTH / 2, HEIGHT / 2), rectPaint);
39 rectPaint.setColor(0x3F00FF00);
40 canvas->drawRect(SkRect::MakeXYWH(0, HEIGHT / 2, WIDTH / 2, HEIGHT / 2), rectPaint);
Robert Phillips22c57ab2016-12-19 16:51:53 -050041 rectPaint.setColor(SK_ColorTRANSPARENT);
senorblanco1ea67a32016-01-19 08:50:18 -080042 canvas->drawRect(SkRect::MakeXYWH(WIDTH / 2, HEIGHT / 2, WIDTH / 2, HEIGHT / 2), rectPaint);
43}
44
Michael Ludwig898bbfa2019-08-02 15:21:23 -040045static SkPaint create_filter_paint(SkIRect* cropRect = nullptr) {
senorblanco1ea67a32016-01-19 08:50:18 -080046 SkIRect rects[2];
47 rects[0] = SkIRect::MakeXYWH(0, 150, WIDTH, HEIGHT - 300);
48 rects[1] = SkIRect::MakeXYWH(150, 0, WIDTH - 300, HEIGHT);
49 SkRegion region;
50 region.setRects(rects, 2);
51
52 SkPaint paint;
Michael Ludwig898bbfa2019-08-02 15:21:23 -040053 sk_sp<SkImageFilter> offset(SkImageFilters::Offset(25, 25, nullptr));
54 paint.setImageFilter(
55 SkImageFilters::AlphaThreshold(region, 0.2f, 0.7f, std::move(offset), cropRect));
senorblanco1ea67a32016-01-19 08:50:18 -080056 return paint;
57}
58
Robert Phillips22c57ab2016-12-19 16:51:53 -050059class ImageAlphaThresholdGM : public skiagm::GM {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000060public:
Brian Osman01015fb2016-10-03 11:06:45 -040061 ImageAlphaThresholdGM(bool useCropRect) : fUseCropRect(useCropRect) {
Robert Phillips22c57ab2016-12-19 16:51:53 -050062 this->setBGColor(SK_ColorWHITE);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000063 }
64
65protected:
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000066
mtklein36352bf2015-03-25 18:17:31 -070067 SkString onShortName() override {
robertphillipsaf9b8c82016-04-12 11:02:25 -070068 if (fUseCropRect) {
69 return SkString("imagealphathreshold_crop");
70 }
71
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000072 return SkString("imagealphathreshold");
73 }
74
mtklein36352bf2015-03-25 18:17:31 -070075 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -070076 return SkISize::Make(WIDTH, HEIGHT);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000077 }
78
mtklein36352bf2015-03-25 18:17:31 -070079 void onDraw(SkCanvas* canvas) override {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000080 SkMatrix matrix;
81 matrix.reset();
82 matrix.setTranslate(WIDTH * .1f, HEIGHT * .1f);
commit-bot@chromium.org9109e182014-01-07 16:04:01 +000083 matrix.postScale(.8f, .8f);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000084
85 canvas->concat(matrix);
86
Michael Ludwig898bbfa2019-08-02 15:21:23 -040087 SkIRect cropRect = SkIRect::MakeLTRB(100, 100, WIDTH - 100, HEIGHT - 100);
robertphillipsaf9b8c82016-04-12 11:02:25 -070088
89 SkPaint paint = create_filter_paint(fUseCropRect ? &cropRect : nullptr);
halcanary96fcdcc2015-08-27 07:41:13 -070090 canvas->saveLayer(nullptr, &paint);
senorblanco1ea67a32016-01-19 08:50:18 -080091 draw_rects(canvas);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000092
93 canvas->restore();
94 }
95
96private:
robertphillipsaf9b8c82016-04-12 11:02:25 -070097 bool fUseCropRect;
98
John Stiles7571f9e2020-09-02 22:42:33 -040099 using INHERITED = GM;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000100};
101
Robert Phillips22c57ab2016-12-19 16:51:53 -0500102// Create a 'width' x 'height' SkSurface that matches the colorType of 'canvas' as
103// best we can
104static sk_sp<SkSurface> make_color_matching_surface(SkCanvas* canvas, int width, int height,
Mike Reed16178992018-02-09 17:35:29 -0500105 SkAlphaType at) {
robertphillipsaf9b8c82016-04-12 11:02:25 -0700106
Robert Phillips22c57ab2016-12-19 16:51:53 -0500107 SkColorType ct = canvas->imageInfo().colorType();
Mike Reed693fdbd2017-01-12 10:13:40 -0500108 sk_sp<SkColorSpace> cs(canvas->imageInfo().refColorSpace());
Robert Phillips22c57ab2016-12-19 16:51:53 -0500109
110 if (kUnknown_SkColorType == ct) {
111 // For backends that aren't yet color-space aware we just fallback to N32.
112 ct = kN32_SkColorType;
113 cs = nullptr;
Mike Reed16178992018-02-09 17:35:29 -0500114 } else if (SkColorTypeIsAlwaysOpaque(ct)) {
115 at = kOpaque_SkAlphaType;
Robert Phillips22c57ab2016-12-19 16:51:53 -0500116 }
117
Mike Reed16178992018-02-09 17:35:29 -0500118 SkImageInfo info = SkImageInfo::Make(width, height, ct, at, std::move(cs));
Robert Phillips22c57ab2016-12-19 16:51:53 -0500119
Mike Kleinea3f0142019-03-20 11:12:10 -0500120 return ToolUtils::makeSurface(canvas, info);
Robert Phillips22c57ab2016-12-19 16:51:53 -0500121}
122
123class ImageAlphaThresholdSurfaceGM : public skiagm::GM {
senorblanco1ea67a32016-01-19 08:50:18 -0800124public:
125 ImageAlphaThresholdSurfaceGM() {
126 this->setBGColor(0xFFFFFFFF);
127 }
128
129protected:
130 SkString onShortName() override {
131 return SkString("imagealphathreshold_surface");
132 }
133
134 SkISize onISize() override {
135 return SkISize::Make(WIDTH, HEIGHT);
136 }
137
Chris Dalton50e24d72019-02-07 16:20:09 -0700138 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
Robert Phillips22c57ab2016-12-19 16:51:53 -0500139 SkMatrix matrix;
140 matrix.reset();
141 matrix.setTranslate(WIDTH * .1f, HEIGHT * .1f);
142 matrix.postScale(.8f, .8f);
143
144 canvas->concat(matrix);
145
146 sk_sp<SkSurface> surface(make_color_matching_surface(canvas, WIDTH, HEIGHT,
147 kPremul_SkAlphaType));
Robert Phillips253b4dd2016-12-20 19:05:09 -0500148 if (!surface) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700149 *errorMsg = "make_color_matching_surface failed";
150 return DrawResult::kFail;
Robert Phillips253b4dd2016-12-20 19:05:09 -0500151 }
Robert Phillips22c57ab2016-12-19 16:51:53 -0500152
153 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
senorblanco1ea67a32016-01-19 08:50:18 -0800154 draw_rects(surface->getCanvas());
155
senorblanco1ea67a32016-01-19 08:50:18 -0800156 SkPaint paint = create_filter_paint();
157 canvas->clipRect(SkRect::MakeLTRB(100, 100, WIDTH - 100, HEIGHT - 100));
Mike Reed07c5f522021-01-23 12:23:23 -0500158 canvas->drawImage(surface->makeImageSnapshot().get(), 0, 0, SkSamplingOptions(), &paint);
Chris Dalton50e24d72019-02-07 16:20:09 -0700159 return DrawResult::kOk;
senorblanco1ea67a32016-01-19 08:50:18 -0800160 }
161
162private:
John Stiles7571f9e2020-09-02 22:42:33 -0400163 using INHERITED = skiagm::GM;
senorblanco1ea67a32016-01-19 08:50:18 -0800164};
165
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000166//////////////////////////////////////////////////////////////////////////////
167
robertphillipsaf9b8c82016-04-12 11:02:25 -0700168DEF_GM(return new ImageAlphaThresholdGM(true);)
169DEF_GM(return new ImageAlphaThresholdGM(false);)
senorblanco1ea67a32016-01-19 08:50:18 -0800170DEF_GM(return new ImageAlphaThresholdSurfaceGM();)
Brian Osmana4aa1332017-10-19 12:54:28 -0400171
172//////////////////////////////////////////////////////////////////////////////
173
174static sk_sp<SkImage> make_img() {
175 SkBitmap bitmap;
176 bitmap.allocPixels(SkImageInfo::MakeS32(WIDTH, HEIGHT, kPremul_SkAlphaType));
177 SkCanvas canvas(bitmap);
178
179 SkPaint paint;
180 SkRect rect = SkRect::MakeWH(WIDTH, HEIGHT);
181 SkRandom rnd;
182
183 while (!rect.isEmpty()) {
184 paint.setColor(rnd.nextU() | (0xFF << 24));
185 canvas.drawRect(rect, paint);
186 rect.inset(25, 25);
187 }
188
Mike Reedac9f0c92020-12-23 10:11:33 -0500189 return bitmap.asImage();
Brian Osmana4aa1332017-10-19 12:54:28 -0400190}
191
192DEF_SIMPLE_GM_BG(imagealphathreshold_image, canvas, WIDTH * 2, HEIGHT, SK_ColorBLACK) {
193 sk_sp<SkImage> image(make_img());
194
195 SkIRect rects[2];
196 rects[0] = SkIRect::MakeXYWH(0, 150, WIDTH, HEIGHT - 300);
197 rects[1] = SkIRect::MakeXYWH(150, 0, WIDTH - 300, HEIGHT);
198 SkRegion region;
199 region.setRects(rects, 2);
200
201 SkPaint filterPaint;
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400202 sk_sp<SkImageFilter> imageSource(SkImageFilters::Image(image));
203 filterPaint.setImageFilter(SkImageFilters::AlphaThreshold(region, 0.2f, 0.7f,
204 std::move(imageSource)));
Brian Osmana4aa1332017-10-19 12:54:28 -0400205
206 canvas->saveLayer(nullptr, &filterPaint);
207 canvas->restore();
208 canvas->translate(WIDTH, 0);
209 canvas->drawImage(image, 0, 0);
210}