Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Functions
PathOpsAsWindingTest.cpp File Reference
#include "include/core/SkPath.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/pathops/SkPathOps.h"
#include "include/utils/SkParsePath.h"
#include "tests/Test.h"
#include <initializer_list>
#include <string>

Go to the source code of this file.

Functions

static SkPath build_squircle (SkPath::Verb verb, const SkRect &rect, SkPathDirection dir)
 
void bug12040_1 (skiatest::Reporter *reporter)
 
void bug12040_2 (skiatest::Reporter *reporter)
 
void bug12040_3 (skiatest::Reporter *reporter)
 
void bug12040_4 (skiatest::Reporter *reporter)
 
void bug12040_5 (skiatest::Reporter *reporter)
 
void bug13496_1 (skiatest::Reporter *reporter)
 
void bug13496_2 (skiatest::Reporter *reporter)
 
void bug13496_3 (skiatest::Reporter *reporter)
 
 DEF_TEST (PathOpsAsWinding, reporter)
 

Function Documentation

◆ bug12040_1()

void bug12040_1 ( skiatest::Reporter reporter)

Definition at line 62 of file PathOpsAsWindingTest.cpp.

62 {
64 path.setFillType(SkPathFillType::kWinding);
65 path.moveTo(375, -30);
66 path.cubicTo(578, -30, 749, 176, 749, 422);
67 path.cubicTo(749, 583, 666, 706, 518, 765);
68 path.lineTo(163, 611);
69 path.lineTo(163, 579);
70 path.lineTo(405, 684);
71 path.cubicTo(551, 609, 645, 468, 645, 322);
72 path.cubicTo(645, 183, 563, 82, 450, 82);
73 path.cubicTo(303, 82, 179, 249, 179, 446);
74 path.cubicTo(179, 579, 235, 689, 341, 768);
75 path.lineTo(327, 786);
76 path.cubicTo(165, 717, 56, 536, 56, 335);
77 path.cubicTo(56, 125, 192, -30, 375, -30);
78 path.close();
79 path.moveTo(214, 225);
80 path.cubicTo(333, 248, 396, 311, 396, 405);
81 path.lineTo(396, 695);
82 path.lineTo(267, 641);
83 path.lineTo(267, 395);
84 path.cubicTo(267, 324, 249, 285, 201, 254);
85 path.cubicTo(201, 254, 214, 225, 214, 225);
86 path.close();
87 path.moveTo(682, -106);
88 path.lineTo(832, 12);
89 path.lineTo(813, 33);
90 path.lineTo(772, 0);
91 path.cubicTo(716, 29, 668, 76, 628, 140);
92 path.lineTo(527, 44);
93 path.cubicTo(575, -26, 628, -77, 682, -106);
94 path.close();
95 path.moveTo(450, 59);
96 path.lineTo(480, 59);
97 path.lineTo(480, 678);
98 path.lineTo(450, 678);
99 path.cubicTo(450, 678, 450, 59, 450, 59);
100 path.close();
101 path.moveTo(463, 374);
102 path.lineTo(633, 459);
103 path.lineTo(633, 490);
104 path.lineTo(463, 406);
105 path.cubicTo(463, 406, 463, 374, 463, 374);
106 path.close();
107 path.moveTo(463, 269);
108 path.lineTo(667, 372);
109 path.lineTo(667, 403);
110 path.lineTo(463, 301);
111 path.cubicTo(463, 301, 463, 269, 463, 269);
112 path.close();
113
116 path2.moveTo(-83.5464f, 188);
117 path2.cubicTo(-83.5464f, 184.285f, -84.8599f, 181.114f, -87.4868f, 178.487f);
118 path2.cubicTo(-90.1138f, 175.86f, -93.2849f, 174.546f, -97, 174.546f);
119 path2.cubicTo(-100.715f, 174.546f, -103.886f, 175.86f, -106.513f, 178.487f);
120 path2.cubicTo(-109.14f, 181.114f, -110.454f, 184.285f, -110.454f, 188);
121 path2.cubicTo(-110.454f, 191.715f, -109.14f, 194.886f, -106.513f, 197.513f);
122 path2.cubicTo(-103.886f, 200.14f, -100.715f, 201.454f, -97, 201.454f);
123 path2.cubicTo(-93.2849f, 201.454f, -90.1138f, 200.14f, -87.4868f, 197.513f);
124 path2.cubicTo(-84.8599f, 194.886f, -83.5464f, 191.715f, -83.5464f, 188);
125 path2.close();
126
127 SkPath opResult;
128 Op(path, path2, kDifference_SkPathOp, &opResult);
129
130 SkPath winding;
131 REPORTER_ASSERT(reporter, AsWinding(opResult, &winding));
133
135 Op(winding, opResult, kXOR_SkPathOp, &difference);
137}
reporter
static SkPath path2()
static size_t difference(size_t minuend, size_t subtrahend)
bool SK_API AsWinding(const SkPath &path, SkPath *result)
@ kDifference_SkPathOp
subtract the op path from the first path
Definition SkPathOps.h:23
@ kXOR_SkPathOp
exclusive-or the two paths
Definition SkPathOps.h:26
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
SkPath & moveTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:678
SkPathFillType getFillType() const
Definition SkPath.h:230
void setFillType(SkPathFillType ft)
Definition SkPath.h:235
SkPath & cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)
Definition SkPath.cpp:789
SkPath & close()
Definition SkPath.cpp:813
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57

