blob: 7b117ebf41d4897e6ab55549efca5f35a365c8bb [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001#include "GrPath.h"
2
3GrPath::GrPath() {}
4
5GrPath::GrPath(const GrPath& src) {
6}
7
8GrPath::GrPath(GrPathIter& iter) {
9 this->resetFromIter(&iter);
10}
11
12GrPath::~GrPath() {
13}
14
15void GrPath::ensureMoveTo() {
16 if (fVerbs.isEmpty() || this->wasLastVerb(kClose)) {
17 *fVerbs.append() = kMove;
18 fPts.append()->set(0, 0);
19 }
20}
21
22void GrPath::moveTo(GrScalar x, GrScalar y) {
23 if (this->wasLastVerb(kMove)) {
24 // overwrite prev kMove value
25 fPts[fPts.count() - 1].set(x, y);
26 } else {
27 *fVerbs.append() = kMove;
28 fPts.append()->set(x, y);
29 }
30}
31
32void GrPath::lineTo(GrScalar x, GrScalar y) {
33 this->ensureMoveTo();
34 *fVerbs.append() = kLine;
35 fPts.append()->set(x, y);
36}
37
38void GrPath::quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1) {
39 this->ensureMoveTo();
40 *fVerbs.append() = kQuad;
41 fPts.append()->set(x0, y0);
42 fPts.append()->set(x1, y1);
43}
44
45void GrPath::cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
46 GrScalar x2, GrScalar y2) {
47 this->ensureMoveTo();
48 *fVerbs.append() = kCubic;
49 fPts.append()->set(x0, y0);
50 fPts.append()->set(x1, y1);
51 fPts.append()->set(x2, y2);
52}
53
54void GrPath::close() {
55 if (!fVerbs.isEmpty() && !this->wasLastVerb(kClose)) {
56 // should we allow kMove followed by kClose?
57 *fVerbs.append() = kClose;
58 }
59}
60
61///////////////////////////////////////////////////////////////////////////////
62
63void GrPath::resetFromIter(GrPathIter* iter) {
64 fPts.reset();
65 fVerbs.reset();
66
67 GrPoint pts[4];
68 GrPathIter::Command cmd;
69
70 while ((cmd = iter->next(pts)) != GrPathIter::kEnd_Command) {
71 switch (cmd) {
72 case GrPathIter::kMove_Command:
73 this->moveTo(pts[0].fX, pts[0].fY);
74 break;
75 case GrPathIter::kLine_Command:
76 this->lineTo(pts[1].fX, pts[1].fY);
77 break;
78 case GrPathIter::kQuadratic_Command:
79 this->quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
80 break;
81 case GrPathIter::kCubic_Command:
82 this->cubicTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY,
83 pts[3].fX, pts[3].fY);
84 break;
85 case GrPathIter::kClose_Command:
86 this->close();
87 break;
88 case GrPathIter::kEnd_Command:
89 // never get here, but include it to avoid the warning
90 break;
91 }
92 }
93}
94
95///////////////////////////////////////////////////////////////////////////////
96
97GrPath::Iter::Iter(const GrPath& path) : fPath(path) {
98 this->rewind();
99}
100
101GrPathIter::Command GrPath::Iter::next(GrPoint points[]) {
102 if (fVerbIndex == fPath.fVerbs.count()) {
103 GrAssert(fPtIndex == fPath.fPts.count());
104 return GrPathIter::kEnd_Command;
105 } else {
106 GrAssert(fVerbIndex < fPath.fVerbs.count());
107 }
108
109 uint8_t cmd = fPath.fVerbs[fVerbIndex++];
110 const GrPoint* srcPts = fPath.fPts.begin() + fPtIndex;
111
112 switch (cmd) {
113 case kMove:
114 if (points) {
115 points[0] = srcPts[0];
116 }
117 fLastPt = srcPts[0];
118 GrAssert(fPtIndex <= fPath.fPts.count() + 1);
119 fPtIndex += 1;
120 break;
121 case kLine:
122 if (points) {
123 points[0] = fLastPt;
124 points[1] = srcPts[0];
125 }
126 fLastPt = srcPts[0];
127 GrAssert(fPtIndex <= fPath.fPts.count() + 1);
128 fPtIndex += 1;
129 break;
130 case kQuad:
131 if (points) {
132 points[0] = fLastPt;
133 points[1] = srcPts[0];
134 points[2] = srcPts[1];
135 }
136 fLastPt = srcPts[2];
137 GrAssert(fPtIndex <= fPath.fPts.count() + 2);
138 fPtIndex += 2;
139 break;
140 case kCubic:
141 if (points) {
142 points[0] = fLastPt;
143 points[1] = srcPts[0];
144 points[2] = srcPts[1];
145 points[3] = srcPts[2];
146 }
147 fLastPt = srcPts[2];
148 GrAssert(fPtIndex <= fPath.fPts.count() + 3);
149 fPtIndex += 3;
150 break;
151 case kClose:
152 break;
153 default:
154 GrAssert(!"unknown grpath verb");
155 break;
156 }
157 return (GrPathIter::Command)cmd;
158}
159
160GrPathIter::ConvexHint GrPath::Iter::hint() const {
161 return fPath.getConvexHint();
162}
163
164GrPathIter::Command GrPath::Iter::next() {
165 return this->next(NULL);
166}
167
168void GrPath::Iter::rewind() {
169 fVerbIndex = fPtIndex = 0;
170}
171
172
173