| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkBuffer.h" | 10 #include "SkBuffer.h" |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 case kMove_Verb: | 362 case kMove_Verb: |
| 363 SkASSERT(!moveCnt); | 363 SkASSERT(!moveCnt); |
| 364 SkDEBUGCODE(++moveCnt); | 364 SkDEBUGCODE(++moveCnt); |
| 365 firstPt = prevPt = pts[0]; | 365 firstPt = prevPt = pts[0]; |
| 366 break; | 366 break; |
| 367 case kLine_Verb: | 367 case kLine_Verb: |
| 368 nextPt = 1; | 368 nextPt = 1; |
| 369 SkASSERT(moveCnt); | 369 SkASSERT(moveCnt); |
| 370 break; | 370 break; |
| 371 case kQuad_Verb: | 371 case kQuad_Verb: |
| 372 case kConic_Verb: |
| 372 SkASSERT(moveCnt); | 373 SkASSERT(moveCnt); |
| 373 nextPt = 2; | 374 nextPt = 2; |
| 374 break; | 375 break; |
| 375 case kCubic_Verb: | 376 case kCubic_Verb: |
| 376 SkASSERT(moveCnt); | 377 SkASSERT(moveCnt); |
| 377 nextPt = 3; | 378 nextPt = 3; |
| 378 break; | 379 break; |
| 379 case kClose_Verb: | 380 case kClose_Verb: |
| 380 break; | 381 break; |
| 381 default: | 382 default: |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 551 // When corners == 3, nextDirection opposes firstDirection. | 552 // When corners == 3, nextDirection opposes firstDirection. |
| 552 // Otherwise, nextDirection at corner 2 opposes corner 4. | 553 // Otherwise, nextDirection at corner 2 opposes corner 4. |
| 553 int turn = firstDirection ^ (corners - 1); | 554 int turn = firstDirection ^ (corners - 1); |
| 554 int directionCycle = 3 == corners ? 0 : nextDirection ^ turn; | 555 int directionCycle = 3 == corners ? 0 : nextDirection ^ turn; |
| 555 if ((directionCycle ^ turn) != nextDirection) { | 556 if ((directionCycle ^ turn) != nextDirection) { |
| 556 return false; // direction didn't follow cycle | 557 return false; // direction didn't follow cycle |
| 557 } | 558 } |
| 558 break; | 559 break; |
| 559 } | 560 } |
| 560 case kQuad_Verb: | 561 case kQuad_Verb: |
| 562 case kConic_Verb: |
| 561 case kCubic_Verb: | 563 case kCubic_Verb: |
| 562 return false; // quadratic, cubic not allowed | 564 return false; // quadratic, cubic not allowed |
| 563 case kMove_Verb: | 565 case kMove_Verb: |
| 564 last = *pts++; | 566 last = *pts++; |
| 565 closedOrMoved = true; | 567 closedOrMoved = true; |
| 566 break; | 568 break; |
| 569 default: |
| 570 SkASSERT(!"unexpected verb"); |
| 571 break; |
| 567 } | 572 } |
| 568 *currVerb += 1; | 573 *currVerb += 1; |
| 569 lastDirection = nextDirection; | 574 lastDirection = nextDirection; |
| 570 } | 575 } |
| 571 // Success if 4 corners and first point equals last | 576 // Success if 4 corners and first point equals last |
| 572 bool result = 4 == corners && (first == last || autoClose); | 577 bool result = 4 == corners && (first == last || autoClose); |
| 573 if (savePts) { | 578 if (savePts) { |
| 574 *ptsPtr = savePts; | 579 *ptsPtr = savePts; |
| 575 } | 580 } |
| 576 if (result && isClosed) { | 581 if (result && isClosed) { |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 } | 803 } |
| 799 | 804 |
| 800 void SkPath::rLineTo(SkScalar x, SkScalar y) { | 805 void SkPath::rLineTo(SkScalar x, SkScalar y) { |
| 801 SkPoint pt; | 806 SkPoint pt; |
| 802 this->getLastPt(&pt); | 807 this->getLastPt(&pt); |
| 803 this->lineTo(pt.fX + x, pt.fY + y); | 808 this->lineTo(pt.fX + x, pt.fY + y); |
| 804 } | 809 } |
| 805 | 810 |
| 806 void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) { | 811 void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) { |
| 807 SkDEBUGCODE(this->validate();) | 812 SkDEBUGCODE(this->validate();) |
| 808 | 813 |
| 809 this->injectMoveToIfNeeded(); | 814 this->injectMoveToIfNeeded(); |
| 810 | 815 |
| 811 SkPathRef::Editor ed(&fPathRef); | 816 SkPathRef::Editor ed(&fPathRef); |
| 812 SkPoint* pts = ed.growForVerb(kQuad_Verb); | 817 SkPoint* pts = ed.growForVerb(kQuad_Verb); |
| 813 pts[0].set(x1, y1); | 818 pts[0].set(x1, y1); |
| 814 pts[1].set(x2, y2); | 819 pts[1].set(x2, y2); |
| 815 fSegmentMask |= kQuad_SegmentMask; | 820 fSegmentMask |= kQuad_SegmentMask; |
| 816 | 821 |
| 817 GEN_ID_INC; | 822 GEN_ID_INC; |
| 818 DIRTY_AFTER_EDIT; | 823 DIRTY_AFTER_EDIT; |
| 819 } | 824 } |
| 820 | 825 |
| 821 void SkPath::rQuadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) { | 826 void SkPath::rQuadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) { |
| 822 SkPoint pt; | 827 SkPoint pt; |
| 823 this->getLastPt(&pt); | 828 this->getLastPt(&pt); |
| 824 this->quadTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2); | 829 this->quadTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2); |
| 825 } | 830 } |
| 826 | 831 |
| 832 void SkPath::conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, |
| 833 SkScalar w) { |
| 834 // check for <= 0 or NaN with this test |
| 835 if (!(w > 0)) { |
| 836 this->lineTo(x2, y2); |
| 837 } else if (!SkScalarIsFinite(w)) { |
| 838 this->lineTo(x1, y1); |
| 839 this->lineTo(x2, y2); |
| 840 } else if (SK_Scalar1 == w) { |
| 841 this->quadTo(x1, y1, x2, y2); |
| 842 } else { |
| 843 SkDEBUGCODE(this->validate();) |
| 844 |
| 845 this->injectMoveToIfNeeded(); |
| 846 |
| 847 SkPathRef::Editor ed(&fPathRef); |
| 848 SkPoint* pts = ed.growForConic(w); |
| 849 pts[0].set(x1, y1); |
| 850 pts[1].set(x2, y2); |
| 851 fSegmentMask |= kConic_SegmentMask; |
| 852 |
| 853 GEN_ID_INC; |
| 854 DIRTY_AFTER_EDIT; |
| 855 } |
| 856 } |
| 857 |
| 858 void SkPath::rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2, |
| 859 SkScalar w) { |
| 860 SkPoint pt; |
| 861 this->getLastPt(&pt); |
| 862 this->conicTo(pt.fX + dx1, pt.fY + dy1, pt.fX + dx2, pt.fY + dy2, w); |
| 863 } |
| 864 |
| 827 void SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, | 865 void SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, |
| 828 SkScalar x3, SkScalar y3) { | 866 SkScalar x3, SkScalar y3) { |
| 829 SkDEBUGCODE(this->validate();) | 867 SkDEBUGCODE(this->validate();) |
| 830 | 868 |
| 831 this->injectMoveToIfNeeded(); | 869 this->injectMoveToIfNeeded(); |
| 832 | 870 |
| 833 SkPathRef::Editor ed(&fPathRef); | 871 SkPathRef::Editor ed(&fPathRef); |
| 834 SkPoint* pts = ed.growForVerb(kCubic_Verb); | 872 SkPoint* pts = ed.growForVerb(kCubic_Verb); |
| 835 pts[0].set(x1, y1); | 873 pts[0].set(x1, y1); |
| 836 pts[1].set(x2, y2); | 874 pts[1].set(x2, y2); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 850 } | 888 } |
| 851 | 889 |
| 852 void SkPath::close() { | 890 void SkPath::close() { |
| 853 SkDEBUGCODE(this->validate();) | 891 SkDEBUGCODE(this->validate();) |
| 854 | 892 |
| 855 int count = fPathRef->countVerbs(); | 893 int count = fPathRef->countVerbs(); |
| 856 if (count > 0) { | 894 if (count > 0) { |
| 857 switch (fPathRef->atVerb(count - 1)) { | 895 switch (fPathRef->atVerb(count - 1)) { |
| 858 case kLine_Verb: | 896 case kLine_Verb: |
| 859 case kQuad_Verb: | 897 case kQuad_Verb: |
| 898 case kConic_Verb: |
| 860 case kCubic_Verb: | 899 case kCubic_Verb: |
| 861 case kMove_Verb: { | 900 case kMove_Verb: { |
| 862 SkPathRef::Editor ed(&fPathRef); | 901 SkPathRef::Editor ed(&fPathRef); |
| 863 ed.growForVerb(kClose_Verb); | 902 ed.growForVerb(kClose_Verb); |
| 864 GEN_ID_INC; | 903 GEN_ID_INC; |
| 865 break; | 904 break; |
| 866 } | 905 } |
| 906 case kClose_Verb: |
| 907 // don't add a close if it's the first verb or a repeat |
| 908 break; |
| 867 default: | 909 default: |
| 868 // don't add a close if it's the first verb or a repeat | 910 SkASSERT(!"unexpected verb"); |
| 869 break; | 911 break; |
| 870 } | 912 } |
| 871 } | 913 } |
| 872 | 914 |
| 873 // signal that we need a moveTo to follow us (unless we're done) | 915 // signal that we need a moveTo to follow us (unless we're done) |
| 874 #if 0 | 916 #if 0 |
| 875 if (fLastMoveToIndex >= 0) { | 917 if (fLastMoveToIndex >= 0) { |
| 876 fLastMoveToIndex = ~fLastMoveToIndex; | 918 fLastMoveToIndex = ~fLastMoveToIndex; |
| 877 } | 919 } |
| 878 #else | 920 #else |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1423 this->moveTo(pts[0]); | 1465 this->moveTo(pts[0]); |
| 1424 break; | 1466 break; |
| 1425 case kLine_Verb: | 1467 case kLine_Verb: |
| 1426 proc(matrix, &pts[1], &pts[1], 1); | 1468 proc(matrix, &pts[1], &pts[1], 1); |
| 1427 this->lineTo(pts[1]); | 1469 this->lineTo(pts[1]); |
| 1428 break; | 1470 break; |
| 1429 case kQuad_Verb: | 1471 case kQuad_Verb: |
| 1430 proc(matrix, &pts[1], &pts[1], 2); | 1472 proc(matrix, &pts[1], &pts[1], 2); |
| 1431 this->quadTo(pts[1], pts[2]); | 1473 this->quadTo(pts[1], pts[2]); |
| 1432 break; | 1474 break; |
| 1475 case kConic_Verb: |
| 1476 proc(matrix, &pts[1], &pts[1], 2); |
| 1477 this->conicTo(pts[1], pts[2], iter.conicWeight()); |
| 1478 break; |
| 1433 case kCubic_Verb: | 1479 case kCubic_Verb: |
| 1434 proc(matrix, &pts[1], &pts[1], 3); | 1480 proc(matrix, &pts[1], &pts[1], 3); |
| 1435 this->cubicTo(pts[1], pts[2], pts[3]); | 1481 this->cubicTo(pts[1], pts[2], pts[3]); |
| 1436 break; | 1482 break; |
| 1437 case kClose_Verb: | 1483 case kClose_Verb: |
| 1438 this->close(); | 1484 this->close(); |
| 1439 break; | 1485 break; |
| 1440 default: | 1486 default: |
| 1441 SkDEBUGFAIL("unknown verb"); | 1487 SkDEBUGFAIL("unknown verb"); |
| 1442 } | 1488 } |
| 1443 } | 1489 } |
| 1444 } | 1490 } |
| 1445 | 1491 |
| 1446 /////////////////////////////////////////////////////////////////////////////// | 1492 /////////////////////////////////////////////////////////////////////////////// |
| 1447 | 1493 |
| 1448 static const uint8_t gPtsInVerb[] = { | 1494 static int pts_in_verb(unsigned verb) { |
| 1449 1, // kMove | 1495 static const uint8_t gPtsInVerb[] = { |
| 1450 1, // kLine | 1496 1, // kMove |
| 1451 2, // kQuad | 1497 1, // kLine |
| 1452 3, // kCubic | 1498 2, // kQuad |
| 1453 0, // kClose | 1499 2, // kConic |
| 1454 0 // kDone | 1500 3, // kCubic |
| 1455 }; | 1501 0, // kClose |
| 1502 0 // kDone |
| 1503 }; |
| 1504 |
| 1505 SkASSERT(verb < SK_ARRAY_COUNT(gPtsInVerb)); |
| 1506 return gPtsInVerb[verb]; |
| 1507 } |
| 1456 | 1508 |
| 1457 // ignore the initial moveto, and stop when the 1st contour ends | 1509 // ignore the initial moveto, and stop when the 1st contour ends |
| 1458 void SkPath::pathTo(const SkPath& path) { | 1510 void SkPath::pathTo(const SkPath& path) { |
| 1459 int i, vcount = path.fPathRef->countVerbs(); | 1511 int i, vcount = path.fPathRef->countVerbs(); |
| 1460 // exit early if the path is empty, or just has a moveTo. | 1512 // exit early if the path is empty, or just has a moveTo. |
| 1461 if (vcount < 2) { | 1513 if (vcount < 2) { |
| 1462 return; | 1514 return; |
| 1463 } | 1515 } |
| 1464 | 1516 |
| 1465 SkPathRef::Editor(&fPathRef, vcount, path.countPoints()); | 1517 SkPathRef::Editor(&fPathRef, vcount, path.countPoints()); |
| 1466 | 1518 |
| 1467 fIsOval = false; | 1519 fIsOval = false; |
| 1468 | 1520 |
| 1469 const uint8_t* verbs = path.fPathRef->verbs(); | 1521 const uint8_t* verbs = path.fPathRef->verbs(); |
| 1470 // skip the initial moveTo | 1522 // skip the initial moveTo |
| 1471 const SkPoint* pts = path.fPathRef->points() + 1; | 1523 const SkPoint* pts = path.fPathRef->points() + 1; |
| 1524 const SkScalar* conicWeight = path.fPathRef->conicWeights(); |
| 1472 | 1525 |
| 1473 SkASSERT(verbs[~0] == kMove_Verb); | 1526 SkASSERT(verbs[~0] == kMove_Verb); |
| 1474 for (i = 1; i < vcount; i++) { | 1527 for (i = 1; i < vcount; i++) { |
| 1475 switch (verbs[~i]) { | 1528 switch (verbs[~i]) { |
| 1476 case kLine_Verb: | 1529 case kLine_Verb: |
| 1477 this->lineTo(pts[0].fX, pts[0].fY); | 1530 this->lineTo(pts[0].fX, pts[0].fY); |
| 1478 break; | 1531 break; |
| 1479 case kQuad_Verb: | 1532 case kQuad_Verb: |
| 1480 this->quadTo(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY); | 1533 this->quadTo(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY); |
| 1481 break; | 1534 break; |
| 1535 case kConic_Verb: |
| 1536 this->conicTo(pts[0], pts[1], *conicWeight++); |
| 1537 break; |
| 1482 case kCubic_Verb: | 1538 case kCubic_Verb: |
| 1483 this->cubicTo(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2]
.fX, pts[2].fY); | 1539 this->cubicTo(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2]
.fX, pts[2].fY); |
| 1484 break; | 1540 break; |
| 1485 case kClose_Verb: | 1541 case kClose_Verb: |
| 1486 return; | 1542 return; |
| 1487 } | 1543 } |
| 1488 pts += gPtsInVerb[verbs[~i]]; | 1544 pts += pts_in_verb(verbs[~i]); |
| 1489 } | 1545 } |
| 1490 } | 1546 } |
| 1491 | 1547 |
| 1492 // ignore the last point of the 1st contour | 1548 // ignore the last point of the 1st contour |
| 1493 void SkPath::reversePathTo(const SkPath& path) { | 1549 void SkPath::reversePathTo(const SkPath& path) { |
| 1494 int i, vcount = path.fPathRef->countVerbs(); | 1550 int i, vcount = path.fPathRef->countVerbs(); |
| 1495 // exit early if the path is empty, or just has a moveTo. | 1551 // exit early if the path is empty, or just has a moveTo. |
| 1496 if (vcount < 2) { | 1552 if (vcount < 2) { |
| 1497 return; | 1553 return; |
| 1498 } | 1554 } |
| 1499 | 1555 |
| 1500 SkPathRef::Editor(&fPathRef, vcount, path.countPoints()); | 1556 SkPathRef::Editor(&fPathRef, vcount, path.countPoints()); |
| 1501 | 1557 |
| 1502 fIsOval = false; | 1558 fIsOval = false; |
| 1503 | 1559 |
| 1504 const uint8_t* verbs = path.fPathRef->verbs(); | 1560 const uint8_t* verbs = path.fPathRef->verbs(); |
| 1505 const SkPoint* pts = path.fPathRef->points(); | 1561 const SkPoint* pts = path.fPathRef->points(); |
| 1562 const SkScalar* conicWeights = path.fPathRef->conicWeights(); |
| 1506 | 1563 |
| 1507 SkASSERT(verbs[~0] == kMove_Verb); | 1564 SkASSERT(verbs[~0] == kMove_Verb); |
| 1508 for (i = 1; i < vcount; ++i) { | 1565 for (i = 1; i < vcount; ++i) { |
| 1509 int n = gPtsInVerb[verbs[~i]]; | 1566 unsigned v = verbs[~i]; |
| 1567 int n = pts_in_verb(v); |
| 1510 if (n == 0) { | 1568 if (n == 0) { |
| 1511 break; | 1569 break; |
| 1512 } | 1570 } |
| 1513 pts += n; | 1571 pts += n; |
| 1572 conicWeights += (SkPath::kConic_Verb == v); |
| 1514 } | 1573 } |
| 1515 | 1574 |
| 1516 while (--i > 0) { | 1575 while (--i > 0) { |
| 1517 switch (verbs[~i]) { | 1576 switch (verbs[~i]) { |
| 1518 case kLine_Verb: | 1577 case kLine_Verb: |
| 1519 this->lineTo(pts[-1].fX, pts[-1].fY); | 1578 this->lineTo(pts[-1].fX, pts[-1].fY); |
| 1520 break; | 1579 break; |
| 1521 case kQuad_Verb: | 1580 case kQuad_Verb: |
| 1522 this->quadTo(pts[-1].fX, pts[-1].fY, pts[-2].fX, pts[-2].fY); | 1581 this->quadTo(pts[-1].fX, pts[-1].fY, pts[-2].fX, pts[-2].fY); |
| 1523 break; | 1582 break; |
| 1583 case kConic_Verb: |
| 1584 this->conicTo(pts[-1], pts[-2], *--conicWeights); |
| 1585 break; |
| 1524 case kCubic_Verb: | 1586 case kCubic_Verb: |
| 1525 this->cubicTo(pts[-1].fX, pts[-1].fY, pts[-2].fX, pts[-2].fY, | 1587 this->cubicTo(pts[-1].fX, pts[-1].fY, pts[-2].fX, pts[-2].fY, |
| 1526 pts[-3].fX, pts[-3].fY); | 1588 pts[-3].fX, pts[-3].fY); |
| 1527 break; | 1589 break; |
| 1528 default: | 1590 default: |
| 1529 SkDEBUGFAIL("bad verb"); | 1591 SkDEBUGFAIL("bad verb"); |
| 1530 break; | 1592 break; |
| 1531 } | 1593 } |
| 1532 pts -= gPtsInVerb[verbs[~i]]; | 1594 pts -= pts_in_verb(verbs[~i]); |
| 1533 } | 1595 } |
| 1534 } | 1596 } |
| 1535 | 1597 |
| 1536 void SkPath::reverseAddPath(const SkPath& src) { | 1598 void SkPath::reverseAddPath(const SkPath& src) { |
| 1537 SkPathRef::Editor ed(&fPathRef, src.fPathRef->countPoints(), src.fPathRef->c
ountVerbs()); | 1599 SkPathRef::Editor ed(&fPathRef, src.fPathRef->countPoints(), src.fPathRef->c
ountVerbs()); |
| 1538 | 1600 |
| 1539 const SkPoint* pts = src.fPathRef->pointsEnd(); | 1601 const SkPoint* pts = src.fPathRef->pointsEnd(); |
| 1540 // we will iterator through src's verbs backwards | 1602 // we will iterator through src's verbs backwards |
| 1541 const uint8_t* verbs = src.fPathRef->verbsMemBegin(); // points at the last
verb | 1603 const uint8_t* verbs = src.fPathRef->verbsMemBegin(); // points at the last
verb |
| 1542 const uint8_t* verbsEnd = src.fPathRef->verbs(); // points just past the fir
st verb | 1604 const uint8_t* verbsEnd = src.fPathRef->verbs(); // points just past the fir
st verb |
| 1605 const SkScalar* conicWeights = src.fPathRef->conicWeightsEnd(); |
| 1543 | 1606 |
| 1544 fIsOval = false; | 1607 fIsOval = false; |
| 1545 | 1608 |
| 1546 bool needMove = true; | 1609 bool needMove = true; |
| 1547 bool needClose = false; | 1610 bool needClose = false; |
| 1548 while (verbs < verbsEnd) { | 1611 while (verbs < verbsEnd) { |
| 1549 uint8_t v = *(verbs++); | 1612 uint8_t v = *(verbs++); |
| 1550 int n = gPtsInVerb[v]; | 1613 int n = pts_in_verb(v); |
| 1551 | 1614 |
| 1552 if (needMove) { | 1615 if (needMove) { |
| 1553 --pts; | 1616 --pts; |
| 1554 this->moveTo(pts->fX, pts->fY); | 1617 this->moveTo(pts->fX, pts->fY); |
| 1555 needMove = false; | 1618 needMove = false; |
| 1556 } | 1619 } |
| 1557 pts -= n; | 1620 pts -= n; |
| 1558 switch (v) { | 1621 switch (v) { |
| 1559 case kMove_Verb: | 1622 case kMove_Verb: |
| 1560 if (needClose) { | 1623 if (needClose) { |
| 1561 this->close(); | 1624 this->close(); |
| 1562 needClose = false; | 1625 needClose = false; |
| 1563 } | 1626 } |
| 1564 needMove = true; | 1627 needMove = true; |
| 1565 pts += 1; // so we see the point in "if (needMove)" above | 1628 pts += 1; // so we see the point in "if (needMove)" above |
| 1566 break; | 1629 break; |
| 1567 case kLine_Verb: | 1630 case kLine_Verb: |
| 1568 this->lineTo(pts[0]); | 1631 this->lineTo(pts[0]); |
| 1569 break; | 1632 break; |
| 1570 case kQuad_Verb: | 1633 case kQuad_Verb: |
| 1571 this->quadTo(pts[1], pts[0]); | 1634 this->quadTo(pts[1], pts[0]); |
| 1572 break; | 1635 break; |
| 1636 case kConic_Verb: |
| 1637 this->conicTo(pts[1], pts[0], *--conicWeights); |
| 1638 break; |
| 1573 case kCubic_Verb: | 1639 case kCubic_Verb: |
| 1574 this->cubicTo(pts[2], pts[1], pts[0]); | 1640 this->cubicTo(pts[2], pts[1], pts[0]); |
| 1575 break; | 1641 break; |
| 1576 case kClose_Verb: | 1642 case kClose_Verb: |
| 1577 needClose = true; | 1643 needClose = true; |
| 1578 break; | 1644 break; |
| 1579 default: | 1645 default: |
| 1580 SkASSERT(!"unexpected verb"); | 1646 SkASSERT(!"unexpected verb"); |
| 1581 } | 1647 } |
| 1582 } | 1648 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1637 switch (verb) { | 1703 switch (verb) { |
| 1638 case kMove_Verb: | 1704 case kMove_Verb: |
| 1639 tmp.moveTo(pts[0]); | 1705 tmp.moveTo(pts[0]); |
| 1640 break; | 1706 break; |
| 1641 case kLine_Verb: | 1707 case kLine_Verb: |
| 1642 tmp.lineTo(pts[1]); | 1708 tmp.lineTo(pts[1]); |
| 1643 break; | 1709 break; |
| 1644 case kQuad_Verb: | 1710 case kQuad_Verb: |
| 1645 subdivide_quad_to(&tmp, pts); | 1711 subdivide_quad_to(&tmp, pts); |
| 1646 break; | 1712 break; |
| 1713 case kConic_Verb: |
| 1714 SkASSERT(!"TODO: compute new weight"); |
| 1715 tmp.conicTo(pts[1], pts[2], iter.conicWeight()); |
| 1716 break; |
| 1647 case kCubic_Verb: | 1717 case kCubic_Verb: |
| 1648 subdivide_cubic_to(&tmp, pts); | 1718 subdivide_cubic_to(&tmp, pts); |
| 1649 break; | 1719 break; |
| 1650 case kClose_Verb: | 1720 case kClose_Verb: |
| 1651 tmp.close(); | 1721 tmp.close(); |
| 1652 break; | 1722 break; |
| 1653 default: | 1723 default: |
| 1654 SkDEBUGFAIL("unknown verb"); | 1724 SkDEBUGFAIL("unknown verb"); |
| 1655 break; | 1725 break; |
| 1656 } | 1726 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1734 // starting processing or we may have just | 1804 // starting processing or we may have just |
| 1735 // closed a contour. | 1805 // closed a contour. |
| 1736 kAfterMove_SegmentState, // We have seen a move, but nothing else. | 1806 kAfterMove_SegmentState, // We have seen a move, but nothing else. |
| 1737 kAfterPrimitive_SegmentState // We have seen a primitive but not yet | 1807 kAfterPrimitive_SegmentState // We have seen a primitive but not yet |
| 1738 // closed the path. Also the initial state. | 1808 // closed the path. Also the initial state. |
| 1739 }; | 1809 }; |
| 1740 | 1810 |
| 1741 SkPath::Iter::Iter() { | 1811 SkPath::Iter::Iter() { |
| 1742 #ifdef SK_DEBUG | 1812 #ifdef SK_DEBUG |
| 1743 fPts = NULL; | 1813 fPts = NULL; |
| 1814 fConicWeights = NULL; |
| 1744 fMoveTo.fX = fMoveTo.fY = fLastPt.fX = fLastPt.fY = 0; | 1815 fMoveTo.fX = fMoveTo.fY = fLastPt.fX = fLastPt.fY = 0; |
| 1745 fForceClose = fCloseLine = false; | 1816 fForceClose = fCloseLine = false; |
| 1746 fSegmentState = kEmptyContour_SegmentState; | 1817 fSegmentState = kEmptyContour_SegmentState; |
| 1747 #endif | 1818 #endif |
| 1748 // need to init enough to make next() harmlessly return kDone_Verb | 1819 // need to init enough to make next() harmlessly return kDone_Verb |
| 1749 fVerbs = NULL; | 1820 fVerbs = NULL; |
| 1750 fVerbStop = NULL; | 1821 fVerbStop = NULL; |
| 1751 fNeedClose = false; | 1822 fNeedClose = false; |
| 1752 } | 1823 } |
| 1753 | 1824 |
| 1754 SkPath::Iter::Iter(const SkPath& path, bool forceClose) { | 1825 SkPath::Iter::Iter(const SkPath& path, bool forceClose) { |
| 1755 this->setPath(path, forceClose); | 1826 this->setPath(path, forceClose); |
| 1756 } | 1827 } |
| 1757 | 1828 |
| 1758 void SkPath::Iter::setPath(const SkPath& path, bool forceClose) { | 1829 void SkPath::Iter::setPath(const SkPath& path, bool forceClose) { |
| 1759 fPts = path.fPathRef->points(); | 1830 fPts = path.fPathRef->points(); |
| 1760 fVerbs = path.fPathRef->verbs(); | 1831 fVerbs = path.fPathRef->verbs(); |
| 1761 fVerbStop = path.fPathRef->verbsMemBegin(); | 1832 fVerbStop = path.fPathRef->verbsMemBegin(); |
| 1833 fConicWeights = path.fPathRef->conicWeights() - 1; // begin one behind |
| 1762 fLastPt.fX = fLastPt.fY = 0; | 1834 fLastPt.fX = fLastPt.fY = 0; |
| 1763 fMoveTo.fX = fMoveTo.fY = 0; | 1835 fMoveTo.fX = fMoveTo.fY = 0; |
| 1764 fForceClose = SkToU8(forceClose); | 1836 fForceClose = SkToU8(forceClose); |
| 1765 fNeedClose = false; | 1837 fNeedClose = false; |
| 1766 fSegmentState = kEmptyContour_SegmentState; | 1838 fSegmentState = kEmptyContour_SegmentState; |
| 1767 } | 1839 } |
| 1768 | 1840 |
| 1769 bool SkPath::Iter::isClosedContour() const { | 1841 bool SkPath::Iter::isClosedContour() const { |
| 1770 if (fVerbs == NULL || fVerbs == fVerbStop) { | 1842 if (fVerbs == NULL || fVerbs == fVerbStop) { |
| 1771 return false; | 1843 return false; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1863 fPts = lastMovePt; | 1935 fPts = lastMovePt; |
| 1864 return; | 1936 return; |
| 1865 } | 1937 } |
| 1866 return; | 1938 return; |
| 1867 } | 1939 } |
| 1868 // Ignore this line and continue | 1940 // Ignore this line and continue |
| 1869 fVerbs--; | 1941 fVerbs--; |
| 1870 fPts++; | 1942 fPts++; |
| 1871 break; | 1943 break; |
| 1872 | 1944 |
| 1945 case kConic_Verb: |
| 1873 case kQuad_Verb: | 1946 case kQuad_Verb: |
| 1874 if (!IsQuadDegenerate(lastPt, fPts[0], fPts[1])) { | 1947 if (!IsQuadDegenerate(lastPt, fPts[0], fPts[1])) { |
| 1875 if (lastMoveVerb) { | 1948 if (lastMoveVerb) { |
| 1876 fVerbs = lastMoveVerb; | 1949 fVerbs = lastMoveVerb; |
| 1877 fPts = lastMovePt; | 1950 fPts = lastMovePt; |
| 1878 return; | 1951 return; |
| 1879 } | 1952 } |
| 1880 return; | 1953 return; |
| 1881 } | 1954 } |
| 1882 // Ignore this line and continue | 1955 // Ignore this line and continue |
| 1883 fVerbs--; | 1956 fVerbs--; |
| 1884 fPts += 2; | 1957 fPts += 2; |
| 1958 fConicWeights += (kConic_Verb == verb); |
| 1885 break; | 1959 break; |
| 1886 | 1960 |
| 1887 case kCubic_Verb: | 1961 case kCubic_Verb: |
| 1888 if (!IsCubicDegenerate(lastPt, fPts[0], fPts[1], fPts[2])) { | 1962 if (!IsCubicDegenerate(lastPt, fPts[0], fPts[1], fPts[2])) { |
| 1889 if (lastMoveVerb) { | 1963 if (lastMoveVerb) { |
| 1890 fVerbs = lastMoveVerb; | 1964 fVerbs = lastMoveVerb; |
| 1891 fPts = lastMovePt; | 1965 fPts = lastMovePt; |
| 1892 return; | 1966 return; |
| 1893 } | 1967 } |
| 1894 return; | 1968 return; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1944 fLastPt = fMoveTo; | 2018 fLastPt = fMoveTo; |
| 1945 fNeedClose = fForceClose; | 2019 fNeedClose = fForceClose; |
| 1946 break; | 2020 break; |
| 1947 case kLine_Verb: | 2021 case kLine_Verb: |
| 1948 pts[0] = this->cons_moveTo(); | 2022 pts[0] = this->cons_moveTo(); |
| 1949 pts[1] = srcPts[0]; | 2023 pts[1] = srcPts[0]; |
| 1950 fLastPt = srcPts[0]; | 2024 fLastPt = srcPts[0]; |
| 1951 fCloseLine = false; | 2025 fCloseLine = false; |
| 1952 srcPts += 1; | 2026 srcPts += 1; |
| 1953 break; | 2027 break; |
| 2028 case kConic_Verb: |
| 2029 fConicWeights += 1; |
| 2030 // fall-through |
| 1954 case kQuad_Verb: | 2031 case kQuad_Verb: |
| 1955 pts[0] = this->cons_moveTo(); | 2032 pts[0] = this->cons_moveTo(); |
| 1956 memcpy(&pts[1], srcPts, 2 * sizeof(SkPoint)); | 2033 memcpy(&pts[1], srcPts, 2 * sizeof(SkPoint)); |
| 1957 fLastPt = srcPts[1]; | 2034 fLastPt = srcPts[1]; |
| 1958 srcPts += 2; | 2035 srcPts += 2; |
| 1959 break; | 2036 break; |
| 1960 case kCubic_Verb: | 2037 case kCubic_Verb: |
| 1961 pts[0] = this->cons_moveTo(); | 2038 pts[0] = this->cons_moveTo(); |
| 1962 memcpy(&pts[1], srcPts, 3 * sizeof(SkPoint)); | 2039 memcpy(&pts[1], srcPts, 3 * sizeof(SkPoint)); |
| 1963 fLastPt = srcPts[2]; | 2040 fLastPt = srcPts[2]; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1976 } | 2053 } |
| 1977 fPts = srcPts; | 2054 fPts = srcPts; |
| 1978 return (Verb)verb; | 2055 return (Verb)verb; |
| 1979 } | 2056 } |
| 1980 | 2057 |
| 1981 /////////////////////////////////////////////////////////////////////////////// | 2058 /////////////////////////////////////////////////////////////////////////////// |
| 1982 | 2059 |
| 1983 SkPath::RawIter::RawIter() { | 2060 SkPath::RawIter::RawIter() { |
| 1984 #ifdef SK_DEBUG | 2061 #ifdef SK_DEBUG |
| 1985 fPts = NULL; | 2062 fPts = NULL; |
| 2063 fConicWeights = NULL; |
| 1986 fMoveTo.fX = fMoveTo.fY = fLastPt.fX = fLastPt.fY = 0; | 2064 fMoveTo.fX = fMoveTo.fY = fLastPt.fX = fLastPt.fY = 0; |
| 1987 #endif | 2065 #endif |
| 1988 // need to init enough to make next() harmlessly return kDone_Verb | 2066 // need to init enough to make next() harmlessly return kDone_Verb |
| 1989 fVerbs = NULL; | 2067 fVerbs = NULL; |
| 1990 fVerbStop = NULL; | 2068 fVerbStop = NULL; |
| 1991 } | 2069 } |
| 1992 | 2070 |
| 1993 SkPath::RawIter::RawIter(const SkPath& path) { | 2071 SkPath::RawIter::RawIter(const SkPath& path) { |
| 1994 this->setPath(path); | 2072 this->setPath(path); |
| 1995 } | 2073 } |
| 1996 | 2074 |
| 1997 void SkPath::RawIter::setPath(const SkPath& path) { | 2075 void SkPath::RawIter::setPath(const SkPath& path) { |
| 1998 fPts = path.fPathRef->points(); | 2076 fPts = path.fPathRef->points(); |
| 1999 fVerbs = path.fPathRef->verbs(); | 2077 fVerbs = path.fPathRef->verbs(); |
| 2000 fVerbStop = path.fPathRef->verbsMemBegin(); | 2078 fVerbStop = path.fPathRef->verbsMemBegin(); |
| 2079 fConicWeights = path.fPathRef->conicWeights() - 1; // begin one behind |
| 2001 fMoveTo.fX = fMoveTo.fY = 0; | 2080 fMoveTo.fX = fMoveTo.fY = 0; |
| 2002 fLastPt.fX = fLastPt.fY = 0; | 2081 fLastPt.fX = fLastPt.fY = 0; |
| 2003 } | 2082 } |
| 2004 | 2083 |
| 2005 SkPath::Verb SkPath::RawIter::next(SkPoint pts[4]) { | 2084 SkPath::Verb SkPath::RawIter::next(SkPoint pts[4]) { |
| 2006 SkASSERT(NULL != pts); | 2085 SkASSERT(NULL != pts); |
| 2007 if (fVerbs == fVerbStop) { | 2086 if (fVerbs == fVerbStop) { |
| 2008 return kDone_Verb; | 2087 return kDone_Verb; |
| 2009 } | 2088 } |
| 2010 | 2089 |
| 2011 // fVerbs points one beyond next verb so decrement first. | 2090 // fVerbs points one beyond next verb so decrement first. |
| 2012 unsigned verb = *(--fVerbs); | 2091 unsigned verb = *(--fVerbs); |
| 2013 const SkPoint* srcPts = fPts; | 2092 const SkPoint* srcPts = fPts; |
| 2014 | 2093 |
| 2015 switch (verb) { | 2094 switch (verb) { |
| 2016 case kMove_Verb: | 2095 case kMove_Verb: |
| 2017 pts[0] = *srcPts; | 2096 pts[0] = *srcPts; |
| 2018 fMoveTo = srcPts[0]; | 2097 fMoveTo = srcPts[0]; |
| 2019 fLastPt = fMoveTo; | 2098 fLastPt = fMoveTo; |
| 2020 srcPts += 1; | 2099 srcPts += 1; |
| 2021 break; | 2100 break; |
| 2022 case kLine_Verb: | 2101 case kLine_Verb: |
| 2023 pts[0] = fLastPt; | 2102 pts[0] = fLastPt; |
| 2024 pts[1] = srcPts[0]; | 2103 pts[1] = srcPts[0]; |
| 2025 fLastPt = srcPts[0]; | 2104 fLastPt = srcPts[0]; |
| 2026 srcPts += 1; | 2105 srcPts += 1; |
| 2027 break; | 2106 break; |
| 2107 case kConic_Verb: |
| 2108 fConicWeights += 1; |
| 2109 // fall-through |
| 2028 case kQuad_Verb: | 2110 case kQuad_Verb: |
| 2029 pts[0] = fLastPt; | 2111 pts[0] = fLastPt; |
| 2030 memcpy(&pts[1], srcPts, 2 * sizeof(SkPoint)); | 2112 memcpy(&pts[1], srcPts, 2 * sizeof(SkPoint)); |
| 2031 fLastPt = srcPts[1]; | 2113 fLastPt = srcPts[1]; |
| 2032 srcPts += 2; | 2114 srcPts += 2; |
| 2033 break; | 2115 break; |
| 2034 case kCubic_Verb: | 2116 case kCubic_Verb: |
| 2035 pts[0] = fLastPt; | 2117 pts[0] = fLastPt; |
| 2036 memcpy(&pts[1], srcPts, 3 * sizeof(SkPoint)); | 2118 memcpy(&pts[1], srcPts, 3 * sizeof(SkPoint)); |
| 2037 fLastPt = srcPts[2]; | 2119 fLastPt = srcPts[2]; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2050 | 2132 |
| 2051 /* | 2133 /* |
| 2052 Format in compressed buffer: [ptCount, verbCount, pts[], verbs[]] | 2134 Format in compressed buffer: [ptCount, verbCount, pts[], verbs[]] |
| 2053 */ | 2135 */ |
| 2054 | 2136 |
| 2055 uint32_t SkPath::writeToMemory(void* storage) const { | 2137 uint32_t SkPath::writeToMemory(void* storage) const { |
| 2056 SkDEBUGCODE(this->validate();) | 2138 SkDEBUGCODE(this->validate();) |
| 2057 | 2139 |
| 2058 if (NULL == storage) { | 2140 if (NULL == storage) { |
| 2059 const int byteCount = sizeof(int32_t) | 2141 const int byteCount = sizeof(int32_t) |
| 2060 #if NEW_PICTURE_FORMAT | |
| 2061 + fPathRef->writeSize() | 2142 + fPathRef->writeSize() |
| 2062 #else | |
| 2063 + 2 * sizeof(int32_t) | |
| 2064 + sizeof(SkPoint) * fPathRef->countPoints() | |
| 2065 + sizeof(uint8_t) * fPathRef->countVerbs() | |
| 2066 #endif | |
| 2067 + sizeof(SkRect); | 2143 + sizeof(SkRect); |
| 2068 return SkAlign4(byteCount); | 2144 return SkAlign4(byteCount); |
| 2069 } | 2145 } |
| 2070 | 2146 |
| 2071 SkWBuffer buffer(storage); | 2147 SkWBuffer buffer(storage); |
| 2072 #if !NEW_PICTURE_FORMAT | |
| 2073 buffer.write32(fPathRef->countPoints()); | |
| 2074 buffer.write32(fPathRef->countVerbs()); | |
| 2075 #endif | |
| 2076 | 2148 |
| 2077 // Call getBounds() to ensure (as a side-effect) that fBounds | 2149 // Call getBounds() to ensure (as a side-effect) that fBounds |
| 2078 // and fIsFinite are computed. | 2150 // and fIsFinite are computed. |
| 2079 const SkRect& bounds = this->getBounds(); | 2151 const SkRect& bounds = this->getBounds(); |
| 2080 SkASSERT(!fBoundsIsDirty); | 2152 SkASSERT(!fBoundsIsDirty); |
| 2081 | 2153 |
| 2082 int32_t packed = ((fIsFinite & 1) << kIsFinite_SerializationShift) | | 2154 int32_t packed = ((fIsFinite & 1) << kIsFinite_SerializationShift) | |
| 2083 ((fIsOval & 1) << kIsOval_SerializationShift) | | 2155 ((fIsOval & 1) << kIsOval_SerializationShift) | |
| 2084 (fConvexity << kConvexity_SerializationShift) | | 2156 (fConvexity << kConvexity_SerializationShift) | |
| 2085 (fFillType << kFillType_SerializationShift) | | 2157 (fFillType << kFillType_SerializationShift) | |
| 2086 (fSegmentMask << kSegmentMask_SerializationShift) | | 2158 (fSegmentMask << kSegmentMask_SerializationShift) | |
| 2087 (fDirection << kDirection_SerializationShift); | 2159 (fDirection << kDirection_SerializationShift); |
| 2088 | 2160 |
| 2089 buffer.write32(packed); | 2161 buffer.write32(packed); |
| 2090 | 2162 |
| 2091 fPathRef->writeToBuffer(&buffer); | 2163 fPathRef->writeToBuffer(&buffer); |
| 2092 | 2164 |
| 2093 buffer.write(&bounds, sizeof(bounds)); | 2165 buffer.write(&bounds, sizeof(bounds)); |
| 2094 | 2166 |
| 2095 buffer.padToAlign4(); | 2167 buffer.padToAlign4(); |
| 2096 return SkToU32(buffer.pos()); | 2168 return SkToU32(buffer.pos()); |
| 2097 } | 2169 } |
| 2098 | 2170 |
| 2099 uint32_t SkPath::readFromMemory(const void* storage) { | 2171 uint32_t SkPath::readFromMemory(const void* storage) { |
| 2100 SkRBuffer buffer(storage); | 2172 SkRBuffer buffer(storage); |
| 2101 #if !NEW_PICTURE_FORMAT | |
| 2102 int32_t pcount = buffer.readS32(); | |
| 2103 int32_t vcount = buffer.readS32(); | |
| 2104 #endif | |
| 2105 | 2173 |
| 2106 uint32_t packed = buffer.readS32(); | 2174 uint32_t packed = buffer.readS32(); |
| 2107 fIsFinite = (packed >> kIsFinite_SerializationShift) & 1; | 2175 fIsFinite = (packed >> kIsFinite_SerializationShift) & 1; |
| 2108 fIsOval = (packed >> kIsOval_SerializationShift) & 1; | 2176 fIsOval = (packed >> kIsOval_SerializationShift) & 1; |
| 2109 fConvexity = (packed >> kConvexity_SerializationShift) & 0xFF; | 2177 fConvexity = (packed >> kConvexity_SerializationShift) & 0xFF; |
| 2110 fFillType = (packed >> kFillType_SerializationShift) & 0xFF; | 2178 fFillType = (packed >> kFillType_SerializationShift) & 0xFF; |
| 2111 fSegmentMask = (packed >> kSegmentMask_SerializationShift) & 0x7; | 2179 fSegmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF; |
| 2112 fDirection = (packed >> kDirection_SerializationShift) & 0x3; | 2180 fDirection = (packed >> kDirection_SerializationShift) & 0x3; |
| 2113 | 2181 |
| 2114 #if NEW_PICTURE_FORMAT | |
| 2115 fPathRef.reset(SkPathRef::CreateFromBuffer(&buffer)); | 2182 fPathRef.reset(SkPathRef::CreateFromBuffer(&buffer)); |
| 2116 #else | |
| 2117 fPathRef.reset(SkPathRef::CreateFromBuffer(vcount, pcount, &buffer)); | |
| 2118 #endif | |
| 2119 | 2183 |
| 2120 buffer.read(&fBounds, sizeof(fBounds)); | 2184 buffer.read(&fBounds, sizeof(fBounds)); |
| 2121 fBoundsIsDirty = false; | 2185 fBoundsIsDirty = false; |
| 2122 | 2186 |
| 2123 buffer.skipToAlign4(); | 2187 buffer.skipToAlign4(); |
| 2124 | 2188 |
| 2125 GEN_ID_INC; | 2189 GEN_ID_INC; |
| 2126 | 2190 |
| 2127 SkDEBUGCODE(this->validate();) | 2191 SkDEBUGCODE(this->validate();) |
| 2128 return SkToU32(buffer.pos()); | 2192 return SkToU32(buffer.pos()); |
| 2129 } | 2193 } |
| 2130 | 2194 |
| 2131 /////////////////////////////////////////////////////////////////////////////// | 2195 /////////////////////////////////////////////////////////////////////////////// |
| 2132 | 2196 |
| 2133 #include "SkString.h" | 2197 #include "SkString.h" |
| 2134 | 2198 |
| 2135 static void append_scalar(SkString* str, SkScalar value) { | 2199 static void append_scalar(SkString* str, SkScalar value) { |
| 2136 SkString tmp; | 2200 SkString tmp; |
| 2137 tmp.printf("%g", value); | 2201 tmp.printf("%g", value); |
| 2138 if (tmp.contains('.')) { | 2202 if (tmp.contains('.')) { |
| 2139 tmp.appendUnichar('f'); | 2203 tmp.appendUnichar('f'); |
| 2140 } | 2204 } |
| 2141 str->append(tmp); | 2205 str->append(tmp); |
| 2142 } | 2206 } |
| 2143 | 2207 |
| 2144 static void append_params(SkString* str, const char label[], const SkPoint pts[]
, | 2208 static void append_params(SkString* str, const char label[], const SkPoint pts[]
, |
| 2145 int count) { | 2209 int count, SkScalar conicWeight = -1) { |
| 2146 str->append(label); | 2210 str->append(label); |
| 2147 str->append("("); | 2211 str->append("("); |
| 2148 | 2212 |
| 2149 const SkScalar* values = &pts[0].fX; | 2213 const SkScalar* values = &pts[0].fX; |
| 2150 count *= 2; | 2214 count *= 2; |
| 2151 | 2215 |
| 2152 for (int i = 0; i < count; ++i) { | 2216 for (int i = 0; i < count; ++i) { |
| 2153 append_scalar(str, values[i]); | 2217 append_scalar(str, values[i]); |
| 2154 if (i < count - 1) { | 2218 if (i < count - 1) { |
| 2155 str->append(", "); | 2219 str->append(", "); |
| 2156 } | 2220 } |
| 2157 } | 2221 } |
| 2222 if (conicWeight >= 0) { |
| 2223 str->append(", "); |
| 2224 append_scalar(str, conicWeight); |
| 2225 } |
| 2158 str->append(");\n"); | 2226 str->append(");\n"); |
| 2159 } | 2227 } |
| 2160 | 2228 |
| 2161 void SkPath::dump(bool forceClose, const char title[]) const { | 2229 void SkPath::dump(bool forceClose, const char title[]) const { |
| 2162 Iter iter(*this, forceClose); | 2230 Iter iter(*this, forceClose); |
| 2163 SkPoint pts[4]; | 2231 SkPoint pts[4]; |
| 2164 Verb verb; | 2232 Verb verb; |
| 2165 | 2233 |
| 2166 SkDebugf("path: forceClose=%s %s\n", forceClose ? "true" : "false", | 2234 SkDebugf("path: forceClose=%s %s\n", forceClose ? "true" : "false", |
| 2167 title ? title : ""); | 2235 title ? title : ""); |
| 2168 | 2236 |
| 2169 SkString builder; | 2237 SkString builder; |
| 2170 | 2238 |
| 2171 while ((verb = iter.next(pts, false)) != kDone_Verb) { | 2239 while ((verb = iter.next(pts, false)) != kDone_Verb) { |
| 2172 switch (verb) { | 2240 switch (verb) { |
| 2173 case kMove_Verb: | 2241 case kMove_Verb: |
| 2174 append_params(&builder, "path.moveTo", &pts[0], 1); | 2242 append_params(&builder, "path.moveTo", &pts[0], 1); |
| 2175 break; | 2243 break; |
| 2176 case kLine_Verb: | 2244 case kLine_Verb: |
| 2177 append_params(&builder, "path.lineTo", &pts[1], 1); | 2245 append_params(&builder, "path.lineTo", &pts[1], 1); |
| 2178 append_params(&builder, "path.lineTo", &pts[1], 1); | 2246 append_params(&builder, "path.lineTo", &pts[1], 1); |
| 2179 break; | 2247 break; |
| 2180 case kQuad_Verb: | 2248 case kQuad_Verb: |
| 2181 append_params(&builder, "path.quadTo", &pts[1], 2); | 2249 append_params(&builder, "path.quadTo", &pts[1], 2); |
| 2182 break; | 2250 break; |
| 2251 case kConic_Verb: |
| 2252 append_params(&builder, "path.conicTo", &pts[1], 2, iter.conicWe
ight()); |
| 2253 break; |
| 2183 case kCubic_Verb: | 2254 case kCubic_Verb: |
| 2184 append_params(&builder, "path.cubicTo", &pts[1], 3); | 2255 append_params(&builder, "path.cubicTo", &pts[1], 3); |
| 2185 break; | 2256 break; |
| 2186 case kClose_Verb: | 2257 case kClose_Verb: |
| 2187 builder.append("path.close();\n"); | 2258 builder.append("path.close();\n"); |
| 2188 break; | 2259 break; |
| 2189 default: | 2260 default: |
| 2190 SkDebugf(" path: UNKNOWN VERB %d, aborting dump...\n", verb); | 2261 SkDebugf(" path: UNKNOWN VERB %d, aborting dump...\n", verb); |
| 2191 verb = kDone_Verb; // stop the loop | 2262 verb = kDone_Verb; // stop the loop |
| 2192 break; | 2263 break; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 uint32_t mask = 0; | 2303 uint32_t mask = 0; |
| 2233 const uint8_t* verbs = const_cast<const SkPathRef*>(fPathRef.get())->verbs()
; | 2304 const uint8_t* verbs = const_cast<const SkPathRef*>(fPathRef.get())->verbs()
; |
| 2234 for (int i = 0; i < fPathRef->countVerbs(); i++) { | 2305 for (int i = 0; i < fPathRef->countVerbs(); i++) { |
| 2235 switch (verbs[~i]) { | 2306 switch (verbs[~i]) { |
| 2236 case kLine_Verb: | 2307 case kLine_Verb: |
| 2237 mask |= kLine_SegmentMask; | 2308 mask |= kLine_SegmentMask; |
| 2238 break; | 2309 break; |
| 2239 case kQuad_Verb: | 2310 case kQuad_Verb: |
| 2240 mask |= kQuad_SegmentMask; | 2311 mask |= kQuad_SegmentMask; |
| 2241 break; | 2312 break; |
| 2313 case kConic_Verb: |
| 2314 mask |= kConic_SegmentMask; |
| 2315 break; |
| 2242 case kCubic_Verb: | 2316 case kCubic_Verb: |
| 2243 mask |= kCubic_SegmentMask; | 2317 mask |= kCubic_SegmentMask; |
| 2244 case kMove_Verb: // these verbs aren't included in the segment mask
. | 2318 case kMove_Verb: // these verbs aren't included in the segment mask
. |
| 2245 case kClose_Verb: | 2319 case kClose_Verb: |
| 2246 break; | 2320 break; |
| 2247 case kDone_Verb: | 2321 case kDone_Verb: |
| 2248 SkDEBUGFAIL("Done verb shouldn't be recorded."); | 2322 SkDEBUGFAIL("Done verb shouldn't be recorded."); |
| 2249 break; | 2323 break; |
| 2250 default: | 2324 default: |
| 2251 SkDEBUGFAIL("Unknown Verb"); | 2325 SkDEBUGFAIL("Unknown Verb"); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2372 case kMove_Verb: | 2446 case kMove_Verb: |
| 2373 if (++contourCount > 1) { | 2447 if (++contourCount > 1) { |
| 2374 fConvexity = kConcave_Convexity; | 2448 fConvexity = kConcave_Convexity; |
| 2375 return kConcave_Convexity; | 2449 return kConcave_Convexity; |
| 2376 } | 2450 } |
| 2377 pts[1] = pts[0]; | 2451 pts[1] = pts[0]; |
| 2378 count = 1; | 2452 count = 1; |
| 2379 break; | 2453 break; |
| 2380 case kLine_Verb: count = 1; break; | 2454 case kLine_Verb: count = 1; break; |
| 2381 case kQuad_Verb: count = 2; break; | 2455 case kQuad_Verb: count = 2; break; |
| 2456 case kConic_Verb: count = 2; break; |
| 2382 case kCubic_Verb: count = 3; break; | 2457 case kCubic_Verb: count = 3; break; |
| 2383 case kClose_Verb: | 2458 case kClose_Verb: |
| 2384 state.close(); | 2459 state.close(); |
| 2385 count = 0; | 2460 count = 0; |
| 2386 break; | 2461 break; |
| 2387 default: | 2462 default: |
| 2388 SkDEBUGFAIL("bad verb"); | 2463 SkDEBUGFAIL("bad verb"); |
| 2389 fConvexity = kConcave_Convexity; | 2464 fConvexity = kConcave_Convexity; |
| 2390 return kConcave_Convexity; | 2465 return kConcave_Convexity; |
| 2391 } | 2466 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2416 // if !done() then these may be called | 2491 // if !done() then these may be called |
| 2417 int count() const { return fCurrPtCount; } | 2492 int count() const { return fCurrPtCount; } |
| 2418 const SkPoint* pts() const { return fCurrPt; } | 2493 const SkPoint* pts() const { return fCurrPt; } |
| 2419 void next(); | 2494 void next(); |
| 2420 | 2495 |
| 2421 private: | 2496 private: |
| 2422 int fCurrPtCount; | 2497 int fCurrPtCount; |
| 2423 const SkPoint* fCurrPt; | 2498 const SkPoint* fCurrPt; |
| 2424 const uint8_t* fCurrVerb; | 2499 const uint8_t* fCurrVerb; |
| 2425 const uint8_t* fStopVerbs; | 2500 const uint8_t* fStopVerbs; |
| 2501 const SkScalar* fCurrConicWeight; |
| 2426 bool fDone; | 2502 bool fDone; |
| 2427 SkDEBUGCODE(int fContourCounter;) | 2503 SkDEBUGCODE(int fContourCounter;) |
| 2428 }; | 2504 }; |
| 2429 | 2505 |
| 2430 ContourIter::ContourIter(const SkPathRef& pathRef) { | 2506 ContourIter::ContourIter(const SkPathRef& pathRef) { |
| 2431 fStopVerbs = pathRef.verbsMemBegin(); | 2507 fStopVerbs = pathRef.verbsMemBegin(); |
| 2432 fDone = false; | 2508 fDone = false; |
| 2433 fCurrPt = pathRef.points(); | 2509 fCurrPt = pathRef.points(); |
| 2434 fCurrVerb = pathRef.verbs(); | 2510 fCurrVerb = pathRef.verbs(); |
| 2511 fCurrConicWeight = pathRef.conicWeights(); |
| 2435 fCurrPtCount = 0; | 2512 fCurrPtCount = 0; |
| 2436 SkDEBUGCODE(fContourCounter = 0;) | 2513 SkDEBUGCODE(fContourCounter = 0;) |
| 2437 this->next(); | 2514 this->next(); |
| 2438 } | 2515 } |
| 2439 | 2516 |
| 2440 void ContourIter::next() { | 2517 void ContourIter::next() { |
| 2441 if (fCurrVerb <= fStopVerbs) { | 2518 if (fCurrVerb <= fStopVerbs) { |
| 2442 fDone = true; | 2519 fDone = true; |
| 2443 } | 2520 } |
| 2444 if (fDone) { | 2521 if (fDone) { |
| 2445 return; | 2522 return; |
| 2446 } | 2523 } |
| 2447 | 2524 |
| 2448 // skip pts of prev contour | 2525 // skip pts of prev contour |
| 2449 fCurrPt += fCurrPtCount; | 2526 fCurrPt += fCurrPtCount; |
| 2450 | 2527 |
| 2451 SkASSERT(SkPath::kMove_Verb == fCurrVerb[~0]); | 2528 SkASSERT(SkPath::kMove_Verb == fCurrVerb[~0]); |
| 2452 int ptCount = 1; // moveTo | 2529 int ptCount = 1; // moveTo |
| 2453 const uint8_t* verbs = fCurrVerb; | 2530 const uint8_t* verbs = fCurrVerb; |
| 2454 | 2531 |
| 2455 for (--verbs; verbs > fStopVerbs; --verbs) { | 2532 for (--verbs; verbs > fStopVerbs; --verbs) { |
| 2456 switch (verbs[~0]) { | 2533 switch (verbs[~0]) { |
| 2457 case SkPath::kMove_Verb: | 2534 case SkPath::kMove_Verb: |
| 2458 goto CONTOUR_END; | 2535 goto CONTOUR_END; |
| 2459 case SkPath::kLine_Verb: | 2536 case SkPath::kLine_Verb: |
| 2460 ptCount += 1; | 2537 ptCount += 1; |
| 2461 break; | 2538 break; |
| 2539 case SkPath::kConic_Verb: |
| 2540 fCurrConicWeight += 1; |
| 2541 // fall-through |
| 2462 case SkPath::kQuad_Verb: | 2542 case SkPath::kQuad_Verb: |
| 2463 ptCount += 2; | 2543 ptCount += 2; |
| 2464 break; | 2544 break; |
| 2465 case SkPath::kCubic_Verb: | 2545 case SkPath::kCubic_Verb: |
| 2466 ptCount += 3; | 2546 ptCount += 3; |
| 2467 break; | 2547 break; |
| 2468 default: // kClose_Verb, just keep going | 2548 case SkPath::kClose_Verb: |
| 2549 break; |
| 2550 default: |
| 2551 SkASSERT(!"unexpected verb"); |
| 2469 break; | 2552 break; |
| 2470 } | 2553 } |
| 2471 } | 2554 } |
| 2472 CONTOUR_END: | 2555 CONTOUR_END: |
| 2473 fCurrPtCount = ptCount; | 2556 fCurrPtCount = ptCount; |
| 2474 fCurrVerb = verbs; | 2557 fCurrVerb = verbs; |
| 2475 SkDEBUGCODE(++fContourCounter;) | 2558 SkDEBUGCODE(++fContourCounter;) |
| 2476 } | 2559 } |
| 2477 | 2560 |
| 2478 // returns cross product of (p1 - p0) and (p2 - p0) | 2561 // returns cross product of (p1 - p0) and (p2 - p0) |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2950 switch (iter.next(pts, false)) { | 3033 switch (iter.next(pts, false)) { |
| 2951 case SkPath::kMove_Verb: | 3034 case SkPath::kMove_Verb: |
| 2952 case SkPath::kClose_Verb: | 3035 case SkPath::kClose_Verb: |
| 2953 break; | 3036 break; |
| 2954 case SkPath::kLine_Verb: | 3037 case SkPath::kLine_Verb: |
| 2955 w += winding_line(pts, x, y); | 3038 w += winding_line(pts, x, y); |
| 2956 break; | 3039 break; |
| 2957 case SkPath::kQuad_Verb: | 3040 case SkPath::kQuad_Verb: |
| 2958 w += winding_quad(pts, x, y); | 3041 w += winding_quad(pts, x, y); |
| 2959 break; | 3042 break; |
| 3043 case SkPath::kConic_Verb: |
| 3044 SkASSERT(0); |
| 3045 break; |
| 2960 case SkPath::kCubic_Verb: | 3046 case SkPath::kCubic_Verb: |
| 2961 w += winding_cubic(pts, x, y); | 3047 w += winding_cubic(pts, x, y); |
| 2962 break; | 3048 break; |
| 2963 case SkPath::kDone_Verb: | 3049 case SkPath::kDone_Verb: |
| 2964 done = true; | 3050 done = true; |
| 2965 break; | 3051 break; |
| 2966 } | 3052 } |
| 2967 } while (!done); | 3053 } while (!done); |
| 2968 | 3054 |
| 2969 switch (this->getFillType()) { | 3055 switch (this->getFillType()) { |
| 2970 case SkPath::kEvenOdd_FillType: | 3056 case SkPath::kEvenOdd_FillType: |
| 2971 case SkPath::kInverseEvenOdd_FillType: | 3057 case SkPath::kInverseEvenOdd_FillType: |
| 2972 w &= 1; | 3058 w &= 1; |
| 2973 break; | 3059 break; |
| 2974 default: | 3060 default: |
| 2975 break; | 3061 break; |
| 2976 } | 3062 } |
| 2977 return SkToBool(w); | 3063 return SkToBool(w); |
| 2978 } | 3064 } |
| OLD | NEW |