◆ bug12040_2()

void bug12040_2 ( skiatest::Reporter reporter)

Definition at line 139 of file PathOpsAsWindingTest.cpp.

139 {
140 SkPath path;
141 path.setFillType(SkPathFillType::kWinding);
142 path.moveTo(375, -30);
143 path.cubicTo(578, -30, 749, 176, 749, 422);
144 path.cubicTo(749, 583, 666, 706, 518, 765);
145 path.lineTo(163, 611);
146 path.lineTo(163, 579);
147 path.lineTo(405, 684);
148 path.cubicTo(551, 609, 645, 468, 645, 322);
149 path.cubicTo(645, 183, 563, 82, 450, 82);
150 path.cubicTo(303, 82, 179, 249, 179, 446);
151 path.cubicTo(179, 579, 235, 689, 341, 768);
152 path.lineTo(327, 786);
153 path.cubicTo(165, 717, 56, 536, 56, 335);
154 path.cubicTo(56, 125, 192, -30, 375, -30);
155 path.close();
156 path.moveTo(214, 225);
157 path.cubicTo(333, 248, 396, 311, 396, 405);
158 path.lineTo(396, 695);
159 path.lineTo(267, 641);
160 path.lineTo(267, 395);
161 path.cubicTo(267, 324, 249, 285, 201, 254);
162 path.cubicTo(201, 254, 214, 225, 214, 225);
163 path.close();
164 path.moveTo(682, -106);
165 path.lineTo(832, 12);
166 path.lineTo(813, 33);
167 path.lineTo(772, 0);
168 path.cubicTo(716, 29, 668, 76, 628, 140);
169 path.lineTo(527, 44);
170 path.cubicTo(575, -26, 628, -77, 682, -106);
171 path.close();
172 path.moveTo(450, 59);
173 path.lineTo(480, 59);
174 path.lineTo(480, 678);
175 path.lineTo(450, 678);
176 path.cubicTo(450, 678, 450, 59, 450, 59);
177 path.close();
178 path.moveTo(463, 374);
179 path.lineTo(633, 459);
180 path.lineTo(633, 490);
181 path.lineTo(463, 406);
182 path.cubicTo(463, 406, 463, 374, 463, 374);
183 path.close();
184 path.moveTo(463, 269);
185 path.lineTo(667, 372);
186 path.lineTo(667, 403);
187 path.lineTo(463, 301);
188 path.cubicTo(463, 301, 463, 269, 463, 269);
189 path.close();
190
193 path2.moveTo(269.134f, 71.3392f);
194 path2.cubicTo(269.134f, 67.6241f, 267.82f, 64.453f, 265.193f, 61.826f);
195 path2.cubicTo(262.566f, 59.1991f, 259.395f, 57.8856f, 255.68f, 57.8856f);
196 path2.cubicTo(251.965f, 57.8856f, 248.794f, 59.1991f, 246.167f, 61.826f);
197 path2.cubicTo(243.54f, 64.453f, 242.226f, 67.6241f, 242.226f, 71.3392f);
198 path2.cubicTo(242.226f, 75.0543f, 243.54f, 78.2255f, 246.167f, 80.8524f);
199 path2.cubicTo(248.794f, 83.4794f, 251.965f, 84.7928f, 255.68f, 84.7928f);
200 path2.cubicTo(259.395f, 84.7928f, 262.566f, 83.4794f, 265.193f, 80.8524f);
201 path2.cubicTo(267.82f, 78.2255f, 269.134f, 75.0543f, 269.134f, 71.3392f);
202 path2.close();
203
204 SkPath opResult;
205 Op(path, path2, kDifference_SkPathOp, &opResult);
206
207 // This produces the correct result in all the cases I've tried.
208 // So it appears to be a winding issue.
209 // canvas->drawPath(opResult, p);
210
211 SkPath winding;
213 REPORTER_ASSERT(reporter, AsWinding(opResult, &winding));
215
217 Op(winding, opResult, kXOR_SkPathOp, &difference);
219}

