1 /*
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/gm.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkBlendMode.h"
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkColorFilter.h"
14 #include "include/core/SkFont.h"
15 #include "include/core/SkImageFilter.h"
16 #include "include/core/SkPaint.h"
17 #include "include/core/SkRect.h"
18 #include "include/core/SkRefCnt.h"
19 #include "include/core/SkScalar.h"
20 #include "include/core/SkSize.h"
21 #include "include/core/SkString.h"
22 #include "include/core/SkTypeface.h"
23 #include "include/core/SkTypes.h"
24 #include "include/effects/SkImageFilters.h"
25 #include "include/utils/SkTextUtils.h"
26 #include "tools/ToolUtils.h"
27 
28 #include <utility>
29 
30 ///////////////////////////////////////////////////////////////////////////////
31 
draw_paint(SkCanvas * canvas,const SkRect & r,sk_sp<SkImageFilter> imf)32 static void draw_paint(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
33     SkPaint paint;
34     paint.setImageFilter(std::move(imf));
35     paint.setColor(SK_ColorBLACK);
36     canvas->save();
37     canvas->clipRect(r);
38     canvas->drawPaint(paint);
39     canvas->restore();
40 }
41 
draw_path(SkCanvas * canvas,const SkRect & r,sk_sp<SkImageFilter> imf)42 static void draw_path(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
43     SkPaint paint;
44     paint.setColor(SK_ColorMAGENTA);
45     paint.setImageFilter(std::move(imf));
46     paint.setAntiAlias(true);
47     canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint);
48 }
49 
draw_text(SkCanvas * canvas,const SkRect & r,sk_sp<SkImageFilter> imf)50 static void draw_text(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
51     SkPaint paint;
52     paint.setImageFilter(std::move(imf));
53     paint.setColor(SK_ColorGREEN);
54 
55     SkFont font(ToolUtils::create_portable_typeface(), r.height() / 2);
56     SkTextUtils::DrawString(canvas, "Text", r.centerX(), r.centerY(), font, paint, SkTextUtils::kCenter_Align);
57 }
58 
draw_bitmap(SkCanvas * canvas,const SkRect & r,sk_sp<SkImageFilter> imf)59 static void draw_bitmap(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) {
60     SkPaint paint;
61 
62     SkIRect bounds;
63     r.roundOut(&bounds);
64 
65     SkBitmap bm;
66     bm.allocN32Pixels(bounds.width(), bounds.height());
67     bm.eraseColor(SK_ColorTRANSPARENT);
68     SkCanvas c(bm);
69     draw_path(&c, r, nullptr);
70 
71     paint.setImageFilter(std::move(imf));
72     canvas->drawBitmap(bm, 0, 0, &paint);
73 }
74 
75 ///////////////////////////////////////////////////////////////////////////////
76 
77 class ImageFiltersCroppedGM : public skiagm::GM {
78 public:
ImageFiltersCroppedGM()79     ImageFiltersCroppedGM () {}
80 
81 protected:
onShortName()82     SkString onShortName() override {
83         return SkString("imagefilterscropped");
84     }
85 
onISize()86     SkISize onISize() override { return SkISize::Make(400, 960); }
87 
make_checkerboard()88     void make_checkerboard() {
89         fCheckerboard.allocN32Pixels(80, 80);
90         SkCanvas canvas(fCheckerboard);
91         canvas.clear(SK_ColorTRANSPARENT);
92         SkPaint darkPaint;
93         darkPaint.setColor(0xFF404040);
94         SkPaint lightPaint;
95         lightPaint.setColor(0xFFA0A0A0);
96         for (int y = 0; y < 80; y += 16) {
97             for (int x = 0; x < 80; x += 16) {
98                 canvas.save();
99                 canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
100                 canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
101                 canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
102                 canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
103                 canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
104                 canvas.restore();
105             }
106         }
107     }
108 
draw_frame(SkCanvas * canvas,const SkRect & r)109     void draw_frame(SkCanvas* canvas, const SkRect& r) {
110         SkPaint paint;
111         paint.setStyle(SkPaint::kStroke_Style);
112         paint.setColor(SK_ColorRED);
113         canvas->drawRect(r, paint);
114     }
115 
onOnceBeforeDraw()116     void onOnceBeforeDraw() override {
117         make_checkerboard();
118     }
119 
onDraw(SkCanvas * canvas)120     void onDraw(SkCanvas* canvas) override {
121         void (*drawProc[])(SkCanvas*, const SkRect&, sk_sp<SkImageFilter>) = {
122             draw_bitmap, draw_path, draw_paint, draw_text
123         };
124 
125         sk_sp<SkColorFilter> cf(SkColorFilters::Blend(SK_ColorBLUE,
126                                                               SkBlendMode::kSrcIn));
127         SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 44, 44);
128         SkIRect bogusRect = SkIRect::MakeXYWH(-100, -100, 10, 10);
129 
130         sk_sp<SkImageFilter> offset(SkImageFilters::Offset(-10, -10, nullptr));
131 
132         sk_sp<SkImageFilter> cfOffset(SkImageFilters::ColorFilter(cf, std::move(offset)));
133 
134         sk_sp<SkImageFilter> erodeX(SkImageFilters::Erode(8, 0, nullptr, &cropRect));
135         sk_sp<SkImageFilter> erodeY(SkImageFilters::Erode(0, 8, nullptr, &cropRect));
136 
137         sk_sp<SkImageFilter> filters[] = {
138             nullptr,
139             SkImageFilters::ColorFilter(cf, nullptr, &cropRect),
140             SkImageFilters::Blur(0.0f, 0.0f, nullptr, &cropRect),
141             SkImageFilters::Blur(1.0f, 1.0f, nullptr, &cropRect),
142             SkImageFilters::Blur(8.0f, 0.0f, nullptr, &cropRect),
143             SkImageFilters::Blur(0.0f, 8.0f, nullptr, &cropRect),
144             SkImageFilters::Blur(8.0f, 8.0f, nullptr, &cropRect),
145             SkImageFilters::Erode(1, 1, nullptr, &cropRect),
146             SkImageFilters::Erode(8, 0, std::move(erodeY), &cropRect),
147             SkImageFilters::Erode(0, 8, std::move(erodeX), &cropRect),
148             SkImageFilters::Erode(8, 8, nullptr, &cropRect),
149             SkImageFilters::Merge(nullptr, std::move(cfOffset), &cropRect),
150             SkImageFilters::Blur(8.0f, 8.0f, nullptr, &bogusRect),
151             SkImageFilters::ColorFilter(cf, nullptr, &bogusRect),
152         };
153 
154         SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
155         SkScalar MARGIN = SkIntToScalar(16);
156         SkScalar DX = r.width() + MARGIN;
157         SkScalar DY = r.height() + MARGIN;
158 
159         canvas->translate(MARGIN, MARGIN);
160         for (size_t j = 0; j < SK_ARRAY_COUNT(drawProc); ++j) {
161             canvas->save();
162             for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
163                 SkPaint paint;
164                 canvas->drawBitmap(fCheckerboard, 0, 0);
165                 drawProc[j](canvas, r, filters[i]);
166                 canvas->translate(0, DY);
167             }
168             canvas->restore();
169             canvas->translate(DX, 0);
170         }
171     }
172 
173 private:
174     SkBitmap fCheckerboard;
175     using INHERITED = GM;
176 };
177 
178 ///////////////////////////////////////////////////////////////////////////////
179 
180 DEF_GM( return new ImageFiltersCroppedGM; )
181