1/* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "PathOpsTSectDebug.h" 9#include "SkOpCoincidence.h" 10#include "SkOpContour.h" 11#include "SkIntersectionHelper.h" 12#include "SkMutex.h" 13#include "SkOpSegment.h" 14#include "SkString.h" 15 16inline void DebugDumpDouble(double x) { 17 if (x == floor(x)) { 18 SkDebugf("%.0f", x); 19 } else { 20 SkDebugf("%1.19g", x); 21 } 22} 23 24inline void DebugDumpFloat(float x) { 25 if (x == floorf(x)) { 26 SkDebugf("%.0f", x); 27 } else { 28 SkDebugf("%1.9gf", x); 29 } 30} 31 32inline void DebugDumpHexFloat(float x) { 33 SkDebugf("SkBits2Float(0x%08x)", SkFloat2Bits(x)); 34} 35 36// if not defined by PathOpsDebug.cpp ... 37#if !defined SK_DEBUG && FORCE_RELEASE 38bool SkPathOpsDebug::ValidWind(int wind) { 39 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF; 40} 41 42void SkPathOpsDebug::WindingPrintf(int wind) { 43 if (wind == SK_MinS32) { 44 SkDebugf("?"); 45 } else { 46 SkDebugf("%d", wind); 47 } 48} 49#endif 50 51static void DumpID(int id) { 52 SkDebugf("} "); 53 if (id >= 0) { 54 SkDebugf("id=%d", id); 55 } 56 SkDebugf("\n"); 57} 58 59void SkDConic::dump() const { 60 dumpInner(); 61 SkDebugf("},\n"); 62} 63 64void SkDConic::dumpID(int id) const { 65 dumpInner(); 66 DumpID(id); 67} 68 69void SkDConic::dumpInner() const { 70 SkDebugf("{"); 71 fPts.dumpInner(); 72 SkDebugf("}}, %1.9gf", fWeight); 73} 74 75void SkDCubic::dump() const { 76 this->dumpInner(); 77 SkDebugf("}},\n"); 78} 79 80void SkDCubic::dumpID(int id) const { 81 this->dumpInner(); 82 SkDebugf("}"); 83 DumpID(id); 84} 85 86static inline bool double_is_NaN(double x) { return x != x; } 87 88void SkDCubic::dumpInner() const { 89 SkDebugf("{{"); 90 int index = 0; 91 do { 92 if (index != 0) { 93 if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) { 94 return; 95 } 96 SkDebugf(", "); 97 } 98 fPts[index].dump(); 99 } while (++index < 3); 100 if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) { 101 return; 102 } 103 SkDebugf(", "); 104 fPts[index].dump(); 105} 106 107void SkDCurve::dump() const { 108 dumpID(-1); 109} 110 111void SkDCurve::dumpID(int id) const { 112#ifndef SK_RELEASE 113 switch(fVerb) { 114 case SkPath::kLine_Verb: 115 fLine.dumpID(id); 116 break; 117 case SkPath::kQuad_Verb: 118 fQuad.dumpID(id); 119 break; 120 case SkPath::kConic_Verb: 121 fConic.dumpID(id); 122 break; 123 case SkPath::kCubic_Verb: 124 fCubic.dumpID(id); 125 break; 126 default: 127 SkASSERT(0); 128 } 129#else 130 fCubic.dumpID(id); 131#endif 132} 133 134void SkDLine::dump() const { 135 this->dumpInner(); 136 SkDebugf("}},\n"); 137} 138 139void SkDLine::dumpID(int id) const { 140 this->dumpInner(); 141 SkDebugf("}"); 142 DumpID(id); 143} 144 145void SkDLine::dumpInner() const { 146 SkDebugf("{{"); 147 fPts[0].dump(); 148 SkDebugf(", "); 149 fPts[1].dump(); 150} 151 152void SkDPoint::dump() const { 153 SkDebugf("{"); 154 DebugDumpDouble(fX); 155 SkDebugf(", "); 156 DebugDumpDouble(fY); 157 SkDebugf("}"); 158} 159 160void SkDPoint::Dump(const SkPoint& pt) { 161 SkDebugf("{"); 162 DebugDumpFloat(pt.fX); 163 SkDebugf(", "); 164 DebugDumpFloat(pt.fY); 165 SkDebugf("}"); 166} 167 168void SkDPoint::DumpHex(const SkPoint& pt) { 169 SkDebugf("{"); 170 DebugDumpHexFloat(pt.fX); 171 SkDebugf(", "); 172 DebugDumpHexFloat(pt.fY); 173 SkDebugf("}"); 174} 175 176void SkDQuad::dump() const { 177 dumpInner(); 178 SkDebugf("}},\n"); 179} 180 181void SkDQuad::dumpID(int id) const { 182 dumpInner(); 183 SkDebugf("}"); 184 DumpID(id); 185} 186 187void SkDQuad::dumpInner() const { 188 SkDebugf("{{"); 189 int index = 0; 190 do { 191 fPts[index].dump(); 192 SkDebugf(", "); 193 } while (++index < 2); 194 fPts[index].dump(); 195} 196 197void SkIntersections::dump() const { 198 SkDebugf("used=%d of %d", fUsed, fMax); 199 for (int index = 0; index < fUsed; ++index) { 200 SkDebugf(" t=(%s%1.9g,%s%1.9g) pt=(%1.9g,%1.9g)", 201 fIsCoincident[0] & (1 << index) ? "*" : "", fT[0][index], 202 fIsCoincident[1] & (1 << index) ? "*" : "", fT[1][index], 203 fPt[index].fX, fPt[index].fY); 204 if (index < 2 && fNearlySame[index]) { 205 SkDebugf(" pt2=(%1.9g,%1.9g)",fPt2[index].fX, fPt2[index].fY); 206 } 207 } 208 SkDebugf("\n"); 209} 210 211const SkOpAngle* SkPathOpsDebug::DebugAngleAngle(const SkOpAngle* angle, int id) { 212 return angle->debugAngle(id); 213} 214 215SkOpContour* SkPathOpsDebug::DebugAngleContour(SkOpAngle* angle, int id) { 216 return angle->debugContour(id); 217} 218 219const SkOpPtT* SkPathOpsDebug::DebugAnglePtT(const SkOpAngle* angle, int id) { 220 return angle->debugPtT(id); 221} 222 223const SkOpSegment* SkPathOpsDebug::DebugAngleSegment(const SkOpAngle* angle, int id) { 224 return angle->debugSegment(id); 225} 226 227const SkOpSpanBase* SkPathOpsDebug::DebugAngleSpan(const SkOpAngle* angle, int id) { 228 return angle->debugSpan(id); 229} 230 231const SkOpAngle* SkPathOpsDebug::DebugContourAngle(SkOpContour* contour, int id) { 232 return contour->debugAngle(id); 233} 234 235SkOpContour* SkPathOpsDebug::DebugContourContour(SkOpContour* contour, int id) { 236 return contour->debugContour(id); 237} 238 239const SkOpPtT* SkPathOpsDebug::DebugContourPtT(SkOpContour* contour, int id) { 240 return contour->debugPtT(id); 241} 242 243const SkOpSegment* SkPathOpsDebug::DebugContourSegment(SkOpContour* contour, int id) { 244 return contour->debugSegment(id); 245} 246 247const SkOpSpanBase* SkPathOpsDebug::DebugContourSpan(SkOpContour* contour, int id) { 248 return contour->debugSpan(id); 249} 250 251const SkOpAngle* SkPathOpsDebug::DebugCoincidenceAngle(SkOpCoincidence* coin, int id) { 252 return coin->debugAngle(id); 253} 254 255SkOpContour* SkPathOpsDebug::DebugCoincidenceContour(SkOpCoincidence* coin, int id) { 256 return coin->debugContour(id); 257} 258 259const SkOpPtT* SkPathOpsDebug::DebugCoincidencePtT(SkOpCoincidence* coin, int id) { 260 return coin->debugPtT(id); 261} 262 263const SkOpSegment* SkPathOpsDebug::DebugCoincidenceSegment(SkOpCoincidence* coin, int id) { 264 return coin->debugSegment(id); 265} 266 267const SkOpSpanBase* SkPathOpsDebug::DebugCoincidenceSpan(SkOpCoincidence* coin, int id) { 268 return coin->debugSpan(id); 269} 270 271const SkOpAngle* SkPathOpsDebug::DebugPtTAngle(const SkOpPtT* ptT, int id) { 272 return ptT->debugAngle(id); 273} 274 275SkOpContour* SkPathOpsDebug::DebugPtTContour(SkOpPtT* ptT, int id) { 276 return ptT->debugContour(id); 277} 278 279const SkOpPtT* SkPathOpsDebug::DebugPtTPtT(const SkOpPtT* ptT, int id) { 280 return ptT->debugPtT(id); 281} 282 283const SkOpSegment* SkPathOpsDebug::DebugPtTSegment(const SkOpPtT* ptT, int id) { 284 return ptT->debugSegment(id); 285} 286 287const SkOpSpanBase* SkPathOpsDebug::DebugPtTSpan(const SkOpPtT* ptT, int id) { 288 return ptT->debugSpan(id); 289} 290 291const SkOpAngle* SkPathOpsDebug::DebugSegmentAngle(const SkOpSegment* span, int id) { 292 return span->debugAngle(id); 293} 294 295SkOpContour* SkPathOpsDebug::DebugSegmentContour(SkOpSegment* span, int id) { 296 return span->debugContour(id); 297} 298 299const SkOpPtT* SkPathOpsDebug::DebugSegmentPtT(const SkOpSegment* span, int id) { 300 return span->debugPtT(id); 301} 302 303const SkOpSegment* SkPathOpsDebug::DebugSegmentSegment(const SkOpSegment* span, int id) { 304 return span->debugSegment(id); 305} 306 307const SkOpSpanBase* SkPathOpsDebug::DebugSegmentSpan(const SkOpSegment* span, int id) { 308 return span->debugSpan(id); 309} 310 311const SkOpAngle* SkPathOpsDebug::DebugSpanAngle(const SkOpSpanBase* span, int id) { 312 return span->debugAngle(id); 313} 314 315SkOpContour* SkPathOpsDebug::DebugSpanContour(SkOpSpanBase* span, int id) { 316 return span->debugContour(id); 317} 318 319const SkOpPtT* SkPathOpsDebug::DebugSpanPtT(const SkOpSpanBase* span, int id) { 320 return span->debugPtT(id); 321} 322 323const SkOpSegment* SkPathOpsDebug::DebugSpanSegment(const SkOpSpanBase* span, int id) { 324 return span->debugSegment(id); 325} 326 327const SkOpSpanBase* SkPathOpsDebug::DebugSpanSpan(const SkOpSpanBase* span, int id) { 328 return span->debugSpan(id); 329} 330 331#if DEBUG_COIN 332void SkPathOpsDebug::DumpCoinDict() { 333 gCoinSumChangedDict.dump("unused coin algorithm", false); 334 gCoinSumVisitedDict.dump("visited coin function", true); 335} 336 337void SkPathOpsDebug::CoinDict::dump(const char* str, bool visitCheck) const { 338 int count = fDict.count(); 339 for (int index = 0; index < count; ++index) { 340 const auto& entry = fDict[index]; 341 if (visitCheck || entry.fGlitchType == kUninitialized_Glitch) { 342 SkDebugf("%s %s : line %d iteration %d", str, entry.fFunctionName, 343 entry.fLineNumber, entry.fIteration); 344 DumpGlitchType(entry.fGlitchType); 345 SkDebugf("\n"); 346 } 347 } 348} 349#endif 350 351void SkOpContour::dumpContours() const { 352 SkOpContour* contour = this->globalState()->contourHead(); 353 do { 354 contour->dump(); 355 } while ((contour = contour->next())); 356} 357 358void SkOpContour::dumpContoursAll() const { 359 SkOpContour* contour = this->globalState()->contourHead(); 360 do { 361 contour->dumpAll(); 362 } while ((contour = contour->next())); 363} 364 365void SkOpContour::dumpContoursAngles() const { 366 SkOpContour* contour = this->globalState()->contourHead(); 367 do { 368 contour->dumpAngles(); 369 } while ((contour = contour->next())); 370} 371 372void SkOpContour::dumpContoursPts() const { 373 SkOpContour* contour = this->globalState()->contourHead(); 374 do { 375 contour->dumpPts(); 376 } while ((contour = contour->next())); 377} 378 379void SkOpContour::dumpContoursPt(int segmentID) const { 380 SkOpContour* contour = this->globalState()->contourHead(); 381 do { 382 contour->dumpPt(segmentID); 383 } while ((contour = contour->next())); 384} 385 386void SkOpContour::dumpContoursSegment(int segmentID) const { 387 SkOpContour* contour = this->globalState()->contourHead(); 388 do { 389 contour->dumpSegment(segmentID); 390 } while ((contour = contour->next())); 391} 392 393void SkOpContour::dumpContoursSpan(int spanID) const { 394 SkOpContour* contour = this->globalState()->contourHead(); 395 do { 396 contour->dumpSpan(spanID); 397 } while ((contour = contour->next())); 398} 399 400void SkOpContour::dumpContoursSpans() const { 401 SkOpContour* contour = this->globalState()->contourHead(); 402 do { 403 contour->dumpSpans(); 404 } while ((contour = contour->next())); 405} 406 407template <typename TCurve, typename OppCurve> 408const SkTSpan<TCurve, OppCurve>* DebugSpan(const SkTSect<TCurve, OppCurve>* sect, int id) { 409 return sect->debugSpan(id); 410} 411 412void DontCallDebugSpan(int id); 413void DontCallDebugSpan(int id) { // exists to instantiate the templates 414 SkDQuad quad; 415 SkDConic conic; 416 SkDCubic cubic; 417 SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 418 SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 419 SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 420 SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 421 SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 422 SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 423 SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 424 SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 425 SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 426 DebugSpan(&q1q2, id); 427 DebugSpan(&q1k2, id); 428 DebugSpan(&q1c2, id); 429 DebugSpan(&k1q2, id); 430 DebugSpan(&k1k2, id); 431 DebugSpan(&k1c2, id); 432 DebugSpan(&c1q2, id); 433 DebugSpan(&c1k2, id); 434 DebugSpan(&c1c2, id); 435} 436 437template <typename TCurve, typename OppCurve> 438const SkTSpan<TCurve, OppCurve>* DebugT(const SkTSect<TCurve, OppCurve>* sect, double t) { 439 return sect->debugT(t); 440} 441 442void DontCallDebugT(double t); 443void DontCallDebugT(double t) { // exists to instantiate the templates 444 SkDQuad quad; 445 SkDConic conic; 446 SkDCubic cubic; 447 SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 448 SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 449 SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 450 SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 451 SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 452 SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 453 SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 454 SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 455 SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 456 DebugT(&q1q2, t); 457 DebugT(&q1k2, t); 458 DebugT(&q1c2, t); 459 DebugT(&k1q2, t); 460 DebugT(&k1k2, t); 461 DebugT(&k1c2, t); 462 DebugT(&c1q2, t); 463 DebugT(&c1k2, t); 464 DebugT(&c1c2, t); 465} 466 467template <typename TCurve, typename OppCurve> 468void Dump(const SkTSect<TCurve, OppCurve>* sect) { 469 sect->dump(); 470} 471 472void DontCallDumpTSect(); 473void DontCallDumpTSect() { // exists to instantiate the templates 474 SkDQuad quad; 475 SkDConic conic; 476 SkDCubic cubic; 477 SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 478 SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 479 SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 480 SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 481 SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 482 SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 483 SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 484 SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 485 SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 486 Dump(&q1q2); 487 Dump(&q1k2); 488 Dump(&q1c2); 489 Dump(&k1q2); 490 Dump(&k1k2); 491 Dump(&k1c2); 492 Dump(&c1q2); 493 Dump(&c1k2); 494 Dump(&c1c2); 495} 496 497template <typename TCurve, typename OppCurve> 498void DumpBoth(SkTSect<TCurve, OppCurve>* sect1, SkTSect<OppCurve, TCurve>* sect2) { 499 sect1->dumpBoth(sect2); 500} 501 502void DontCallDumpBoth(); 503void DontCallDumpBoth() { // exists to instantiate the templates 504 SkDQuad quad; 505 SkDConic conic; 506 SkDCubic cubic; 507 SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 508 SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 509 SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 510 SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 511 SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 512 SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 513 SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 514 SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 515 SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 516 DumpBoth(&q1q2, &q1q2); 517 DumpBoth(&q1k2, &k1q2); 518 DumpBoth(&q1c2, &c1q2); 519 DumpBoth(&k1q2, &q1k2); 520 DumpBoth(&k1k2, &k1k2); 521 DumpBoth(&k1c2, &c1k2); 522 DumpBoth(&c1q2, &q1c2); 523 DumpBoth(&c1k2, &k1c2); 524 DumpBoth(&c1c2, &c1c2); 525} 526 527template <typename TCurve, typename OppCurve> 528void DumpBounded(SkTSect<TCurve, OppCurve>* sect1, int id) { 529 sect1->dumpBounded(id); 530} 531 532void DontCallDumpBounded(); 533void DontCallDumpBounded() { 534 SkDQuad quad; 535 SkDConic conic; 536 SkDCubic cubic; 537 SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 538 SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 539 SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 540 SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 541 SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 542 SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 543 SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 544 SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 545 SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 546 DumpBounded(&q1q2, 0); 547 DumpBounded(&q1k2, 0); 548 DumpBounded(&q1c2, 0); 549 DumpBounded(&k1q2, 0); 550 DumpBounded(&k1k2, 0); 551 DumpBounded(&k1c2, 0); 552 DumpBounded(&c1q2, 0); 553 DumpBounded(&c1k2, 0); 554 DumpBounded(&c1c2, 0); 555} 556 557template <typename TCurve, typename OppCurve> 558void DumpBounds(SkTSect<TCurve, OppCurve>* sect1) { 559 sect1->dumpBounds(); 560} 561 562void DontCallDumpBounds(); 563void DontCallDumpBounds() { 564 SkDQuad quad; 565 SkDConic conic; 566 SkDCubic cubic; 567 SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 568 SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 569 SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 570 SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 571 SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 572 SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 573 SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 574 SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 575 SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 576 DumpBounds(&q1q2); 577 DumpBounds(&q1k2); 578 DumpBounds(&q1c2); 579 DumpBounds(&k1q2); 580 DumpBounds(&k1k2); 581 DumpBounds(&k1c2); 582 DumpBounds(&c1q2); 583 DumpBounds(&c1k2); 584 DumpBounds(&c1c2); 585} 586 587template <typename TCurve, typename OppCurve> 588void DumpCoin(SkTSect<TCurve, OppCurve>* sect1) { 589 sect1->dumpCoin(); 590} 591 592void DontCallDumpCoin(); 593void DontCallDumpCoin() { // exists to instantiate the templates 594 SkDQuad quad; 595 SkDConic conic; 596 SkDCubic cubic; 597 SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 598 SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 599 SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 600 SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 601 SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 602 SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 603 SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 604 SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 605 SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 606 DumpCoin(&q1q2); 607 DumpCoin(&q1k2); 608 DumpCoin(&q1c2); 609 DumpCoin(&k1q2); 610 DumpCoin(&k1k2); 611 DumpCoin(&k1c2); 612 DumpCoin(&c1q2); 613 DumpCoin(&c1k2); 614 DumpCoin(&c1c2); 615} 616 617template <typename TCurve, typename OppCurve> 618void DumpCoinCurves(SkTSect<TCurve, OppCurve>* sect1) { 619 sect1->dumpCoinCurves(); 620} 621 622void DontCallDumpCoinCurves(); 623void DontCallDumpCoinCurves() { // exists to instantiate the templates 624 SkDQuad quad; 625 SkDConic conic; 626 SkDCubic cubic; 627 SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 628 SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 629 SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 630 SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 631 SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 632 SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 633 SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 634 SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 635 SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 636 DumpCoinCurves(&q1q2); 637 DumpCoinCurves(&q1k2); 638 DumpCoinCurves(&q1c2); 639 DumpCoinCurves(&k1q2); 640 DumpCoinCurves(&k1k2); 641 DumpCoinCurves(&k1c2); 642 DumpCoinCurves(&c1q2); 643 DumpCoinCurves(&c1k2); 644 DumpCoinCurves(&c1c2); 645} 646 647template <typename TCurve, typename OppCurve> 648void DumpCurves(const SkTSect<TCurve, OppCurve>* sect) { 649 sect->dumpCurves(); 650} 651 652void DontCallDumpCurves(); 653void DontCallDumpCurves() { // exists to instantiate the templates 654 SkDQuad quad; 655 SkDConic conic; 656 SkDCubic cubic; 657 SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 658 SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 659 SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 660 SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 661 SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 662 SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 663 SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 664 SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 665 SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); 666 DumpCurves(&q1q2); 667 DumpCurves(&q1k2); 668 DumpCurves(&q1c2); 669 DumpCurves(&k1q2); 670 DumpCurves(&k1k2); 671 DumpCurves(&k1c2); 672 DumpCurves(&c1q2); 673 DumpCurves(&c1k2); 674 DumpCurves(&c1c2); 675} 676 677template <typename TCurve, typename OppCurve> 678void Dump(const SkTSpan<TCurve, OppCurve>* span) { 679 span->dump(); 680} 681 682void DontCallDumpTSpan(); 683void DontCallDumpTSpan() { // exists to instantiate the templates 684 SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit(); 685 SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit(); 686 SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit(); 687 SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit(); 688 SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit(); 689 SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit(); 690 SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit(); 691 SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit(); 692 SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit(); 693 Dump(&q1q2); 694 Dump(&q1k2); 695 Dump(&q1c2); 696 Dump(&k1q2); 697 Dump(&k1k2); 698 Dump(&k1c2); 699 Dump(&c1q2); 700 Dump(&c1k2); 701 Dump(&c1c2); 702} 703 704template <typename TCurve, typename OppCurve> 705void DumpAll(const SkTSpan<TCurve, OppCurve>* span) { 706 span->dumpAll(); 707} 708 709void DontCallDumpSpanAll(); 710void DontCallDumpSpanAll() { // exists to instantiate the templates 711 SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit(); 712 SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit(); 713 SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit(); 714 SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit(); 715 SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit(); 716 SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit(); 717 SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit(); 718 SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit(); 719 SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit(); 720 DumpAll(&q1q2); 721 DumpAll(&q1k2); 722 DumpAll(&q1c2); 723 DumpAll(&k1q2); 724 DumpAll(&k1k2); 725 DumpAll(&k1c2); 726 DumpAll(&c1q2); 727 DumpAll(&c1k2); 728 DumpAll(&c1c2); 729} 730 731template <typename TCurve, typename OppCurve> 732void DumpBounded(const SkTSpan<TCurve, OppCurve>* span) { 733 span->dumpBounded(0); 734} 735 736void DontCallDumpSpanBounded(); 737void DontCallDumpSpanBounded() { // exists to instantiate the templates 738 SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit(); 739 SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit(); 740 SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit(); 741 SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit(); 742 SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit(); 743 SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit(); 744 SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit(); 745 SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit(); 746 SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit(); 747 DumpBounded(&q1q2); 748 DumpBounded(&q1k2); 749 DumpBounded(&q1c2); 750 DumpBounded(&k1q2); 751 DumpBounded(&k1k2); 752 DumpBounded(&k1c2); 753 DumpBounded(&c1q2); 754 DumpBounded(&c1k2); 755 DumpBounded(&c1c2); 756} 757 758template <typename TCurve, typename OppCurve> 759void DumpCoin(const SkTSpan<TCurve, OppCurve>* span) { 760 span->dumpCoin(); 761} 762 763void DontCallDumpSpanCoin(); 764void DontCallDumpSpanCoin() { // exists to instantiate the templates 765 SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit(); 766 SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit(); 767 SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit(); 768 SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit(); 769 SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit(); 770 SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit(); 771 SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit(); 772 SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit(); 773 SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit(); 774 DumpCoin(&q1q2); 775 DumpCoin(&q1k2); 776 DumpCoin(&q1c2); 777 DumpCoin(&k1q2); 778 DumpCoin(&k1k2); 779 DumpCoin(&k1c2); 780 DumpCoin(&c1q2); 781 DumpCoin(&c1k2); 782 DumpCoin(&c1c2); 783} 784 785static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) { 786 SkDebugf("\n<div id=\"quad%d\">\n", testNo); 787 quad1.dumpInner(); 788 SkDebugf("}}, "); 789 quad2.dump(); 790 SkDebugf("</div>\n\n"); 791} 792 793static void dumpTestTrailer() { 794 SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n"); 795 SkDebugf(" var testDivs = [\n"); 796} 797 798static void dumpTestList(int testNo, double min) { 799 SkDebugf(" quad%d,", testNo); 800 if (min > 0) { 801 SkDebugf(" // %1.9g", min); 802 } 803 SkDebugf("\n"); 804} 805 806void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) { 807 SkDebugf("\n"); 808 dumpTestCase(quad1, quad2, testNo); 809 dumpTestTrailer(); 810 dumpTestList(testNo, 0); 811 SkDebugf("\n"); 812} 813 814void DumpT(const SkDQuad& quad, double t) { 815 SkDLine line = {{quad.ptAtT(t), quad[0]}}; 816 line.dump(); 817} 818 819const SkOpAngle* SkOpAngle::debugAngle(int id) const { 820 return this->segment()->debugAngle(id); 821} 822 823const SkOpCoincidence* SkOpAngle::debugCoincidence() const { 824 return this->segment()->debugCoincidence(); 825} 826 827SkOpContour* SkOpAngle::debugContour(int id) const { 828 return this->segment()->debugContour(id); 829} 830 831const SkOpPtT* SkOpAngle::debugPtT(int id) const { 832 return this->segment()->debugPtT(id); 833} 834 835const SkOpSegment* SkOpAngle::debugSegment(int id) const { 836 return this->segment()->debugSegment(id); 837} 838 839int SkOpAngle::debugSign() const { 840 SkASSERT(fStart->t() != fEnd->t()); 841 return fStart->t() < fEnd->t() ? -1 : 1; 842} 843 844const SkOpSpanBase* SkOpAngle::debugSpan(int id) const { 845 return this->segment()->debugSpan(id); 846} 847 848void SkOpAngle::dump() const { 849 dumpOne(true); 850 SkDebugf("\n"); 851} 852 853void SkOpAngle::dumpOne(bool functionHeader) const { 854// fSegment->debugValidate(); 855 const SkOpSegment* segment = this->segment(); 856 const SkOpSpan& mSpan = *fStart->starter(fEnd); 857 if (functionHeader) { 858 SkDebugf("%s ", __FUNCTION__); 859 } 860 SkDebugf("[%d", segment->debugID()); 861 SkDebugf("/%d", debugID()); 862 SkDebugf("] next="); 863 if (fNext) { 864 SkDebugf("%d", fNext->fStart->segment()->debugID()); 865 SkDebugf("/%d", fNext->debugID()); 866 } else { 867 SkDebugf("?"); 868 } 869 SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd); 870 SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fStart->t(), fStart->debugID(), 871 fEnd->t(), fEnd->debugID()); 872 SkDebugf(" sgn=%d windVal=%d", this->debugSign(), mSpan.windValue()); 873 874 SkDebugf(" windSum="); 875 SkPathOpsDebug::WindingPrintf(mSpan.windSum()); 876 if (mSpan.oppValue() != 0 || mSpan.oppSum() != SK_MinS32) { 877 SkDebugf(" oppVal=%d", mSpan.oppValue()); 878 SkDebugf(" oppSum="); 879 SkPathOpsDebug::WindingPrintf(mSpan.oppSum()); 880 } 881 if (mSpan.done()) { 882 SkDebugf(" done"); 883 } 884 if (unorderable()) { 885 SkDebugf(" unorderable"); 886 } 887 if (segment->operand()) { 888 SkDebugf(" operand"); 889 } 890} 891 892void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const { 893 const SkOpAngle* first = this; 894 const SkOpAngle* next = this; 895 const char* indent = ""; 896 do { 897 SkDebugf("%s", indent); 898 next->dumpOne(false); 899 if (segment == next->fStart->segment()) { 900 if (this == fNext) { 901 SkDebugf(" << from"); 902 } 903 if (to == fNext) { 904 SkDebugf(" << to"); 905 } 906 } 907 SkDebugf("\n"); 908 indent = " "; 909 next = next->fNext; 910 } while (next && next != first); 911} 912 913void SkOpAngle::dumpCurves() const { 914 const SkOpAngle* first = this; 915 const SkOpAngle* next = this; 916 do { 917 next->fPart.fCurve.dumpID(next->segment()->debugID()); 918 next = next->fNext; 919 } while (next && next != first); 920} 921 922void SkOpAngle::dumpLoop() const { 923 const SkOpAngle* first = this; 924 const SkOpAngle* next = this; 925 do { 926 next->dumpOne(false); 927 SkDebugf("\n"); 928 next = next->fNext; 929 } while (next && next != first); 930} 931 932void SkOpAngle::dumpTest() const { 933 const SkOpAngle* first = this; 934 const SkOpAngle* next = this; 935 do { 936 SkDebugf("{ "); 937 SkOpSegment* segment = next->segment(); 938 segment->dumpPts(); 939 SkDebugf(", %d, %1.9g, %1.9g, {} },\n", SkPathOpsVerbToPoints(segment->verb()) + 1, 940 next->start()->t(), next->end()->t()); 941 next = next->fNext; 942 } while (next && next != first); 943} 944 945bool SkOpPtT::debugMatchID(int id) const { 946 int limit = this->debugLoopLimit(false); 947 int loop = 0; 948 const SkOpPtT* ptT = this; 949 do { 950 if (ptT->debugID() == id) { 951 return true; 952 } 953 } while ((!limit || ++loop <= limit) && (ptT = ptT->next()) && ptT != this); 954 return false; 955} 956 957const SkOpAngle* SkOpPtT::debugAngle(int id) const { 958 return this->span()->debugAngle(id); 959} 960 961SkOpContour* SkOpPtT::debugContour(int id) const { 962 return this->span()->debugContour(id); 963} 964 965const SkOpCoincidence* SkOpPtT::debugCoincidence() const { 966 return this->span()->debugCoincidence(); 967} 968 969const SkOpPtT* SkOpPtT::debugPtT(int id) const { 970 return this->span()->debugPtT(id); 971} 972 973const SkOpSegment* SkOpPtT::debugSegment(int id) const { 974 return this->span()->debugSegment(id); 975} 976 977const SkOpSpanBase* SkOpPtT::debugSpan(int id) const { 978 return this->span()->debugSpan(id); 979} 980 981void SkOpPtT::dump() const { 982 SkDebugf("seg=%d span=%d ptT=%d", 983 this->segment()->debugID(), this->span()->debugID(), this->debugID()); 984 this->dumpBase(); 985 SkDebugf("\n"); 986} 987 988void SkOpPtT::dumpAll() const { 989 contour()->indentDump(); 990 const SkOpPtT* next = this; 991 int limit = debugLoopLimit(true); 992 int loop = 0; 993 do { 994 SkDebugf("%.*s", contour()->debugIndent(), " "); 995 SkDebugf("seg=%d span=%d ptT=%d", 996 next->segment()->debugID(), next->span()->debugID(), next->debugID()); 997 next->dumpBase(); 998 SkDebugf("\n"); 999 if (limit && ++loop >= limit) { 1000 SkDebugf("*** abort loop ***\n"); 1001 break; 1002 } 1003 } while ((next = next->fNext) && next != this); 1004 contour()->outdentDump(); 1005} 1006 1007void SkOpPtT::dumpBase() const { 1008 SkDebugf(" t=%1.9g pt=(%1.9g,%1.9g)%s%s%s", this->fT, this->fPt.fX, this->fPt.fY, 1009 this->fCoincident ? " coin" : "", 1010 this->fDuplicatePt ? " dup" : "", this->fDeleted ? " deleted" : ""); 1011} 1012 1013const SkOpAngle* SkOpSpanBase::debugAngle(int id) const { 1014 return this->segment()->debugAngle(id); 1015} 1016 1017const SkOpCoincidence* SkOpSpanBase::debugCoincidence() const { 1018 return this->segment()->debugCoincidence(); 1019} 1020 1021SkOpContour* SkOpSpanBase::debugContour(int id) const { 1022 return this->segment()->debugContour(id); 1023} 1024 1025const SkOpPtT* SkOpSpanBase::debugPtT(int id) const { 1026 return this->segment()->debugPtT(id); 1027} 1028 1029const SkOpSegment* SkOpSpanBase::debugSegment(int id) const { 1030 return this->segment()->debugSegment(id); 1031} 1032 1033const SkOpSpanBase* SkOpSpanBase::debugSpan(int id) const { 1034 return this->segment()->debugSpan(id); 1035} 1036 1037void SkOpSpanBase::dump() const { 1038 this->dumpHead(); 1039 this->fPtT.dump(); 1040} 1041 1042void SkOpSpanBase::dumpHead() const { 1043 SkDebugf("%.*s", contour()->debugIndent(), " "); 1044 SkDebugf("seg=%d span=%d", this->segment()->debugID(), this->debugID()); 1045 this->dumpBase(); 1046 SkDebugf("\n"); 1047} 1048 1049void SkOpSpanBase::dumpAll() const { 1050 this->dumpHead(); 1051 this->fPtT.dumpAll(); 1052} 1053 1054void SkOpSpanBase::dumpBase() const { 1055 if (this->fAligned) { 1056 SkDebugf(" aligned"); 1057 } 1058 if (this->fChased) { 1059 SkDebugf(" chased"); 1060 } 1061#ifdef SK_DEBUG 1062 if (this->fDebugDeleted) { 1063 SkDebugf(" deleted"); 1064 } 1065#endif 1066 if (!this->final()) { 1067 this->upCast()->dumpSpan(); 1068 } 1069 const SkOpSpanBase* coin = this->coinEnd(); 1070 if (this != coin) { 1071 SkDebugf(" coinEnd seg/span=%d/%d", coin->segment()->debugID(), coin->debugID()); 1072 } else if (this->final() || !this->upCast()->isCoincident()) { 1073 const SkOpPtT* oPt = this->ptT()->next(); 1074 SkDebugf(" seg/span=%d/%d", oPt->segment()->debugID(), oPt->span()->debugID()); 1075 } 1076 SkDebugf(" adds=%d", fSpanAdds); 1077} 1078 1079void SkOpSpanBase::dumpCoin() const { 1080 const SkOpSpan* span = this->upCastable(); 1081 if (!span) { 1082 return; 1083 } 1084 if (!span->isCoincident()) { 1085 return; 1086 } 1087 span->dumpCoin(); 1088} 1089 1090void SkOpSpan::dumpCoin() const { 1091 const SkOpSpan* coincident = fCoincident; 1092 bool ok = debugCoinLoopCheck(); 1093 this->dump(); 1094 int loop = 0; 1095 do { 1096 coincident->dump(); 1097 if (!ok && ++loop > 10) { 1098 SkDebugf("*** abort loop ***\n"); 1099 break; 1100 } 1101 } while ((coincident = coincident->fCoincident) != this); 1102} 1103 1104bool SkOpSpan::dumpSpan() const { 1105 SkOpSpan* coin = fCoincident; 1106 if (this != coin) { 1107 SkDebugf(" coinStart seg/span=%d/%d", coin->segment()->debugID(), coin->debugID()); 1108 } 1109 SkDebugf(" windVal=%d", this->windValue()); 1110 SkDebugf(" windSum="); 1111 SkPathOpsDebug::WindingPrintf(this->windSum()); 1112 if (this->oppValue() != 0 || this->oppSum() != SK_MinS32) { 1113 SkDebugf(" oppVal=%d", this->oppValue()); 1114 SkDebugf(" oppSum="); 1115 SkPathOpsDebug::WindingPrintf(this->oppSum()); 1116 } 1117 if (this->done()) { 1118 SkDebugf(" done"); 1119 } 1120 return this != coin; 1121} 1122 1123const SkOpAngle* SkOpSegment::debugAngle(int id) const { 1124 return this->contour()->debugAngle(id); 1125} 1126 1127 1128const SkOpCoincidence* SkOpSegment::debugCoincidence() const { 1129 return this->contour()->debugCoincidence(); 1130} 1131 1132SkOpContour* SkOpSegment::debugContour(int id) const { 1133 return this->contour()->debugContour(id); 1134} 1135 1136const SkOpPtT* SkOpSegment::debugPtT(int id) const { 1137 return this->contour()->debugPtT(id); 1138} 1139 1140const SkOpSegment* SkOpSegment::debugSegment(int id) const { 1141 return this->contour()->debugSegment(id); 1142} 1143 1144const SkOpSpanBase* SkOpSegment::debugSpan(int id) const { 1145 return this->contour()->debugSpan(id); 1146} 1147 1148void SkOpSegment::dump() const { 1149 SkDebugf("%.*s", contour()->debugIndent(), " "); 1150 this->dumpPts(); 1151 const SkOpSpanBase* span = &fHead; 1152 contour()->indentDump(); 1153 do { 1154 SkDebugf("%.*s span=%d ", contour()->debugIndent(), " ", span->debugID()); 1155 span->ptT()->dumpBase(); 1156 span->dumpBase(); 1157 SkDebugf("\n"); 1158 } while (!span->final() && (span = span->upCast()->next())); 1159 contour()->outdentDump(); 1160} 1161 1162void SkOpSegment::dumpAll() const { 1163 SkDebugf("%.*s", contour()->debugIndent(), " "); 1164 this->dumpPts(); 1165 const SkOpSpanBase* span = &fHead; 1166 contour()->indentDump(); 1167 do { 1168 span->dumpAll(); 1169 } while (!span->final() && (span = span->upCast()->next())); 1170 contour()->outdentDump(); 1171} 1172 1173void SkOpSegment::dumpAngles() const { 1174 SkDebugf("seg=%d\n", debugID()); 1175 const SkOpSpanBase* span = &fHead; 1176 do { 1177 const SkOpAngle* fAngle = span->fromAngle(); 1178 const SkOpAngle* tAngle = span->final() ? nullptr : span->upCast()->toAngle(); 1179 if (fAngle) { 1180 SkDebugf(" span=%d from=%d ", span->debugID(), fAngle->debugID()); 1181 fAngle->dumpTo(this, tAngle); 1182 } 1183 if (tAngle) { 1184 SkDebugf(" span=%d to=%d ", span->debugID(), tAngle->debugID()); 1185 tAngle->dumpTo(this, fAngle); 1186 } 1187 } while (!span->final() && (span = span->upCast()->next())); 1188} 1189 1190void SkOpSegment::dumpCoin() const { 1191 const SkOpSpan* span = &fHead; 1192 do { 1193 span->dumpCoin(); 1194 } while ((span = span->next()->upCastable())); 1195} 1196 1197void SkOpSegment::dumpPtsInner(const char* prefix) const { 1198 int last = SkPathOpsVerbToPoints(fVerb); 1199 SkDebugf("%s=%d {{", prefix, this->debugID()); 1200 if (fVerb == SkPath::kConic_Verb) { 1201 SkDebugf("{"); 1202 } 1203 int index = 0; 1204 do { 1205 SkDPoint::Dump(fPts[index]); 1206 SkDebugf(", "); 1207 } while (++index < last); 1208 SkDPoint::Dump(fPts[index]); 1209 SkDebugf("}}"); 1210 if (fVerb == SkPath::kConic_Verb) { 1211 SkDebugf(", %1.9gf}", fWeight); 1212 } 1213} 1214 1215void SkOpSegment::dumpPts(const char* prefix) const { 1216 dumpPtsInner(prefix); 1217 SkDebugf("\n"); 1218} 1219 1220void SkCoincidentSpans::dump() const { 1221 SkDebugf("- seg=%d span=%d ptT=%d ", fCoinPtTStart->segment()->debugID(), 1222 fCoinPtTStart->span()->debugID(), fCoinPtTStart->debugID()); 1223 fCoinPtTStart->dumpBase(); 1224 SkDebugf(" span=%d ptT=%d ", fCoinPtTEnd->span()->debugID(), fCoinPtTEnd->debugID()); 1225 fCoinPtTEnd->dumpBase(); 1226 if (fCoinPtTStart->segment()->operand()) { 1227 SkDebugf(" operand"); 1228 } 1229 if (fCoinPtTStart->segment()->isXor()) { 1230 SkDebugf(" xor"); 1231 } 1232 SkDebugf("\n"); 1233 SkDebugf("+ seg=%d span=%d ptT=%d ", fOppPtTStart->segment()->debugID(), 1234 fOppPtTStart->span()->debugID(), fOppPtTStart->debugID()); 1235 fOppPtTStart->dumpBase(); 1236 SkDebugf(" span=%d ptT=%d ", fOppPtTEnd->span()->debugID(), fOppPtTEnd->debugID()); 1237 fOppPtTEnd->dumpBase(); 1238 if (fOppPtTStart->segment()->operand()) { 1239 SkDebugf(" operand"); 1240 } 1241 if (fOppPtTStart->segment()->isXor()) { 1242 SkDebugf(" xor"); 1243 } 1244 SkDebugf("\n"); 1245} 1246 1247void SkOpCoincidence::dump() const { 1248 SkCoincidentSpans* span = fHead; 1249 while (span) { 1250 span->dump(); 1251 span = span->next(); 1252 } 1253 if (!fTop || fHead == fTop) { 1254 return; 1255 } 1256 SkDebugf("top:\n"); 1257 span = fTop; 1258 int count = 0; 1259 while (span) { 1260 span->dump(); 1261 span = span->next(); 1262 SkCoincidentSpans* check = fTop; 1263 ++count; 1264 for (int index = 0; index < count; ++index) { 1265 if (span == check) { 1266 SkDebugf("(loops to #%d)\n", index); 1267 return; 1268 } 1269 check = check->next(); 1270 } 1271 } 1272} 1273 1274void SkOpContour::dump() const { 1275 SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor); 1276 if (!fCount) { 1277 return; 1278 } 1279 const SkOpSegment* segment = &fHead; 1280 SkDEBUGCODE(fDebugIndent = 0); 1281 this->indentDump(); 1282 do { 1283 segment->dump(); 1284 } while ((segment = segment->next())); 1285 this->outdentDump(); 1286} 1287 1288void SkOpContour::dumpAll() const { 1289 SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor); 1290 if (!fCount) { 1291 return; 1292 } 1293 const SkOpSegment* segment = &fHead; 1294 SkDEBUGCODE(fDebugIndent = 0); 1295 this->indentDump(); 1296 do { 1297 segment->dumpAll(); 1298 } while ((segment = segment->next())); 1299 this->outdentDump(); 1300} 1301 1302 1303void SkOpContour::dumpAngles() const { 1304 SkDebugf("contour=%d\n", this->debugID()); 1305 const SkOpSegment* segment = &fHead; 1306 do { 1307 SkDebugf(" seg=%d ", segment->debugID()); 1308 segment->dumpAngles(); 1309 } while ((segment = segment->next())); 1310} 1311 1312void SkOpContour::dumpPt(int index) const { 1313 const SkOpSegment* segment = &fHead; 1314 do { 1315 if (segment->debugID() == index) { 1316 segment->dumpPts(); 1317 } 1318 } while ((segment = segment->next())); 1319} 1320 1321void SkOpContour::dumpPts(const char* prefix) const { 1322 SkDebugf("contour=%d\n", this->debugID()); 1323 const SkOpSegment* segment = &fHead; 1324 do { 1325 SkDebugf(" %s=%d ", prefix, segment->debugID()); 1326 segment->dumpPts(prefix); 1327 } while ((segment = segment->next())); 1328} 1329 1330void SkOpContour::dumpPtsX(const char* prefix) const { 1331 if (!this->fCount) { 1332 SkDebugf("<empty>\n"); 1333 return; 1334 } 1335 const SkOpSegment* segment = &fHead; 1336 do { 1337 segment->dumpPts(prefix); 1338 } while ((segment = segment->next())); 1339} 1340 1341void SkOpContour::dumpSegment(int index) const { 1342 debugSegment(index)->dump(); 1343} 1344 1345void SkOpContour::dumpSegments(const char* prefix, SkPathOp op) const { 1346 bool firstOp = false; 1347 const SkOpContour* c = this; 1348 do { 1349 if (!firstOp && c->operand()) { 1350#if DEBUG_ACTIVE_OP 1351 SkDebugf("op %s\n", SkPathOpsDebug::kPathOpStr[op]); 1352#endif 1353 firstOp = true; 1354 } 1355 c->dumpPtsX(prefix); 1356 } while ((c = c->next())); 1357} 1358 1359void SkOpContour::dumpSpan(int index) const { 1360 debugSpan(index)->dump(); 1361} 1362 1363void SkOpContour::dumpSpans() const { 1364 SkDebugf("contour=%d\n", this->debugID()); 1365 const SkOpSegment* segment = &fHead; 1366 do { 1367 SkDebugf(" seg=%d ", segment->debugID()); 1368 segment->dump(); 1369 } while ((segment = segment->next())); 1370} 1371 1372void SkOpCurve::dump() const { 1373 int count = SkPathOpsVerbToPoints(SkDEBUGRELEASE(fVerb, SkPath::kCubic_Verb)); 1374 SkDebugf("{{"); 1375 int index; 1376 for (index = 0; index <= count - 1; ++index) { 1377 SkDebugf("{%1.9gf,%1.9gf}, ", fPts[index].fX, fPts[index].fY); 1378 } 1379 SkDebugf("{%1.9gf,%1.9gf}}}\n", fPts[index].fX, fPts[index].fY); 1380} 1381 1382#ifdef SK_DEBUG 1383const SkOpAngle* SkOpGlobalState::debugAngle(int id) const { 1384 const SkOpContour* contour = fContourHead; 1385 do { 1386 const SkOpSegment* segment = contour->first(); 1387 while (segment) { 1388 const SkOpSpan* span = segment->head(); 1389 do { 1390 SkOpAngle* angle = span->fromAngle(); 1391 if (angle && angle->debugID() == id) { 1392 return angle; 1393 } 1394 angle = span->toAngle(); 1395 if (angle && angle->debugID() == id) { 1396 return angle; 1397 } 1398 } while ((span = span->next()->upCastable())); 1399 const SkOpSpanBase* tail = segment->tail(); 1400 SkOpAngle* angle = tail->fromAngle(); 1401 if (angle && angle->debugID() == id) { 1402 return angle; 1403 } 1404 segment = segment->next(); 1405 } 1406 } while ((contour = contour->next())); 1407 return nullptr; 1408} 1409 1410SkOpContour* SkOpGlobalState::debugContour(int id) const { 1411 SkOpContour* contour = fContourHead; 1412 do { 1413 if (contour->debugID() == id) { 1414 return contour; 1415 } 1416 } while ((contour = contour->next())); 1417 return nullptr; 1418} 1419 1420const SkOpPtT* SkOpGlobalState::debugPtT(int id) const { 1421 const SkOpContour* contour = fContourHead; 1422 do { 1423 const SkOpSegment* segment = contour->first(); 1424 while (segment) { 1425 const SkOpSpan* span = segment->head(); 1426 do { 1427 const SkOpPtT* ptT = span->ptT(); 1428 if (ptT->debugMatchID(id)) { 1429 return ptT; 1430 } 1431 } while ((span = span->next()->upCastable())); 1432 const SkOpSpanBase* tail = segment->tail(); 1433 const SkOpPtT* ptT = tail->ptT(); 1434 if (ptT->debugMatchID(id)) { 1435 return ptT; 1436 } 1437 segment = segment->next(); 1438 } 1439 } while ((contour = contour->next())); 1440 return nullptr; 1441} 1442 1443const SkOpSegment* SkOpGlobalState::debugSegment(int id) const { 1444 const SkOpContour* contour = fContourHead; 1445 do { 1446 const SkOpSegment* segment = contour->first(); 1447 while (segment) { 1448 if (segment->debugID() == id) { 1449 return segment; 1450 } 1451 segment = segment->next(); 1452 } 1453 } while ((contour = contour->next())); 1454 return nullptr; 1455} 1456 1457const SkOpSpanBase* SkOpGlobalState::debugSpan(int id) const { 1458 const SkOpContour* contour = fContourHead; 1459 do { 1460 const SkOpSegment* segment = contour->first(); 1461 while (segment) { 1462 const SkOpSpan* span = segment->head(); 1463 do { 1464 if (span->debugID() == id) { 1465 return span; 1466 } 1467 } while ((span = span->next()->upCastable())); 1468 const SkOpSpanBase* tail = segment->tail(); 1469 if (tail->debugID() == id) { 1470 return tail; 1471 } 1472 segment = segment->next(); 1473 } 1474 } while ((contour = contour->next())); 1475 return nullptr; 1476} 1477#endif 1478 1479#if DEBUG_T_SECT_DUMP > 1 1480int gDumpTSectNum; 1481#endif 1482