◆ bug12040_3()

void bug12040_3 ( skiatest::Reporter reporter)

Definition at line 221 of file PathOpsAsWindingTest.cpp.

221 {
222 SkPath path;
223 path.setFillType(SkPathFillType::kWinding);
224 path.moveTo(375, -30);
225 path.cubicTo(578, -30, 749, 176, 749, 422);
226 path.cubicTo(749, 583, 666, 706, 518, 765);
227 path.lineTo(163, 611);
228 path.lineTo(163, 579);
229 path.lineTo(405, 684);
230 path.cubicTo(551, 609, 645, 468, 645, 322);
231 path.cubicTo(645, 183, 563, 82, 450, 82);
232 path.cubicTo(303, 82, 179, 249, 179, 446);
233 path.cubicTo(179, 579, 235, 689, 341, 768);
234 path.lineTo(327, 786);
235 path.cubicTo(165, 717, 56, 536, 56, 335);
236 path.cubicTo(56, 125, 192, -30, 375, -30);
237 path.close();
238 path.moveTo(214, 225);
239 path.cubicTo(333, 248, 396, 311, 396, 405);
240 path.lineTo(396, 695);
241 path.lineTo(267, 641);
242 path.lineTo(267, 395);
243 path.cubicTo(267, 324, 249, 285, 201, 254);
244 path.cubicTo(201, 254, 214, 225, 214, 225);
245 path.close();
246 path.moveTo(682, -106);
247 path.lineTo(832, 12);
248 path.lineTo(813, 33);
249 path.lineTo(772, 0);
250 path.cubicTo(716, 29, 668, 76, 628, 140);
251 path.lineTo(527, 44);
252 path.cubicTo(575, -26, 628, -77, 682, -106);
253 path.close();
254 path.moveTo(450, 59);
255 path.lineTo(480, 59);
256 path.lineTo(480, 678);
257 path.lineTo(450, 678);
258 path.cubicTo(450, 678, 450, 59, 450, 59);
259 path.close();
260 path.moveTo(463, 374);
261 path.lineTo(633, 459);
262 path.lineTo(633, 490);
263 path.lineTo(463, 406);
264 path.cubicTo(463, 406, 463, 374, 463, 374);
265 path.close();
266 path.moveTo(463, 269);
267 path.lineTo(667, 372);
268 path.lineTo(667, 403);
269 path.lineTo(463, 301);
270 path.cubicTo(463, 301, 463, 269, 463, 269);
271 path.close();
272
275 path2.moveTo(492.041f, 525.339f);
276 path2.cubicTo(492.041f, 521.624f, 490.727f, 518.453f, 488.1f, 515.826f);
277 path2.cubicTo(485.473f, 513.199f, 482.302f, 511.886f, 478.587f, 511.886f);
278 path2.cubicTo(474.872f, 511.886f, 471.701f, 513.199f, 469.074f, 515.826f);
279 path2.cubicTo(466.447f, 518.453f, 465.134f, 521.624f, 465.134f, 525.339f);
280 path2.cubicTo(465.134f, 529.054f, 466.447f, 532.226f, 469.074f, 534.853f);
281 path2.cubicTo(471.701f, 537.479f, 474.872f, 538.793f, 478.587f, 538.793f);
282 path2.cubicTo(482.302f, 538.793f, 485.473f, 537.479f, 488.1f, 534.853f);
283 path2.cubicTo(490.727f, 532.226f, 492.041f, 529.054f, 492.041f, 525.339f);
284 path2.close();
285
286 SkPath opResult;
287 Op(path, path2, kDifference_SkPathOp, &opResult);
288
289 SkPath winding;
291 REPORTER_ASSERT(reporter, AsWinding(opResult, &winding));
293
295 Op(winding, opResult, kXOR_SkPathOp, &difference);
297}

