Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: src/core/SkPath.cpp

Issue 16195004: add asserts to point<-->verb helpers (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/core/SkEdgeBuilder.cpp ('k') | src/core/SkPathMeasure.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/core/SkEdgeBuilder.cpp ('k') | src/core/SkPathMeasure.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698