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