blob: ef85e7cd37c91df70c368efe7eda62a101fda2c4 [file] [log] [blame]
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +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"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkImage.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040013#include "include/core/SkImageFilter.h"
14#include "include/core/SkMatrix.h"
15#include "include/core/SkPaint.h"
16#include "include/core/SkRect.h"
17#include "include/core/SkRefCnt.h"
18#include "include/core/SkScalar.h"
19#include "include/core/SkSize.h"
20#include "include/core/SkString.h"
Michael Ludwig898bbfa2019-08-02 15:21:23 -040021#include "include/effects/SkImageFilters.h"
Michael Ludwig8ee6cf32019-08-02 09:57:04 -040022#include "src/core/SkImageFilter_Base.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "tools/ToolUtils.h"
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000024
Ben Wagner7fde8e12019-05-01 17:28:53 -040025#include <utility>
26
senorblanco@chromium.orge09244d2014-03-04 19:05:25 +000027#define WIDTH 600
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000028#define HEIGHT 100
29#define MARGIN 12
30
reed462a33c2015-06-22 09:10:14 -070031class OffsetImageFilterGM : public skiagm::GM {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000032public:
reed462a33c2015-06-22 09:10:14 -070033 OffsetImageFilterGM() {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000034 this->setBGColor(0xFF000000);
35 }
36
37protected:
reed462a33c2015-06-22 09:10:14 -070038 SkString onShortName() override {
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000039 return SkString("offsetimagefilter");
40 }
41
reed462a33c2015-06-22 09:10:14 -070042 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -070043 return SkISize::Make(WIDTH, HEIGHT);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000044 }
45
fmalita5598b632015-09-15 11:26:13 -070046 void onOnceBeforeDraw() override {
Mike Reedac9f0c92020-12-23 10:11:33 -050047 fBitmap = ToolUtils::create_string_image(80, 80, 0xD000D000, 15, 65, 96, "e");
halcanary9d524f22016-03-29 09:03:52 -070048
Mike Reeddb873dd2020-12-04 12:22:10 -050049 fCheckerboard = ToolUtils::create_checkerboard_image(80, 80, 0xFFA0A0A0, 0xFF404040, 8);
fmalita5598b632015-09-15 11:26:13 -070050 }
51
52 void onDraw(SkCanvas* canvas) override {
53 canvas->clear(SK_ColorBLACK);
54 SkPaint paint;
55
56 for (int i = 0; i < 4; i++) {
robertphillips549c8992016-04-01 09:28:51 -070057 sk_sp<SkImage> image = (i & 0x01) ? fCheckerboard : fBitmap;
fmalita5598b632015-09-15 11:26:13 -070058 SkIRect cropRect = SkIRect::MakeXYWH(i * 12,
59 i * 8,
60 image->width() - i * 8,
61 image->height() - i * 12);
Michael Ludwig898bbfa2019-08-02 15:21:23 -040062 sk_sp<SkImageFilter> tileInput(SkImageFilters::Image(image));
fmalita5598b632015-09-15 11:26:13 -070063 SkScalar dx = SkIntToScalar(i*5);
64 SkScalar dy = SkIntToScalar(i*10);
Michael Ludwig898bbfa2019-08-02 15:21:23 -040065 paint.setImageFilter(SkImageFilters::Offset(dx, dy, std::move(tileInput), &cropRect));
robertphillips549c8992016-04-01 09:28:51 -070066 DrawClippedImage(canvas, image.get(), paint, 1, cropRect);
fmalita5598b632015-09-15 11:26:13 -070067 canvas->translate(SkIntToScalar(image->width() + MARGIN), 0);
68 }
69
70 SkIRect cropRect = SkIRect::MakeXYWH(0, 0, 100, 100);
Michael Ludwig898bbfa2019-08-02 15:21:23 -040071 paint.setImageFilter(SkImageFilters::Offset(-5, -10, nullptr, &cropRect));
reed9ce9d672016-03-17 10:51:11 -070072 DrawClippedImage(canvas, fBitmap.get(), paint, 2, cropRect);
fmalita5598b632015-09-15 11:26:13 -070073 }
74private:
75 static void DrawClippedImage(SkCanvas* canvas, const SkImage* image, const SkPaint& paint,
76 SkScalar scale, const SkIRect& cropRect) {
77 SkRect clipRect = SkRect::MakeIWH(image->width(), image->height());
reed462a33c2015-06-22 09:10:14 -070078
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000079 canvas->save();
senorblanco@chromium.orge09244d2014-03-04 19:05:25 +000080 canvas->clipRect(clipRect);
81 canvas->scale(scale, scale);
Mike Reedd396cd52021-01-23 21:14:47 -050082 canvas->drawImage(image, 0, 0, SkSamplingOptions(), &paint);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000083 canvas->restore();
senorblanco@chromium.orge09244d2014-03-04 19:05:25 +000084
reed462a33c2015-06-22 09:10:14 -070085 // Draw a boundary rect around the intersection of the clip rect and crop rect.
senorblanco@chromium.orge09244d2014-03-04 19:05:25 +000086 SkRect cropRectFloat;
Mike Reed1f607332020-05-21 12:11:27 -040087 SkMatrix::Scale(scale, scale).mapRect(&cropRectFloat, SkRect::Make(cropRect));
robertphillipsf4e59952015-01-07 12:16:10 -080088 if (clipRect.intersect(cropRectFloat)) {
reed462a33c2015-06-22 09:10:14 -070089 SkPaint strokePaint;
90 strokePaint.setStyle(SkPaint::kStroke_Style);
caryclark5f7f4282015-07-16 07:06:46 -070091 strokePaint.setStrokeWidth(2);
reed462a33c2015-06-22 09:10:14 -070092 strokePaint.setColor(SK_ColorRED);
robertphillipsf4e59952015-01-07 12:16:10 -080093 canvas->drawRect(clipRect, strokePaint);
94 }
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000095 }
96
reed9ce9d672016-03-17 10:51:11 -070097 sk_sp<SkImage> fBitmap, fCheckerboard;
robertphillips943a4622015-09-03 13:32:33 -070098
John Stiles7571f9e2020-09-02 22:42:33 -040099 using INHERITED = skiagm::GM;
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +0000100};
reed462a33c2015-06-22 09:10:14 -0700101DEF_GM( return new OffsetImageFilterGM; )
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +0000102
103//////////////////////////////////////////////////////////////////////////////
104
reed477fdd82015-06-23 06:01:10 -0700105class SimpleOffsetImageFilterGM : public skiagm::GM {
106public:
107 SimpleOffsetImageFilterGM() {}
halcanary9d524f22016-03-29 09:03:52 -0700108
reed477fdd82015-06-23 06:01:10 -0700109protected:
110 SkString onShortName() override {
111 return SkString("simple-offsetimagefilter");
112 }
halcanary9d524f22016-03-29 09:03:52 -0700113
reed5fbb6232015-06-23 14:34:58 -0700114 SkISize onISize() override { return SkISize::Make(640, 200); }
halcanary9d524f22016-03-29 09:03:52 -0700115
robertphillips51a315e2016-03-31 09:05:49 -0700116 void doDraw(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imgf,
Michael Ludwig747c31e2021-01-28 13:20:16 -0500117 const SkIRect* cropR = nullptr, const SkRect* clipR = nullptr) {
reed477fdd82015-06-23 06:01:10 -0700118 SkPaint p;
119
120 if (clipR) {
121 p.setColor(0xFF00FF00);
122 p.setStyle(SkPaint::kStroke_Style);
123 canvas->drawRect(clipR->makeInset(SK_ScalarHalf, SK_ScalarHalf), p);
124 p.setStyle(SkPaint::kFill_Style);
125 }
126
Michael Ludwig8ee6cf32019-08-02 09:57:04 -0400127 // Visualize the crop rect for debugging
Michael Ludwig747c31e2021-01-28 13:20:16 -0500128 if (imgf && cropR) {
reedb3fe1b82015-06-23 08:29:20 -0700129 p.setColor(0x66FF00FF);
130 p.setStyle(SkPaint::kStroke_Style);
Michael Ludwig747c31e2021-01-28 13:20:16 -0500131
132 SkRect cr = SkRect::Make(*cropR).makeInset(SK_ScalarHalf, SK_ScalarHalf);
133 canvas->drawRect(cr, p);
reedb3fe1b82015-06-23 08:29:20 -0700134 p.setStyle(SkPaint::kFill_Style);
135 }
136
137 p.setColor(0x660000FF);
reed477fdd82015-06-23 06:01:10 -0700138 canvas->drawRect(r, p);
139
140 if (clipR) {
141 canvas->save();
142 canvas->clipRect(*clipR);
143 }
robertphillipsda571052015-06-23 09:28:52 -0700144 if (imgf) {
robertphillips51a315e2016-03-31 09:05:49 -0700145 p.setImageFilter(std::move(imgf));
robertphillipsda571052015-06-23 09:28:52 -0700146 }
reedb3fe1b82015-06-23 08:29:20 -0700147 p.setColor(0x66FF0000);
reed477fdd82015-06-23 06:01:10 -0700148 canvas->drawRect(r, p);
reedb3fe1b82015-06-23 08:29:20 -0700149
reed477fdd82015-06-23 06:01:10 -0700150 if (clipR) {
151 canvas->restore();
152 }
153 }
154
155 void onDraw(SkCanvas* canvas) override {
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400156 SkIRect cr0 = SkIRect::MakeWH(40, 40);
157 SkIRect cr1 = SkIRect::MakeWH(20, 20);
158 SkIRect cr2 = SkIRect::MakeXYWH(40, 0, 40, 40);
159 const SkRect r = SkRect::Make(cr0);
160 const SkRect r2 = SkRect::Make(cr2);
reed477fdd82015-06-23 06:01:10 -0700161
reed5fbb6232015-06-23 14:34:58 -0700162 canvas->translate(40, 40);
halcanary9d524f22016-03-29 09:03:52 -0700163
reed5fbb6232015-06-23 14:34:58 -0700164 canvas->save();
halcanary96fcdcc2015-08-27 07:41:13 -0700165 this->doDraw(canvas, r, nullptr);
halcanary9d524f22016-03-29 09:03:52 -0700166
reed5fbb6232015-06-23 14:34:58 -0700167 canvas->translate(100, 0);
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400168 this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr));
halcanary9d524f22016-03-29 09:03:52 -0700169
reed5fbb6232015-06-23 14:34:58 -0700170 canvas->translate(100, 0);
Michael Ludwig747c31e2021-01-28 13:20:16 -0500171 this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr, &cr0), &cr0);
halcanary9d524f22016-03-29 09:03:52 -0700172
reed5fbb6232015-06-23 14:34:58 -0700173 canvas->translate(100, 0);
Michael Ludwig747c31e2021-01-28 13:20:16 -0500174 this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr), /* cropR */ nullptr, &r);
halcanary9d524f22016-03-29 09:03:52 -0700175
reed5fbb6232015-06-23 14:34:58 -0700176 canvas->translate(100, 0);
Michael Ludwig747c31e2021-01-28 13:20:16 -0500177 this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr, &cr1), &cr1);
halcanary9d524f22016-03-29 09:03:52 -0700178
reed5fbb6232015-06-23 14:34:58 -0700179 SkRect clipR = SkRect::MakeXYWH(40, 40, 40, 40);
180 canvas->translate(100, 0);
Michael Ludwig747c31e2021-01-28 13:20:16 -0500181 this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr), /* cropR */ nullptr, &clipR);
reed5fbb6232015-06-23 14:34:58 -0700182 canvas->restore();
183
184 // 2nd row
185 canvas->translate(0, 80);
186
187 /*
188 * combos of clip and crop rects that align with src and dst
189 */
190
191 // crop==clip==src
Michael Ludwig747c31e2021-01-28 13:20:16 -0500192 this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr0), &cr0, &r);
reed5fbb6232015-06-23 14:34:58 -0700193
194 // crop==src, clip==dst
195 canvas->translate(100, 0);
Michael Ludwig747c31e2021-01-28 13:20:16 -0500196 this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr0), &cr0, &r2);
reed5fbb6232015-06-23 14:34:58 -0700197
198 // crop==dst, clip==src
199 canvas->translate(100, 0);
Michael Ludwig747c31e2021-01-28 13:20:16 -0500200 this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr2), &cr2, &r);
reed5fbb6232015-06-23 14:34:58 -0700201
202 // crop==clip==dst
203 canvas->translate(100, 0);
Michael Ludwig747c31e2021-01-28 13:20:16 -0500204 this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr2), &cr2, &r2);
reed477fdd82015-06-23 06:01:10 -0700205 }
206
207private:
John Stiles7571f9e2020-09-02 22:42:33 -0400208 using INHERITED = skiagm::GM;
reed477fdd82015-06-23 06:01:10 -0700209};
210DEF_GM( return new SimpleOffsetImageFilterGM; )