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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 builder->addQuad(&monoX[i * 2]); | 160 builder->addQuad(&monoX[i * 2]); |
161 } | 161 } |
162 } | 162 } |
163 | 163 |
164 int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, | 164 int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, |
165 int shiftUp) { | 165 int shiftUp) { |
166 fAlloc.reset(); | 166 fAlloc.reset(); |
167 fList.reset(); | 167 fList.reset(); |
168 fShiftUp = shiftUp; | 168 fShiftUp = shiftUp; |
169 | 169 |
170 SkScalar conicTol = SK_ScalarHalf * (1 << shiftUp); | |
171 | |
172 if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) { | 170 if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) { |
173 return this->buildPoly(path, iclip, shiftUp); | 171 return this->buildPoly(path, iclip, shiftUp); |
174 } | 172 } |
175 | 173 |
| 174 SkAutoConicToQuads quadder; |
| 175 const SkScalar conicTol = (SK_Scalar1 / 4) * (1 << shiftUp); |
| 176 |
176 SkPath::Iter iter(path, true); | 177 SkPath::Iter iter(path, true); |
177 SkPoint pts[4]; | 178 SkPoint pts[4]; |
178 SkPath::Verb verb; | 179 SkPath::Verb verb; |
179 | 180 |
180 if (iclip) { | 181 if (iclip) { |
181 SkRect clip; | 182 SkRect clip; |
182 setShiftedClip(&clip, *iclip, shiftUp); | 183 setShiftedClip(&clip, *iclip, shiftUp); |
183 SkEdgeClipper clipper; | 184 SkEdgeClipper clipper; |
184 | 185 |
185 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { | 186 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { |
(...skipping 10 matching lines...) Expand all Loading... |
196 this->addLine(&lines[i]); | 197 this->addLine(&lines[i]); |
197 } | 198 } |
198 break; | 199 break; |
199 } | 200 } |
200 case SkPath::kQuad_Verb: | 201 case SkPath::kQuad_Verb: |
201 if (clipper.clipQuad(pts, clip)) { | 202 if (clipper.clipQuad(pts, clip)) { |
202 this->addClipper(&clipper); | 203 this->addClipper(&clipper); |
203 } | 204 } |
204 break; | 205 break; |
205 case SkPath::kConic_Verb: { | 206 case SkPath::kConic_Verb: { |
206 const int MAX_POW2 = 4; | 207 const SkPoint* quadPts = quadder.computeQuads( |
207 const int MAX_QUADS = 1 << MAX_POW2; | 208 pts, iter.conicWeight(), conicTol); |
208 const int MAX_QUAD_PTS = 1 + 2 * MAX_QUADS; | 209 for (int i = 0; i < quadder.countQuads(); ++i) { |
209 SkPoint storage[MAX_QUAD_PTS]; | 210 if (clipper.clipQuad(quadPts, clip)) { |
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); | 211 this->addClipper(&clipper); |
220 } | 212 } |
| 213 quadPts += 2; |
221 } | 214 } |
222 } break; | 215 } break; |
223 case SkPath::kCubic_Verb: | 216 case SkPath::kCubic_Verb: |
224 if (clipper.clipCubic(pts, clip)) { | 217 if (clipper.clipCubic(pts, clip)) { |
225 this->addClipper(&clipper); | 218 this->addClipper(&clipper); |
226 } | 219 } |
227 break; | 220 break; |
228 default: | 221 default: |
229 SkDEBUGFAIL("unexpected verb"); | 222 SkDEBUGFAIL("unexpected verb"); |
230 break; | 223 break; |
231 } | 224 } |
232 } | 225 } |
233 } else { | 226 } else { |
234 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { | 227 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { |
235 switch (verb) { | 228 switch (verb) { |
236 case SkPath::kMove_Verb: | 229 case SkPath::kMove_Verb: |
237 case SkPath::kClose_Verb: | 230 case SkPath::kClose_Verb: |
238 // we ignore these, and just get the whole segment from | 231 // we ignore these, and just get the whole segment from |
239 // the corresponding line/quad/cubic verbs | 232 // the corresponding line/quad/cubic verbs |
240 break; | 233 break; |
241 case SkPath::kLine_Verb: | 234 case SkPath::kLine_Verb: |
242 this->addLine(pts); | 235 this->addLine(pts); |
243 break; | 236 break; |
244 case SkPath::kQuad_Verb: { | 237 case SkPath::kQuad_Verb: { |
245 handle_quad(this, pts); | 238 handle_quad(this, pts); |
246 break; | 239 break; |
247 } | 240 } |
248 case SkPath::kConic_Verb: { | 241 case SkPath::kConic_Verb: { |
249 const int MAX_POW2 = 4; | 242 const SkPoint* quadPts = quadder.computeQuads( |
250 const int MAX_QUADS = 1 << MAX_POW2; | 243 pts, iter.conicWeight(), conicTol); |
251 const int MAX_QUAD_PTS = 1 + 2 * MAX_QUADS; | 244 for (int i = 0; i < quadder.countQuads(); ++i) { |
252 SkPoint storage[MAX_QUAD_PTS]; | 245 handle_quad(this, quadPts); |
253 | 246 quadPts += 2; |
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 for (int i = 0; i < quadCount; ++i) { | |
261 handle_quad(this, &storage[i * 2]); | |
262 } | 247 } |
263 } break; | 248 } break; |
264 case SkPath::kCubic_Verb: { | 249 case SkPath::kCubic_Verb: { |
265 SkPoint monoY[10]; | 250 SkPoint monoY[10]; |
266 int n = SkChopCubicAtYExtrema(pts, monoY); | 251 int n = SkChopCubicAtYExtrema(pts, monoY); |
267 for (int i = 0; i <= n; i++) { | 252 for (int i = 0; i <= n; i++) { |
268 this->addCubic(&monoY[i * 3]); | 253 this->addCubic(&monoY[i * 3]); |
269 } | 254 } |
270 break; | 255 break; |
271 } | 256 } |
272 default: | 257 default: |
273 SkDEBUGFAIL("unexpected verb"); | 258 SkDEBUGFAIL("unexpected verb"); |
274 break; | 259 break; |
275 } | 260 } |
276 } | 261 } |
277 } | 262 } |
278 fEdgeList = fList.begin(); | 263 fEdgeList = fList.begin(); |
279 return fList.count(); | 264 return fList.count(); |
280 } | 265 } |
OLD | NEW |