◆ bug12040_4()

void bug12040_4 ( skiatest::Reporter reporter)

Definition at line 299 of file PathOpsAsWindingTest.cpp.

299 {
300 for (int moveX = 199; moveX <= 201; ++moveX) {
301 for (int moveY = 299; moveY <= 301; ++moveY) {
302 for (int lineX = 199; lineX <= 201; ++lineX) {
303 for (int lineY = 199; lineY <= 201; ++lineY) {
304 SkPath path;
305 path.setFillType(SkPathFillType::kWinding);
306 path.addCircle(250, 250, 150);
307
310 path2.moveTo(moveX, moveY); // 200, 300 works... But not 200, 301!!
311 path2.lineTo(lineX, lineY); // 200, 200 works... But not 199, 200!!
312 path2.lineTo(300, 300);
313 path2.close();
314
315 SkPath opResult;
316 Op(path, path2, kDifference_SkPathOp, &opResult);
317
318 SkPath winding;
319 REPORTER_ASSERT(reporter, AsWinding(opResult, &winding));
321
323 Op(winding, opResult, kXOR_SkPathOp, &difference);
325 }
326 }
327 }
328 }
329}
SkPath & lineTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:718

◆ bug12040_5()

void bug12040_5 ( skiatest::Reporter reporter)

Definition at line 331 of file PathOpsAsWindingTest.cpp.

331 {
332 for (int moveX = 199; moveX <= 201; ++moveX) {
333 for (int moveY = 299; moveY <= 301; ++moveY) {
334 for (int lineX = 199; lineX <= 201; ++lineX) {
335 for (int lineY = 199; lineY <= 201; ++lineY) {
336 SkPath path;
337 path.setFillType(SkPathFillType::kWinding);
338 path.addRect(100, 100, 400, 400);
339
342 path2.moveTo(moveX, moveY);
343 path2.lineTo(lineX, lineY); // 200, 200 works... But not 199, 200!!
344 path2.lineTo(300, 300);
345 path2.close();
346
347 SkPath opResult;
348 Op(path, path2, kDifference_SkPathOp, &opResult);
349
350 SkPath winding;
351 REPORTER_ASSERT(reporter, AsWinding(opResult, &winding));
353
355 Op(winding, opResult, kXOR_SkPathOp, &difference);
357 }
358 }
359 }
360 }
361}

◆ bug13496_1()

void bug13496_1 ( skiatest::Reporter reporter)

