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/SkBlurTypes.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkFont.h"
13 #include "include/core/SkMaskFilter.h"
14 #include "include/core/SkPaint.h"
15 #include "include/core/SkPathBuilder.h"
16 #include "include/core/SkRect.h"
17 #include "include/core/SkRefCnt.h"
18 #include "include/core/SkScalar.h"
19 #include "include/core/SkTypeface.h"
20 #include "include/core/SkTypes.h"
21 #include "include/effects/SkImageFilters.h"
22 #include "src/core/SkBlurMask.h"
23 #include "tools/Resources.h"
24 #include "tools/ToolUtils.h"
25
DEF_SIMPLE_GM_BG(blurs, canvas, 700, 500, 0xFFDDDDDD)26 DEF_SIMPLE_GM_BG(blurs, canvas, 700, 500, 0xFFDDDDDD) {
27 SkBlurStyle NONE = SkBlurStyle(-999);
28 const struct {
29 SkBlurStyle fStyle;
30 int fCx, fCy;
31 } gRecs[] = {
32 { NONE, 0, 0 },
33 { kInner_SkBlurStyle, -1, 0 },
34 { kNormal_SkBlurStyle, 0, 1 },
35 { kSolid_SkBlurStyle, 0, -1 },
36 { kOuter_SkBlurStyle, 1, 0 },
37 };
38
39 SkPaint paint;
40 paint.setAntiAlias(true);
41 paint.setColor(SK_ColorBLUE);
42
43 canvas->translate(SkIntToScalar(-40), SkIntToScalar(0));
44
45 for (size_t i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
46 if (gRecs[i].fStyle != NONE) {
47 paint.setMaskFilter(SkMaskFilter::MakeBlur(gRecs[i].fStyle,
48 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(20))));
49 } else {
50 paint.setMaskFilter(nullptr);
51 }
52 canvas->drawCircle(SkIntToScalar(200 + gRecs[i].fCx*100),
53 SkIntToScalar(200 + gRecs[i].fCy*100),
54 SkIntToScalar(50),
55 paint);
56 }
57 // draw text
58 {
59 SkFont font(ToolUtils::create_portable_typeface(), 25);
60 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle,
61 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(4))));
62 SkScalar x = SkIntToScalar(70);
63 SkScalar y = SkIntToScalar(400);
64 paint.setColor(SK_ColorBLACK);
65 canvas->drawString("Hamburgefons Style", x, y, font, paint);
66 canvas->drawString("Hamburgefons Style",
67 x, y + SkIntToScalar(50), font, paint);
68 paint.setMaskFilter(nullptr);
69 paint.setColor(SK_ColorWHITE);
70 x -= SkIntToScalar(2);
71 y -= SkIntToScalar(2);
72 canvas->drawString("Hamburgefons Style", x, y, font, paint);
73 }
74 }
75
76 //////////////////////////////////////////////////////////////////////////////////////////////
77
78 // exercise a special-case of blurs, which is two nested rects. These are drawn specially,
79 // and possibly cached.
80 //
81 // in particular, we want to notice that the 2nd rect draws slightly differently, since it
82 // is translated a fractional amount.
83 //
DEF_SIMPLE_GM(blur2rects, canvas, 700, 500)84 DEF_SIMPLE_GM(blur2rects, canvas, 700, 500) {
85 SkPaint paint;
86
87 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 2.3f));
88
89 SkRect outer = SkRect::MakeXYWH(10.125f, 10.125f, 100.125f, 100);
90 SkRect inner = SkRect::MakeXYWH(20.25f, 20.125f, 80, 80);
91 SkPath path = SkPathBuilder().addRect(outer, SkPathDirection::kCW)
92 .addRect(inner, SkPathDirection::kCCW)
93 .detach();
94
95 canvas->drawPath(path, paint);
96 // important to translate by a factional amount to exercise a different "phase"
97 // of the same path w.r.t. the pixel grid
98 SkScalar dx = SkScalarRoundToScalar(path.getBounds().width()) + 14 + 0.25f;
99 canvas->translate(dx, 0);
100 canvas->drawPath(path, paint);
101 }
102
DEF_SIMPLE_GM(blur2rectsnonninepatch, canvas, 700, 500)103 DEF_SIMPLE_GM(blur2rectsnonninepatch, canvas, 700, 500) {
104 SkPaint paint;
105 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 4.3f));
106
107 SkRect outer = SkRect::MakeXYWH(10, 110, 100, 100);
108 SkRect inner = SkRect::MakeXYWH(50, 150, 10, 10);
109 SkPath path = SkPathBuilder().addRect(outer, SkPathDirection::kCW)
110 .addRect(inner, SkPathDirection::kCW)
111 .detach();
112 canvas->drawPath(path, paint);
113
114 SkScalar dx = SkScalarRoundToScalar(path.getBounds().width()) + 40 + 0.25f;
115 canvas->translate(dx, 0);
116 canvas->drawPath(path, paint);
117
118 // Translate to outside of clip bounds.
119 canvas->translate(-dx, 0);
120 canvas->translate(-30, -150);
121 canvas->drawPath(path, paint);
122 }
123
DEF_SIMPLE_GM(BlurDrawImage, canvas, 256, 256)124 DEF_SIMPLE_GM(BlurDrawImage, canvas, 256, 256) {
125 SkPaint paint;
126 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 10));
127 canvas->clear(0xFF88FF88);
128 if (auto image = GetResourceAsImage("images/mandrill_512_q075.jpg")) {
129 canvas->scale(0.25, 0.25);
130 canvas->drawImage(image, 256, 256, SkSamplingOptions(), &paint);
131 }
132 }
133
DEF_SIMPLE_GM(BlurBigSigma, canvas, 1024, 1024)134 DEF_SIMPLE_GM(BlurBigSigma, canvas, 1024, 1024) {
135 SkPaint layerPaint, p;
136
137 p.setImageFilter(SkImageFilters::Blur(500, 500, nullptr));
138
139 canvas->drawRect(SkRect::MakeWH(700, 800), p);
140 }
141
DEF_SIMPLE_GM(BlurSmallSigma, canvas, 512, 256)142 DEF_SIMPLE_GM(BlurSmallSigma, canvas, 512, 256) {
143 {
144 // Normal sigma on x-axis, a small but non-zero sigma on y-axis that should
145 // be treated as identity.
146 SkPaint paint;
147 paint.setImageFilter(SkImageFilters::Blur(16.f, 1e-5f, nullptr));
148 canvas->drawRect(SkRect::MakeLTRB(64, 64, 192, 192), paint);
149 }
150
151 {
152 // Small sigma on both axes, should be treated as identity and no red should show
153 SkPaint paint;
154 paint.setColor(SK_ColorRED);
155 SkRect rect = SkRect::MakeLTRB(320, 64, 448, 192);
156 canvas->drawRect(rect, paint);
157 paint.setColor(SK_ColorBLACK);
158 paint.setImageFilter(SkImageFilters::Blur(1e-5f, 1e-5f, nullptr));
159 canvas->drawRect(rect, paint);
160 }
161 }
162