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

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

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