OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
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 #include "SkEdgeBuilder.h" | 8 #include "SkEdgeBuilder.h" |
9 #include "SkPath.h" | 9 #include "SkPath.h" |
10 #include "SkEdge.h" | 10 #include "SkEdge.h" |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 SkDEBUGFAIL("unexpected verb"); | 146 SkDEBUGFAIL("unexpected verb"); |
147 break; | 147 break; |
148 } | 148 } |
149 } | 149 } |
150 } | 150 } |
151 SkASSERT((char*)edge <= (char*)fEdgeList); | 151 SkASSERT((char*)edge <= (char*)fEdgeList); |
152 SkASSERT(edgePtr - fEdgeList <= maxEdgeCount); | 152 SkASSERT(edgePtr - fEdgeList <= maxEdgeCount); |
153 return edgePtr - fEdgeList; | 153 return edgePtr - fEdgeList; |
154 } | 154 } |
155 | 155 |
| 156 static void handle_quad(SkEdgeBuilder* builder, const SkPoint pts[3]) { |
| 157 SkPoint monoX[5]; |
| 158 int n = SkChopQuadAtYExtrema(pts, monoX); |
| 159 for (int i = 0; i <= n; i++) { |
| 160 builder->addQuad(&monoX[i * 2]); |
| 161 } |
| 162 } |
| 163 |
156 int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, | 164 int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, |
157 int shiftUp) { | 165 int shiftUp) { |
158 fAlloc.reset(); | 166 fAlloc.reset(); |
159 fList.reset(); | 167 fList.reset(); |
160 fShiftUp = shiftUp; | 168 fShiftUp = shiftUp; |
161 | 169 |
| 170 SkScalar conicTol = SK_ScalarHalf * (1 << shiftUp); |
| 171 |
162 if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) { | 172 if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) { |
163 return this->buildPoly(path, iclip, shiftUp); | 173 return this->buildPoly(path, iclip, shiftUp); |
164 } | 174 } |
165 | 175 |
166 SkPath::Iter iter(path, true); | 176 SkPath::Iter iter(path, true); |
167 SkPoint pts[4]; | 177 SkPoint pts[4]; |
168 SkPath::Verb verb; | 178 SkPath::Verb verb; |
169 | 179 |
170 if (iclip) { | 180 if (iclip) { |
171 SkRect clip; | 181 SkRect clip; |
(...skipping 13 matching lines...) Expand all Loading... |
185 for (int i = 0; i < lineCount; i++) { | 195 for (int i = 0; i < lineCount; i++) { |
186 this->addLine(&lines[i]); | 196 this->addLine(&lines[i]); |
187 } | 197 } |
188 break; | 198 break; |
189 } | 199 } |
190 case SkPath::kQuad_Verb: | 200 case SkPath::kQuad_Verb: |
191 if (clipper.clipQuad(pts, clip)) { | 201 if (clipper.clipQuad(pts, clip)) { |
192 this->addClipper(&clipper); | 202 this->addClipper(&clipper); |
193 } | 203 } |
194 break; | 204 break; |
| 205 case SkPath::kConic_Verb: { |
| 206 const int MAX_POW2 = 4; |
| 207 const int MAX_QUADS = 1 << MAX_POW2; |
| 208 const int MAX_QUAD_PTS = 1 + 2 * MAX_QUADS; |
| 209 SkPoint storage[MAX_QUAD_PTS]; |
| 210 |
| 211 SkConic conic; |
| 212 conic.set(pts, iter.conicWeight()); |
| 213 int pow2 = conic.computeQuadPOW2(conicTol); |
| 214 pow2 = SkMin32(pow2, MAX_POW2); |
| 215 int quadCount = conic.chopIntoQuadsPOW2(storage, pow2); |
| 216 SkASSERT(quadCount <= MAX_QUADS); |
| 217 for (int i = 0; i < quadCount; ++i) { |
| 218 if (clipper.clipQuad(&storage[i * 2], clip)) { |
| 219 this->addClipper(&clipper); |
| 220 } |
| 221 } |
| 222 } break; |
195 case SkPath::kCubic_Verb: | 223 case SkPath::kCubic_Verb: |
196 if (clipper.clipCubic(pts, clip)) { | 224 if (clipper.clipCubic(pts, clip)) { |
197 this->addClipper(&clipper); | 225 this->addClipper(&clipper); |
198 } | 226 } |
199 break; | 227 break; |
200 default: | 228 default: |
201 SkDEBUGFAIL("unexpected verb"); | 229 SkDEBUGFAIL("unexpected verb"); |
202 break; | 230 break; |
203 } | 231 } |
204 } | 232 } |
205 } else { | 233 } else { |
206 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { | 234 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { |
207 switch (verb) { | 235 switch (verb) { |
208 case SkPath::kMove_Verb: | 236 case SkPath::kMove_Verb: |
209 case SkPath::kClose_Verb: | 237 case SkPath::kClose_Verb: |
210 // we ignore these, and just get the whole segment from | 238 // we ignore these, and just get the whole segment from |
211 // the corresponding line/quad/cubic verbs | 239 // the corresponding line/quad/cubic verbs |
212 break; | 240 break; |
213 case SkPath::kLine_Verb: | 241 case SkPath::kLine_Verb: |
214 this->addLine(pts); | 242 this->addLine(pts); |
215 break; | 243 break; |
216 case SkPath::kQuad_Verb: { | 244 case SkPath::kQuad_Verb: { |
217 SkPoint monoX[5]; | 245 handle_quad(this, pts); |
218 int n = SkChopQuadAtYExtrema(pts, monoX); | |
219 for (int i = 0; i <= n; i++) { | |
220 this->addQuad(&monoX[i * 2]); | |
221 } | |
222 break; | 246 break; |
223 } | 247 } |
| 248 case SkPath::kConic_Verb: { |
| 249 const int MAX_POW2 = 4; |
| 250 const int MAX_QUADS = 1 << MAX_POW2; |
| 251 const int MAX_QUAD_PTS = 1 + 2 * MAX_QUADS; |
| 252 SkPoint storage[MAX_QUAD_PTS]; |
| 253 |
| 254 SkConic conic; |
| 255 conic.set(pts, iter.conicWeight()); |
| 256 int pow2 = conic.computeQuadPOW2(conicTol); |
| 257 pow2 = SkMin32(pow2, MAX_POW2); |
| 258 int quadCount = conic.chopIntoQuadsPOW2(storage, pow2); |
| 259 SkASSERT(quadCount <= MAX_QUADS); |
| 260 SkDebugf("--- quadCount = %d\n", quadCount); |
| 261 for (int i = 0; i < quadCount; ++i) { |
| 262 handle_quad(this, &storage[i * 2]); |
| 263 } |
| 264 } break; |
224 case SkPath::kCubic_Verb: { | 265 case SkPath::kCubic_Verb: { |
225 SkPoint monoY[10]; | 266 SkPoint monoY[10]; |
226 int n = SkChopCubicAtYExtrema(pts, monoY); | 267 int n = SkChopCubicAtYExtrema(pts, monoY); |
227 for (int i = 0; i <= n; i++) { | 268 for (int i = 0; i <= n; i++) { |
228 this->addCubic(&monoY[i * 3]); | 269 this->addCubic(&monoY[i * 3]); |
229 } | 270 } |
230 break; | 271 break; |
231 } | 272 } |
232 default: | 273 default: |
233 SkDEBUGFAIL("unexpected verb"); | 274 SkDEBUGFAIL("unexpected verb"); |
234 break; | 275 break; |
235 } | 276 } |
236 } | 277 } |
237 } | 278 } |
238 fEdgeList = fList.begin(); | 279 fEdgeList = fList.begin(); |
239 return fList.count(); | 280 return fList.count(); |
240 } | 281 } |
OLD | NEW |