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 16 inline void DebugDumpDouble(double x) { 17 if (x == floor(x)) { 18 SkDebugf("%.0f", x); 19 } else { 20 SkDebugf("%1.19g", x); 21 } 22 } 23 24 inline void DebugDumpFloat(float x) { 25 if (x == floorf(x)) { 26 SkDebugf("%.0f", x); 27 } else { 28 SkDebugf("%1.9gf", x); 29 } 30 } 31 32 inline 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 38 bool SkPathOpsDebug::ValidWind(int wind) { 39 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF; 40 } 41 42 void SkPathOpsDebug::WindingPrintf(int wind) { 43 if (wind == SK_MinS32) { 44 SkDebugf("?"); 45 } else { 46 SkDebugf("%d", wind); 47 } 48 } 49 #endif 50 51 static void DumpID(int id) { 52 SkDebugf("} "); 53 if (id >= 0) { 54 SkDebugf("id=%d", id); 55 } 56 SkDebugf("\n"); 57 } 58 59 void SkDConic::dump() const { 60 dumpInner(); 61 SkDebugf("},\n"); 62 } 63 64 void SkDConic::dumpID(int id) const { 65 dumpInner(); 66 DumpID(id); 67 } 68 69 void SkDConic::dumpInner() const { 70 SkDebugf("{"); 71 fPts.dumpInner(); 72 SkDebugf("}}, %1.9gf", fWeight); 73 } 74 75 void SkDCubic::dump() const { 76 this->dumpInner(); 77 SkDebugf("}},\n"); 78 } 79 80 void SkDCubic::dumpID(int id) const { 81 this->dumpInner(); 82 SkDebugf("}"); 83 DumpID(id); 84 } 85 86 static inline bool double_is_NaN(double x) { return x != x; } 87 88 void 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 107 void SkDCurve::dump() const { 108 dumpID(-1); 109 } 110 111 void 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 134 void SkDLine::dump() const { 135 this->dumpInner(); 136 SkDebugf("}},\n"); 137 } 138 139 void SkDLine::dumpID(int id) const { 140 this->dumpInner(); 141 SkDebugf("}"); 142 DumpID(id); 143 } 144 145 void SkDLine::dumpInner() const { 146 SkDebugf("{{"); 147 fPts[0].dump(); 148 SkDebugf(", "); 149 fPts[1].dump(); 150 } 151 152 void SkDPoint::dump() const { 153 SkDebugf("{"); 154 DebugDumpDouble(fX); 155 SkDebugf(", "); 156 DebugDumpDouble(fY); 157 SkDebugf("}"); 158 } 159 160 void SkDPoint::Dump(const SkPoint& pt) { 161 SkDebugf("{"); 162 DebugDumpFloat(pt.fX); 163 SkDebugf(", "); 164 DebugDumpFloat(pt.fY); 165 SkDebugf("}"); 166 } 167 168 void SkDPoint::DumpHex(const SkPoint& pt) { 169 SkDebugf("{"); 170 DebugDumpHexFloat(pt.fX); 171 SkDebugf(", "); 172 DebugDumpHexFloat(pt.fY); 173 SkDebugf("}"); 174 } 175 176 void SkDQuad::dump() const { 177 dumpInner(); 178 SkDebugf("}},\n"); 179 } 180 181 void SkDQuad::dumpID(int id) const { 182 dumpInner(); 183 SkDebugf("}"); 184 DumpID(id); 185 } 186 187 void 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 197 void 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 211 const SkOpAngle* SkPathOpsDebug::DebugAngleAngle(const SkOpAngle* angle, int id) { 212 return angle->debugAngle(id); 213 } 214 215 SkOpContour* SkPathOpsDebug::DebugAngleContour(SkOpAngle* angle, int id) { 216 return angle->debugContour(id); 217 } 218 219 const SkOpPtT* SkPathOpsDebug::DebugAnglePtT(const SkOpAngle* angle, int id) { 220 return angle->debugPtT(id); 221 } 222 223 const SkOpSegment* SkPathOpsDebug::DebugAngleSegment(const SkOpAngle* angle, int id) { 224 return angle->debugSegment(id); 225 } 226 227 const SkOpSpanBase* SkPathOpsDebug::DebugAngleSpan(const SkOpAngle* angle, int id) { 228 return angle->debugSpan(id); 229 } 230 231 const SkOpAngle* SkPathOpsDebug::DebugContourAngle(SkOpContour* contour, int id) { 232 return contour->debugAngle(id); 233 } 234 235 SkOpContour* SkPathOpsDebug::DebugContourContour(SkOpContour* contour, int id) { 236 return contour->debugContour(id); 237 } 238 239 const SkOpPtT* SkPathOpsDebug::DebugContourPtT(SkOpContour* contour, int id) { 240 return contour->debugPtT(id); 241 } 242 243 const SkOpSegment* SkPathOpsDebug::DebugContourSegment(SkOpContour* contour, int id) { 244 return contour->debugSegment(id); 245 } 246 247 const SkOpSpanBase* SkPathOpsDebug::DebugContourSpan(SkOpContour* contour, int id) { 248 return contour->debugSpan(id); 249 } 250 251 const SkOpAngle* SkPathOpsDebug::DebugCoincidenceAngle(SkOpCoincidence* coin, int id) { 252 return coin->debugAngle(id); 253 } 254 255 SkOpContour* SkPathOpsDebug::DebugCoincidenceContour(SkOpCoincidence* coin, int id) { 256 return coin->debugContour(id); 257 } 258 259 const SkOpPtT* SkPathOpsDebug::DebugCoincidencePtT(SkOpCoincidence* coin, int id) { 260 return coin->debugPtT(id); 261 } 262 263 const SkOpSegment* SkPathOpsDebug::DebugCoincidenceSegment(SkOpCoincidence* coin, int id) { 264 return coin->debugSegment(id); 265 } 266 267 const SkOpSpanBase* SkPathOpsDebug::DebugCoincidenceSpan(SkOpCoincidence* coin, int id) { 268 return coin->debugSpan(id); 269 } 270 271 const SkOpAngle* SkPathOpsDebug::DebugPtTAngle(const SkOpPtT* ptT, int id) { 272 return ptT->debugAngle(id); 273 } 274 275 SkOpContour* SkPathOpsDebug::DebugPtTContour(SkOpPtT* ptT, int id) { 276 return ptT->debugContour(id); 277 } 278 279 const SkOpPtT* SkPathOpsDebug::DebugPtTPtT(const SkOpPtT* ptT, int id) { 280 return ptT->debugPtT(id); 281 } 282 283 const SkOpSegment* SkPathOpsDebug::DebugPtTSegment(const SkOpPtT* ptT, int id) { 284 return ptT->debugSegment(id); 285 } 286 287 const SkOpSpanBase* SkPathOpsDebug::DebugPtTSpan(const SkOpPtT* ptT, int id) { 288 return ptT->debugSpan(id); 289 } 290 291 const SkOpAngle* SkPathOpsDebug::DebugSegmentAngle(const SkOpSegment* span, int id) { 292 return span->debugAngle(id); 293 } 294 295 SkOpContour* SkPathOpsDebug::DebugSegmentContour(SkOpSegment* span, int id) { 296 return span->debugContour(id); 297 } 298 299 const SkOpPtT* SkPathOpsDebug::DebugSegmentPtT(const SkOpSegment* span, int id) { 300 return span->debugPtT(id); 301 } 302 303 const SkOpSegment* SkPathOpsDebug::DebugSegmentSegment(const SkOpSegment* span, int id) { 304 return span->debugSegment(id); 305 } 306 307 const SkOpSpanBase* SkPathOpsDebug::DebugSegmentSpan(const SkOpSegment* span, int id) { 308 return span->debugSpan(id); 309 } 310 311 const SkOpAngle* SkPathOpsDebug::DebugSpanAngle(const SkOpSpanBase* span, int id) { 312 return span->debugAngle(id); 313 } 314 315 SkOpContour* SkPathOpsDebug::DebugSpanContour(SkOpSpanBase* span, int id) { 316 return span->debugContour(id); 317 } 318 319 const SkOpPtT* SkPathOpsDebug::DebugSpanPtT(const SkOpSpanBase* span, int id) { 320 return span->debugPtT(id); 321 } 322 323 const SkOpSegment* SkPathOpsDebug::DebugSpanSegment(const SkOpSpanBase* span, int id) { 324 return span->debugSegment(id); 325 } 326 327 const SkOpSpanBase* SkPathOpsDebug::DebugSpanSpan(const SkOpSpanBase* span, int id) { 328 return span->debugSpan(id); 329 } 330 331 #if DEBUG_COIN 332 void SkPathOpsDebug::DumpCoinDict() { 333 gCoinSumChangedDict.dump("unused coin algorithm", false); 334 gCoinSumVisitedDict.dump("visited coin function", true); 335 } 336 337 void 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 351 void SkOpContour::dumpContours() const { 352 SkOpContour* contour = this->globalState()->contourHead(); 353 do { 354 contour->dump(); 355 } while ((contour = contour->next())); 356 } 357 358 void SkOpContour::dumpContoursAll() const { 359 SkOpContour* contour = this->globalState()->contourHead(); 360 do { 361 contour->dumpAll(); 362 } while ((contour = contour->next())); 363 } 364 365 void SkOpContour::dumpContoursAngles() const { 366 SkOpContour* contour = this->globalState()->contourHead(); 367 do { 368 contour->dumpAngles(); 369 } while ((contour = contour->next())); 370 } 371 372 void SkOpContour::dumpContoursPts() const { 373 SkOpContour* contour = this->globalState()->contourHead(); 374 do { 375 contour->dumpPts(); 376 } while ((contour = contour->next())); 377 } 378 379 void SkOpContour::dumpContoursPt(int segmentID) const { 380 SkOpContour* contour = this->globalState()->contourHead(); 381 do { 382 contour->dumpPt(segmentID); 383 } while ((contour = contour->next())); 384 } 385 386 void SkOpContour::dumpContoursSegment(int segmentID) const { 387 SkOpContour* contour = this->globalState()->contourHead(); 388 do { 389 contour->dumpSegment(segmentID); 390 } while ((contour = contour->next())); 391 } 392 393 void SkOpContour::dumpContoursSpan(int spanID) const { 394 SkOpContour* contour = this->globalState()->contourHead(); 395 do { 396 contour->dumpSpan(spanID); 397 } while ((contour = contour->next())); 398 } 399 400 void SkOpContour::dumpContoursSpans() const { 401 SkOpContour* contour = this->globalState()->contourHead(); 402 do { 403 contour->dumpSpans(); 404 } while ((contour = contour->next())); 405 } 406 407 template <typename TCurve, typename OppCurve> 408 const SkTSpan<TCurve, OppCurve>* DebugSpan(const SkTSect<TCurve, OppCurve>* sect, int id) { 409 return sect->debugSpan(id); 410 } 411 412 void DontCallDebugSpan(int id); 413 void 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 437 template <typename TCurve, typename OppCurve> 438 const SkTSpan<TCurve, OppCurve>* DebugT(const SkTSect<TCurve, OppCurve>* sect, double t) { 439 return sect->debugT(t); 440 } 441 442 void DontCallDebugT(double t); 443 void 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 467 template <typename TCurve, typename OppCurve> 468 void Dump(const SkTSect<TCurve, OppCurve>* sect) { 469 sect->dump(); 470 } 471 472 void DontCallDumpTSect(); 473 void 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 497 template <typename TCurve, typename OppCurve> 498 void DumpBoth(SkTSect<TCurve, OppCurve>* sect1, SkTSect<OppCurve, TCurve>* sect2) { 499 sect1->dumpBoth(sect2); 500 } 501 502 void DontCallDumpBoth(); 503 void 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 527 template <typename TCurve, typename OppCurve> 528 void DumpBounded(SkTSect<TCurve, OppCurve>* sect1, int id) { 529 sect1->dumpBounded(id); 530 } 531 532 void DontCallDumpBounded(); 533 void 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 557 template <typename TCurve, typename OppCurve> 558 void DumpBounds(SkTSect<TCurve, OppCurve>* sect1) { 559 sect1->dumpBounds(); 560 } 561 562 void DontCallDumpBounds(); 563 void 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 587 template <typename TCurve, typename OppCurve> 588 void DumpCoin(SkTSect<TCurve, OppCurve>* sect1) { 589 sect1->dumpCoin(); 590 } 591 592 void DontCallDumpCoin(); 593 void 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 617 template <typename TCurve, typename OppCurve> 618 void DumpCoinCurves(SkTSect<TCurve, OppCurve>* sect1) { 619 sect1->dumpCoinCurves(); 620 } 621 622 void DontCallDumpCoinCurves(); 623 void 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 647 template <typename TCurve, typename OppCurve> 648 void DumpCurves(const SkTSect<TCurve, OppCurve>* sect) { 649 sect->dumpCurves(); 650 } 651 652 void DontCallDumpCurves(); 653 void 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 677 template <typename TCurve, typename OppCurve> 678 void Dump(const SkTSpan<TCurve, OppCurve>* span) { 679 span->dump(); 680 } 681 682 void DontCallDumpTSpan(); 683 void 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 704 template <typename TCurve, typename OppCurve> 705 void DumpAll(const SkTSpan<TCurve, OppCurve>* span) { 706 span->dumpAll(); 707 } 708 709 void DontCallDumpSpanAll(); 710 void 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 731 template <typename TCurve, typename OppCurve> 732 void DumpBounded(const SkTSpan<TCurve, OppCurve>* span) { 733 span->dumpBounded(0); 734 } 735 736 void DontCallDumpSpanBounded(); 737 void 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 758 template <typename TCurve, typename OppCurve> 759 void DumpCoin(const SkTSpan<TCurve, OppCurve>* span) { 760 span->dumpCoin(); 761 } 762 763 void DontCallDumpSpanCoin(); 764 void 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 785 static 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 793 static void dumpTestTrailer() { 794 SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n"); 795 SkDebugf(" var testDivs = [\n"); 796 } 797 798 static 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 806 void 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 814 void DumpT(const SkDQuad& quad, double t) { 815 SkDLine line = {{quad.ptAtT(t), quad[0]}}; 816 line.dump(); 817 } 818 819 const SkOpAngle* SkOpAngle::debugAngle(int id) const { 820 return this->segment()->debugAngle(id); 821 } 822 823 const SkOpCoincidence* SkOpAngle::debugCoincidence() const { 824 return this->segment()->debugCoincidence(); 825 } 826 827 SkOpContour* SkOpAngle::debugContour(int id) const { 828 return this->segment()->debugContour(id); 829 } 830 831 const SkOpPtT* SkOpAngle::debugPtT(int id) const { 832 return this->segment()->debugPtT(id); 833 } 834 835 const SkOpSegment* SkOpAngle::debugSegment(int id) const { 836 return this->segment()->debugSegment(id); 837 } 838 839 int SkOpAngle::debugSign() const { 840 SkASSERT(fStart->t() != fEnd->t()); 841 return fStart->t() < fEnd->t() ? -1 : 1; 842 } 843 844 const SkOpSpanBase* SkOpAngle::debugSpan(int id) const { 845 return this->segment()->debugSpan(id); 846 } 847 848 void SkOpAngle::dump() const { 849 dumpOne(true); 850 SkDebugf("\n"); 851 } 852 853 void 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 892 void 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 913 void 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 922 void 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 932 void 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 945 bool 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 957 const SkOpAngle* SkOpPtT::debugAngle(int id) const { 958 return this->span()->debugAngle(id); 959 } 960 961 SkOpContour* SkOpPtT::debugContour(int id) const { 962 return this->span()->debugContour(id); 963 } 964 965 const SkOpCoincidence* SkOpPtT::debugCoincidence() const { 966 return this->span()->debugCoincidence(); 967 } 968 969 const SkOpPtT* SkOpPtT::debugPtT(int id) const { 970 return this->span()->debugPtT(id); 971 } 972 973 const SkOpSegment* SkOpPtT::debugSegment(int id) const { 974 return this->span()->debugSegment(id); 975 } 976 977 const SkOpSpanBase* SkOpPtT::debugSpan(int id) const { 978 return this->span()->debugSpan(id); 979 } 980 981 void 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 988 void 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 1007 void 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 1013 const SkOpAngle* SkOpSpanBase::debugAngle(int id) const { 1014 return this->segment()->debugAngle(id); 1015 } 1016 1017 const SkOpCoincidence* SkOpSpanBase::debugCoincidence() const { 1018 return this->segment()->debugCoincidence(); 1019 } 1020 1021 SkOpContour* SkOpSpanBase::debugContour(int id) const { 1022 return this->segment()->debugContour(id); 1023 } 1024 1025 const SkOpPtT* SkOpSpanBase::debugPtT(int id) const { 1026 return this->segment()->debugPtT(id); 1027 } 1028 1029 const SkOpSegment* SkOpSpanBase::debugSegment(int id) const { 1030 return this->segment()->debugSegment(id); 1031 } 1032 1033 const SkOpSpanBase* SkOpSpanBase::debugSpan(int id) const { 1034 return this->segment()->debugSpan(id); 1035 } 1036 1037 void SkOpSpanBase::dump() const { 1038 this->dumpHead(); 1039 this->fPtT.dump(); 1040 } 1041 1042 void 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 1049 void SkOpSpanBase::dumpAll() const { 1050 this->dumpHead(); 1051 this->fPtT.dumpAll(); 1052 } 1053 1054 void 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 1079 void 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 1090 void 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 1104 bool 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 1123 const SkOpAngle* SkOpSegment::debugAngle(int id) const { 1124 return this->contour()->debugAngle(id); 1125 } 1126 1127 1128 const SkOpCoincidence* SkOpSegment::debugCoincidence() const { 1129 return this->contour()->debugCoincidence(); 1130 } 1131 1132 SkOpContour* SkOpSegment::debugContour(int id) const { 1133 return this->contour()->debugContour(id); 1134 } 1135 1136 const SkOpPtT* SkOpSegment::debugPtT(int id) const { 1137 return this->contour()->debugPtT(id); 1138 } 1139 1140 const SkOpSegment* SkOpSegment::debugSegment(int id) const { 1141 return this->contour()->debugSegment(id); 1142 } 1143 1144 const SkOpSpanBase* SkOpSegment::debugSpan(int id) const { 1145 return this->contour()->debugSpan(id); 1146 } 1147 1148 void 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 1162 void 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 1173 void 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 1190 void SkOpSegment::dumpCoin() const { 1191 const SkOpSpan* span = &fHead; 1192 do { 1193 span->dumpCoin(); 1194 } while ((span = span->next()->upCastable())); 1195 } 1196 1197 void 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 1215 void SkOpSegment::dumpPts(const char* prefix) const { 1216 dumpPtsInner(prefix); 1217 SkDebugf("\n"); 1218 } 1219 1220 void 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 1247 void 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 1274 void 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 1288 void 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 1303 void 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 1312 void 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 1321 void 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 1330 void 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 1341 void SkOpContour::dumpSegment(int index) const { 1342 debugSegment(index)->dump(); 1343 } 1344 1345 void SkOpContour::dumpSegments(const char* prefix, SkPathOp op) const { 1346 bool firstOp = false; 1347 const SkOpContour* c = this; 1348 do { 1349 if (!firstOp && c->operand() && op >= 0) { 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 1359 void SkOpContour::dumpSpan(int index) const { 1360 debugSpan(index)->dump(); 1361 } 1362 1363 void 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 1372 void 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 1383 const 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 1410 SkOpContour* 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 1420 const 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 1443 const 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 1457 const 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 1480 int gDumpTSectNum; 1481 #endif 1482