1 #include "SkOpContour.h" 2 #include "SkIntersectionHelper.h" 3 #include "SkOpSegment.h" 4 #include "SkString.h" 5 6 inline void DebugDumpDouble(double x) { 7 if (x == floor(x)) { 8 SkDebugf("%.0f", x); 9 } else { 10 SkDebugf("%1.19g", x); 11 } 12 } 13 14 inline void DebugDumpFloat(float x) { 15 if (x == floorf(x)) { 16 SkDebugf("%.0f", x); 17 } else { 18 SkDebugf("%1.9gf", x); 19 } 20 } 21 22 23 #if DEBUG_SHOW_TEST_NAME 24 25 static void output_scalar(SkScalar num) { 26 if (num == (int) num) { 27 SkDebugf("%d", (int) num); 28 } else { 29 SkString str; 30 str.printf("%1.9g", num); 31 int width = (int) str.size(); 32 const char* cStr = str.c_str(); 33 while (cStr[width - 1] == '0') { 34 --width; 35 } 36 str.resize(width); 37 SkDebugf("%sf", str.c_str()); 38 } 39 } 40 41 static void output_points(const SkPoint* pts, int count) { 42 for (int index = 0; index < count; ++index) { 43 output_scalar(pts[index].fX); 44 SkDebugf(", "); 45 output_scalar(pts[index].fY); 46 if (index + 1 < count) { 47 SkDebugf(", "); 48 } 49 } 50 SkDebugf(");\n"); 51 } 52 53 static void showPathContours(SkPath::RawIter& iter, const char* pathName) { 54 uint8_t verb; 55 SkPoint pts[4]; 56 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 57 switch (verb) { 58 case SkPath::kMove_Verb: 59 SkDebugf(" %s.moveTo(", pathName); 60 output_points(&pts[0], 1); 61 continue; 62 case SkPath::kLine_Verb: 63 SkDebugf(" %s.lineTo(", pathName); 64 output_points(&pts[1], 1); 65 break; 66 case SkPath::kQuad_Verb: 67 SkDebugf(" %s.quadTo(", pathName); 68 output_points(&pts[1], 2); 69 break; 70 case SkPath::kCubic_Verb: 71 SkDebugf(" %s.cubicTo(", pathName); 72 output_points(&pts[1], 3); 73 break; 74 case SkPath::kClose_Verb: 75 SkDebugf(" %s.close();\n", pathName); 76 break; 77 default: 78 SkDEBUGFAIL("bad verb"); 79 return; 80 } 81 } 82 } 83 84 static const char* gFillTypeStr[] = { 85 "kWinding_FillType", 86 "kEvenOdd_FillType", 87 "kInverseWinding_FillType", 88 "kInverseEvenOdd_FillType" 89 }; 90 91 void SkPathOpsDebug::ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration) { 92 SkPath::RawIter iter(path); 93 #define SUPPORT_RECT_CONTOUR_DETECTION 0 94 #if SUPPORT_RECT_CONTOUR_DETECTION 95 int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0; 96 if (rectCount > 0) { 97 SkTDArray<SkRect> rects; 98 SkTDArray<SkPath::Direction> directions; 99 rects.setCount(rectCount); 100 directions.setCount(rectCount); 101 path.rectContours(rects.begin(), directions.begin()); 102 for (int contour = 0; contour < rectCount; ++contour) { 103 const SkRect& rect = rects[contour]; 104 SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop, 105 rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction 106 ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction"); 107 } 108 return; 109 } 110 #endif 111 SkPath::FillType fillType = path.getFillType(); 112 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInverseEvenOdd_FillType); 113 if (includeDeclaration) { 114 SkDebugf(" SkPath %s;\n", name); 115 } 116 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]); 117 iter.setPath(path); 118 showPathContours(iter, name); 119 } 120 121 static void show_function_header(const char* functionName) { 122 SkDebugf("\nstatic void %s(skiatest::Reporter* reporter, const char* filename) {\n", functionName); 123 if (strcmp("skphealth_com76", functionName) == 0) { 124 SkDebugf("found it\n"); 125 } 126 } 127 128 static const char* gOpStrs[] = { 129 "kDifference_PathOp", 130 "kIntersect_PathOp", 131 "kUnion_PathOp", 132 "kXor_PathOp", 133 "kReverseDifference_PathOp", 134 }; 135 136 static void show_op(SkPathOp op, const char* pathOne, const char* pathTwo) { 137 SkDebugf(" testPathOp(reporter, %s, %s, %s, filename);\n", pathOne, pathTwo, gOpStrs[op]); 138 SkDebugf("}\n"); 139 } 140 141 SK_DECLARE_STATIC_MUTEX(gTestMutex); 142 143 void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp, 144 const char* testName) { 145 SkAutoMutexAcquire ac(gTestMutex); 146 show_function_header(testName); 147 ShowOnePath(a, "path", true); 148 ShowOnePath(b, "pathB", true); 149 show_op(shapeOp, "path", "pathB"); 150 } 151 #endif 152 153 // if not defined by PathOpsDebug.cpp ... 154 #if !defined SK_DEBUG && FORCE_RELEASE 155 bool SkPathOpsDebug::ValidWind(int wind) { 156 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF; 157 } 158 159 void SkPathOpsDebug::WindingPrintf(int wind) { 160 if (wind == SK_MinS32) { 161 SkDebugf("?"); 162 } else { 163 SkDebugf("%d", wind); 164 } 165 } 166 #endif 167 168 void SkOpAngle::dump() const { 169 dumpOne(true); 170 SkDebugf("\n"); 171 } 172 173 void SkOpAngle::dumpOne(bool functionHeader) const { 174 // fSegment->debugValidate(); 175 const SkOpSpan& mSpan = fSegment->span(SkMin32(fStart, fEnd)); 176 if (functionHeader) { 177 SkDebugf("%s ", __FUNCTION__); 178 } 179 SkDebugf("[%d", fSegment->debugID()); 180 SkDebugf("/%d", debugID()); 181 SkDebugf("] next="); 182 if (fNext) { 183 SkDebugf("%d", fNext->fSegment->debugID()); 184 SkDebugf("/%d", fNext->debugID()); 185 } else { 186 SkDebugf("?"); 187 } 188 SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd); 189 SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fSegment->span(fStart).fT, fStart, 190 fSegment->span(fEnd).fT, fEnd); 191 SkDebugf(" sgn=%d windVal=%d", sign(), mSpan.fWindValue); 192 193 SkDebugf(" windSum="); 194 SkPathOpsDebug::WindingPrintf(mSpan.fWindSum); 195 if (mSpan.fOppValue != 0 || mSpan.fOppSum != SK_MinS32) { 196 SkDebugf(" oppVal=%d", mSpan.fOppValue); 197 SkDebugf(" oppSum="); 198 SkPathOpsDebug::WindingPrintf(mSpan.fOppSum); 199 } 200 if (mSpan.fDone) { 201 SkDebugf(" done"); 202 } 203 if (unorderable()) { 204 SkDebugf(" unorderable"); 205 } 206 if (small()) { 207 SkDebugf(" small"); 208 } 209 if (mSpan.fTiny) { 210 SkDebugf(" tiny"); 211 } 212 if (fSegment->operand()) { 213 SkDebugf(" operand"); 214 } 215 if (fStop) { 216 SkDebugf(" stop"); 217 } 218 } 219 220 void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const { 221 const SkOpAngle* first = this; 222 const SkOpAngle* next = this; 223 const char* indent = ""; 224 do { 225 SkDebugf("%s", indent); 226 next->dumpOne(false); 227 if (segment == next->fSegment) { 228 if (this == fNext) { 229 SkDebugf(" << from"); 230 } 231 if (to == fNext) { 232 SkDebugf(" << to"); 233 } 234 } 235 SkDebugf("\n"); 236 indent = " "; 237 next = next->fNext; 238 } while (next && next != first); 239 } 240 241 void SkOpAngle::dumpLoop() const { 242 const SkOpAngle* first = this; 243 const SkOpAngle* next = this; 244 do { 245 next->dumpOne(false); 246 SkDebugf("\n"); 247 next = next->fNext; 248 } while (next && next != first); 249 } 250 251 void SkOpAngle::dumpPartials() const { 252 const SkOpAngle* first = this; 253 const SkOpAngle* next = this; 254 do { 255 next->fCurvePart.dumpNumber(); 256 next = next->fNext; 257 } while (next && next != first); 258 } 259 260 void SkOpAngleSet::dump() const { 261 // FIXME: unimplemented 262 /* This requires access to the internal SkChunkAlloc data 263 Defer implementing this until it is needed for debugging 264 */ 265 SkASSERT(0); 266 } 267 268 void SkOpContour::dump() const { 269 int segmentCount = fSegments.count(); 270 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); 271 for (int test = 0; test < segmentCount; ++test) { 272 SkDebugf(" [%d] ((SkOpSegment*) 0x%p) [%d]\n", test, &fSegments[test], 273 fSegments[test].debugID()); 274 } 275 } 276 277 void SkOpContour::dumpAngles() const { 278 int segmentCount = fSegments.count(); 279 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); 280 for (int test = 0; test < segmentCount; ++test) { 281 SkDebugf(" [%d] ", test); 282 fSegments[test].dumpAngles(); 283 } 284 } 285 286 void SkOpContour::dumpCoincidence(const SkCoincidence& coin) const { 287 int thisIndex = coin.fSegments[0]; 288 const SkOpSegment& s1 = fSegments[thisIndex]; 289 int otherIndex = coin.fSegments[1]; 290 const SkOpSegment& s2 = coin.fOther->fSegments[otherIndex]; 291 SkDebugf("((SkOpSegment*) 0x%p) [%d] ((SkOpSegment*) 0x%p) [%d]\n", &s1, s1.debugID(), 292 &s2, s2.debugID()); 293 for (int index = 0; index < 2; ++index) { 294 SkDebugf(" {%1.9gf, %1.9gf}", coin.fPts[0][index].fX, coin.fPts[0][index].fY); 295 if (coin.fNearly[index]) { 296 SkDebugf(" {%1.9gf, %1.9gf}", coin.fPts[1][index].fX, coin.fPts[1][index].fY); 297 } 298 SkDebugf(" seg1t=%1.9g seg2t=%1.9g\n", coin.fTs[0][index], coin.fTs[1][index]); 299 } 300 } 301 302 void SkOpContour::dumpCoincidences() const { 303 int count = fCoincidences.count(); 304 if (count > 0) { 305 SkDebugf("fCoincidences count=%d\n", count); 306 for (int test = 0; test < count; ++test) { 307 dumpCoincidence(fCoincidences[test]); 308 } 309 } 310 count = fPartialCoincidences.count(); 311 if (count == 0) { 312 return; 313 } 314 SkDebugf("fPartialCoincidences count=%d\n", count); 315 for (int test = 0; test < count; ++test) { 316 dumpCoincidence(fPartialCoincidences[test]); 317 } 318 } 319 320 void SkOpContour::dumpPt(int index) const { 321 int segmentCount = fSegments.count(); 322 for (int test = 0; test < segmentCount; ++test) { 323 const SkOpSegment& segment = fSegments[test]; 324 if (segment.debugID() == index) { 325 fSegments[test].dumpPts(); 326 } 327 } 328 } 329 330 void SkOpContour::dumpPts() const { 331 int segmentCount = fSegments.count(); 332 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); 333 for (int test = 0; test < segmentCount; ++test) { 334 SkDebugf(" [%d] ", test); 335 fSegments[test].dumpPts(); 336 } 337 } 338 339 void SkOpContour::dumpSpan(int index) const { 340 int segmentCount = fSegments.count(); 341 for (int test = 0; test < segmentCount; ++test) { 342 const SkOpSegment& segment = fSegments[test]; 343 if (segment.debugID() == index) { 344 fSegments[test].dumpSpans(); 345 } 346 } 347 } 348 349 void SkOpContour::dumpSpans() const { 350 int segmentCount = fSegments.count(); 351 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); 352 for (int test = 0; test < segmentCount; ++test) { 353 SkDebugf(" [%d] ", test); 354 fSegments[test].dumpSpans(); 355 } 356 } 357 358 void SkDCubic::dump() const { 359 SkDebugf("{{"); 360 int index = 0; 361 do { 362 fPts[index].dump(); 363 SkDebugf(", "); 364 } while (++index < 3); 365 fPts[index].dump(); 366 SkDebugf("}}\n"); 367 } 368 369 void SkDCubic::dumpNumber() const { 370 SkDebugf("{{"); 371 int index = 0; 372 bool dumpedOne = false; 373 do { 374 if (!(fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY)) { 375 continue; 376 } 377 if (dumpedOne) { 378 SkDebugf(", "); 379 } 380 fPts[index].dump(); 381 dumpedOne = true; 382 } while (++index < 3); 383 if (fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY) { 384 if (dumpedOne) { 385 SkDebugf(", "); 386 } 387 fPts[index].dump(); 388 } 389 SkDebugf("}}\n"); 390 } 391 392 void SkDLine::dump() const { 393 SkDebugf("{{"); 394 fPts[0].dump(); 395 SkDebugf(", "); 396 fPts[1].dump(); 397 SkDebugf("}}\n"); 398 } 399 400 void SkDPoint::dump() const { 401 SkDebugf("{"); 402 DebugDumpDouble(fX); 403 SkDebugf(", "); 404 DebugDumpDouble(fY); 405 SkDebugf("}"); 406 } 407 408 void SkDPoint::Dump(const SkPoint& pt) { 409 SkDebugf("{"); 410 DebugDumpFloat(pt.fX); 411 SkDebugf(", "); 412 DebugDumpFloat(pt.fY); 413 SkDebugf("}"); 414 } 415 416 417 void SkDQuad::dumpComma(const char* comma) const { 418 SkDebugf("{{"); 419 int index = 0; 420 do { 421 fPts[index].dump(); 422 SkDebugf(", "); 423 } while (++index < 2); 424 fPts[index].dump(); 425 SkDebugf("}}%s\n", comma ? comma : ""); 426 } 427 428 void SkDQuad::dump() const { 429 dumpComma(""); 430 } 431 432 void SkIntersectionHelper::dump() const { 433 SkDPoint::Dump(pts()[0]); 434 SkDPoint::Dump(pts()[1]); 435 if (verb() >= SkPath::kQuad_Verb) { 436 SkDPoint::Dump(pts()[2]); 437 } 438 if (verb() >= SkPath::kCubic_Verb) { 439 SkDPoint::Dump(pts()[3]); 440 } 441 } 442 443 const SkTDArray<SkOpSpan>& SkOpSegment::debugSpans() const { 444 return fTs; 445 } 446 447 void SkOpSegment::dumpAngles() const { 448 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID()); 449 const SkOpAngle* fromAngle = NULL; 450 const SkOpAngle* toAngle = NULL; 451 for (int index = 0; index < count(); ++index) { 452 const SkOpAngle* fAngle = fTs[index].fFromAngle; 453 const SkOpAngle* tAngle = fTs[index].fToAngle; 454 if (fromAngle == fAngle && toAngle == tAngle) { 455 continue; 456 } 457 if (fAngle) { 458 SkDebugf(" [%d] from=%d ", index, fAngle->debugID()); 459 fAngle->dumpTo(this, tAngle); 460 } 461 if (tAngle) { 462 SkDebugf(" [%d] to=%d ", index, tAngle->debugID()); 463 tAngle->dumpTo(this, fAngle); 464 } 465 fromAngle = fAngle; 466 toAngle = tAngle; 467 } 468 } 469 470 void SkOpSegment::dumpContour(int firstID, int lastID) const { 471 if (debugID() < 0) { 472 return; 473 } 474 const SkOpSegment* test = this - (debugID() - 1); 475 test += (firstID - 1); 476 const SkOpSegment* last = test + (lastID - firstID); 477 while (test <= last) { 478 test->dumpSpans(); 479 ++test; 480 } 481 } 482 483 void SkOpSegment::dumpPts() const { 484 int last = SkPathOpsVerbToPoints(fVerb); 485 SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID()); 486 int index = 0; 487 do { 488 SkDPoint::Dump(fPts[index]); 489 SkDebugf(", "); 490 } while (++index < last); 491 SkDPoint::Dump(fPts[index]); 492 SkDebugf("}}\n"); 493 } 494 495 void SkOpSegment::dumpDPts() const { 496 int count = SkPathOpsVerbToPoints(fVerb); 497 SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID()); 498 int index = 0; 499 do { 500 SkDPoint dPt = {fPts[index].fX, fPts[index].fY}; 501 dPt.dump(); 502 if (index != count) { 503 SkDebugf(", "); 504 } 505 } while (++index <= count); 506 SkDebugf("}}\n"); 507 } 508 509 void SkOpSegment::dumpSpans() const { 510 int count = this->count(); 511 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID()); 512 for (int index = 0; index < count; ++index) { 513 const SkOpSpan& span = this->span(index); 514 SkDebugf(" [%d] ", index); 515 span.dumpOne(); 516 } 517 } 518 519 void SkPathOpsDebug::DumpCoincidence(const SkTArray<SkOpContour, true>& contours) { 520 int count = contours.count(); 521 for (int index = 0; index < count; ++index) { 522 contours[index].dumpCoincidences(); 523 } 524 } 525 526 void SkPathOpsDebug::DumpCoincidence(const SkTArray<SkOpContour* , true>& contours) { 527 int count = contours.count(); 528 for (int index = 0; index < count; ++index) { 529 contours[index]->dumpCoincidences(); 530 } 531 } 532 533 void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour, true>& contours) { 534 int count = contours.count(); 535 for (int index = 0; index < count; ++index) { 536 contours[index].dump(); 537 } 538 } 539 540 void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour* , true>& contours) { 541 int count = contours.count(); 542 for (int index = 0; index < count; ++index) { 543 contours[index]->dump(); 544 } 545 } 546 547 void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour, true>& contours) { 548 int count = contours.count(); 549 for (int index = 0; index < count; ++index) { 550 contours[index].dumpAngles(); 551 } 552 } 553 554 void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour* , true>& contours) { 555 int count = contours.count(); 556 for (int index = 0; index < count; ++index) { 557 contours[index]->dumpAngles(); 558 } 559 } 560 561 void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour, true>& contours) { 562 int count = contours.count(); 563 for (int index = 0; index < count; ++index) { 564 contours[index].dumpPts(); 565 } 566 } 567 568 void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour* , true>& contours) { 569 int count = contours.count(); 570 for (int index = 0; index < count; ++index) { 571 contours[index]->dumpPts(); 572 } 573 } 574 575 void SkPathOpsDebug::DumpContourPt(const SkTArray<SkOpContour, true>& contours, int segmentID) { 576 int count = contours.count(); 577 for (int index = 0; index < count; ++index) { 578 contours[index].dumpPt(segmentID); 579 } 580 } 581 582 void SkPathOpsDebug::DumpContourPt(const SkTArray<SkOpContour* , true>& contours, int segmentID) { 583 int count = contours.count(); 584 for (int index = 0; index < count; ++index) { 585 contours[index]->dumpPt(segmentID); 586 } 587 } 588 589 void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour, true>& contours) { 590 int count = contours.count(); 591 for (int index = 0; index < count; ++index) { 592 contours[index].dumpSpans(); 593 } 594 } 595 596 void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour* , true>& contours) { 597 int count = contours.count(); 598 for (int index = 0; index < count; ++index) { 599 contours[index]->dumpSpans(); 600 } 601 } 602 603 void SkPathOpsDebug::DumpContourSpan(const SkTArray<SkOpContour, true>& contours, int segmentID) { 604 int count = contours.count(); 605 for (int index = 0; index < count; ++index) { 606 contours[index].dumpSpan(segmentID); 607 } 608 } 609 610 void SkPathOpsDebug::DumpContourSpan(const SkTArray<SkOpContour* , true>& contours, int segmentID) { 611 int count = contours.count(); 612 for (int index = 0; index < count; ++index) { 613 contours[index]->dumpSpan(segmentID); 614 } 615 } 616 617 void SkPathOpsDebug::DumpSpans(const SkTDArray<SkOpSpan *>& spans) { 618 int count = spans.count(); 619 for (int index = 0; index < count; ++index) { 620 const SkOpSpan* span = spans[index]; 621 const SkOpSpan& oSpan = span->fOther->span(span->fOtherIndex); 622 const SkOpSegment* segment = oSpan.fOther; 623 SkDebugf("((SkOpSegment*) 0x%p) [%d] ", segment, segment->debugID()); 624 SkDebugf("spanIndex:%d ", oSpan.fOtherIndex); 625 span->dumpOne(); 626 } 627 } 628 629 // this does not require that other T index is initialized or correct 630 const SkOpSegment* SkOpSpan::debugToSegment(ptrdiff_t* spanIndex) const { 631 if (!fOther) { 632 return NULL; 633 } 634 int oppCount = fOther->count(); 635 for (int index = 0; index < oppCount; ++index) { 636 const SkOpSpan& otherSpan = fOther->span(index); 637 double otherTestT = otherSpan.fT; 638 if (otherTestT < fOtherT) { 639 continue; 640 } 641 SkASSERT(otherTestT == fOtherT); 642 const SkOpSegment* candidate = otherSpan.fOther; 643 const SkOpSpan* first = candidate->debugSpans().begin(); 644 const SkOpSpan* last = candidate->debugSpans().end() - 1; 645 if (first <= this && this <= last) { 646 if (spanIndex) { 647 *spanIndex = this - first; 648 } 649 return candidate; 650 } 651 } 652 SkASSERT(0); 653 return NULL; 654 } 655 656 void SkOpSpan::dumpOne() const { 657 SkDebugf("t="); 658 DebugDumpDouble(fT); 659 SkDebugf(" pt="); 660 SkDPoint::Dump(fPt); 661 if (fOther) { 662 SkDebugf(" other.fID=%d", fOther->debugID()); 663 SkDebugf(" [%d] otherT=", fOtherIndex); 664 DebugDumpDouble(fOtherT); 665 } else { 666 SkDebugf(" other.fID=? [?] otherT=?"); 667 } 668 if (fWindSum != SK_MinS32) { 669 SkDebugf(" windSum=%d", fWindSum); 670 } 671 if (fOppSum != SK_MinS32 && (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0)) { 672 SkDebugf(" oppSum=%d", fOppSum); 673 } 674 SkDebugf(" windValue=%d", fWindValue); 675 if (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0) { 676 SkDebugf(" oppValue=%d", fOppValue); 677 } 678 if (fFromAngle && fFromAngle->debugID()) { 679 SkDebugf(" from=%d", fFromAngle->debugID()); 680 } 681 if (fToAngle && fToAngle->debugID()) { 682 SkDebugf(" to=%d", fToAngle->debugID()); 683 } 684 if (fChased) { 685 SkDebugf(" chased"); 686 } 687 if (fCoincident) { 688 SkDebugf(" coincident"); 689 } 690 if (fDone) { 691 SkDebugf(" done"); 692 } 693 if (fLoop) { 694 SkDebugf(" loop"); 695 } 696 if (fMultiple) { 697 SkDebugf(" multiple"); 698 } 699 if (fNear) { 700 SkDebugf(" near"); 701 } 702 if (fSmall) { 703 SkDebugf(" small"); 704 } 705 if (fTiny) { 706 SkDebugf(" tiny"); 707 } 708 SkDebugf("\n"); 709 } 710 711 void SkOpSpan::dump() const { 712 ptrdiff_t spanIndex; 713 const SkOpSegment* segment = debugToSegment(&spanIndex); 714 if (segment) { 715 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", segment, segment->debugID()); 716 SkDebugf(" [%d] ", spanIndex); 717 } else { 718 SkDebugf("((SkOpSegment*) ?) [?]\n"); 719 SkDebugf(" [?] "); 720 } 721 dumpOne(); 722 } 723 724 void Dump(const SkTArray<class SkOpContour, true>& contours) { 725 SkPathOpsDebug::DumpContours(contours); 726 } 727 728 void Dump(const SkTArray<class SkOpContour* , true>& contours) { 729 SkPathOpsDebug::DumpContours(contours); 730 } 731 732 void Dump(const SkTArray<class SkOpContour, true>* contours) { 733 SkPathOpsDebug::DumpContours(*contours); 734 } 735 736 void Dump(const SkTArray<class SkOpContour* , true>* contours) { 737 SkPathOpsDebug::DumpContours(*contours); 738 } 739 740 void Dump(const SkTDArray<SkOpSpan *>& chase) { 741 SkPathOpsDebug::DumpSpans(chase); 742 } 743 744 void Dump(const SkTDArray<SkOpSpan *>* chase) { 745 SkPathOpsDebug::DumpSpans(*chase); 746 } 747 748 void DumpAngles(const SkTArray<class SkOpContour, true>& contours) { 749 SkPathOpsDebug::DumpContourAngles(contours); 750 } 751 752 void DumpAngles(const SkTArray<class SkOpContour* , true>& contours) { 753 SkPathOpsDebug::DumpContourAngles(contours); 754 } 755 756 void DumpAngles(const SkTArray<class SkOpContour, true>* contours) { 757 SkPathOpsDebug::DumpContourAngles(*contours); 758 } 759 760 void DumpAngles(const SkTArray<class SkOpContour* , true>* contours) { 761 SkPathOpsDebug::DumpContourAngles(*contours); 762 } 763 764 void DumpCoin(const SkTArray<class SkOpContour, true>& contours) { 765 SkPathOpsDebug::DumpCoincidence(contours); 766 } 767 768 void DumpCoin(const SkTArray<class SkOpContour* , true>& contours) { 769 SkPathOpsDebug::DumpCoincidence(contours); 770 } 771 772 void DumpCoin(const SkTArray<class SkOpContour, true>* contours) { 773 SkPathOpsDebug::DumpCoincidence(*contours); 774 } 775 776 void DumpCoin(const SkTArray<class SkOpContour* , true>* contours) { 777 SkPathOpsDebug::DumpCoincidence(*contours); 778 } 779 780 void DumpSpans(const SkTArray<class SkOpContour, true>& contours) { 781 SkPathOpsDebug::DumpContourSpans(contours); 782 } 783 784 void DumpSpans(const SkTArray<class SkOpContour* , true>& contours) { 785 SkPathOpsDebug::DumpContourSpans(contours); 786 } 787 788 void DumpSpans(const SkTArray<class SkOpContour, true>* contours) { 789 SkPathOpsDebug::DumpContourSpans(*contours); 790 } 791 792 void DumpSpans(const SkTArray<class SkOpContour* , true>* contours) { 793 SkPathOpsDebug::DumpContourSpans(*contours); 794 } 795 796 void DumpSpan(const SkTArray<class SkOpContour, true>& contours, int segmentID) { 797 SkPathOpsDebug::DumpContourSpan(contours, segmentID); 798 } 799 800 void DumpSpan(const SkTArray<class SkOpContour* , true>& contours, int segmentID) { 801 SkPathOpsDebug::DumpContourSpan(contours, segmentID); 802 } 803 804 void DumpSpan(const SkTArray<class SkOpContour, true>* contours, int segmentID) { 805 SkPathOpsDebug::DumpContourSpan(*contours, segmentID); 806 } 807 808 void DumpSpan(const SkTArray<class SkOpContour* , true>* contours, int segmentID) { 809 SkPathOpsDebug::DumpContourSpan(*contours, segmentID); 810 } 811 812 void DumpPts(const SkTArray<class SkOpContour, true>& contours) { 813 SkPathOpsDebug::DumpContourPts(contours); 814 } 815 816 void DumpPts(const SkTArray<class SkOpContour* , true>& contours) { 817 SkPathOpsDebug::DumpContourPts(contours); 818 } 819 820 void DumpPts(const SkTArray<class SkOpContour, true>* contours) { 821 SkPathOpsDebug::DumpContourPts(*contours); 822 } 823 824 void DumpPts(const SkTArray<class SkOpContour* , true>* contours) { 825 SkPathOpsDebug::DumpContourPts(*contours); 826 } 827 828 void DumpPt(const SkTArray<class SkOpContour, true>& contours, int segmentID) { 829 SkPathOpsDebug::DumpContourPt(contours, segmentID); 830 } 831 832 void DumpPt(const SkTArray<class SkOpContour* , true>& contours, int segmentID) { 833 SkPathOpsDebug::DumpContourPt(contours, segmentID); 834 } 835 836 void DumpPt(const SkTArray<class SkOpContour, true>* contours, int segmentID) { 837 SkPathOpsDebug::DumpContourPt(*contours, segmentID); 838 } 839 840 void DumpPt(const SkTArray<class SkOpContour* , true>* contours, int segmentID) { 841 SkPathOpsDebug::DumpContourPt(*contours, segmentID); 842 } 843 844 static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) { 845 SkDebugf("<div id=\"quad%d\">\n", testNo); 846 quad1.dumpComma(","); 847 quad2.dump(); 848 SkDebugf("</div>\n\n"); 849 } 850 851 static void dumpTestTrailer() { 852 SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n"); 853 SkDebugf(" var testDivs = [\n"); 854 } 855 856 static void dumpTestList(int testNo, double min) { 857 SkDebugf(" quad%d,", testNo); 858 if (min > 0) { 859 SkDebugf(" // %1.9g", min); 860 } 861 SkDebugf("\n"); 862 } 863 864 void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) { 865 SkDebugf("\n"); 866 dumpTestCase(quad1, quad2, testNo); 867 dumpTestTrailer(); 868 dumpTestList(testNo, 0); 869 SkDebugf("\n"); 870 } 871 872 void DumpT(const SkDQuad& quad, double t) { 873 SkDLine line = {{quad.ptAtT(t), quad[0]}}; 874 line.dump(); 875 } 876