Definition at line 363 of file PathOpsAsWindingTest.cpp.

363 {
364 std::string originalPathStr =
365 "M5.93 -3.12C5.93 -5.03 4.73 -6.06 3.5 -6.06C2.67 -6.06 1.98 -5.59 1.76 -5.34L1.67 "
366 "-5.93L0.75 -5.93L0.75 2.23L1.87 2.04L1.87 -0.12C2.12 -0.03 2.62 0.07 3.18 0.07C4.57 "
367 "0.07 5.93 -1.06 5.93 -3.12ZM4.81 -3.09C4.81 -1.51 4.18 -0.85 3.17 -0.85C2.57 -0.85 "
368 "2.15 -0.98 1.87 -1.12L1.87 -4.15C2.34 -4.73 2.75 -5.09 3.42 -5.09C4.31 -5.09 4.81 "
369 "-4.46 4.81 -3.09Z";
370
371 SkPath path;
372 SkParsePath::FromSVGString(originalPathStr.c_str(), &path);
373
374 SkPath simplifiedPath;
375 Simplify(path, &simplifiedPath);
376
377 SkPath windingPath;
378 REPORTER_ASSERT(reporter, AsWinding(simplifiedPath, &windingPath));
380
382 Op(windingPath, simplifiedPath, kXOR_SkPathOp, &difference);
384}
bool SK_API Simplify(const SkPath &path, SkPath *result)
static bool FromSVGString(const char str[], SkPath *)

◆ bug13496_2()

void bug13496_2 ( skiatest::Reporter reporter)

Definition at line 386 of file PathOpsAsWindingTest.cpp.

386 {
387 std::string originalPathStr =
388 "M4 0"
389 "L0 0"
390 "L0 5"
391 "L4 4"
392 "Z"
393 "M3 3"
394 "L1 3"
395 "L1 1"
396 "L3 1"
397 "Z";
398
399 SkPath path;
400 SkParsePath::FromSVGString(originalPathStr.c_str(), &path);
401
402 SkPath simplifiedPath;
403 Simplify(path, &simplifiedPath);
404
405 SkPath windingPath;
406 REPORTER_ASSERT(reporter, AsWinding(simplifiedPath, &windingPath));
408
410 Op(windingPath, simplifiedPath, kXOR_SkPathOp, &difference);
412}

◆ bug13496_3()

void bug13496_3 ( skiatest::Reporter reporter)

Definition at line 414 of file PathOpsAsWindingTest.cpp.

414 {
415 std::string originalPathStr =
416 "M4 0"
417 "L0 0"
418 "L0 4"
419 "L4 4"
420 "Z"
421 "M3 3"
422 "L1 3"
423 "L1 1"
424 "L3 1"
425 "Z";
426
427 SkPath path;
428 SkParsePath::FromSVGString(originalPathStr.c_str(), &path);
429
430 SkPath simplifiedPath;
431 Simplify(path, &simplifiedPath);
432
433 SkPath windingPath;
434 REPORTER_ASSERT(reporter, AsWinding(simplifiedPath, &windingPath));
436
438 Op(windingPath, simplifiedPath, kXOR_SkPathOp, &difference);
440}

◆ build_squircle()

static SkPath build_squircle ( SkPath::Verb  verb,
const SkRect rect,
SkPathDirection  dir 
)
static

Definition at line 21 of file PathOpsAsWindingTest.cpp.

