| OLD | NEW |
| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 "d", | 42 "d", |
| 43 "i", | 43 "i", |
| 44 "u", | 44 "u", |
| 45 "o", | 45 "o", |
| 46 }; | 46 }; |
| 47 | 47 |
| 48 static bool gShowPath = false; | 48 static bool gShowPath = false; |
| 49 static bool gComparePathsAssert = true; | 49 static bool gComparePathsAssert = true; |
| 50 static bool gPathStrAssert = true; | 50 static bool gPathStrAssert = true; |
| 51 | 51 |
| 52 static const char* gFillTypeStr[] = { | |
| 53 "kWinding_FillType", | |
| 54 "kEvenOdd_FillType", | |
| 55 "kInverseWinding_FillType", | |
| 56 "kInverseEvenOdd_FillType" | |
| 57 }; | |
| 58 | |
| 59 static void output_scalar(SkScalar num) { | |
| 60 if (num == (int) num) { | |
| 61 SkDebugf("%d", (int) num); | |
| 62 } else { | |
| 63 SkString str; | |
| 64 str.printf("%1.9g", num); | |
| 65 int width = (int) str.size(); | |
| 66 const char* cStr = str.c_str(); | |
| 67 while (cStr[width - 1] == '0') { | |
| 68 --width; | |
| 69 } | |
| 70 str.resize(width); | |
| 71 SkDebugf("%sf", str.c_str()); | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 static void output_points(const SkPoint* pts, int count) { | |
| 76 for (int index = 0; index < count; ++index) { | |
| 77 output_scalar(pts[index].fX); | |
| 78 SkDebugf(", "); | |
| 79 output_scalar(pts[index].fY); | |
| 80 if (index + 1 < count) { | |
| 81 SkDebugf(", "); | |
| 82 } | |
| 83 } | |
| 84 SkDebugf(");\n"); | |
| 85 } | |
| 86 | |
| 87 static void showPathContours(SkPath::RawIter& iter, const char* pathName) { | |
| 88 uint8_t verb; | |
| 89 SkPoint pts[4]; | |
| 90 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { | |
| 91 switch (verb) { | |
| 92 case SkPath::kMove_Verb: | |
| 93 SkDebugf(" %s.moveTo(", pathName); | |
| 94 output_points(&pts[0], 1); | |
| 95 continue; | |
| 96 case SkPath::kLine_Verb: | |
| 97 SkDebugf(" %s.lineTo(", pathName); | |
| 98 output_points(&pts[1], 1); | |
| 99 break; | |
| 100 case SkPath::kQuad_Verb: | |
| 101 SkDebugf(" %s.quadTo(", pathName); | |
| 102 output_points(&pts[1], 2); | |
| 103 break; | |
| 104 case SkPath::kCubic_Verb: | |
| 105 SkDebugf(" %s.cubicTo(", pathName); | |
| 106 output_points(&pts[1], 3); | |
| 107 break; | |
| 108 case SkPath::kClose_Verb: | |
| 109 SkDebugf(" %s.close();\n", pathName); | |
| 110 break; | |
| 111 default: | |
| 112 SkDEBUGFAIL("bad verb"); | |
| 113 return; | |
| 114 } | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 static void showPath(const SkPath& path, const char* pathName, bool includeDecla
ration) { | |
| 119 SkPath::RawIter iter(path); | |
| 120 #define SUPPORT_RECT_CONTOUR_DETECTION 0 | |
| 121 #if SUPPORT_RECT_CONTOUR_DETECTION | |
| 122 int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0; | |
| 123 if (rectCount > 0) { | |
| 124 SkTDArray<SkRect> rects; | |
| 125 SkTDArray<SkPath::Direction> directions; | |
| 126 rects.setCount(rectCount); | |
| 127 directions.setCount(rectCount); | |
| 128 path.rectContours(rects.begin(), directions.begin()); | |
| 129 for (int contour = 0; contour < rectCount; ++contour) { | |
| 130 const SkRect& rect = rects[contour]; | |
| 131 SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLe
ft, rect.fTop, | |
| 132 rect.fRight, rect.fBottom, directions[contour] == SkPath::kC
CW_Direction | |
| 133 ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction"); | |
| 134 } | |
| 135 return; | |
| 136 } | |
| 137 #endif | |
| 138 SkPath::FillType fillType = path.getFillType(); | |
| 139 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); | |
| 140 if (includeDeclaration) { | |
| 141 SkDebugf(" SkPath %s;\n", pathName); | |
| 142 } | |
| 143 SkDebugf(" %s.setFillType(SkPath::%s);\n", pathName, gFillTypeStr[fillTyp
e]); | |
| 144 iter.setPath(path); | |
| 145 showPathContours(iter, pathName); | |
| 146 } | |
| 147 | |
| 148 #if DEBUG_SHOW_TEST_NAME | 52 #if DEBUG_SHOW_TEST_NAME |
| 149 static void showPathData(const SkPath& path) { | 53 static void showPathData(const SkPath& path) { |
| 150 SkPath::RawIter iter(path); | 54 SkPath::RawIter iter(path); |
| 151 uint8_t verb; | 55 uint8_t verb; |
| 152 SkPoint pts[4]; | 56 SkPoint pts[4]; |
| 153 SkPoint firstPt = {0, 0}, lastPt = {0, 0}; | 57 SkPoint firstPt = {0, 0}, lastPt = {0, 0}; |
| 154 bool firstPtSet = false; | 58 bool firstPtSet = false; |
| 155 bool lastPtSet = true; | 59 bool lastPtSet = true; |
| 156 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { | 60 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
| 157 switch (verb) { | 61 switch (verb) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 break; | 122 break; |
| 219 case kReverseDifference_PathOp: | 123 case kReverseDifference_PathOp: |
| 220 SkDebugf("op reverse difference\n"); | 124 SkDebugf("op reverse difference\n"); |
| 221 break; | 125 break; |
| 222 default: | 126 default: |
| 223 SkASSERT(0); | 127 SkASSERT(0); |
| 224 } | 128 } |
| 225 } | 129 } |
| 226 | 130 |
| 227 #if DEBUG_SHOW_TEST_NAME | 131 #if DEBUG_SHOW_TEST_NAME |
| 228 | |
| 229 void ShowFunctionHeader(const char* functionName) { | |
| 230 SkDebugf("\nstatic void %s(skiatest::Reporter* reporter, const char* filenam
e) {\n", functionName); | |
| 231 if (strcmp("skphealth_com76", functionName) == 0) { | |
| 232 SkDebugf("found it\n"); | |
| 233 } | |
| 234 } | |
| 235 | |
| 236 static const char* gOpStrs[] = { | |
| 237 "kDifference_PathOp", | |
| 238 "kIntersect_PathOp", | |
| 239 "kUnion_PathOp", | |
| 240 "kXor_PathOp", | |
| 241 "kReverseDifference_PathOp", | |
| 242 }; | |
| 243 | |
| 244 void ShowOp(SkPathOp op, const char* pathOne, const char* pathTwo) { | |
| 245 SkDebugf(" testPathOp(reporter, %s, %s, %s, filename);\n", pathOne, pathT
wo, gOpStrs[op]); | |
| 246 SkDebugf("}\n"); | |
| 247 } | |
| 248 #endif | |
| 249 | |
| 250 #if DEBUG_SHOW_TEST_NAME | |
| 251 static char hexorator(int x) { | 132 static char hexorator(int x) { |
| 252 if (x < 10) { | 133 if (x < 10) { |
| 253 return x + '0'; | 134 return x + '0'; |
| 254 } | 135 } |
| 255 x -= 10; | 136 x -= 10; |
| 256 SkASSERT(x < 26); | 137 SkASSERT(x < 26); |
| 257 return x + 'A'; | 138 return x + 'A'; |
| 258 } | 139 } |
| 259 #endif | 140 #endif |
| 260 | 141 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); | 294 SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); |
| 414 SkString defaultTestName; | 295 SkString defaultTestName; |
| 415 if (!testName) { | 296 if (!testName) { |
| 416 defaultTestName.printf("xOp%d%s", gTestNo, opSuffixes[shapeOp]); | 297 defaultTestName.printf("xOp%d%s", gTestNo, opSuffixes[shapeOp]); |
| 417 testName = defaultTestName.c_str(); | 298 testName = defaultTestName.c_str(); |
| 418 } | 299 } |
| 419 SkDebugf("static void %s(skiatest::Reporter* reporter, const char* filename)
{\n", testName); | 300 SkDebugf("static void %s(skiatest::Reporter* reporter, const char* filename)
{\n", testName); |
| 420 *gTestOp.append() = shapeOp; | 301 *gTestOp.append() = shapeOp; |
| 421 ++gTestNo; | 302 ++gTestNo; |
| 422 SkDebugf(" SkPath path, pathB;\n"); | 303 SkDebugf(" SkPath path, pathB;\n"); |
| 423 showPath(a, "path", false); | 304 #if DEBUG_SHOW_TEST_NAME |
| 424 showPath(b, "pathB", false); | 305 SkPathOpsDebug::ShowOnePath(a, "path", false); |
| 306 SkPathOpsDebug::ShowOnePath(b, "pathB", false); |
| 307 #endif |
| 425 SkDebugf(" testPathOp(reporter, path, pathB, %s, filename);\n", opStrs[sh
apeOp]); | 308 SkDebugf(" testPathOp(reporter, path, pathB, %s, filename);\n", opStrs[sh
apeOp]); |
| 426 SkDebugf("}\n"); | 309 SkDebugf("}\n"); |
| 427 drawAsciiPaths(scaledOne, scaledTwo, true); | 310 drawAsciiPaths(scaledOne, scaledTwo, true); |
| 428 } | 311 } |
| 429 | 312 |
| 430 void ShowTestArray() { | 313 void ShowTestArray() { |
| 431 for (int x = gTestFirst; x < gTestNo; ++x) { | 314 for (int x = gTestFirst; x < gTestNo; ++x) { |
| 432 SkDebugf(" TEST(xOp%d%s),\n", x, opSuffixes[gTestOp[x - gTestFirst]])
; | 315 SkDebugf(" TEST(xOp%d%s),\n", x, opSuffixes[gTestOp[x - gTestFirst]])
; |
| 433 } | 316 } |
| 434 } | 317 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 writeTestName(nameSuffix, outFile); | 399 writeTestName(nameSuffix, outFile); |
| 517 outFile.writeText("),\n"); | 400 outFile.writeText("),\n"); |
| 518 #endif | 401 #endif |
| 519 outFile.flush(); | 402 outFile.flush(); |
| 520 } | 403 } |
| 521 | 404 |
| 522 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st
ate, | 405 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st
ate, |
| 523 const char* pathStr) { | 406 const char* pathStr) { |
| 524 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi
nding_FillType; | 407 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi
nding_FillType; |
| 525 path.setFillType(fillType); | 408 path.setFillType(fillType); |
| 409 #if DEBUG_SHOW_TEST_NAME |
| 526 if (gShowPath) { | 410 if (gShowPath) { |
| 527 showPath(path, "path", false); | 411 SkPathOpsDebug::ShowOnePath(path, "path", false); |
| 528 } | 412 } |
| 413 #endif |
| 529 if (!Simplify(path, &out)) { | 414 if (!Simplify(path, &out)) { |
| 530 SkDebugf("%s did not expect failure\n", __FUNCTION__); | 415 SkDebugf("%s did not expect failure\n", __FUNCTION__); |
| 531 REPORTER_ASSERT(state.fReporter, 0); | 416 REPORTER_ASSERT(state.fReporter, 0); |
| 532 return false; | 417 return false; |
| 533 } | 418 } |
| 534 if (!state.fReporter->verbose()) { | 419 if (!state.fReporter->verbose()) { |
| 535 return true; | 420 return true; |
| 536 } | 421 } |
| 537 int result = comparePaths(state.fReporter, NULL, path, out, *state.fBitmap); | 422 int result = comparePaths(state.fReporter, NULL, path, out, *state.fBitmap); |
| 538 if (result && gPathStrAssert) { | 423 if (result && gPathStrAssert) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 569 SkBitmap bitmap; | 454 SkBitmap bitmap; |
| 570 int result = comparePaths(reporter, filename, path, out, bitmap); | 455 int result = comparePaths(reporter, filename, path, out, bitmap); |
| 571 if (result && gPathStrAssert) { | 456 if (result && gPathStrAssert) { |
| 572 REPORTER_ASSERT(reporter, 0); | 457 REPORTER_ASSERT(reporter, 0); |
| 573 } | 458 } |
| 574 reporter->bumpTestCount(); | 459 reporter->bumpTestCount(); |
| 575 return result == 0; | 460 return result == 0; |
| 576 } | 461 } |
| 577 | 462 |
| 578 #if DEBUG_SHOW_TEST_NAME | 463 #if DEBUG_SHOW_TEST_NAME |
| 579 | |
| 580 SK_DECLARE_STATIC_MUTEX(gTestMutex); | |
| 581 | |
| 582 void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp
, | |
| 583 const char* testName) { | |
| 584 SkAutoMutexAcquire ac(gTestMutex); | |
| 585 ShowFunctionHeader(testName); | |
| 586 showPath(a, "path", true); | |
| 587 showPath(b, "pathB", true); | |
| 588 ShowOp(shapeOp, "path", "pathB"); | |
| 589 } | |
| 590 #endif | |
| 591 | |
| 592 #if DEBUG_SHOW_TEST_NAME | |
| 593 static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) { | 464 static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) { |
| 594 SkDebugf("\n"); | 465 SkDebugf("\n"); |
| 595 showPathData(a); | 466 showPathData(a); |
| 596 showOp(shapeOp); | 467 showOp(shapeOp); |
| 597 showPathData(b); | 468 showPathData(b); |
| 598 } | 469 } |
| 599 #endif | 470 #endif |
| 600 | 471 |
| 601 static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
ath& b, | 472 static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
ath& b, |
| 602 const SkPathOp shapeOp, const char* testName, bool threaded) { | 473 const SkPathOp shapeOp, const char* testName, bool threaded) { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 if (tests[index].fun == stopTest) { | 620 if (tests[index].fun == stopTest) { |
| 750 SkDebugf("lastTest\n"); | 621 SkDebugf("lastTest\n"); |
| 751 break; | 622 break; |
| 752 } | 623 } |
| 753 if (index == last) { | 624 if (index == last) { |
| 754 break; | 625 break; |
| 755 } | 626 } |
| 756 index += reverse ? -1 : 1; | 627 index += reverse ? -1 : 1; |
| 757 } while (true); | 628 } while (true); |
| 758 } | 629 } |
| OLD | NEW |