blob: 5472f2d98a2c2fcd1ef01dc8ac65ec724f6c82c3 [file] [log] [blame]
reed@google.com8926b162012-03-23 15:36:36 +00001/*
2 * Copyright 2011 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
8#include "gm.h"
9#include "SkCanvas.h"
10#include "SkColorFilter.h"
11#include "SkColorPriv.h"
12#include "SkShader.h"
13
14#include "SkBlurImageFilter.h"
senorblanco@chromium.org44888c62012-08-20 19:23:24 +000015#include "SkColorFilterImageFilter.h"
junov@chromium.orgf44fcdc2013-08-07 20:00:55 +000016#include "SkDropShadowImageFilter.h"
reed@google.com8926b162012-03-23 15:36:36 +000017#include "SkTestImageFilters.h"
18
19class FailImageFilter : public SkImageFilter {
20public:
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000021 static FailImageFilter* Create() {
22 return SkNEW(FailImageFilter);
23 }
djsollen@google.comba28d032012-03-26 17:57:35 +000024
25 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter)
reed9fa60da2014-08-21 07:59:51 -070026
reed@google.com8926b162012-03-23 15:36:36 +000027protected:
reed9fa60da2014-08-21 07:59:51 -070028 FailImageFilter() : INHERITED(0, NULL) {
29 static bool gOnce;
30 if (!gOnce) {
31 gOnce = true;
32 SkFlattenable::Register("FailImageFilter", this->getFactory(),
33 this->GetFlattenableType());
34 }
35 }
36
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000037 virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
commit-bot@chromium.orgf7efa502014-04-11 18:57:00 +000038 SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
reed@google.com8926b162012-03-23 15:36:36 +000039 return false;
40 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000041
reed9fa60da2014-08-21 07:59:51 -070042#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
43 FailImageFilter(SkReadBuffer& buffer) : INHERITED(0, buffer) {}
44#endif
reed@google.com8926b162012-03-23 15:36:36 +000045
46private:
reed@google.com8926b162012-03-23 15:36:36 +000047 typedef SkImageFilter INHERITED;
48};
49
reed9fa60da2014-08-21 07:59:51 -070050SkFlattenable* FailImageFilter::CreateProc(SkReadBuffer& buffer) {
51 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
52 return FailImageFilter::Create();
53}
djsollen@google.comba28d032012-03-26 17:57:35 +000054
reed@google.com8926b162012-03-23 15:36:36 +000055class IdentityImageFilter : public SkImageFilter {
56public:
senorblanco9ea3d572014-07-08 09:16:22 -070057 static IdentityImageFilter* Create(SkImageFilter* input = NULL) {
58 return SkNEW_ARGS(IdentityImageFilter, (input));
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000059 }
reed@google.com8926b162012-03-23 15:36:36 +000060
djsollen@google.comba28d032012-03-26 17:57:35 +000061 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(IdentityImageFilter)
reed@google.com8926b162012-03-23 15:36:36 +000062protected:
reed9fa60da2014-08-21 07:59:51 -070063 IdentityImageFilter(SkImageFilter* input) : INHERITED(1, &input) {
64 static bool gOnce;
65 if (!gOnce) {
66 gOnce = true;
67 SkFlattenable::Register("IdentityImageFilter", this->getFactory(),
68 this->GetFlattenableType());
69 }
70 }
71
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000072 virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
commit-bot@chromium.orgf7efa502014-04-11 18:57:00 +000073 SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
reed@google.com8926b162012-03-23 15:36:36 +000074 *result = src;
commit-bot@chromium.orgf7efa502014-04-11 18:57:00 +000075 offset->set(0, 0);
reed@google.com8926b162012-03-23 15:36:36 +000076 return true;
77 }
78
reed9fa60da2014-08-21 07:59:51 -070079#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
80 IdentityImageFilter(SkReadBuffer& buffer) : INHERITED(1, buffer) {}
81#endif
reed@google.com8926b162012-03-23 15:36:36 +000082
83private:
reed@google.com8926b162012-03-23 15:36:36 +000084 typedef SkImageFilter INHERITED;
85};
86
reed9fa60da2014-08-21 07:59:51 -070087SkFlattenable* IdentityImageFilter::CreateProc(SkReadBuffer& buffer) {
88 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
89 return IdentityImageFilter::Create(common.getInput(0));
90}
djsollen@google.comba28d032012-03-26 17:57:35 +000091
reed@google.com8926b162012-03-23 15:36:36 +000092///////////////////////////////////////////////////////////////////////////////
93
94static void draw_paint(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
95 SkPaint paint;
96 paint.setImageFilter(imf);
97 paint.setColor(SK_ColorGREEN);
98 canvas->save();
99 canvas->clipRect(r);
100 canvas->drawPaint(paint);
101 canvas->restore();
102}
103
104static void draw_line(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
105 SkPaint paint;
106 paint.setColor(SK_ColorBLUE);
107 paint.setImageFilter(imf);
108 paint.setStrokeWidth(r.width()/10);
109 canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
110}
111
112static void draw_rect(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
113 SkPaint paint;
114 paint.setColor(SK_ColorYELLOW);
115 paint.setImageFilter(imf);
116 SkRect rr(r);
117 rr.inset(r.width()/10, r.height()/10);
118 canvas->drawRect(rr, paint);
119}
120
121static void draw_path(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
122 SkPaint paint;
123 paint.setColor(SK_ColorMAGENTA);
124 paint.setImageFilter(imf);
125 paint.setAntiAlias(true);
126 canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint);
127}
128
129static void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
130 SkPaint paint;
131 paint.setImageFilter(imf);
132 paint.setColor(SK_ColorCYAN);
133 paint.setAntiAlias(true);
Cary Clark992c7b02014-07-31 08:58:44 -0400134 sk_tool_utils::set_portable_typeface(&paint);
reed@google.com8926b162012-03-23 15:36:36 +0000135 paint.setTextSize(r.height()/2);
136 paint.setTextAlign(SkPaint::kCenter_Align);
137 canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint);
138}
139
140static void draw_bitmap(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
141 SkPaint paint;
142 paint.setImageFilter(imf);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000143
reed@google.com8926b162012-03-23 15:36:36 +0000144 SkIRect bounds;
145 r.roundOut(&bounds);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000146
reed@google.com8926b162012-03-23 15:36:36 +0000147 SkBitmap bm;
reed@google.comeb9a46c2014-01-25 16:46:20 +0000148 bm.allocN32Pixels(bounds.width(), bounds.height());
junov@google.comdbfac8a2012-12-06 21:47:40 +0000149 bm.eraseColor(SK_ColorTRANSPARENT);
reed@google.com8926b162012-03-23 15:36:36 +0000150 SkCanvas c(bm);
151 draw_path(&c, r, NULL);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000152
reed@google.com8926b162012-03-23 15:36:36 +0000153 canvas->drawBitmap(bm, 0, 0, &paint);
154}
155
156static void draw_sprite(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
157 SkPaint paint;
158 paint.setImageFilter(imf);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000159
reed@google.com8926b162012-03-23 15:36:36 +0000160 SkIRect bounds;
161 r.roundOut(&bounds);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000162
reed@google.com8926b162012-03-23 15:36:36 +0000163 SkBitmap bm;
reed@google.comeb9a46c2014-01-25 16:46:20 +0000164 bm.allocN32Pixels(bounds.width(), bounds.height());
junov@google.comdbfac8a2012-12-06 21:47:40 +0000165 bm.eraseColor(SK_ColorTRANSPARENT);
reed@google.com8926b162012-03-23 15:36:36 +0000166 SkCanvas c(bm);
167 draw_path(&c, r, NULL);
168
169 SkPoint loc = { r.fLeft, r.fTop };
170 canvas->getTotalMatrix().mapPoints(&loc, 1);
171 canvas->drawSprite(bm,
172 SkScalarRoundToInt(loc.fX), SkScalarRoundToInt(loc.fY),
173 &paint);
174}
175
176///////////////////////////////////////////////////////////////////////////////
177
178class ImageFiltersBaseGM : public skiagm::GM {
179public:
180 ImageFiltersBaseGM () {}
181
182protected:
reed@google.com8926b162012-03-23 15:36:36 +0000183 virtual SkString onShortName() {
184 return SkString("imagefiltersbase");
185 }
186
junov@chromium.orgf44fcdc2013-08-07 20:00:55 +0000187 virtual SkISize onISize() { return SkISize::Make(700, 500); }
reed@google.com8926b162012-03-23 15:36:36 +0000188
189 void draw_frame(SkCanvas* canvas, const SkRect& r) {
190 SkPaint paint;
191 paint.setStyle(SkPaint::kStroke_Style);
192 paint.setColor(SK_ColorRED);
193 canvas->drawRect(r, paint);
194 }
195
junov@chromium.orgff06af22013-01-14 16:27:50 +0000196 virtual uint32_t onGetFlags() const {
197 // Because of the use of drawSprite, this test is excluded
198 // from scaled replay tests because drawSprite ignores the
199 // reciprocal scale that is applied at record time, which is
200 // the intended behavior of drawSprite.
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000201 return kSkipScaledReplay_Flag | kSkipTiled_Flag;
junov@chromium.orgff06af22013-01-14 16:27:50 +0000202 }
203
reed@google.com8926b162012-03-23 15:36:36 +0000204 virtual void onDraw(SkCanvas* canvas) {
205 void (*drawProc[])(SkCanvas*, const SkRect&, SkImageFilter*) = {
206 draw_paint,
207 draw_line, draw_rect, draw_path, draw_text,
208 draw_bitmap,
209 draw_sprite
210 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000211
reed@google.com8926b162012-03-23 15:36:36 +0000212 SkColorFilter* cf = SkColorFilter::CreateModeFilter(SK_ColorRED,
213 SkXfermode::kSrcIn_Mode);
214 SkImageFilter* filters[] = {
reed@google.com8926b162012-03-23 15:36:36 +0000215 NULL,
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +0000216 IdentityImageFilter::Create(),
217 FailImageFilter::Create(),
senorblanco@chromium.orgcd9f5592012-10-26 19:37:00 +0000218 SkColorFilterImageFilter::Create(cf),
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +0000219 SkBlurImageFilter::Create(12.0f, 0.0f),
senorblancobc9845b2014-07-22 12:49:25 -0700220 SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE),
reed@google.com8926b162012-03-23 15:36:36 +0000221 };
222 cf->unref();
223
224 SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
225 SkScalar MARGIN = SkIntToScalar(16);
226 SkScalar DX = r.width() + MARGIN;
227 SkScalar DY = r.height() + MARGIN;
228
229 canvas->translate(MARGIN, MARGIN);
230 for (size_t i = 0; i < SK_ARRAY_COUNT(drawProc); ++i) {
231 canvas->save();
232 for (size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
233 drawProc[i](canvas, r, filters[j]);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000234
reed@google.com8926b162012-03-23 15:36:36 +0000235 draw_frame(canvas, r);
236 canvas->translate(0, DY);
237 }
238 canvas->restore();
239 canvas->translate(DX, 0);
240 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000241
reed@google.com4bca84d2012-06-27 14:00:06 +0000242 for(size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
243 SkSafeUnref(filters[j]);
244 }
reed@google.com8926b162012-03-23 15:36:36 +0000245 }
246
247private:
248 typedef GM INHERITED;
249};
250
251///////////////////////////////////////////////////////////////////////////////
252
253static skiagm::GM* MyFactory(void*) { return new ImageFiltersBaseGM; }
254static skiagm::GMRegistry reg(MyFactory);