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

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

Issue 137863006: Revert of r13379 (Move fLastMoveToIndex from SkPath to SkPathRef) (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 6 years, 10 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 | « include/core/SkPathRef.h ('k') | src/core/SkPathRef.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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 115
116 The iterator does more cleanup, especially if forceClose == true 116 The iterator does more cleanup, especially if forceClose == true
117 1. If we encounter degenerate segments, remove them 117 1. If we encounter degenerate segments, remove them
118 2. if we encounter Close, return a cons'd up Line() first (if the curr-pt != start-pt) 118 2. if we encounter Close, return a cons'd up Line() first (if the curr-pt != start-pt)
119 3. if we encounter Move without a preceeding Close, and forceClose is true, goto #2 119 3. if we encounter Move without a preceeding Close, and forceClose is true, goto #2
120 4. if we encounter Line | Quad | Cubic after Close, cons up a Move 120 4. if we encounter Line | Quad | Cubic after Close, cons up a Move
121 */ 121 */
122 122
123 //////////////////////////////////////////////////////////////////////////// 123 ////////////////////////////////////////////////////////////////////////////
124 124
125 // flag to require a moveTo if we begin with something else, like lineTo etc.
126 #define INITIAL_LASTMOVETOINDEX_VALUE ~0
127
125 SkPath::SkPath() 128 SkPath::SkPath()
126 : fPathRef(SkPathRef::CreateEmpty()) 129 : fPathRef(SkPathRef::CreateEmpty())
127 #ifdef SK_BUILD_FOR_ANDROID 130 #ifdef SK_BUILD_FOR_ANDROID
128 , fSourcePath(NULL) 131 , fSourcePath(NULL)
129 #endif 132 #endif
130 { 133 {
131 this->resetFields(); 134 this->resetFields();
132 } 135 }
133 136
134 void SkPath::resetFields() { 137 void SkPath::resetFields() {
135 //fPathRef is assumed to have been emptied by the caller. 138 //fPathRef is assumed to have been emptied by the caller.
139 fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE;
136 fFillType = kWinding_FillType; 140 fFillType = kWinding_FillType;
137 fConvexity = kUnknown_Convexity; 141 fConvexity = kUnknown_Convexity;
138 fDirection = kUnknown_Direction; 142 fDirection = kUnknown_Direction;
139 143
140 // We don't touch Android's fSourcePath. It's used to track texture garbage collection, so we 144 // We don't touch Android's fSourcePath. It's used to track texture garbage collection, so we
141 // don't want to muck with it if it's been set to something non-NULL. 145 // don't want to muck with it if it's been set to something non-NULL.
142 } 146 }
143 147
144 SkPath::SkPath(const SkPath& that) 148 SkPath::SkPath(const SkPath& that)
145 : fPathRef(SkRef(that.fPathRef.get())) { 149 : fPathRef(SkRef(that.fPathRef.get())) {
(...skipping 17 matching lines...) Expand all
163 #ifdef SK_BUILD_FOR_ANDROID 167 #ifdef SK_BUILD_FOR_ANDROID
164 fSourcePath = that.fSourcePath; 168 fSourcePath = that.fSourcePath;
165 #endif 169 #endif
166 } 170 }
167 SkDEBUGCODE(this->validate();) 171 SkDEBUGCODE(this->validate();)
168 return *this; 172 return *this;
169 } 173 }
170 174
171 void SkPath::copyFields(const SkPath& that) { 175 void SkPath::copyFields(const SkPath& that) {
172 //fPathRef is assumed to have been set by the caller. 176 //fPathRef is assumed to have been set by the caller.
177 fLastMoveToIndex = that.fLastMoveToIndex;
173 fFillType = that.fFillType; 178 fFillType = that.fFillType;
174 fConvexity = that.fConvexity; 179 fConvexity = that.fConvexity;
175 fDirection = that.fDirection; 180 fDirection = that.fDirection;
176 } 181 }
177 182
178 bool operator==(const SkPath& a, const SkPath& b) { 183 bool operator==(const SkPath& a, const SkPath& b) {
179 // note: don't need to look at isConvex or bounds, since just comparing the 184 // note: don't need to look at isConvex or bounds, since just comparing the
180 // raw data is sufficient. 185 // raw data is sufficient.
181 return &a == &b || 186 return &a == &b ||
182 (a.fFillType == b.fFillType && *a.fPathRef.get() == *b.fPathRef.get()); 187 (a.fFillType == b.fFillType && *a.fPathRef.get() == *b.fPathRef.get());
183 } 188 }
184 189
185 void SkPath::swap(SkPath& that) { 190 void SkPath::swap(SkPath& that) {
186 SkASSERT(&that != NULL); 191 SkASSERT(&that != NULL);
187 192
188 if (this != &that) { 193 if (this != &that) {
189 fPathRef.swap(&that.fPathRef); 194 fPathRef.swap(&that.fPathRef);
195 SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex);
190 SkTSwap<uint8_t>(fFillType, that.fFillType); 196 SkTSwap<uint8_t>(fFillType, that.fFillType);
191 SkTSwap<uint8_t>(fConvexity, that.fConvexity); 197 SkTSwap<uint8_t>(fConvexity, that.fConvexity);
192 SkTSwap<uint8_t>(fDirection, that.fDirection); 198 SkTSwap<uint8_t>(fDirection, that.fDirection);
193 #ifdef SK_BUILD_FOR_ANDROID 199 #ifdef SK_BUILD_FOR_ANDROID
194 SkTSwap<const SkPath*>(fSourcePath, that.fSourcePath); 200 SkTSwap<const SkPath*>(fSourcePath, that.fSourcePath);
195 #endif 201 #endif
196 } 202 }
197 } 203 }
198 204
199 static inline bool check_edge_against_rect(const SkPoint& p0, 205 static inline bool check_edge_against_rect(const SkPoint& p0,
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 SkDEBUGCODE(this->validate();) 660 SkDEBUGCODE(this->validate();)
655 SkPathRef::Editor(&fPathRef, inc, inc); 661 SkPathRef::Editor(&fPathRef, inc, inc);
656 SkDEBUGCODE(this->validate();) 662 SkDEBUGCODE(this->validate();)
657 } 663 }
658 664
659 void SkPath::moveTo(SkScalar x, SkScalar y) { 665 void SkPath::moveTo(SkScalar x, SkScalar y) {
660 SkDEBUGCODE(this->validate();) 666 SkDEBUGCODE(this->validate();)
661 667
662 SkPathRef::Editor ed(&fPathRef); 668 SkPathRef::Editor ed(&fPathRef);
663 669
670 // remember our index
671 fLastMoveToIndex = fPathRef->countPoints();
672
664 ed.growForVerb(kMove_Verb)->set(x, y); 673 ed.growForVerb(kMove_Verb)->set(x, y);
665 } 674 }
666 675
667 void SkPath::rMoveTo(SkScalar x, SkScalar y) { 676 void SkPath::rMoveTo(SkScalar x, SkScalar y) {
668 SkPoint pt; 677 SkPoint pt;
669 this->getLastPt(&pt); 678 this->getLastPt(&pt);
670 this->moveTo(pt.fX + x, pt.fY + y); 679 this->moveTo(pt.fX + x, pt.fY + y);
671 } 680 }
672 681
682 void SkPath::injectMoveToIfNeeded() {
683 if (fLastMoveToIndex < 0) {
684 SkScalar x, y;
685 if (fPathRef->countVerbs() == 0) {
686 x = y = 0;
687 } else {
688 const SkPoint& pt = fPathRef->atPoint(~fLastMoveToIndex);
689 x = pt.fX;
690 y = pt.fY;
691 }
692 this->moveTo(x, y);
693 }
694 }
695
673 void SkPath::lineTo(SkScalar x, SkScalar y) { 696 void SkPath::lineTo(SkScalar x, SkScalar y) {
674 SkDEBUGCODE(this->validate();) 697 SkDEBUGCODE(this->validate();)
675 698
699 this->injectMoveToIfNeeded();
700
676 SkPathRef::Editor ed(&fPathRef); 701 SkPathRef::Editor ed(&fPathRef);
677 ed.injectMoveToIfNeeded();
678 ed.growForVerb(kLine_Verb)->set(x, y); 702 ed.growForVerb(kLine_Verb)->set(x, y);
679 703
680 DIRTY_AFTER_EDIT; 704 DIRTY_AFTER_EDIT;
681 } 705 }
682 706
683 void SkPath::rLineTo(SkScalar x, SkScalar y) { 707 void SkPath::rLineTo(SkScalar x, SkScalar y) {
684 this->injectMoveToIfNeeded(); // This can change the result of this->getLas tPt(). 708 this->injectMoveToIfNeeded(); // This can change the result of this->getLas tPt().
685 SkPoint pt; 709 SkPoint pt;
686 this->getLastPt(&pt); 710 this->getLastPt(&pt);
687 this->lineTo(pt.fX + x, pt.fY + y); 711 this->lineTo(pt.fX + x, pt.fY + y);
688 } 712 }
689 713
690 void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) { 714 void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
691 SkDEBUGCODE(this->validate();) 715 SkDEBUGCODE(this->validate();)
692 716
717 this->injectMoveToIfNeeded();
718
693 SkPathRef::Editor ed(&fPathRef); 719 SkPathRef::Editor ed(&fPathRef);
694 ed.injectMoveToIfNeeded();
695 SkPoint* pts = ed.growForVerb(kQuad_Verb); 720 SkPoint* pts = ed.growForVerb(kQuad_Verb);
696 pts[0].set(x1, y1); 721 pts[0].set(x1, y1);
697 pts[1].set(x2, y2); 722 pts[1].set(x2, y2);
698 723
699 DIRTY_AFTER_EDIT; 724 DIRTY_AFTER_EDIT;
700 } 725 }
701 726
702 void SkPath::rQuadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) { 727 void SkPath::rQuadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
703 this->injectMoveToIfNeeded(); // This can change the result of this->getLas tPt(). 728 this->injectMoveToIfNeeded(); // This can change the result of this->getLas tPt().
704 SkPoint pt; 729 SkPoint pt;
705 this->getLastPt(&pt); 730 this->getLastPt(&pt);
706 this->quadTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2); 731 this->quadTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2);
707 } 732 }
708 733
709 void SkPath::conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, 734 void SkPath::conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
710 SkScalar w) { 735 SkScalar w) {
711 // check for <= 0 or NaN with this test 736 // check for <= 0 or NaN with this test
712 if (!(w > 0)) { 737 if (!(w > 0)) {
713 this->lineTo(x2, y2); 738 this->lineTo(x2, y2);
714 } else if (!SkScalarIsFinite(w)) { 739 } else if (!SkScalarIsFinite(w)) {
715 this->lineTo(x1, y1); 740 this->lineTo(x1, y1);
716 this->lineTo(x2, y2); 741 this->lineTo(x2, y2);
717 } else if (SK_Scalar1 == w) { 742 } else if (SK_Scalar1 == w) {
718 this->quadTo(x1, y1, x2, y2); 743 this->quadTo(x1, y1, x2, y2);
719 } else { 744 } else {
720 SkDEBUGCODE(this->validate();) 745 SkDEBUGCODE(this->validate();)
721 746
747 this->injectMoveToIfNeeded();
748
722 SkPathRef::Editor ed(&fPathRef); 749 SkPathRef::Editor ed(&fPathRef);
723 ed.injectMoveToIfNeeded();
724 SkPoint* pts = ed.growForVerb(kConic_Verb, w); 750 SkPoint* pts = ed.growForVerb(kConic_Verb, w);
725 pts[0].set(x1, y1); 751 pts[0].set(x1, y1);
726 pts[1].set(x2, y2); 752 pts[1].set(x2, y2);
727 753
728 DIRTY_AFTER_EDIT; 754 DIRTY_AFTER_EDIT;
729 } 755 }
730 } 756 }
731 757
732 void SkPath::rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2, 758 void SkPath::rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
733 SkScalar w) { 759 SkScalar w) {
734 this->injectMoveToIfNeeded(); // This can change the result of this->getLas tPt(). 760 this->injectMoveToIfNeeded(); // This can change the result of this->getLas tPt().
735 SkPoint pt; 761 SkPoint pt;
736 this->getLastPt(&pt); 762 this->getLastPt(&pt);
737 this->conicTo(pt.fX + dx1, pt.fY + dy1, pt.fX + dx2, pt.fY + dy2, w); 763 this->conicTo(pt.fX + dx1, pt.fY + dy1, pt.fX + dx2, pt.fY + dy2, w);
738 } 764 }
739 765
740 void SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, 766 void SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
741 SkScalar x3, SkScalar y3) { 767 SkScalar x3, SkScalar y3) {
742 SkDEBUGCODE(this->validate();) 768 SkDEBUGCODE(this->validate();)
743 769
770 this->injectMoveToIfNeeded();
771
744 SkPathRef::Editor ed(&fPathRef); 772 SkPathRef::Editor ed(&fPathRef);
745 ed.injectMoveToIfNeeded();
746 SkPoint* pts = ed.growForVerb(kCubic_Verb); 773 SkPoint* pts = ed.growForVerb(kCubic_Verb);
747 pts[0].set(x1, y1); 774 pts[0].set(x1, y1);
748 pts[1].set(x2, y2); 775 pts[1].set(x2, y2);
749 pts[2].set(x3, y3); 776 pts[2].set(x3, y3);
750 777
751 DIRTY_AFTER_EDIT; 778 DIRTY_AFTER_EDIT;
752 } 779 }
753 780
754 void SkPath::rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, 781 void SkPath::rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
755 SkScalar x3, SkScalar y3) { 782 SkScalar x3, SkScalar y3) {
(...skipping 20 matching lines...) Expand all
776 break; 803 break;
777 } 804 }
778 case kClose_Verb: 805 case kClose_Verb:
779 // don't add a close if it's the first verb or a repeat 806 // don't add a close if it's the first verb or a repeat
780 break; 807 break;
781 default: 808 default:
782 SkDEBUGFAIL("unexpected verb"); 809 SkDEBUGFAIL("unexpected verb");
783 break; 810 break;
784 } 811 }
785 } 812 }
813
814 // signal that we need a moveTo to follow us (unless we're done)
815 #if 0
816 if (fLastMoveToIndex >= 0) {
817 fLastMoveToIndex = ~fLastMoveToIndex;
818 }
819 #else
820 fLastMoveToIndex ^= ~fLastMoveToIndex >> (8 * sizeof(fLastMoveToIndex) - 1);
821 #endif
786 } 822 }
787 823
788 /////////////////////////////////////////////////////////////////////////////// 824 ///////////////////////////////////////////////////////////////////////////////
789 825
790 static void assert_known_direction(int dir) { 826 static void assert_known_direction(int dir) {
791 SkASSERT(SkPath::kCW_Direction == dir || SkPath::kCCW_Direction == dir); 827 SkASSERT(SkPath::kCW_Direction == dir || SkPath::kCCW_Direction == dir);
792 } 828 }
793 829
794 void SkPath::addRect(const SkRect& rect, Direction dir) { 830 void SkPath::addRect(const SkRect& rect, Direction dir) {
795 this->addRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, dir); 831 this->addRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, dir);
(...skipping 21 matching lines...) Expand all
817 } 853 }
818 this->close(); 854 this->close();
819 } 855 }
820 856
821 void SkPath::addPoly(const SkPoint pts[], int count, bool close) { 857 void SkPath::addPoly(const SkPoint pts[], int count, bool close) {
822 SkDEBUGCODE(this->validate();) 858 SkDEBUGCODE(this->validate();)
823 if (count <= 0) { 859 if (count <= 0) {
824 return; 860 return;
825 } 861 }
826 862
863 fLastMoveToIndex = fPathRef->countPoints();
864
827 // +close makes room for the extra kClose_Verb 865 // +close makes room for the extra kClose_Verb
828 SkPathRef::Editor ed(&fPathRef, count+close, count); 866 SkPathRef::Editor ed(&fPathRef, count+close, count);
829 867
830 ed.growForVerb(kMove_Verb)->set(pts[0].fX, pts[0].fY); 868 ed.growForVerb(kMove_Verb)->set(pts[0].fX, pts[0].fY);
831 if (count > 1) { 869 if (count > 1) {
832 SkPoint* p = ed.growForRepeatedVerb(kLine_Verb, count - 1); 870 SkPoint* p = ed.growForRepeatedVerb(kLine_Verb, count - 1);
833 memcpy(p, &pts[1], (count-1) * sizeof(SkPoint)); 871 memcpy(p, &pts[1], (count-1) * sizeof(SkPoint));
834 } 872 }
835 873
836 if (close) { 874 if (close) {
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 this->addOval(oval, sweepAngle > 0 ? kCW_Direction : kCCW_Direction); 1351 this->addOval(oval, sweepAngle > 0 ? kCW_Direction : kCCW_Direction);
1314 return; 1352 return;
1315 } 1353 }
1316 1354
1317 SkPoint pts[kSkBuildQuadArcStorage]; 1355 SkPoint pts[kSkBuildQuadArcStorage];
1318 int count = build_arc_points(oval, startAngle, sweepAngle, pts); 1356 int count = build_arc_points(oval, startAngle, sweepAngle, pts);
1319 1357
1320 SkDEBUGCODE(this->validate();) 1358 SkDEBUGCODE(this->validate();)
1321 SkASSERT(count & 1); 1359 SkASSERT(count & 1);
1322 1360
1361 fLastMoveToIndex = fPathRef->countPoints();
1362
1323 SkPathRef::Editor ed(&fPathRef, 1+(count-1)/2, count); 1363 SkPathRef::Editor ed(&fPathRef, 1+(count-1)/2, count);
1324 1364
1325 ed.growForVerb(kMove_Verb)->set(pts[0].fX, pts[0].fY); 1365 ed.growForVerb(kMove_Verb)->set(pts[0].fX, pts[0].fY);
1326 if (count > 1) { 1366 if (count > 1) {
1327 SkPoint* p = ed.growForRepeatedVerb(kQuad_Verb, (count-1)/2); 1367 SkPoint* p = ed.growForRepeatedVerb(kQuad_Verb, (count-1)/2);
1328 memcpy(p, &pts[1], (count-1) * sizeof(SkPoint)); 1368 memcpy(p, &pts[1], (count-1) * sizeof(SkPoint));
1329 } 1369 }
1330 1370
1331 DIRTY_AFTER_EDIT; 1371 DIRTY_AFTER_EDIT;
1332 SkDEBUGCODE(this->validate();) 1372 SkDEBUGCODE(this->validate();)
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after
2847 switch (this->getFillType()) { 2887 switch (this->getFillType()) {
2848 case SkPath::kEvenOdd_FillType: 2888 case SkPath::kEvenOdd_FillType:
2849 case SkPath::kInverseEvenOdd_FillType: 2889 case SkPath::kInverseEvenOdd_FillType:
2850 w &= 1; 2890 w &= 1;
2851 break; 2891 break;
2852 default: 2892 default:
2853 break; 2893 break;
2854 } 2894 }
2855 return SkToBool(w); 2895 return SkToBool(w);
2856 } 2896 }
OLDNEW
« no previous file with comments | « include/core/SkPathRef.h ('k') | src/core/SkPathRef.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698