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 |