| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 1 | /* | 
| humper@google.com | a99a92c | 2013-02-20 16:42:06 +0000 | [diff] [blame] | 2 | * Copyright 2012 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 | */ | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 7 |  | 
| Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 8 | #include "gm/gm.h" | 
| Ben Wagner | 6a34f3a | 2019-05-01 10:59:30 -0400 | [diff] [blame] | 9 | #include "include/core/SkBitmap.h" | 
|  | 10 | #include "include/core/SkBlurTypes.h" | 
| Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 11 | #include "include/core/SkCanvas.h" | 
| Ben Wagner | 6a34f3a | 2019-05-01 10:59:30 -0400 | [diff] [blame] | 12 | #include "include/core/SkColor.h" | 
| Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 13 | #include "include/core/SkMaskFilter.h" | 
| Ben Wagner | 6a34f3a | 2019-05-01 10:59:30 -0400 | [diff] [blame] | 14 | #include "include/core/SkMatrix.h" | 
|  | 15 | #include "include/core/SkPaint.h" | 
| Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 16 | #include "include/core/SkPath.h" | 
| Ben Wagner | 6a34f3a | 2019-05-01 10:59:30 -0400 | [diff] [blame] | 17 | #include "include/core/SkPoint.h" | 
|  | 18 | #include "include/core/SkRect.h" | 
|  | 19 | #include "include/core/SkRefCnt.h" | 
|  | 20 | #include "include/core/SkScalar.h" | 
|  | 21 | #include "include/core/SkShader.h" | 
|  | 22 | #include "include/core/SkSize.h" | 
|  | 23 | #include "include/core/SkString.h" | 
|  | 24 | #include "include/core/SkTileMode.h" | 
|  | 25 | #include "include/core/SkTypes.h" | 
|  | 26 | #include "include/effects/SkGradientShader.h" | 
| Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 27 | #include "include/private/SkTo.h" | 
|  | 28 | #include "src/core/SkBlurMask.h" | 
| Ben Wagner | 6a34f3a | 2019-05-01 10:59:30 -0400 | [diff] [blame] | 29 | #include "src/core/SkMask.h" | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 30 |  | 
|  | 31 | #define STROKE_WIDTH    SkIntToScalar(10) | 
|  | 32 |  | 
|  | 33 | typedef void (*Proc)(SkCanvas*, const SkRect&, const SkPaint&); | 
|  | 34 |  | 
|  | 35 | static void fill_rect(SkCanvas* canvas, const SkRect& r, const SkPaint& p) { | 
|  | 36 | canvas->drawRect(r, p); | 
|  | 37 | } | 
|  | 38 |  | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 39 | static void draw_donut(SkCanvas* canvas, const SkRect& r, const SkPaint& p) { | 
|  | 40 | SkRect  rect; | 
|  | 41 | SkPath  path; | 
| skia.committer@gmail.com | 3458716 | 2012-11-20 02:01:23 +0000 | [diff] [blame] | 42 |  | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 43 | rect = r; | 
|  | 44 | rect.outset(STROKE_WIDTH/2, STROKE_WIDTH/2); | 
|  | 45 | path.addRect(rect); | 
|  | 46 | rect = r; | 
|  | 47 | rect.inset(STROKE_WIDTH/2, STROKE_WIDTH/2); | 
| skia.committer@gmail.com | 3458716 | 2012-11-20 02:01:23 +0000 | [diff] [blame] | 48 |  | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 49 | path.addRect(rect); | 
|  | 50 | path.setFillType(SkPath::kEvenOdd_FillType); | 
| skia.committer@gmail.com | 3458716 | 2012-11-20 02:01:23 +0000 | [diff] [blame] | 51 |  | 
| reed@google.com | 808b70f | 2012-11-19 16:14:02 +0000 | [diff] [blame] | 52 | canvas->drawPath(path, p); | 
|  | 53 | } | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 54 |  | 
| reed@google.com | 808b70f | 2012-11-19 16:14:02 +0000 | [diff] [blame] | 55 | static void draw_donut_skewed(SkCanvas* canvas, const SkRect& r, const SkPaint& p) { | 
|  | 56 | SkRect  rect; | 
|  | 57 | SkPath  path; | 
| skia.committer@gmail.com | 3458716 | 2012-11-20 02:01:23 +0000 | [diff] [blame] | 58 |  | 
| reed@google.com | 808b70f | 2012-11-19 16:14:02 +0000 | [diff] [blame] | 59 | rect = r; | 
|  | 60 | rect.outset(STROKE_WIDTH/2, STROKE_WIDTH/2); | 
|  | 61 | path.addRect(rect); | 
|  | 62 | rect = r; | 
|  | 63 | rect.inset(STROKE_WIDTH/2, STROKE_WIDTH/2); | 
| skia.committer@gmail.com | 3458716 | 2012-11-20 02:01:23 +0000 | [diff] [blame] | 64 |  | 
| reed@google.com | 808b70f | 2012-11-19 16:14:02 +0000 | [diff] [blame] | 65 | rect.offset(7, -7); | 
| skia.committer@gmail.com | 3458716 | 2012-11-20 02:01:23 +0000 | [diff] [blame] | 66 |  | 
| reed@google.com | 808b70f | 2012-11-19 16:14:02 +0000 | [diff] [blame] | 67 | path.addRect(rect); | 
|  | 68 | path.setFillType(SkPath::kEvenOdd_FillType); | 
| skia.committer@gmail.com | 3458716 | 2012-11-20 02:01:23 +0000 | [diff] [blame] | 69 |  | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 70 | canvas->drawPath(path, p); | 
|  | 71 | } | 
|  | 72 |  | 
| joshualitt | 341400e | 2014-12-18 11:54:13 -0800 | [diff] [blame] | 73 | /* | 
|  | 74 | * Spits out a dummy gradient to test blur with shader on paint | 
|  | 75 | */ | 
| Robert Phillips | 09dfc47 | 2017-09-13 15:25:47 -0400 | [diff] [blame] | 76 | static sk_sp<SkShader> make_radial() { | 
| joshualitt | 341400e | 2014-12-18 11:54:13 -0800 | [diff] [blame] | 77 | SkPoint pts[2] = { | 
|  | 78 | { 0, 0 }, | 
|  | 79 | { SkIntToScalar(100), SkIntToScalar(100) } | 
|  | 80 | }; | 
| Mike Reed | fae8fce | 2019-04-03 10:27:45 -0400 | [diff] [blame] | 81 | SkTileMode tm = SkTileMode::kClamp; | 
| joshualitt | 341400e | 2014-12-18 11:54:13 -0800 | [diff] [blame] | 82 | const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, }; | 
|  | 83 | const SkScalar pos[] = { SK_Scalar1/4, SK_Scalar1*3/4 }; | 
|  | 84 | SkMatrix scale; | 
|  | 85 | scale.setScale(0.5f, 0.5f); | 
|  | 86 | scale.postTranslate(25.f, 25.f); | 
|  | 87 | SkPoint center0, center1; | 
|  | 88 | center0.set(SkScalarAve(pts[0].fX, pts[1].fX), | 
|  | 89 | SkScalarAve(pts[0].fY, pts[1].fY)); | 
|  | 90 | center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), | 
|  | 91 | SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); | 
| reed | 2ad1aa6 | 2016-03-09 09:50:50 -0800 | [diff] [blame] | 92 | return SkGradientShader::MakeTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7, | 
|  | 93 | center0, (pts[1].fX - pts[0].fX) / 2, | 
|  | 94 | colors, pos, SK_ARRAY_COUNT(colors), tm, | 
|  | 95 | 0, &scale); | 
| joshualitt | 341400e | 2014-12-18 11:54:13 -0800 | [diff] [blame] | 96 | } | 
|  | 97 |  | 
| reed@google.com | 53007a2 | 2012-11-26 14:39:50 +0000 | [diff] [blame] | 98 | typedef void (*PaintProc)(SkPaint*, SkScalar width); | 
|  | 99 |  | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 100 | class BlurRectGM : public skiagm::GM { | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 101 | public: | 
| Hal Canary | 594fe85 | 2019-07-18 13:35:49 -0400 | [diff] [blame^] | 102 | BlurRectGM(const char name[], U8CPU alpha) : fName(name), fAlpha(SkToU8(alpha)) {} | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 103 |  | 
| Hal Canary | 594fe85 | 2019-07-18 13:35:49 -0400 | [diff] [blame^] | 104 | private: | 
|  | 105 | sk_sp<SkMaskFilter> fMaskFilters[kLastEnum_SkBlurStyle + 1]; | 
|  | 106 | const char* fName; | 
|  | 107 | SkAlpha fAlpha; | 
|  | 108 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 109 | void onOnceBeforeDraw() override { | 
| commit-bot@chromium.org | e396455 | 2014-04-28 16:25:35 +0000 | [diff] [blame] | 110 | for (int i = 0; i <= kLastEnum_SkBlurStyle; ++i) { | 
| Mike Reed | 1be1f8d | 2018-03-14 13:01:17 -0400 | [diff] [blame] | 111 | fMaskFilters[i] = SkMaskFilter::MakeBlur((SkBlurStyle)i, | 
|  | 112 | SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(STROKE_WIDTH/2))); | 
| commit-bot@chromium.org | 7cced56 | 2014-01-10 23:10:13 +0000 | [diff] [blame] | 113 | } | 
|  | 114 | } | 
|  | 115 |  | 
| Hal Canary | 594fe85 | 2019-07-18 13:35:49 -0400 | [diff] [blame^] | 116 | SkString onShortName() override { return SkString(fName); } | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 117 |  | 
| Hal Canary | 594fe85 | 2019-07-18 13:35:49 -0400 | [diff] [blame^] | 118 | SkISize onISize() override { return {860, 820}; } | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 119 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 120 | void onDraw(SkCanvas* canvas) override { | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 121 | canvas->translate(STROKE_WIDTH*3/2, STROKE_WIDTH*3/2); | 
|  | 122 |  | 
| commit-bot@chromium.org | 7cced56 | 2014-01-10 23:10:13 +0000 | [diff] [blame] | 123 | SkRect  r = { 0, 0, 100, 50 }; | 
|  | 124 | SkScalar scales[] = { SK_Scalar1, 0.6f }; | 
| skia.committer@gmail.com | 8ccf590 | 2012-11-27 02:01:19 +0000 | [diff] [blame] | 125 |  | 
| commit-bot@chromium.org | 7cced56 | 2014-01-10 23:10:13 +0000 | [diff] [blame] | 126 | for (size_t s = 0; s < SK_ARRAY_COUNT(scales); ++s) { | 
|  | 127 | canvas->save(); | 
|  | 128 | for (size_t f = 0; f < SK_ARRAY_COUNT(fMaskFilters); ++f) { | 
|  | 129 | SkPaint paint; | 
|  | 130 | paint.setMaskFilter(fMaskFilters[f]); | 
|  | 131 | paint.setAlpha(fAlpha); | 
|  | 132 |  | 
| joshualitt | 341400e | 2014-12-18 11:54:13 -0800 | [diff] [blame] | 133 | SkPaint paintWithRadial = paint; | 
| Robert Phillips | 09dfc47 | 2017-09-13 15:25:47 -0400 | [diff] [blame] | 134 | paintWithRadial.setShader(make_radial()); | 
| joshualitt | 341400e | 2014-12-18 11:54:13 -0800 | [diff] [blame] | 135 |  | 
| mtklein | dbfd7ab | 2016-09-01 11:24:54 -0700 | [diff] [blame] | 136 | constexpr Proc procs[] = { | 
| commit-bot@chromium.org | 7cced56 | 2014-01-10 23:10:13 +0000 | [diff] [blame] | 137 | fill_rect, draw_donut, draw_donut_skewed | 
|  | 138 | }; | 
|  | 139 |  | 
|  | 140 | canvas->save(); | 
|  | 141 | canvas->scale(scales[s], scales[s]); | 
|  | 142 | this->drawProcs(canvas, r, paint, false, procs, SK_ARRAY_COUNT(procs)); | 
|  | 143 | canvas->translate(r.width() * 4/3, 0); | 
| joshualitt | 341400e | 2014-12-18 11:54:13 -0800 | [diff] [blame] | 144 | this->drawProcs(canvas, r, paintWithRadial, false, procs, SK_ARRAY_COUNT(procs)); | 
|  | 145 | canvas->translate(r.width() * 4/3, 0); | 
| commit-bot@chromium.org | 7cced56 | 2014-01-10 23:10:13 +0000 | [diff] [blame] | 146 | this->drawProcs(canvas, r, paint, true, procs, SK_ARRAY_COUNT(procs)); | 
| joshualitt | 341400e | 2014-12-18 11:54:13 -0800 | [diff] [blame] | 147 | canvas->translate(r.width() * 4/3, 0); | 
|  | 148 | this->drawProcs(canvas, r, paintWithRadial, true, procs, SK_ARRAY_COUNT(procs)); | 
| commit-bot@chromium.org | 7cced56 | 2014-01-10 23:10:13 +0000 | [diff] [blame] | 149 | canvas->restore(); | 
|  | 150 |  | 
|  | 151 | canvas->translate(0, SK_ARRAY_COUNT(procs) * r.height() * 4/3 * scales[s]); | 
|  | 152 | } | 
|  | 153 | canvas->restore(); | 
| joshualitt | 341400e | 2014-12-18 11:54:13 -0800 | [diff] [blame] | 154 | canvas->translate(4 * r.width() * 4/3 * scales[s], 0); | 
| reed@google.com | 53007a2 | 2012-11-26 14:39:50 +0000 | [diff] [blame] | 155 | } | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 156 | } | 
|  | 157 |  | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 158 | void drawProcs(SkCanvas* canvas, const SkRect& r, const SkPaint& paint, | 
|  | 159 | bool doClip, const Proc procs[], size_t procsCount) { | 
|  | 160 | SkAutoCanvasRestore acr(canvas, true); | 
|  | 161 | for (size_t i = 0; i < procsCount; ++i) { | 
|  | 162 | if (doClip) { | 
|  | 163 | SkRect clipRect(r); | 
|  | 164 | clipRect.inset(STROKE_WIDTH/2, STROKE_WIDTH/2); | 
|  | 165 | canvas->save(); | 
|  | 166 | canvas->clipRect(r); | 
|  | 167 | } | 
|  | 168 | procs[i](canvas, r, paint); | 
|  | 169 | if (doClip) { | 
|  | 170 | canvas->restore(); | 
|  | 171 | } | 
|  | 172 | canvas->translate(0, r.height() * 4/3); | 
|  | 173 | } | 
|  | 174 | } | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 175 | }; | 
|  | 176 |  | 
| halcanary | 2a24338 | 2015-09-09 08:16:41 -0700 | [diff] [blame] | 177 | DEF_SIMPLE_GM(blurrect_gallery, canvas, 1200, 1024) { | 
|  | 178 | const int fGMWidth = 1200; | 
|  | 179 | const int fPadding = 10; | 
|  | 180 | const int fMargin = 100; | 
| commit-bot@chromium.org | 3c1594a | 2014-05-28 21:52:12 +0000 | [diff] [blame] | 181 |  | 
| commit-bot@chromium.org | 3c1594a | 2014-05-28 21:52:12 +0000 | [diff] [blame] | 182 | const int widths[] = {25, 5, 5, 100, 150, 25}; | 
|  | 183 | const int heights[] = {100, 100, 5, 25, 150, 25}; | 
|  | 184 | const SkBlurStyle styles[] = {kNormal_SkBlurStyle, kInner_SkBlurStyle, kOuter_SkBlurStyle}; | 
|  | 185 | const float radii[] = {20, 5, 10}; | 
|  | 186 |  | 
|  | 187 | canvas->translate(50,20); | 
|  | 188 |  | 
|  | 189 | int cur_x = 0; | 
|  | 190 | int cur_y = 0; | 
|  | 191 |  | 
|  | 192 | int max_height = 0; | 
|  | 193 |  | 
|  | 194 | for (size_t i = 0 ; i < SK_ARRAY_COUNT(widths) ; i++) { | 
|  | 195 | int width = widths[i]; | 
|  | 196 | int height = heights[i]; | 
|  | 197 | SkRect r; | 
|  | 198 | r.setWH(SkIntToScalar(width), SkIntToScalar(height)); | 
|  | 199 | SkAutoCanvasRestore autoRestore(canvas, true); | 
|  | 200 |  | 
|  | 201 | for (size_t j = 0 ; j < SK_ARRAY_COUNT(radii) ; j++) { | 
|  | 202 | float radius = radii[j]; | 
|  | 203 | for (size_t k = 0 ; k < SK_ARRAY_COUNT(styles) ; k++) { | 
|  | 204 | SkBlurStyle style = styles[k]; | 
|  | 205 |  | 
|  | 206 | SkMask mask; | 
| robertphillips | e80eb92 | 2015-12-17 11:33:12 -0800 | [diff] [blame] | 207 | if (!SkBlurMask::BlurRect(SkBlurMask::ConvertRadiusToSigma(radius), | 
|  | 208 | &mask, r, style)) { | 
|  | 209 | continue; | 
|  | 210 | } | 
| commit-bot@chromium.org | 3c1594a | 2014-05-28 21:52:12 +0000 | [diff] [blame] | 211 |  | 
|  | 212 | SkAutoMaskFreeImage amfi(mask.fImage); | 
|  | 213 |  | 
|  | 214 | SkBitmap bm; | 
|  | 215 | bm.installMaskPixels(mask); | 
|  | 216 |  | 
|  | 217 | if (cur_x + bm.width() >= fGMWidth - fMargin) { | 
|  | 218 | cur_x = 0; | 
|  | 219 | cur_y += max_height + fPadding; | 
|  | 220 | max_height = 0; | 
|  | 221 | } | 
|  | 222 |  | 
|  | 223 | canvas->save(); | 
| commit-bot@chromium.org | 793ddd9 | 2014-05-28 22:42:31 +0000 | [diff] [blame] | 224 | canvas->translate((SkScalar)cur_x, (SkScalar)cur_y); | 
| commit-bot@chromium.org | 3c1594a | 2014-05-28 21:52:12 +0000 | [diff] [blame] | 225 | canvas->translate(-(bm.width() - r.width())/2, -(bm.height()-r.height())/2); | 
| halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 226 | canvas->drawBitmap(bm, 0.f, 0.f, nullptr); | 
| commit-bot@chromium.org | 3c1594a | 2014-05-28 21:52:12 +0000 | [diff] [blame] | 227 | canvas->restore(); | 
|  | 228 |  | 
|  | 229 | cur_x += bm.width() + fPadding; | 
|  | 230 | if (bm.height() > max_height) | 
|  | 231 | max_height = bm.height(); | 
|  | 232 | } | 
|  | 233 | } | 
|  | 234 | } | 
| halcanary | 2a24338 | 2015-09-09 08:16:41 -0700 | [diff] [blame] | 235 | } | 
| humper@google.com | 7c7292c | 2013-01-04 20:29:03 +0000 | [diff] [blame] | 236 |  | 
| reed@google.com | db87c96 | 2012-11-02 21:11:12 +0000 | [diff] [blame] | 237 | ////////////////////////////////////////////////////////////////////////////// | 
|  | 238 |  | 
| commit-bot@chromium.org | 7cced56 | 2014-01-10 23:10:13 +0000 | [diff] [blame] | 239 | DEF_GM(return new BlurRectGM("blurrects", 0xFF);) |