21 {
24 switch (verb) {
26 path.addRect(rect, dir);
27 reverse = false;
28 break;
30 path.moveTo(rect.centerX(), rect.fTop);
31 path.quadTo(rect.fRight, rect.fTop, rect.fRight, rect.centerY());
32 path.quadTo(rect.fRight, rect.fBottom, rect.centerX(), rect.fBottom);
33 path.quadTo(rect.fLeft, rect.fBottom, rect.fLeft, rect.centerY());
34 path.quadTo(rect.fLeft, rect.fTop, rect.centerX(), rect.fTop);
35 break;
37 path.addCircle(rect.centerX(), rect.centerY(), rect.width() / 2, dir);
38 reverse = false;
39 break;
41 SkScalar aX14 = rect.fLeft + rect.width() * 1 / 4;
42 SkScalar aX34 = rect.fLeft + rect.width() * 3 / 4;
43 SkScalar aY14 = rect.fTop + rect.height() * 1 / 4;
44 SkScalar aY34 = rect.fTop + rect.height() * 3 / 4;
45 path.moveTo(rect.centerX(), rect.fTop);
46 path.cubicTo(aX34, rect.fTop, rect.fRight, aY14, rect.fRight, rect.centerY());
47 path.cubicTo(rect.fRight, aY34, aX34, rect.fBottom, rect.centerX(), rect.fBottom);
48 path.cubicTo(aX14, rect.fBottom, rect.fLeft, aY34, rect.fLeft, rect.centerY());
49 path.cubicTo(rect.fLeft, aY14, aX14, rect.fTop, rect.centerX(), rect.fTop);
50 } break;
51 default:
52 SkASSERT(0);
53 }
54 if (reverse) {
55 SkPath temp;
56 temp.reverseAddPath(path);
57 path.swap(temp);
58 }
59 return path;
60}
#define SkASSERT(cond)
Definition SkAssert.h:116
SkPath & reverseAddPath(const SkPath &src)
Definition SkPath.cpp:1569
@ kConic_Verb
Definition SkPath.h:1461
@ kCubic_Verb
Definition SkPath.h:1462
@ kQuad_Verb
Definition SkPath.h:1460
@ kLine_Verb
Definition SkPath.h:1459
float SkScalar
Definition extension.cpp:12
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
Definition switches.h:145

◆ DEF_TEST()

DEF_TEST ( PathOpsAsWinding  ,
reporter   
)

Definition at line 442 of file PathOpsAsWindingTest.cpp.

