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

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

Issue 455043002: use conics (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: address comments Created 6 years 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
« no previous file with comments | « include/core/SkPathMeasure.h ('k') | src/core/SkGeometry.h » ('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 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
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
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 }
OLDNEW
« no previous file with comments | « include/core/SkPathMeasure.h ('k') | src/core/SkGeometry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698