Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(945)

Side by Side Diff: tests/PathOpsExtendedTest.cpp

Issue 18058007: path ops work in progress (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: try try again Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tests/PathOpsExtendedTest.h ('k') | tests/PathOpsLineIntersectionTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "PathOpsExtendedTest.h" 8 #include "PathOpsExtendedTest.h"
9 #include "PathOpsThreadedCommon.h" 9 #include "PathOpsThreadedCommon.h"
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
(...skipping 27 matching lines...) Expand all
38 "i", 38 "i",
39 "u", 39 "u",
40 "o", 40 "o",
41 }; 41 };
42 42
43 static bool gShowPath = false; 43 static bool gShowPath = false;
44 static bool gComparePaths = true; 44 static bool gComparePaths = true;
45 static bool gComparePathsAssert = true; 45 static bool gComparePathsAssert = true;
46 static bool gPathStrAssert = true; 46 static bool gPathStrAssert = true;
47 47
48 static void showPathContours(SkPath::Iter& iter, const char* suffix) { 48 static const char* gFillTypeStr[] = {
49 "kWinding_FillType",
50 "kEvenOdd_FillType",
51 "kInverseWinding_FillType",
52 "kInverseEvenOdd_FillType"
53 };
54
55 static void showPathContours(SkPath::RawIter& iter, const char* pathName) {
49 uint8_t verb; 56 uint8_t verb;
50 SkPoint pts[4]; 57 SkPoint pts[4];
51 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 58 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
52 switch (verb) { 59 switch (verb) {
53 case SkPath::kMove_Verb: 60 case SkPath::kMove_Verb:
54 SkDebugf(" path%s.moveTo(%1.9g,%1.9g);\n", suffix, pts[0].fX, pts[0].fY); 61 SkDebugf(" %s.moveTo(%#1.9gf, %#1.9gf);\n", pathName, pts[0]. fX, pts[0].fY);
55 continue; 62 continue;
56 case SkPath::kLine_Verb: 63 case SkPath::kLine_Verb:
57 SkDebugf(" path%s.lineTo(%1.9g,%1.9g);\n", suffix, pts[1].fX, pts[1].fY); 64 SkDebugf(" %s.lineTo(%#1.9gf, %#1.9gf);\n", pathName, pts[1]. fX, pts[1].fY);
58 break; 65 break;
59 case SkPath::kQuad_Verb: 66 case SkPath::kQuad_Verb:
60 SkDebugf(" path%s.quadTo(%1.9g,%1.9g, %1.9g,%1.9g);\n", suffi x, 67 SkDebugf(" %s.quadTo(%#1.9gf, %#1.9gf, %#1.9gf, %#1.9gf);\n", pathName,
61 pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY); 68 pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
62 break; 69 break;
63 case SkPath::kCubic_Verb: 70 case SkPath::kCubic_Verb:
64 SkDebugf(" path%s.cubicTo(%1.9g,%1.9g, %1.9g,%1.9g, %1.9g,%1. 9g);\n", suffix, 71 SkDebugf(" %s.cubicTo(%#1.9gf, %#1.9gf, %#1.9gf, %#1.9gf, %#1 .9gf, %#1.9gf);\n",
65 pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3 ].fY); 72 pathName, pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3] .fX, pts[3].fY);
66 break; 73 break;
67 case SkPath::kClose_Verb: 74 case SkPath::kClose_Verb:
68 SkDebugf(" path%s.close();\n", suffix); 75 SkDebugf(" %s.close();\n", pathName);
69 break; 76 break;
70 default: 77 default:
71 SkDEBUGFAIL("bad verb"); 78 SkDEBUGFAIL("bad verb");
72 return; 79 return;
73 } 80 }
74 } 81 }
75 } 82 }
76 83
77 static const char* fillTypeStr[] = { 84 static void showPath(const SkPath& path, const char* pathName, bool includeDecla ration) {
78 "kWinding_FillType", 85 SkPath::RawIter iter(path);
79 "kEvenOdd_FillType",
80 "kInverseWinding_FillType",
81 "kInverseEvenOdd_FillType"
82 };
83
84 static void showPath(const SkPath& path, const char* suffix) {
85 SkPath::Iter iter(path, true);
86 #define SUPPORT_RECT_CONTOUR_DETECTION 0 86 #define SUPPORT_RECT_CONTOUR_DETECTION 0
87 #if SUPPORT_RECT_CONTOUR_DETECTION 87 #if SUPPORT_RECT_CONTOUR_DETECTION
88 int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0; 88 int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0;
89 if (rectCount > 0) { 89 if (rectCount > 0) {
90 SkTDArray<SkRect> rects; 90 SkTDArray<SkRect> rects;
91 SkTDArray<SkPath::Direction> directions; 91 SkTDArray<SkPath::Direction> directions;
92 rects.setCount(rectCount); 92 rects.setCount(rectCount);
93 directions.setCount(rectCount); 93 directions.setCount(rectCount);
94 path.rectContours(rects.begin(), directions.begin()); 94 path.rectContours(rects.begin(), directions.begin());
95 for (int contour = 0; contour < rectCount; ++contour) { 95 for (int contour = 0; contour < rectCount; ++contour) {
96 const SkRect& rect = rects[contour]; 96 const SkRect& rect = rects[contour];
97 SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLe ft, rect.fTop, 97 SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLe ft, rect.fTop,
98 rect.fRight, rect.fBottom, directions[contour] == SkPath::kC CW_Direction 98 rect.fRight, rect.fBottom, directions[contour] == SkPath::kC CW_Direction
99 ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction"); 99 ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction");
100 } 100 }
101 return; 101 return;
102 } 102 }
103 #endif 103 #endif
104 SkPath::FillType fillType = path.getFillType(); 104 SkPath::FillType fillType = path.getFillType();
105 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver seEvenOdd_FillType); 105 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver seEvenOdd_FillType);
106 SkDebugf(" path%s.setFillType(SkPath::%s);\n", suffix, fillTypeStr[fillTy pe]); 106 if (includeDeclaration) {
107 iter.setPath(path, true); 107 SkDebugf(" SkPath %s;\n", pathName);
108 showPathContours(iter, suffix); 108 }
109 SkDebugf(" %s.setFillType(SkPath::%s);\n", pathName, gFillTypeStr[fillTyp e]);
110 iter.setPath(path);
111 showPathContours(iter, pathName);
109 } 112 }
110 113
111 #if DEBUG_SHOW_TEST_NAME 114 #if DEBUG_SHOW_TEST_NAME
112 static void showPathData(const SkPath& path) { 115 static void showPathData(const SkPath& path) {
113 SkPath::Iter iter(path, true); 116 SkPath::RawIter iter(path);
114 uint8_t verb; 117 uint8_t verb;
115 SkPoint pts[4]; 118 SkPoint pts[4];
116 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 119 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
117 switch (verb) { 120 switch (verb) {
118 case SkPath::kMove_Verb: 121 case SkPath::kMove_Verb:
119 continue; 122 continue;
120 case SkPath::kLine_Verb: 123 case SkPath::kLine_Verb:
121 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0]. fY, 124 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0]. fY,
122 pts[1].fX, pts[1].fY); 125 pts[1].fX, pts[1].fY);
123 break; 126 break;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 SkDebugf("op xor\n"); 158 SkDebugf("op xor\n");
156 break; 159 break;
157 case kReverseDifference_PathOp: 160 case kReverseDifference_PathOp:
158 SkDebugf("op reverse difference\n"); 161 SkDebugf("op reverse difference\n");
159 break; 162 break;
160 default: 163 default:
161 SkASSERT(0); 164 SkASSERT(0);
162 } 165 }
163 } 166 }
164 167
165 #if 0 168 #if DEBUG_SHOW_TEST_NAME
166 static void showPath(const SkPath& path, const char* str, const SkMatrix& scale) { 169
167 SkPath scaled; 170 void ShowFunctionHeader(const char* functionName) {
168 SkMatrix inverse; 171 SkDebugf("\nstatic void %s(skiatest::Reporter* reporter) {\n", functionName) ;
169 bool success = scale.invert(&inverse); 172 if (strcmp("skphealth_com76", functionName) == 0) {
170 if (!success) { 173 SkDebugf("found it\n");
171 SkASSERT(0);
172 } 174 }
173 path.transform(inverse, &scaled); 175 }
174 showPath(scaled, str); 176
177 static const char* gOpStrs[] = {
178 "kDifference_PathOp",
179 "kIntersect_PathOp",
180 "kUnion_PathOp",
181 "kXor_PathOp",
182 "kReverseDifference_PathOp",
183 };
184
185 void ShowOp(SkPathOp op, const char* pathOne, const char* pathTwo) {
186 SkDebugf(" testPathOp(reporter, %s, %s, %s);\n", pathOne, pathTwo, gOpStr s[op]);
187 SkDebugf("}\n");
175 } 188 }
176 #endif 189 #endif
177 190
178 #if DEBUG_SHOW_TEST_NAME 191 #if DEBUG_SHOW_TEST_NAME
179 static char hexorator(int x) { 192 static char hexorator(int x) {
180 if (x < 10) { 193 if (x < 10) {
181 return x + '0'; 194 return x + '0';
182 } 195 }
183 x -= 10; 196 x -= 10;
184 SkASSERT(x < 26); 197 SkASSERT(x < 26);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x'; 331 *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x';
319 } 332 }
320 *outPtr++ = '\0'; 333 *outPtr++ = '\0';
321 SkDebugf("%s\n", out); 334 SkDebugf("%s\n", out);
322 } 335 }
323 return true; 336 return true;
324 } 337 }
325 338
326 static void showSimplifiedPath(const SkPath& one, const SkPath& two, 339 static void showSimplifiedPath(const SkPath& one, const SkPath& two,
327 const SkPath& scaledOne, const SkPath& scaledTwo) { 340 const SkPath& scaledOne, const SkPath& scaledTwo) {
328 showPath(one, ""); 341 showPath(one, "path", false);
329 // showPath(two, "simplified:");
330 drawAsciiPaths(scaledOne, scaledTwo, true); 342 drawAsciiPaths(scaledOne, scaledTwo, true);
331 } 343 }
332 344
333 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S kPath& two, 345 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S kPath& two,
334 SkBitmap& bitmap) { 346 SkBitmap& bitmap) {
335 int errors2x2; 347 int errors2x2;
336 SkPath scaledOne, scaledTwo; 348 SkPath scaledOne, scaledTwo;
337 int errors = pathsDrawTheSame(one, two, bitmap, scaledOne, scaledTwo, errors 2x2); 349 int errors = pathsDrawTheSame(one, two, bitmap, scaledOne, scaledTwo, errors 2x2);
338 if (errors2x2 == 0) { 350 if (errors2x2 == 0) {
339 return 0; 351 return 0;
340 } 352 }
341 const int MAX_ERRORS = 9; 353 const int MAX_ERRORS = 9;
342 if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) { 354 if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) {
343 showSimplifiedPath(one, two, scaledOne, scaledTwo); 355 showSimplifiedPath(one, two, scaledOne, scaledTwo);
344 } 356 }
345 if (errors2x2 > MAX_ERRORS && gComparePathsAssert) { 357 if (errors2x2 > MAX_ERRORS && gComparePathsAssert) {
346 SkDebugf("%s errors=%d\n", __FUNCTION__, errors); 358 SkDebugf("%s errors=%d\n", __FUNCTION__, errors);
347 showSimplifiedPath(one, two, scaledOne, scaledTwo); 359 showSimplifiedPath(one, two, scaledOne, scaledTwo);
348 REPORTER_ASSERT(reporter, 0); 360 REPORTER_ASSERT(reporter, 0);
349 } 361 }
350 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; 362 return errors2x2 > MAX_ERRORS ? errors2x2 : 0;
351 } 363 }
352 364
353 static void showPathOpPath(const SkPath& one, const SkPath& two, const SkPath& a , const SkPath& b, 365 static void showPathOpPath(const SkPath& one, const SkPath& two, const SkPath& a , const SkPath& b,
354 const SkPath& scaledOne, const SkPath& scaledTwo, const SkPathOp shapeOp , 366 const SkPath& scaledOne, const SkPath& scaledTwo, const SkPathOp shapeOp ,
355 const SkMatrix& scale) { 367 const SkMatrix& scale) {
356 SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); 368 SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs));
357 SkDebugf("static void xOp#%s(skiatest::Reporter* reporter) {\n", opSuffixes[ shapeOp]); 369 SkDebugf("static void xOp#%s(skiatest::Reporter* reporter) {\n", opSuffixes[ shapeOp]);
358 SkDebugf(" SkPath path, pathB;\n"); 370 SkDebugf(" SkPath path, pathB;\n");
359 showPath(a, ""); 371 showPath(a, "path", false);
360 showPath(b, "B"); 372 showPath(b, "pathB", false);
361 SkDebugf(" testPathOp(reporter, path, pathB, %s);\n", opStrs[shapeOp]); 373 SkDebugf(" testPathOp(reporter, path, pathB, %s);\n", opStrs[shapeOp]);
362 SkDebugf("}\n"); 374 SkDebugf("}\n");
363 // the region often isn't very helpful since it approximates curves with a l ot of line-tos
364 // if (0) showPath(scaledOne, "region:", scale);
365 // showPath(two, "op result:");
366 drawAsciiPaths(scaledOne, scaledTwo, true); 375 drawAsciiPaths(scaledOne, scaledTwo, true);
367 } 376 }
368 377
369 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S kPath& scaledOne, 378 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S kPath& scaledOne,
370 const SkPath& two, const SkPath& scaledTwo, SkBitmap& bi tmap, 379 const SkPath& two, const SkPath& scaledTwo, SkBitmap& bi tmap,
371 const SkPath& a, const SkPath& b, const SkPathOp shapeOp , 380 const SkPath& a, const SkPath& b, const SkPathOp shapeOp ,
372 const SkMatrix& scale) { 381 const SkMatrix& scale) {
373 int errors2x2; 382 int errors2x2;
374 int errors = pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); 383 int errors = pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2);
375 if (errors2x2 == 0) { 384 if (errors2x2 == 0) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 writeTestName(nameSuffix, outFile); 452 writeTestName(nameSuffix, outFile);
444 outFile.writeText("),\n"); 453 outFile.writeText("),\n");
445 outFile.flush(); 454 outFile.flush();
446 } 455 }
447 456
448 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st ate, 457 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st ate,
449 const char* pathStr) { 458 const char* pathStr) {
450 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi nding_FillType; 459 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi nding_FillType;
451 path.setFillType(fillType); 460 path.setFillType(fillType);
452 if (gShowPath) { 461 if (gShowPath) {
453 showPath(path, ""); 462 showPath(path, "path", false);
454 } 463 }
455 if (!Simplify(path, &out)) { 464 if (!Simplify(path, &out)) {
456 SkDebugf("%s did not expect failure\n", __FUNCTION__); 465 SkDebugf("%s did not expect failure\n", __FUNCTION__);
457 REPORTER_ASSERT(state.fReporter, 0); 466 REPORTER_ASSERT(state.fReporter, 0);
458 return false; 467 return false;
459 } 468 }
460 if (!gComparePaths) { 469 if (!gComparePaths) {
461 return true; 470 return true;
462 } 471 }
463 int result = comparePaths(state.fReporter, path, out, *state.fBitmap); 472 int result = comparePaths(state.fReporter, path, out, *state.fBitmap);
(...skipping 28 matching lines...) Expand all
492 } 501 }
493 SkBitmap bitmap; 502 SkBitmap bitmap;
494 int result = comparePaths(reporter, path, out, bitmap); 503 int result = comparePaths(reporter, path, out, bitmap);
495 if (result && gPathStrAssert) { 504 if (result && gPathStrAssert) {
496 REPORTER_ASSERT(reporter, 0); 505 REPORTER_ASSERT(reporter, 0);
497 } 506 }
498 reporter->bumpTestCount(); 507 reporter->bumpTestCount();
499 return result == 0; 508 return result == 0;
500 } 509 }
501 510
511 #if DEBUG_SHOW_TEST_NAME
512 void DebugShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp, const cha r* testName) {
513 ShowFunctionHeader(testName);
514 showPath(a, "path", true);
515 showPath(b, "pathB", true);
516 ShowOp(shapeOp, "path", "pathB");
517 }
518 #endif
519
502 bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, 520 bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
503 const SkPathOp shapeOp) { 521 const SkPathOp shapeOp, const char* testName) {
504 #if DEBUG_SHOW_TEST_NAME 522 #if DEBUG_SHOW_TEST_NAME
505 showPathData(a); 523 if (testName == NULL) {
506 showOp(shapeOp); 524 showPathData(a);
507 showPathData(b); 525 showOp(shapeOp);
526 showPathData(b);
527 } else {
528 DebugShowPath(a, b, shapeOp, testName);
529 }
508 #endif 530 #endif
509 SkPath out; 531 SkPath out;
510 if (!Op(a, b, shapeOp, &out) ) { 532 if (!Op(a, b, shapeOp, &out) ) {
511 SkDebugf("%s did not expect failure\n", __FUNCTION__); 533 SkDebugf("%s did not expect failure\n", __FUNCTION__);
512 REPORTER_ASSERT(reporter, 0); 534 REPORTER_ASSERT(reporter, 0);
513 return false; 535 return false;
514 } 536 }
515 SkPath pathOut, scaledPathOut; 537 SkPath pathOut, scaledPathOut;
516 SkRegion rgnA, rgnB, openClip, rgnOut; 538 SkRegion rgnA, rgnB, openClip, rgnOut;
517 openClip.setRect(-16000, -16000, 16000, 16000); 539 openClip.setRect(-16000, -16000, 16000, 16000);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 } 638 }
617 if (tests[index].fun == stopTest) { 639 if (tests[index].fun == stopTest) {
618 SkDebugf("lastTest\n"); 640 SkDebugf("lastTest\n");
619 } 641 }
620 if (index == last) { 642 if (index == last) {
621 break; 643 break;
622 } 644 }
623 index += reverse ? -1 : 1; 645 index += reverse ? -1 : 1;
624 } while (true); 646 } while (true);
625 } 647 }
OLDNEW
« no previous file with comments | « tests/PathOpsExtendedTest.h ('k') | tests/PathOpsLineIntersectionTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698