OLD | NEW |
(Empty) | |
| 1 #include "SkOpContour.h" |
| 2 #include "SkIntersectionHelper.h" |
| 3 #include "SkOpSegment.h" |
| 4 |
| 5 inline void DebugDumpDouble(double x) { |
| 6 if (x == floor(x)) { |
| 7 SkDebugf("%.0f", x); |
| 8 } else { |
| 9 SkDebugf("%1.19g", x); |
| 10 } |
| 11 } |
| 12 |
| 13 inline void DebugDumpFloat(float x) { |
| 14 if (x == floorf(x)) { |
| 15 SkDebugf("%.0f", x); |
| 16 } else { |
| 17 SkDebugf("%1.9gf", x); |
| 18 } |
| 19 } |
| 20 |
| 21 // if not defined by PathOpsDebug.cpp ... |
| 22 #if !defined SK_DEBUG && FORCE_RELEASE |
| 23 bool SkPathOpsDebug::ValidWind(int wind) { |
| 24 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF; |
| 25 } |
| 26 |
| 27 void SkPathOpsDebug::WindingPrintf(int wind) { |
| 28 if (wind == SK_MinS32) { |
| 29 SkDebugf("?"); |
| 30 } else { |
| 31 SkDebugf("%d", wind); |
| 32 } |
| 33 } |
| 34 #endif |
| 35 |
| 36 void SkOpAngle::dump() const { |
| 37 #if DEBUG_SORT |
| 38 debugOne(false); |
| 39 #endif |
| 40 SkDebugf("\n"); |
| 41 } |
| 42 |
| 43 void SkOpAngle::dumpFromTo(const SkOpSegment* segment, int from, int to) const { |
| 44 #if DEBUG_SORT && DEBUG_ANGLE |
| 45 const SkOpAngle* first = this; |
| 46 const SkOpAngle* next = this; |
| 47 const char* indent = ""; |
| 48 do { |
| 49 SkDebugf("%s", indent); |
| 50 next->debugOne(false); |
| 51 if (segment == next->fSegment) { |
| 52 if (fNext && from == fNext->debugID()) { |
| 53 SkDebugf(" << from"); |
| 54 } |
| 55 if (fNext && to == fNext->debugID()) { |
| 56 SkDebugf(" << to"); |
| 57 } |
| 58 } |
| 59 SkDebugf("\n"); |
| 60 indent = " "; |
| 61 next = next->fNext; |
| 62 } while (next && next != first); |
| 63 #endif |
| 64 } |
| 65 |
| 66 void SkOpAngle::dumpLoop() const { |
| 67 const SkOpAngle* first = this; |
| 68 const SkOpAngle* next = this; |
| 69 do { |
| 70 next->dump(); |
| 71 next = next->fNext; |
| 72 } while (next && next != first); |
| 73 } |
| 74 |
| 75 void SkOpAngle::dumpPartials() const { |
| 76 const SkOpAngle* first = this; |
| 77 const SkOpAngle* next = this; |
| 78 do { |
| 79 next->fCurvePart.dumpNumber(); |
| 80 next = next->fNext; |
| 81 } while (next && next != first); |
| 82 } |
| 83 |
| 84 void SkOpContour::dump() const { |
| 85 int segmentCount = fSegments.count(); |
| 86 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); |
| 87 for (int test = 0; test < segmentCount; ++test) { |
| 88 SkDebugf(" [%d] ((SkOpSegment*) 0x%p) [%d]\n", test, &fSegments[test], |
| 89 fSegments[test].debugID()); |
| 90 } |
| 91 } |
| 92 |
| 93 void SkOpContour::dumpAngles() const { |
| 94 int segmentCount = fSegments.count(); |
| 95 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); |
| 96 for (int test = 0; test < segmentCount; ++test) { |
| 97 SkDebugf(" [%d] ", test); |
| 98 fSegments[test].dumpAngles(); |
| 99 } |
| 100 } |
| 101 |
| 102 void SkOpContour::dumpPts() const { |
| 103 int segmentCount = fSegments.count(); |
| 104 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); |
| 105 for (int test = 0; test < segmentCount; ++test) { |
| 106 SkDebugf(" [%d] ", test); |
| 107 fSegments[test].dumpPts(); |
| 108 } |
| 109 } |
| 110 |
| 111 void SkOpContour::dumpSpans() const { |
| 112 int segmentCount = fSegments.count(); |
| 113 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); |
| 114 for (int test = 0; test < segmentCount; ++test) { |
| 115 SkDebugf(" [%d] ", test); |
| 116 fSegments[test].dumpSpans(); |
| 117 } |
| 118 } |
| 119 |
| 120 void SkDCubic::dump() const { |
| 121 SkDebugf("{{"); |
| 122 int index = 0; |
| 123 do { |
| 124 fPts[index].dump(); |
| 125 SkDebugf(", "); |
| 126 } while (++index < 3); |
| 127 fPts[index].dump(); |
| 128 SkDebugf("}}\n"); |
| 129 } |
| 130 |
| 131 void SkDCubic::dumpNumber() const { |
| 132 SkDebugf("{{"); |
| 133 int index = 0; |
| 134 bool dumpedOne = false; |
| 135 do { |
| 136 if (!(fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].
fY)) { |
| 137 continue; |
| 138 } |
| 139 if (dumpedOne) { |
| 140 SkDebugf(", "); |
| 141 } |
| 142 fPts[index].dump(); |
| 143 dumpedOne = true; |
| 144 } while (++index < 3); |
| 145 if (fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY) { |
| 146 if (dumpedOne) { |
| 147 SkDebugf(", "); |
| 148 } |
| 149 fPts[index].dump(); |
| 150 } |
| 151 SkDebugf("}}\n"); |
| 152 } |
| 153 |
| 154 void SkDLine::dump() const { |
| 155 SkDebugf("{{"); |
| 156 fPts[0].dump(); |
| 157 SkDebugf(", "); |
| 158 fPts[1].dump(); |
| 159 SkDebugf("}}\n"); |
| 160 } |
| 161 |
| 162 void SkDPoint::dump() const { |
| 163 SkDebugf("{"); |
| 164 DebugDumpDouble(fX); |
| 165 SkDebugf(", "); |
| 166 DebugDumpDouble(fY); |
| 167 SkDebugf("}"); |
| 168 } |
| 169 |
| 170 void SkDPoint::Dump(const SkPoint& pt) { |
| 171 SkDebugf("{"); |
| 172 DebugDumpFloat(pt.fX); |
| 173 SkDebugf(", "); |
| 174 DebugDumpFloat(pt.fY); |
| 175 SkDebugf("}"); |
| 176 } |
| 177 |
| 178 |
| 179 void SkDQuad::dumpComma(const char* comma) const { |
| 180 SkDebugf("{{"); |
| 181 int index = 0; |
| 182 do { |
| 183 fPts[index].dump(); |
| 184 SkDebugf(", "); |
| 185 } while (++index < 2); |
| 186 fPts[index].dump(); |
| 187 SkDebugf("}}%s\n", comma ? comma : ""); |
| 188 } |
| 189 |
| 190 void SkDQuad::dump() const { |
| 191 dumpComma(""); |
| 192 } |
| 193 |
| 194 void SkIntersectionHelper::dump() const { |
| 195 SkDPoint::Dump(pts()[0]); |
| 196 SkDPoint::Dump(pts()[1]); |
| 197 if (verb() >= SkPath::kQuad_Verb) { |
| 198 SkDPoint::Dump(pts()[2]); |
| 199 } |
| 200 if (verb() >= SkPath::kCubic_Verb) { |
| 201 SkDPoint::Dump(pts()[3]); |
| 202 } |
| 203 } |
| 204 |
| 205 void SkOpSegment::dumpAngles() const { |
| 206 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID()); |
| 207 int fromIndex = -1, toIndex = -1; |
| 208 for (int index = 0; index < count(); ++index) { |
| 209 int fIndex = fTs[index].fFromAngleIndex; |
| 210 int tIndex = fTs[index].fToAngleIndex; |
| 211 if (fromIndex == fIndex && tIndex == toIndex) { |
| 212 continue; |
| 213 } |
| 214 if (fIndex >= 0) { |
| 215 SkDebugf(" [%d] from=%d ", index, fIndex); |
| 216 const SkOpAngle& angle = this->angle(fIndex); |
| 217 angle.dumpFromTo(this, fIndex, tIndex); |
| 218 } |
| 219 if (tIndex >= 0) { |
| 220 SkDebugf(" [%d] to=%d ", index, tIndex); |
| 221 const SkOpAngle& angle = this->angle(tIndex); |
| 222 angle.dumpFromTo(this, fIndex, tIndex); |
| 223 } |
| 224 fromIndex = fIndex; |
| 225 toIndex = tIndex; |
| 226 } |
| 227 } |
| 228 |
| 229 void SkOpSegment::dumpContour(int firstID, int lastID) const { |
| 230 if (debugID() < 0) { |
| 231 return; |
| 232 } |
| 233 const SkOpSegment* test = this - (debugID() - 1); |
| 234 test += (firstID - 1); |
| 235 const SkOpSegment* last = test + (lastID - firstID); |
| 236 while (test <= last) { |
| 237 test->dumpSpans(); |
| 238 ++test; |
| 239 } |
| 240 } |
| 241 |
| 242 void SkOpSegment::dumpPts() const { |
| 243 int last = SkPathOpsVerbToPoints(fVerb); |
| 244 SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID()); |
| 245 int index = 0; |
| 246 do { |
| 247 SkDPoint::Dump(fPts[index]); |
| 248 SkDebugf(", "); |
| 249 } while (++index < last); |
| 250 SkDPoint::Dump(fPts[index]); |
| 251 SkDebugf("}}\n"); |
| 252 } |
| 253 |
| 254 void SkOpSegment::dumpDPts() const { |
| 255 int count = SkPathOpsVerbToPoints(fVerb); |
| 256 SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID()); |
| 257 int index = 0; |
| 258 do { |
| 259 SkDPoint dPt = {fPts[index].fX, fPts[index].fY}; |
| 260 dPt.dump(); |
| 261 if (index != count) { |
| 262 SkDebugf(", "); |
| 263 } |
| 264 } while (++index <= count); |
| 265 SkDebugf("}}\n"); |
| 266 } |
| 267 |
| 268 void SkOpSegment::dumpSpans() const { |
| 269 int count = this->count(); |
| 270 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID()); |
| 271 for (int index = 0; index < count; ++index) { |
| 272 const SkOpSpan& span = this->span(index); |
| 273 SkDebugf(" [%d] ", index); |
| 274 span.dumpOne(); |
| 275 } |
| 276 } |
| 277 |
| 278 void SkPathOpsDebug::DumpAngles(const SkTArray<SkOpAngle, true>& angles) { |
| 279 int count = angles.count(); |
| 280 for (int index = 0; index < count; ++index) { |
| 281 angles[index].dump(); |
| 282 } |
| 283 } |
| 284 |
| 285 void SkPathOpsDebug::DumpAngles(const SkTArray<SkOpAngle* , true>& angles) { |
| 286 int count = angles.count(); |
| 287 for (int index = 0; index < count; ++index) { |
| 288 angles[index]->dump(); |
| 289 } |
| 290 } |
| 291 |
| 292 void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour, true>& contours) { |
| 293 int count = contours.count(); |
| 294 for (int index = 0; index < count; ++index) { |
| 295 contours[index].dump(); |
| 296 } |
| 297 } |
| 298 |
| 299 void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour* , true>& contours)
{ |
| 300 int count = contours.count(); |
| 301 for (int index = 0; index < count; ++index) { |
| 302 contours[index]->dump(); |
| 303 } |
| 304 } |
| 305 |
| 306 void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour, true>& contou
rs) { |
| 307 int count = contours.count(); |
| 308 for (int index = 0; index < count; ++index) { |
| 309 contours[index].dumpAngles(); |
| 310 } |
| 311 } |
| 312 |
| 313 void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour* , true>& cont
ours) { |
| 314 int count = contours.count(); |
| 315 for (int index = 0; index < count; ++index) { |
| 316 contours[index]->dumpAngles(); |
| 317 } |
| 318 } |
| 319 |
| 320 void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour, true>& contours)
{ |
| 321 int count = contours.count(); |
| 322 for (int index = 0; index < count; ++index) { |
| 323 contours[index].dumpPts(); |
| 324 } |
| 325 } |
| 326 |
| 327 void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour* , true>& contour
s) { |
| 328 int count = contours.count(); |
| 329 for (int index = 0; index < count; ++index) { |
| 330 contours[index]->dumpPts(); |
| 331 } |
| 332 } |
| 333 |
| 334 void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour, true>& contour
s) { |
| 335 int count = contours.count(); |
| 336 for (int index = 0; index < count; ++index) { |
| 337 contours[index].dumpSpans(); |
| 338 } |
| 339 } |
| 340 |
| 341 void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour* , true>& conto
urs) { |
| 342 int count = contours.count(); |
| 343 for (int index = 0; index < count; ++index) { |
| 344 contours[index]->dumpSpans(); |
| 345 } |
| 346 } |
| 347 |
| 348 void SkPathOpsDebug::DumpSpans(const SkTDArray<SkOpSpan *>& spans) { |
| 349 int count = spans.count(); |
| 350 for (int index = 0; index < count; ++index) { |
| 351 const SkOpSpan* span = spans[index]; |
| 352 const SkOpSpan& oSpan = span->fOther->span(span->fOtherIndex); |
| 353 const SkOpSegment* segment = oSpan.fOther; |
| 354 SkDebugf("((SkOpSegment*) 0x%p) [%d] ", segment, segment->debugID()); |
| 355 SkDebugf("spanIndex:%d ", oSpan.fOtherIndex); |
| 356 span->dumpOne(); |
| 357 } |
| 358 } |
| 359 |
| 360 // this does not require that other T index is initialized or correct |
| 361 const SkOpSegment* SkOpSpan::debugToSegment(ptrdiff_t* spanIndex) const { |
| 362 if (!fOther) { |
| 363 return NULL; |
| 364 } |
| 365 int oppCount = fOther->count(); |
| 366 for (int index = 0; index < oppCount; ++index) { |
| 367 const SkOpSpan& otherSpan = fOther->span(index); |
| 368 double otherTestT = otherSpan.fT; |
| 369 if (otherTestT < fOtherT) { |
| 370 continue; |
| 371 } |
| 372 SkASSERT(otherTestT == fOtherT); |
| 373 const SkOpSegment* candidate = otherSpan.fOther; |
| 374 const SkOpSpan* first = candidate->spans().begin(); |
| 375 const SkOpSpan* last = candidate->spans().end() - 1; |
| 376 if (first <= this && this <= last) { |
| 377 if (spanIndex) { |
| 378 *spanIndex = this - first; |
| 379 } |
| 380 return candidate; |
| 381 } |
| 382 } |
| 383 SkASSERT(0); |
| 384 return NULL; |
| 385 } |
| 386 |
| 387 void SkOpSpan::dumpOne() const { |
| 388 SkDebugf("t="); |
| 389 DebugDumpDouble(fT); |
| 390 SkDebugf(" pt="); |
| 391 SkDPoint::Dump(fPt); |
| 392 if (fOther) { |
| 393 SkDebugf(" other.fID=%d", fOther->debugID()); |
| 394 SkDebugf(" [%d] otherT=", fOtherIndex); |
| 395 DebugDumpDouble(fOtherT); |
| 396 } else { |
| 397 SkDebugf(" other.fID=? [?] otherT=?"); |
| 398 } |
| 399 #if DEBUG_WINDING |
| 400 SkDebugf(" windSum="); |
| 401 SkPathOpsDebug::WindingPrintf(fWindSum); |
| 402 #endif |
| 403 if (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0) { |
| 404 #if DEBUG_WINDING |
| 405 SkDebugf(" oppSum="); |
| 406 SkPathOpsDebug::WindingPrintf(fOppSum); |
| 407 #endif |
| 408 } |
| 409 SkDebugf(" windValue=%d", fWindValue); |
| 410 if (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0) { |
| 411 SkDebugf(" oppValue=%d", fOppValue); |
| 412 } |
| 413 SkDebugf(" from=%d", fFromAngleIndex); |
| 414 SkDebugf(" to=%d", fToAngleIndex); |
| 415 if (fDone) { |
| 416 SkDebugf(" done"); |
| 417 } |
| 418 if (fUnsortableStart) { |
| 419 SkDebugf(" unsortable-start"); |
| 420 } |
| 421 if (fUnsortableEnd) { |
| 422 SkDebugf(" unsortable-end"); |
| 423 } |
| 424 if (fTiny) { |
| 425 SkDebugf(" tiny"); |
| 426 } |
| 427 if (fSmall) { |
| 428 SkDebugf(" small"); |
| 429 } |
| 430 if (fLoop) { |
| 431 SkDebugf(" loop"); |
| 432 } |
| 433 SkDebugf("\n"); |
| 434 } |
| 435 |
| 436 void SkOpSpan::dump() const { |
| 437 ptrdiff_t spanIndex; |
| 438 const SkOpSegment* segment = debugToSegment(&spanIndex); |
| 439 if (segment) { |
| 440 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", segment, segment->debugID()); |
| 441 SkDebugf(" [%d] ", spanIndex); |
| 442 } else { |
| 443 SkDebugf("((SkOpSegment*) ?) [?]\n"); |
| 444 SkDebugf(" [?] "); |
| 445 } |
| 446 dumpOne(); |
| 447 } |
| 448 |
| 449 void Dump(const SkTArray<class SkOpAngle, true>& angles) { |
| 450 SkPathOpsDebug::DumpAngles(angles); |
| 451 } |
| 452 |
| 453 void Dump(const SkTArray<class SkOpAngle* , true>& angles) { |
| 454 SkPathOpsDebug::DumpAngles(angles); |
| 455 } |
| 456 |
| 457 void Dump(const SkTArray<class SkOpAngle, true>* angles) { |
| 458 SkPathOpsDebug::DumpAngles(*angles); |
| 459 } |
| 460 |
| 461 void Dump(const SkTArray<class SkOpAngle* , true>* angles) { |
| 462 SkPathOpsDebug::DumpAngles(*angles); |
| 463 } |
| 464 |
| 465 void Dump(const SkTArray<class SkOpContour, true>& contours) { |
| 466 SkPathOpsDebug::DumpContours(contours); |
| 467 } |
| 468 |
| 469 void Dump(const SkTArray<class SkOpContour* , true>& contours) { |
| 470 SkPathOpsDebug::DumpContours(contours); |
| 471 } |
| 472 |
| 473 void Dump(const SkTArray<class SkOpContour, true>* contours) { |
| 474 SkPathOpsDebug::DumpContours(*contours); |
| 475 } |
| 476 |
| 477 void Dump(const SkTArray<class SkOpContour* , true>* contours) { |
| 478 SkPathOpsDebug::DumpContours(*contours); |
| 479 } |
| 480 |
| 481 void Dump(const SkTDArray<SkOpSpan *>& chaseArray) { |
| 482 SkPathOpsDebug::DumpSpans(chaseArray); |
| 483 } |
| 484 |
| 485 void Dump(const SkTDArray<SkOpSpan *>* chaseArray) { |
| 486 SkPathOpsDebug::DumpSpans(*chaseArray); |
| 487 } |
| 488 |
| 489 void DumpAngles(const SkTArray<class SkOpContour, true>& contours) { |
| 490 SkPathOpsDebug::DumpContourAngles(contours); |
| 491 } |
| 492 |
| 493 void DumpAngles(const SkTArray<class SkOpContour* , true>& contours) { |
| 494 SkPathOpsDebug::DumpContourAngles(contours); |
| 495 } |
| 496 |
| 497 void DumpAngles(const SkTArray<class SkOpContour, true>* contours) { |
| 498 SkPathOpsDebug::DumpContourAngles(*contours); |
| 499 } |
| 500 |
| 501 void DumpAngles(const SkTArray<class SkOpContour* , true>* contours) { |
| 502 SkPathOpsDebug::DumpContourAngles(*contours); |
| 503 } |
| 504 |
| 505 void DumpSpans(const SkTArray<class SkOpContour, true>& contours) { |
| 506 SkPathOpsDebug::DumpContourSpans(contours); |
| 507 } |
| 508 |
| 509 void DumpSpans(const SkTArray<class SkOpContour* , true>& contours) { |
| 510 SkPathOpsDebug::DumpContourSpans(contours); |
| 511 } |
| 512 |
| 513 void DumpSpans(const SkTArray<class SkOpContour, true>* contours) { |
| 514 SkPathOpsDebug::DumpContourSpans(*contours); |
| 515 } |
| 516 |
| 517 void DumpSpans(const SkTArray<class SkOpContour* , true>* contours) { |
| 518 SkPathOpsDebug::DumpContourSpans(*contours); |
| 519 } |
| 520 |
| 521 void DumpPts(const SkTArray<class SkOpContour, true>& contours) { |
| 522 SkPathOpsDebug::DumpContourPts(contours); |
| 523 } |
| 524 |
| 525 void DumpPts(const SkTArray<class SkOpContour* , true>& contours) { |
| 526 SkPathOpsDebug::DumpContourPts(contours); |
| 527 } |
| 528 |
| 529 void DumpPts(const SkTArray<class SkOpContour, true>* contours) { |
| 530 SkPathOpsDebug::DumpContourPts(*contours); |
| 531 } |
| 532 |
| 533 void DumpPts(const SkTArray<class SkOpContour* , true>* contours) { |
| 534 SkPathOpsDebug::DumpContourPts(*contours); |
| 535 } |
| 536 |
| 537 static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo)
{ |
| 538 SkDebugf("<div id=\"quad%d\">\n", testNo); |
| 539 quad1.dumpComma(","); |
| 540 quad2.dump(); |
| 541 SkDebugf("</div>\n\n"); |
| 542 } |
| 543 |
| 544 static void dumpTestTrailer() { |
| 545 SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n"); |
| 546 SkDebugf(" var testDivs = [\n"); |
| 547 } |
| 548 |
| 549 static void dumpTestList(int testNo, double min) { |
| 550 SkDebugf(" quad%d,", testNo); |
| 551 if (min > 0) { |
| 552 SkDebugf(" // %1.9g", min); |
| 553 } |
| 554 SkDebugf("\n"); |
| 555 } |
| 556 |
| 557 void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) { |
| 558 SkDebugf("\n"); |
| 559 dumpTestCase(quad1, quad2, testNo); |
| 560 dumpTestTrailer(); |
| 561 dumpTestList(testNo, 0); |
| 562 SkDebugf("\n"); |
| 563 } |
| 564 |
| 565 void DumpT(const SkDQuad& quad, double t) { |
| 566 SkDLine line = {{quad.ptAtT(t), quad[0]}}; |
| 567 line.dump(); |
| 568 } |
OLD | NEW |