blob: 7a006cc8c6f880d0574644aaf5a3eac728e478d3 [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 {
reed9ce9d672016-03-17 10:51:11 -070047 fBitmap = SkImage::MakeFromBitmap(
Mike Kleinea3f0142019-03-20 11:12:10 -050048 ToolUtils::create_string_bitmap(80, 80, 0xD000D000, 15, 65, 96, "e"));
halcanary9d524f22016-03-29 09:03:52 -070049
reed9ce9d672016-03-17 10:51:11 -070050 fCheckerboard = SkImage::MakeFromBitmap(
Mike Kleinea3f0142019-03-20 11:12:10 -050051 ToolUtils::create_checkerboard_bitmap(80, 80, 0xFFA0A0A0, 0xFF404040, 8));
fmalita5598b632015-09-15 11:26:13 -070052 }
53
54 void onDraw(SkCanvas* canvas) override {
55 canvas->clear(SK_ColorBLACK);
56 SkPaint paint;
57
58 for (int i = 0; i < 4; i++) {
robertphillips549c8992016-04-01 09:28:51 -070059 sk_sp<SkImage> image = (i & 0x01) ? fCheckerboard : fBitmap;
fmalita5598b632015-09-15 11:26:13 -070060 SkIRect cropRect = SkIRect::MakeXYWH(i * 12,
61 i * 8,
62 image->width() - i * 8,
63 image->height() - i * 12);
Michael Ludwig898bbfa2019-08-02 15:21:23 -040064 sk_sp<SkImageFilter> tileInput(SkImageFilters::Image(image));
fmalita5598b632015-09-15 11:26:13 -070065 SkScalar dx = SkIntToScalar(i*5);
66 SkScalar dy = SkIntToScalar(i*10);
Michael Ludwig898bbfa2019-08-02 15:21:23 -040067 paint.setImageFilter(SkImageFilters::Offset(dx, dy, std::move(tileInput), &cropRect));
robertphillips549c8992016-04-01 09:28:51 -070068 DrawClippedImage(canvas, image.get(), paint, 1, cropRect);
fmalita5598b632015-09-15 11:26:13 -070069 canvas->translate(SkIntToScalar(image->width() + MARGIN), 0);
70 }
71
72 SkIRect cropRect = SkIRect::MakeXYWH(0, 0, 100, 100);
Michael Ludwig898bbfa2019-08-02 15:21:23 -040073 paint.setImageFilter(SkImageFilters::Offset(-5, -10, nullptr, &cropRect));
reed9ce9d672016-03-17 10:51:11 -070074 DrawClippedImage(canvas, fBitmap.get(), paint, 2, cropRect);
fmalita5598b632015-09-15 11:26:13 -070075 }
76private:
77 static void DrawClippedImage(SkCanvas* canvas, const SkImage* image, const SkPaint& paint,
78 SkScalar scale, const SkIRect& cropRect) {
79 SkRect clipRect = SkRect::MakeIWH(image->width(), image->height());
reed462a33c2015-06-22 09:10:14 -070080
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000081 canvas->save();
senorblanco@chromium.orge09244d2014-03-04 19:05:25 +000082 canvas->clipRect(clipRect);
83 canvas->scale(scale, scale);
fmalita5598b632015-09-15 11:26:13 -070084 canvas->drawImage(image, 0, 0, &paint);
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000085 canvas->restore();
senorblanco@chromium.orge09244d2014-03-04 19:05:25 +000086
reed462a33c2015-06-22 09:10:14 -070087 // Draw a boundary rect around the intersection of the clip rect and crop rect.
senorblanco@chromium.orge09244d2014-03-04 19:05:25 +000088 SkRect cropRectFloat;
reed462a33c2015-06-22 09:10:14 -070089 SkMatrix::MakeScale(scale, scale).mapRect(&cropRectFloat, SkRect::Make(cropRect));
robertphillipsf4e59952015-01-07 12:16:10 -080090 if (clipRect.intersect(cropRectFloat)) {
reed462a33c2015-06-22 09:10:14 -070091 SkPaint strokePaint;
92 strokePaint.setStyle(SkPaint::kStroke_Style);
caryclark5f7f4282015-07-16 07:06:46 -070093 strokePaint.setStrokeWidth(2);
reed462a33c2015-06-22 09:10:14 -070094 strokePaint.setColor(SK_ColorRED);
robertphillipsf4e59952015-01-07 12:16:10 -080095 canvas->drawRect(clipRect, strokePaint);
96 }
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +000097 }
98
reed9ce9d672016-03-17 10:51:11 -070099 sk_sp<SkImage> fBitmap, fCheckerboard;
robertphillips943a4622015-09-03 13:32:33 -0700100
101 typedef skiagm::GM INHERITED;
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +0000102};
reed462a33c2015-06-22 09:10:14 -0700103DEF_GM( return new OffsetImageFilterGM; )
commit-bot@chromium.org1a4fb702013-09-26 16:09:28 +0000104
105//////////////////////////////////////////////////////////////////////////////
106
reed477fdd82015-06-23 06:01:10 -0700107class SimpleOffsetImageFilterGM : public skiagm::GM {
108public:
109 SimpleOffsetImageFilterGM() {}
halcanary9d524f22016-03-29 09:03:52 -0700110
reed477fdd82015-06-23 06:01:10 -0700111protected:
112 SkString onShortName() override {
113 return SkString("simple-offsetimagefilter");
114 }
halcanary9d524f22016-03-29 09:03:52 -0700115
reed5fbb6232015-06-23 14:34:58 -0700116 SkISize onISize() override { return SkISize::Make(640, 200); }
halcanary9d524f22016-03-29 09:03:52 -0700117
robertphillips51a315e2016-03-31 09:05:49 -0700118 void doDraw(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imgf,
halcanary96fcdcc2015-08-27 07:41:13 -0700119 const SkRect* clipR = nullptr) {
reed477fdd82015-06-23 06:01:10 -0700120 SkPaint p;
121
122 if (clipR) {
123 p.setColor(0xFF00FF00);
124 p.setStyle(SkPaint::kStroke_Style);
125 canvas->drawRect(clipR->makeInset(SK_ScalarHalf, SK_ScalarHalf), p);
126 p.setStyle(SkPaint::kFill_Style);
127 }
128
Michael Ludwig8ee6cf32019-08-02 09:57:04 -0400129 // Visualize the crop rect for debugging
130 if (imgf && as_IFB(imgf)->cropRectIsSet()) {
131 SkImageFilter::CropRect cr = as_IFB(imgf)->getCropRect();
reedb3fe1b82015-06-23 08:29:20 -0700132
133 p.setColor(0x66FF00FF);
134 p.setStyle(SkPaint::kStroke_Style);
135 canvas->drawRect(cr.rect().makeInset(SK_ScalarHalf, SK_ScalarHalf), p);
136 p.setStyle(SkPaint::kFill_Style);
137 }
138
139 p.setColor(0x660000FF);
reed477fdd82015-06-23 06:01:10 -0700140 canvas->drawRect(r, p);
141
142 if (clipR) {
143 canvas->save();
144 canvas->clipRect(*clipR);
145 }
robertphillipsda571052015-06-23 09:28:52 -0700146 if (imgf) {
robertphillips51a315e2016-03-31 09:05:49 -0700147 p.setImageFilter(std::move(imgf));
robertphillipsda571052015-06-23 09:28:52 -0700148 }
reedb3fe1b82015-06-23 08:29:20 -0700149 p.setColor(0x66FF0000);
reed477fdd82015-06-23 06:01:10 -0700150 canvas->drawRect(r, p);
reedb3fe1b82015-06-23 08:29:20 -0700151
reed477fdd82015-06-23 06:01:10 -0700152 if (clipR) {
153 canvas->restore();
154 }
155 }
156
157 void onDraw(SkCanvas* canvas) override {
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400158 SkIRect cr0 = SkIRect::MakeWH(40, 40);
159 SkIRect cr1 = SkIRect::MakeWH(20, 20);
160 SkIRect cr2 = SkIRect::MakeXYWH(40, 0, 40, 40);
161 const SkRect r = SkRect::Make(cr0);
162 const SkRect r2 = SkRect::Make(cr2);
reed477fdd82015-06-23 06:01:10 -0700163
reed5fbb6232015-06-23 14:34:58 -0700164 canvas->translate(40, 40);
halcanary9d524f22016-03-29 09:03:52 -0700165
reed5fbb6232015-06-23 14:34:58 -0700166 canvas->save();
halcanary96fcdcc2015-08-27 07:41:13 -0700167 this->doDraw(canvas, r, nullptr);
halcanary9d524f22016-03-29 09:03:52 -0700168
reed5fbb6232015-06-23 14:34:58 -0700169 canvas->translate(100, 0);
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400170 this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr));
halcanary9d524f22016-03-29 09:03:52 -0700171
reed5fbb6232015-06-23 14:34:58 -0700172 canvas->translate(100, 0);
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400173 this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr, &cr0));
halcanary9d524f22016-03-29 09:03:52 -0700174
reed5fbb6232015-06-23 14:34:58 -0700175 canvas->translate(100, 0);
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400176 this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr), &r);
halcanary9d524f22016-03-29 09:03:52 -0700177
reed5fbb6232015-06-23 14:34:58 -0700178 canvas->translate(100, 0);
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400179 this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr, &cr1));
halcanary9d524f22016-03-29 09:03:52 -0700180
reed5fbb6232015-06-23 14:34:58 -0700181 SkRect clipR = SkRect::MakeXYWH(40, 40, 40, 40);
182 canvas->translate(100, 0);
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400183 this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr, nullptr), &clipR);
reed5fbb6232015-06-23 14:34:58 -0700184 canvas->restore();
185
186 // 2nd row
187 canvas->translate(0, 80);
188
189 /*
190 * combos of clip and crop rects that align with src and dst
191 */
192
193 // crop==clip==src
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400194 this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr0), &r);
reed5fbb6232015-06-23 14:34:58 -0700195
196 // crop==src, clip==dst
197 canvas->translate(100, 0);
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400198 this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr0), &r2);
reed5fbb6232015-06-23 14:34:58 -0700199
200 // crop==dst, clip==src
201 canvas->translate(100, 0);
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400202 this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr2), &r);
reed5fbb6232015-06-23 14:34:58 -0700203
204 // crop==clip==dst
205 canvas->translate(100, 0);
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400206 this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr2), &r2);
reed477fdd82015-06-23 06:01:10 -0700207 }
208
209private:
210 typedef skiagm::GM INHERITED;
211};
212DEF_GM( return new SimpleOffsetImageFilterGM; )