1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2013 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlurTypes.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMaskFilter.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathEffect.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkDashPathEffect.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkImageFilters.h"
21*c8dee2aaSAndroid Build Coastguard Worker
22*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
23*c8dee2aaSAndroid Build Coastguard Worker
generate_square(SkScalar cx,SkScalar cy,SkScalar w)24*c8dee2aaSAndroid Build Coastguard Worker static SkPath generate_square(SkScalar cx, SkScalar cy, SkScalar w) {
25*c8dee2aaSAndroid Build Coastguard Worker return SkPath::Rect(SkRect::MakeXYWH(cx - w / 2, cy - w / 2, w, w));
26*c8dee2aaSAndroid Build Coastguard Worker }
27*c8dee2aaSAndroid Build Coastguard Worker
generate_rect_line(SkScalar cx,SkScalar cy,SkScalar l)28*c8dee2aaSAndroid Build Coastguard Worker static SkPath generate_rect_line(SkScalar cx, SkScalar cy, SkScalar l) {
29*c8dee2aaSAndroid Build Coastguard Worker return SkPath::Rect(SkRect::MakeXYWH(cx - l / 2, cy, l, 0));
30*c8dee2aaSAndroid Build Coastguard Worker }
31*c8dee2aaSAndroid Build Coastguard Worker
generate_circle(SkScalar cx,SkScalar cy,SkScalar d)32*c8dee2aaSAndroid Build Coastguard Worker static SkPath generate_circle(SkScalar cx, SkScalar cy, SkScalar d) {
33*c8dee2aaSAndroid Build Coastguard Worker return SkPath::Circle(cx, cy, d/2, SkPathDirection::kCW);
34*c8dee2aaSAndroid Build Coastguard Worker }
35*c8dee2aaSAndroid Build Coastguard Worker
generate_line(SkScalar cx,SkScalar cy,SkScalar l)36*c8dee2aaSAndroid Build Coastguard Worker static SkPath generate_line(SkScalar cx, SkScalar cy, SkScalar l) {
37*c8dee2aaSAndroid Build Coastguard Worker return SkPath::Line({cx - l / 2, cy}, {cx + l / 2, cy});
38*c8dee2aaSAndroid Build Coastguard Worker }
39*c8dee2aaSAndroid Build Coastguard Worker
40*c8dee2aaSAndroid Build Coastguard Worker namespace {
41*c8dee2aaSAndroid Build Coastguard Worker struct Style {
Style__anon4e0d744e0111::Style42*c8dee2aaSAndroid Build Coastguard Worker Style(SkPaint::Style paintStyle, sk_sp<SkPathEffect> pe = sk_sp<SkPathEffect>())
43*c8dee2aaSAndroid Build Coastguard Worker : fPaintStyle(paintStyle)
44*c8dee2aaSAndroid Build Coastguard Worker , fPathEffect(std::move(pe)) {}
45*c8dee2aaSAndroid Build Coastguard Worker SkPaint::Style fPaintStyle;
46*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPathEffect> fPathEffect;
47*c8dee2aaSAndroid Build Coastguard Worker };
48*c8dee2aaSAndroid Build Coastguard Worker
make_dash()49*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPathEffect> make_dash() {
50*c8dee2aaSAndroid Build Coastguard Worker constexpr SkScalar kIntervals[] = { 4.f, 3.f };
51*c8dee2aaSAndroid Build Coastguard Worker return SkDashPathEffect::Make(kIntervals, std::size(kIntervals), 0);
52*c8dee2aaSAndroid Build Coastguard Worker }
53*c8dee2aaSAndroid Build Coastguard Worker
54*c8dee2aaSAndroid Build Coastguard Worker Style styles[] {
55*c8dee2aaSAndroid Build Coastguard Worker {SkPaint::kStroke_Style},
56*c8dee2aaSAndroid Build Coastguard Worker {SkPaint::kStrokeAndFill_Style},
57*c8dee2aaSAndroid Build Coastguard Worker {SkPaint::kFill_Style},
58*c8dee2aaSAndroid Build Coastguard Worker {SkPaint::kStroke_Style, make_dash()},
59*c8dee2aaSAndroid Build Coastguard Worker };
60*c8dee2aaSAndroid Build Coastguard Worker
61*c8dee2aaSAndroid Build Coastguard Worker SkScalar pathSizes[] = {
62*c8dee2aaSAndroid Build Coastguard Worker 40,
63*c8dee2aaSAndroid Build Coastguard Worker 10,
64*c8dee2aaSAndroid Build Coastguard Worker 0
65*c8dee2aaSAndroid Build Coastguard Worker };
66*c8dee2aaSAndroid Build Coastguard Worker SkScalar strokeWidths[] = {
67*c8dee2aaSAndroid Build Coastguard Worker 10,
68*c8dee2aaSAndroid Build Coastguard Worker 0
69*c8dee2aaSAndroid Build Coastguard Worker };
70*c8dee2aaSAndroid Build Coastguard Worker SkPath (*paths[])(SkScalar, SkScalar, SkScalar) = {
71*c8dee2aaSAndroid Build Coastguard Worker generate_square,
72*c8dee2aaSAndroid Build Coastguard Worker generate_rect_line,
73*c8dee2aaSAndroid Build Coastguard Worker generate_circle,
74*c8dee2aaSAndroid Build Coastguard Worker generate_line
75*c8dee2aaSAndroid Build Coastguard Worker };
76*c8dee2aaSAndroid Build Coastguard Worker
77*c8dee2aaSAndroid Build Coastguard Worker const SkScalar slideWidth = 90, slideHeight = 90;
78*c8dee2aaSAndroid Build Coastguard Worker const SkScalar slideBoundary = 5;
79*c8dee2aaSAndroid Build Coastguard Worker
80*c8dee2aaSAndroid Build Coastguard Worker } // namespace
81*c8dee2aaSAndroid Build Coastguard Worker
82*c8dee2aaSAndroid Build Coastguard Worker DEF_SIMPLE_GM(inverse_paths, canvas, 800, 1200) {
83*c8dee2aaSAndroid Build Coastguard Worker SkScalar cx = slideWidth / 2 + slideBoundary;
84*c8dee2aaSAndroid Build Coastguard Worker SkScalar cy = slideHeight / 2 + slideBoundary;
85*c8dee2aaSAndroid Build Coastguard Worker SkScalar dx = slideWidth + 2 * slideBoundary;
86*c8dee2aaSAndroid Build Coastguard Worker SkScalar dy = slideHeight + 2 * slideBoundary;
87*c8dee2aaSAndroid Build Coastguard Worker
88*c8dee2aaSAndroid Build Coastguard Worker SkRect clipRect = SkRect::MakeLTRB(slideBoundary, slideBoundary,
89*c8dee2aaSAndroid Build Coastguard Worker slideBoundary + slideWidth,
90*c8dee2aaSAndroid Build Coastguard Worker slideBoundary + slideHeight);
91*c8dee2aaSAndroid Build Coastguard Worker SkPaint clipPaint;
92*c8dee2aaSAndroid Build Coastguard Worker clipPaint.setStyle(SkPaint::kStroke_Style);
93*c8dee2aaSAndroid Build Coastguard Worker clipPaint.setStrokeWidth(SkIntToScalar(2));
94*c8dee2aaSAndroid Build Coastguard Worker
95*c8dee2aaSAndroid Build Coastguard Worker SkPaint outlinePaint;
96*c8dee2aaSAndroid Build Coastguard Worker outlinePaint.setColor(0x40000000);
97*c8dee2aaSAndroid Build Coastguard Worker outlinePaint.setStyle(SkPaint::kStroke_Style);
98*c8dee2aaSAndroid Build Coastguard Worker outlinePaint.setStrokeWidth(SkIntToScalar(0));
99*c8dee2aaSAndroid Build Coastguard Worker
100*c8dee2aaSAndroid Build Coastguard Worker for (size_t styleIndex = 0; styleIndex < std::size(styles);
101*c8dee2aaSAndroid Build Coastguard Worker styleIndex++) {
102*c8dee2aaSAndroid Build Coastguard Worker for (size_t sizeIndex = 0; sizeIndex < std::size(pathSizes);
103*c8dee2aaSAndroid Build Coastguard Worker sizeIndex++) {
104*c8dee2aaSAndroid Build Coastguard Worker SkScalar size = pathSizes[sizeIndex];
105*c8dee2aaSAndroid Build Coastguard Worker
106*c8dee2aaSAndroid Build Coastguard Worker canvas->save();
107*c8dee2aaSAndroid Build Coastguard Worker
108*c8dee2aaSAndroid Build Coastguard Worker for (size_t widthIndex = 0;
109*c8dee2aaSAndroid Build Coastguard Worker widthIndex < std::size(strokeWidths);
110*c8dee2aaSAndroid Build Coastguard Worker widthIndex++) {
111*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
112*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(0xff007000);
113*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(strokeWidths[widthIndex]);
114*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(styles[styleIndex].fPaintStyle);
115*c8dee2aaSAndroid Build Coastguard Worker paint.setPathEffect(styles[styleIndex].fPathEffect);
116*c8dee2aaSAndroid Build Coastguard Worker
117*c8dee2aaSAndroid Build Coastguard Worker for (size_t pathIndex = 0;
118*c8dee2aaSAndroid Build Coastguard Worker pathIndex < std::size(paths);
119*c8dee2aaSAndroid Build Coastguard Worker pathIndex++) {
120*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(clipRect, clipPaint);
121*c8dee2aaSAndroid Build Coastguard Worker
122*c8dee2aaSAndroid Build Coastguard Worker canvas->save();
123*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(clipRect);
124*c8dee2aaSAndroid Build Coastguard Worker
125*c8dee2aaSAndroid Build Coastguard Worker SkPath path = paths[pathIndex](cx, cy, size);
126*c8dee2aaSAndroid Build Coastguard Worker path.setFillType(SkPathFillType::kInverseWinding);
127*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, paint);
128*c8dee2aaSAndroid Build Coastguard Worker
129*c8dee2aaSAndroid Build Coastguard Worker path.setFillType(SkPathFillType::kWinding);
130*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, outlinePaint);
131*c8dee2aaSAndroid Build Coastguard Worker
132*c8dee2aaSAndroid Build Coastguard Worker canvas->restore();
133*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(dx, 0);
134*c8dee2aaSAndroid Build Coastguard Worker }
135*c8dee2aaSAndroid Build Coastguard Worker }
136*c8dee2aaSAndroid Build Coastguard Worker canvas->restore();
137*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, dy);
138*c8dee2aaSAndroid Build Coastguard Worker }
139*c8dee2aaSAndroid Build Coastguard Worker }
140*c8dee2aaSAndroid Build Coastguard Worker }
141*c8dee2aaSAndroid Build Coastguard Worker
142*c8dee2aaSAndroid Build Coastguard Worker DEF_SIMPLE_GM(inverse_fill_filters, canvas, 384, 128) {
__anon4e0d744e0202(const SkPaint& paint) 143*c8dee2aaSAndroid Build Coastguard Worker auto draw = [canvas](const SkPaint& paint) {
144*c8dee2aaSAndroid Build Coastguard Worker SkPath path = SkPath::Circle(65.f, 65.f, 30.f);
145*c8dee2aaSAndroid Build Coastguard Worker path.setFillType(SkPathFillType::kInverseWinding);
146*c8dee2aaSAndroid Build Coastguard Worker
147*c8dee2aaSAndroid Build Coastguard Worker canvas->save();
148*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect({0, 0, 128, 128});
149*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, paint);
150*c8dee2aaSAndroid Build Coastguard Worker canvas->restore();
151*c8dee2aaSAndroid Build Coastguard Worker
152*c8dee2aaSAndroid Build Coastguard Worker SkPaint stroke;
153*c8dee2aaSAndroid Build Coastguard Worker stroke.setStyle(SkPaint::kStroke_Style);
154*c8dee2aaSAndroid Build Coastguard Worker stroke.setColor(SK_ColorWHITE);
155*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect({0, 0, 128, 128}, stroke);
156*c8dee2aaSAndroid Build Coastguard Worker };
157*c8dee2aaSAndroid Build Coastguard Worker
158*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
159*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
160*c8dee2aaSAndroid Build Coastguard Worker
161*c8dee2aaSAndroid Build Coastguard Worker draw(paint);
162*c8dee2aaSAndroid Build Coastguard Worker
163*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(128, 0);
164*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::Blur(5.f, 5.f, nullptr));
165*c8dee2aaSAndroid Build Coastguard Worker draw(paint);
166*c8dee2aaSAndroid Build Coastguard Worker
167*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(128, 0);
168*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(nullptr);
169*c8dee2aaSAndroid Build Coastguard Worker paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 5));
170*c8dee2aaSAndroid Build Coastguard Worker draw(paint);
171*c8dee2aaSAndroid Build Coastguard Worker }
172*c8dee2aaSAndroid Build Coastguard Worker
173*c8dee2aaSAndroid Build Coastguard Worker DEF_SIMPLE_GM(inverse_windingmode_filters, canvas, 256, 100) {
174*c8dee2aaSAndroid Build Coastguard Worker SkPath path;
175*c8dee2aaSAndroid Build Coastguard Worker path.addRect({10, 10, 30, 30}, SkPathDirection::kCW);
176*c8dee2aaSAndroid Build Coastguard Worker path.addRect({20, 20, 40, 40}, SkPathDirection::kCW);
177*c8dee2aaSAndroid Build Coastguard Worker path.addRect({10, 60, 30, 80}, SkPathDirection::kCW);
178*c8dee2aaSAndroid Build Coastguard Worker path.addRect({20, 70, 40, 90}, SkPathDirection::kCCW);
179*c8dee2aaSAndroid Build Coastguard Worker SkPaint strokePaint;
180*c8dee2aaSAndroid Build Coastguard Worker strokePaint.setStyle(SkPaint::kStroke_Style);
181*c8dee2aaSAndroid Build Coastguard Worker SkRect clipRect = {0, 0, 51, 99};
182*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, strokePaint);
183*c8dee2aaSAndroid Build Coastguard Worker SkPaint fillPaint;
184*c8dee2aaSAndroid Build Coastguard Worker fillPaint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 1.0f));
185*c8dee2aaSAndroid Build Coastguard Worker for (auto fillType : { SkPathFillType::kWinding,
186*c8dee2aaSAndroid Build Coastguard Worker SkPathFillType::kEvenOdd,
187*c8dee2aaSAndroid Build Coastguard Worker SkPathFillType::kInverseWinding,
188*c8dee2aaSAndroid Build Coastguard Worker SkPathFillType::kInverseEvenOdd } ) {
189*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(51, 0);
190*c8dee2aaSAndroid Build Coastguard Worker canvas->save();
191*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(clipRect);
192*c8dee2aaSAndroid Build Coastguard Worker path.setFillType(fillType);
193*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, fillPaint);
194*c8dee2aaSAndroid Build Coastguard Worker canvas->restore();
195*c8dee2aaSAndroid Build Coastguard Worker SkPaint clipPaint;
196*c8dee2aaSAndroid Build Coastguard Worker clipPaint.setColor(SK_ColorRED);
197*c8dee2aaSAndroid Build Coastguard Worker clipPaint.setStyle(SkPaint::kStroke_Style);
198*c8dee2aaSAndroid Build Coastguard Worker clipPaint.setStrokeWidth(1.f);
199*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(clipRect, clipPaint);
200*c8dee2aaSAndroid Build Coastguard Worker }
201*c8dee2aaSAndroid Build Coastguard Worker }
202