442 {
444 test.addRect({1, 2, 3, 4});
445 // if test is winding
448 // if test is empty
449 test.reset();
450 test.setFillType(SkPathFillType::kEvenOdd);
452 REPORTER_ASSERT(reporter, result.isEmpty());
454 // if test is convex
455 test.addCircle(5, 5, 10);
457 REPORTER_ASSERT(reporter, result.isConvex());
458 test.setFillType(SkPathFillType::kWinding);
460 // if test has infinity
461 test.reset();
462 test.addRect({1, 2, 3, SK_ScalarInfinity});
463 test.setFillType(SkPathFillType::kEvenOdd);
465 // if test has only one contour
466 test.reset();
467 SkPoint ell[] = {{0, 0}, {4, 0}, {4, 1}, {1, 1}, {1, 4}, {0, 4}};
468 test.addPoly(ell, std::size(ell), true);
469 test.setFillType(SkPathFillType::kEvenOdd);
471 REPORTER_ASSERT(reporter, !result.isConvex());
472 test.setFillType(SkPathFillType::kWinding);
474 // test two contours that do not overlap or share bounds
475 test.addRect({5, 2, 6, 3});
476 test.setFillType(SkPathFillType::kEvenOdd);
478 REPORTER_ASSERT(reporter, !result.isConvex());
479 test.setFillType(SkPathFillType::kWinding);
481 // test two contours that do not overlap but share bounds
482 test.reset();
483 test.addPoly(ell, std::size(ell), true);
484 test.addRect({2, 2, 3, 3});
485 test.setFillType(SkPathFillType::kEvenOdd);
487 REPORTER_ASSERT(reporter, !result.isConvex());
488 test.setFillType(SkPathFillType::kWinding);
490 // test two contours that partially overlap
491 test.reset();
492 test.addRect({0, 0, 3, 3});
493 test.addRect({1, 1, 4, 4});
494 test.setFillType(SkPathFillType::kEvenOdd);
496 REPORTER_ASSERT(reporter, !result.isConvex());
497 test.setFillType(SkPathFillType::kWinding);
499 // test that result may be input
500 SkPath copy = test;
501 test.setFillType(SkPathFillType::kEvenOdd);
503 REPORTER_ASSERT(reporter, !test.isConvex());
505 // test a in b, b in a, cw/ccw
506 constexpr SkRect rectA = {0, 0, 3, 3};
507 constexpr SkRect rectB = {1, 1, 2, 2};
508 const std::initializer_list<SkPoint> revBccw = {{1, 2}, {2, 2}, {2, 1}, {1, 1}};
509 const std::initializer_list<SkPoint> revBcw = {{2, 1}, {2, 2}, {1, 2}, {1, 1}};
510 for (bool aFirst : {false, true}) {
511 for (auto dirA : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
512 for (auto dirB : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
513 test.reset();
514 test.setFillType(SkPathFillType::kEvenOdd);
515 if (aFirst) {
516 test.addRect(rectA, dirA);
517 test.addRect(rectB, dirB);
518 } else {
519 test.addRect(rectB, dirB);
520 test.addRect(rectA, dirA);
521 }
522 SkPath original = test;
525 test.reset();
526 if (aFirst) {
527 test.addRect(rectA, dirA);
528 }
529 if (dirA != dirB) {
530 test.addRect(rectB, dirB);
531 } else {
532 test.addPoly(SkPathDirection::kCW == dirA ? revBccw : revBcw, true);
533 }
534 if (!aFirst) {
535 test.addRect(rectA, dirA);
536 }
538 // test that result may be input
539 REPORTER_ASSERT(reporter, AsWinding(original, &original));
541 REPORTER_ASSERT(reporter, original == result);
542 }
543 }
544 }
545 // Test curve types with donuts. Create a donut with outer and hole in all directions.
546 // After converting to winding, all donuts should have a hole in the middle.
547 for (bool aFirst : {false, true}) {
548 for (auto dirA : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
549 for (auto dirB : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
550 for (auto curveA : { SkPath::kLine_Verb, SkPath::kQuad_Verb,
552 SkPath pathA = build_squircle(curveA, rectA, dirA);
553 for (auto curveB : { SkPath::kLine_Verb, SkPath::kQuad_Verb,
555 test = aFirst ? pathA : SkPath();
556 test.addPath(build_squircle(curveB, rectB, dirB));
557 if (!aFirst) {
558 test.addPath(pathA);
559 }
560 test.setFillType(SkPathFillType::kEvenOdd);
563 for (SkScalar x = rectA.fLeft - 1; x <= rectA.fRight + 1; ++x) {
564 for (SkScalar y = rectA.fTop - 1; y <= rectA.fBottom + 1; ++y) {
565 bool evenOddContains = test.contains(x, y);
566 bool windingContains = result.contains(x, y);
567 REPORTER_ASSERT(reporter, evenOddContains == windingContains);
568 }
569 }
570 }
571 }
572 }
573 }
574 }
575 // test https://bugs.chromium.org/p/skia/issues/detail?id=12040
581 // test https://bugs.chromium.org/p/skia/issues/detail?id=13496
585}
#define test(name)
void bug12040_4(skiatest::Reporter *reporter)
void bug12040_3(skiatest::Reporter *reporter)
void bug13496_3(skiatest::Reporter *reporter)
void bug12040_2(skiatest::Reporter *reporter)
static SkPath build_squircle(SkPath::Verb verb, const SkRect &rect, SkPathDirection dir)
void bug13496_1(skiatest::Reporter *reporter)
void bug13496_2(skiatest::Reporter *reporter)
void bug12040_1(skiatest::Reporter *reporter)
void bug12040_5(skiatest::Reporter *reporter)
#define SK_ScalarInfinity
Definition SkScalar.h:26
GAsyncResult * result
double y
double x
Definition copy.py:1
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15