| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkBuffer.h" | 8 #include "SkBuffer.h" |
| 9 #include "SkErrorInternals.h" | 9 #include "SkErrorInternals.h" |
| 10 #include "SkGeometry.h" | 10 #include "SkGeometry.h" |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 SkPoint first, last; | 389 SkPoint first, last; |
| 390 const SkPoint* pts = *ptsPtr; | 390 const SkPoint* pts = *ptsPtr; |
| 391 const SkPoint* savePts = NULL; | 391 const SkPoint* savePts = NULL; |
| 392 first.set(0, 0); | 392 first.set(0, 0); |
| 393 last.set(0, 0); | 393 last.set(0, 0); |
| 394 int firstDirection = 0; | 394 int firstDirection = 0; |
| 395 int lastDirection = 0; | 395 int lastDirection = 0; |
| 396 int nextDirection = 0; | 396 int nextDirection = 0; |
| 397 bool closedOrMoved = false; | 397 bool closedOrMoved = false; |
| 398 bool autoClose = false; | 398 bool autoClose = false; |
| 399 bool insertClose = false; |
| 399 int verbCnt = fPathRef->countVerbs(); | 400 int verbCnt = fPathRef->countVerbs(); |
| 400 while (*currVerb < verbCnt && (!allowPartial || !autoClose)) { | 401 while (*currVerb < verbCnt && (!allowPartial || !autoClose)) { |
| 401 switch (fPathRef->atVerb(*currVerb)) { | 402 uint8_t verb = insertClose ? (uint8_t) kClose_Verb : fPathRef->atVerb(*c
urrVerb); |
| 403 switch (verb) { |
| 402 case kClose_Verb: | 404 case kClose_Verb: |
| 403 savePts = pts; | 405 savePts = pts; |
| 404 pts = *ptsPtr; | 406 pts = *ptsPtr; |
| 405 autoClose = true; | 407 autoClose = true; |
| 408 insertClose = false; |
| 406 case kLine_Verb: { | 409 case kLine_Verb: { |
| 407 SkScalar left = last.fX; | 410 SkScalar left = last.fX; |
| 408 SkScalar top = last.fY; | 411 SkScalar top = last.fY; |
| 409 SkScalar right = pts->fX; | 412 SkScalar right = pts->fX; |
| 410 SkScalar bottom = pts->fY; | 413 SkScalar bottom = pts->fY; |
| 411 ++pts; | 414 ++pts; |
| 412 if (left != right && top != bottom) { | 415 if (left != right && top != bottom) { |
| 413 return false; // diagonal | 416 return false; // diagonal |
| 414 } | 417 } |
| 415 if (left == right && top == bottom) { | 418 if (left == right && top == bottom) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 if ((directionCycle ^ turn) != nextDirection) { | 451 if ((directionCycle ^ turn) != nextDirection) { |
| 449 return false; // direction didn't follow cycle | 452 return false; // direction didn't follow cycle |
| 450 } | 453 } |
| 451 break; | 454 break; |
| 452 } | 455 } |
| 453 case kQuad_Verb: | 456 case kQuad_Verb: |
| 454 case kConic_Verb: | 457 case kConic_Verb: |
| 455 case kCubic_Verb: | 458 case kCubic_Verb: |
| 456 return false; // quadratic, cubic not allowed | 459 return false; // quadratic, cubic not allowed |
| 457 case kMove_Verb: | 460 case kMove_Verb: |
| 461 if (allowPartial && !autoClose && firstDirection) { |
| 462 insertClose = true; |
| 463 *currVerb -= 1; // try move again afterwards |
| 464 goto addMissingClose; |
| 465 } |
| 458 last = *pts++; | 466 last = *pts++; |
| 459 closedOrMoved = true; | 467 closedOrMoved = true; |
| 460 break; | 468 break; |
| 461 default: | 469 default: |
| 462 SkDEBUGFAIL("unexpected verb"); | 470 SkDEBUGFAIL("unexpected verb"); |
| 463 break; | 471 break; |
| 464 } | 472 } |
| 465 *currVerb += 1; | 473 *currVerb += 1; |
| 466 lastDirection = nextDirection; | 474 lastDirection = nextDirection; |
| 475 addMissingClose: |
| 476 ; |
| 467 } | 477 } |
| 468 // Success if 4 corners and first point equals last | 478 // Success if 4 corners and first point equals last |
| 469 bool result = 4 == corners && (first == last || autoClose); | 479 bool result = 4 == corners && (first == last || autoClose); |
| 470 if (!result) { | 480 if (!result) { |
| 471 // check if we are just an incomplete rectangle, in which case we can | 481 // check if we are just an incomplete rectangle, in which case we can |
| 472 // return true, but not claim to be closed. | 482 // return true, but not claim to be closed. |
| 473 // e.g. | 483 // e.g. |
| 474 // 3 sided rectangle | 484 // 3 sided rectangle |
| 475 // 4 sided but the last edge is not long enough to reach the start | 485 // 4 sided but the last edge is not long enough to reach the start |
| 476 // | 486 // |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 if (num) { | 521 if (num) { |
| 512 rect->set(first, num); | 522 rect->set(first, num); |
| 513 } else { | 523 } else { |
| 514 // 'pts' isn't updated for open rects | 524 // 'pts' isn't updated for open rects |
| 515 *rect = this->getBounds(); | 525 *rect = this->getBounds(); |
| 516 } | 526 } |
| 517 } | 527 } |
| 518 return true; | 528 return true; |
| 519 } | 529 } |
| 520 | 530 |
| 521 bool SkPath::isNestedRects(SkRect rects[2], Direction dirs[2]) const { | 531 bool SkPath::isNestedFillRects(SkRect rects[2], Direction dirs[2]) const { |
| 522 SkDEBUGCODE(this->validate();) | 532 SkDEBUGCODE(this->validate();) |
| 523 int currVerb = 0; | 533 int currVerb = 0; |
| 524 const SkPoint* pts = fPathRef->points(); | 534 const SkPoint* pts = fPathRef->points(); |
| 525 const SkPoint* first = pts; | 535 const SkPoint* first = pts; |
| 526 Direction testDirs[2]; | 536 Direction testDirs[2]; |
| 527 if (!isRectContour(true, &currVerb, &pts, NULL, &testDirs[0])) { | 537 if (!isRectContour(true, &currVerb, &pts, NULL, &testDirs[0])) { |
| 528 return false; | 538 return false; |
| 529 } | 539 } |
| 530 const SkPoint* last = pts; | 540 const SkPoint* last = pts; |
| 531 SkRect testRects[2]; | 541 SkRect testRects[2]; |
| 532 if (isRectContour(false, &currVerb, &pts, NULL, &testDirs[1])) { | 542 bool isClosed; |
| 543 if (isRectContour(false, &currVerb, &pts, &isClosed, &testDirs[1])) { |
| 533 testRects[0].set(first, SkToS32(last - first)); | 544 testRects[0].set(first, SkToS32(last - first)); |
| 545 if (!isClosed) { |
| 546 pts = fPathRef->points() + fPathRef->countPoints(); |
| 547 } |
| 534 testRects[1].set(last, SkToS32(pts - last)); | 548 testRects[1].set(last, SkToS32(pts - last)); |
| 535 if (testRects[0].contains(testRects[1])) { | 549 if (testRects[0].contains(testRects[1])) { |
| 536 if (rects) { | 550 if (rects) { |
| 537 rects[0] = testRects[0]; | 551 rects[0] = testRects[0]; |
| 538 rects[1] = testRects[1]; | 552 rects[1] = testRects[1]; |
| 539 } | 553 } |
| 540 if (dirs) { | 554 if (dirs) { |
| 541 dirs[0] = testDirs[0]; | 555 dirs[0] = testDirs[0]; |
| 542 dirs[1] = testDirs[1]; | 556 dirs[1] = testDirs[1]; |
| 543 } | 557 } |
| (...skipping 2220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2764 switch (this->getFillType()) { | 2778 switch (this->getFillType()) { |
| 2765 case SkPath::kEvenOdd_FillType: | 2779 case SkPath::kEvenOdd_FillType: |
| 2766 case SkPath::kInverseEvenOdd_FillType: | 2780 case SkPath::kInverseEvenOdd_FillType: |
| 2767 w &= 1; | 2781 w &= 1; |
| 2768 break; | 2782 break; |
| 2769 default: | 2783 default: |
| 2770 break; | 2784 break; |
| 2771 } | 2785 } |
| 2772 return SkToBool(w); | 2786 return SkToBool(w); |
| 2773 } | 2787 } |
| OLD | NEW |