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

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

Issue 1113963002: use pathops utils to improve precision of cubic chopping in scan converter (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: use LineCubicIntersect utility for more robustness Created 5 years, 7 months 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 | « no previous file | 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 2009 The Android Open Source Project 3 * Copyright 2009 The Android Open Source Project
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 8
9 9
10 #include "SkEdgeClipper.h" 10 #include "SkEdgeClipper.h"
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 } 218 }
219 219
220 *fCurrVerb = SkPath::kDone_Verb; 220 *fCurrVerb = SkPath::kDone_Verb;
221 fCurrPoint = fPoints; 221 fCurrPoint = fPoints;
222 fCurrVerb = fVerbs; 222 fCurrVerb = fVerbs;
223 return SkPath::kDone_Verb != fVerbs[0]; 223 return SkPath::kDone_Verb != fVerbs[0];
224 } 224 }
225 225
226 /////////////////////////////////////////////////////////////////////////////// 226 ///////////////////////////////////////////////////////////////////////////////
227 227
228 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER
228 static SkScalar eval_cubic_coeff(SkScalar A, SkScalar B, SkScalar C, 229 static SkScalar eval_cubic_coeff(SkScalar A, SkScalar B, SkScalar C,
229 SkScalar D, SkScalar t) { 230 SkScalar D, SkScalar t) {
230 return SkScalarMulAdd(SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C), t, D); 231 return SkScalarMulAdd(SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C), t, D);
231 } 232 }
232 233
233 /* Given 4 cubic points (either Xs or Ys), and a target X or Y, compute the 234 /* Given 4 cubic points (either Xs or Ys), and a target X or Y, compute the
234 t value such that cubic(t) = target 235 t value such that cubic(t) = target
235 */ 236 */
236 static bool chopMonoCubicAt(SkScalar c0, SkScalar c1, SkScalar c2, SkScalar c3, 237 static bool chopMonoCubicAt(SkScalar c0, SkScalar c1, SkScalar c2, SkScalar c3,
237 SkScalar target, SkScalar* t) { 238 SkScalar target, SkScalar* t) {
(...skipping 29 matching lines...) Expand all
267 return true; 268 return true;
268 } 269 }
269 270
270 static bool chopMonoCubicAtY(SkPoint pts[4], SkScalar y, SkScalar* t) { 271 static bool chopMonoCubicAtY(SkPoint pts[4], SkScalar y, SkScalar* t) {
271 return chopMonoCubicAt(pts[0].fY, pts[1].fY, pts[2].fY, pts[3].fY, y, t); 272 return chopMonoCubicAt(pts[0].fY, pts[1].fY, pts[2].fY, pts[3].fY, y, t);
272 } 273 }
273 274
274 static bool chopMonoCubicAtX(SkPoint pts[4], SkScalar x, SkScalar* t) { 275 static bool chopMonoCubicAtX(SkPoint pts[4], SkScalar x, SkScalar* t) {
275 return chopMonoCubicAt(pts[0].fX, pts[1].fX, pts[2].fX, pts[3].fX, x, t); 276 return chopMonoCubicAt(pts[0].fX, pts[1].fX, pts[2].fX, pts[3].fX, x, t);
276 } 277 }
278 #endif
277 279
278 // Modify pts[] in place so that it is clipped in Y to the clip rect 280 // Modify pts[] in place so that it is clipped in Y to the clip rect
279 static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) { 281 static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {
280 282
281 // are we partially above 283 // are we partially above
282 if (pts[0].fY < clip.fTop) { 284 if (pts[0].fY < clip.fTop) {
285 SkPoint tmp[7];
286 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER
283 SkScalar t; 287 SkScalar t;
284 if (chopMonoCubicAtY(pts, clip.fTop, &t)) { 288 if (chopMonoCubicAtY(pts, clip.fTop, &t)) {
285 SkPoint tmp[7];
286 SkChopCubicAt(pts, tmp, t); 289 SkChopCubicAt(pts, tmp, t);
287 290 #else
288 // tmp[3, 4, 5].fY should all be to the below clip.fTop. 291 if (SkChopMonoCubicAtY(pts, clip.fTop, tmp)) {
292 #endif
293 // tmp[3, 4].fY should all be to the below clip.fTop.
289 // Since we can't trust the numerics of 294 // Since we can't trust the numerics of
290 // the chopper, we force those conditions now 295 // the chopper, we force those conditions now
291 tmp[3].fY = clip.fTop; 296 tmp[3].fY = clip.fTop;
292 clamp_ge(tmp[4].fY, clip.fTop); 297 clamp_ge(tmp[4].fY, clip.fTop);
298 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER
293 clamp_ge(tmp[5].fY, clip.fTop); 299 clamp_ge(tmp[5].fY, clip.fTop);
300 #endif
294 301
295 pts[0] = tmp[3]; 302 pts[0] = tmp[3];
296 pts[1] = tmp[4]; 303 pts[1] = tmp[4];
297 pts[2] = tmp[5]; 304 pts[2] = tmp[5];
298 } else { 305 } else {
299 // if chopMonoCubicAtY failed, then we may have hit inexact numerics 306 // if chopMonoCubicAtY failed, then we may have hit inexact numerics
300 // so we just clamp against the top 307 // so we just clamp against the top
301 for (int i = 0; i < 4; i++) { 308 for (int i = 0; i < 4; i++) {
302 clamp_ge(pts[i].fY, clip.fTop); 309 clamp_ge(pts[i].fY, clip.fTop);
303 } 310 }
304 } 311 }
305 } 312 }
306 313
307 // are we partially below 314 // are we partially below
308 if (pts[3].fY > clip.fBottom) { 315 if (pts[3].fY > clip.fBottom) {
316 SkPoint tmp[7];
317 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER
309 SkScalar t; 318 SkScalar t;
310 if (chopMonoCubicAtY(pts, clip.fBottom, &t)) { 319 if (chopMonoCubicAtY(pts, clip.fBottom, &t)) {
311 SkPoint tmp[7];
312 SkChopCubicAt(pts, tmp, t); 320 SkChopCubicAt(pts, tmp, t);
321 #else
322 if (SkChopMonoCubicAtY(pts, clip.fBottom, tmp)) {
323 #endif
313 tmp[3].fY = clip.fBottom; 324 tmp[3].fY = clip.fBottom;
314 clamp_le(tmp[2].fY, clip.fBottom); 325 clamp_le(tmp[2].fY, clip.fBottom);
315 326
316 pts[1] = tmp[1]; 327 pts[1] = tmp[1];
317 pts[2] = tmp[2]; 328 pts[2] = tmp[2];
318 pts[3] = tmp[3]; 329 pts[3] = tmp[3];
319 } else { 330 } else {
320 // if chopMonoCubicAtY failed, then we may have hit inexact numerics 331 // if chopMonoCubicAtY failed, then we may have hit inexact numerics
321 // so we just clamp against the bottom 332 // so we just clamp against the bottom
322 for (int i = 0; i < 4; i++) { 333 for (int i = 0; i < 4; i++) {
(...skipping 30 matching lines...) Expand all
353 } 364 }
354 if (pts[0].fX >= clip.fRight) { // wholly to the right 365 if (pts[0].fX >= clip.fRight) { // wholly to the right
355 if (!this->canCullToTheRight()) { 366 if (!this->canCullToTheRight()) {
356 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse); 367 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse);
357 } 368 }
358 return; 369 return;
359 } 370 }
360 371
361 // are we partially to the left 372 // are we partially to the left
362 if (pts[0].fX < clip.fLeft) { 373 if (pts[0].fX < clip.fLeft) {
374 SkPoint tmp[7];
375 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER
363 SkScalar t; 376 SkScalar t;
364 if (chopMonoCubicAtX(pts, clip.fLeft, &t)) { 377 if (chopMonoCubicAtX(pts, clip.fLeft, &t)) {
365 SkPoint tmp[7];
366 SkChopCubicAt(pts, tmp, t); 378 SkChopCubicAt(pts, tmp, t);
379 #else
380 if (SkChopMonoCubicAtX(pts, clip.fLeft, tmp)) {
381 #endif
367 this->appendVLine(clip.fLeft, tmp[0].fY, tmp[3].fY, reverse); 382 this->appendVLine(clip.fLeft, tmp[0].fY, tmp[3].fY, reverse);
368 383
369 // tmp[3, 4, 5].fX should all be to the right of clip.fLeft. 384 // tmp[3, 4].fX should all be to the right of clip.fLeft.
370 // Since we can't trust the numerics of 385 // Since we can't trust the numerics of
371 // the chopper, we force those conditions now 386 // the chopper, we force those conditions now
372 tmp[3].fX = clip.fLeft; 387 tmp[3].fX = clip.fLeft;
373 clamp_ge(tmp[4].fX, clip.fLeft); 388 clamp_ge(tmp[4].fX, clip.fLeft);
389 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER
374 clamp_ge(tmp[5].fX, clip.fLeft); 390 clamp_ge(tmp[5].fX, clip.fLeft);
391 #endif
375 392
376 pts[0] = tmp[3]; 393 pts[0] = tmp[3];
377 pts[1] = tmp[4]; 394 pts[1] = tmp[4];
378 pts[2] = tmp[5]; 395 pts[2] = tmp[5];
379 } else { 396 } else {
380 // if chopMonocubicAtY failed, then we may have hit inexact numerics 397 // if chopMonocubicAtY failed, then we may have hit inexact numerics
381 // so we just clamp against the left 398 // so we just clamp against the left
382 this->appendVLine(clip.fLeft, pts[0].fY, pts[3].fY, reverse); 399 this->appendVLine(clip.fLeft, pts[0].fY, pts[3].fY, reverse);
383 return; 400 return;
384 } 401 }
385 } 402 }
386 403
387 // are we partially to the right 404 // are we partially to the right
388 if (pts[3].fX > clip.fRight) { 405 if (pts[3].fX > clip.fRight) {
406 SkPoint tmp[7];
407 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER
389 SkScalar t; 408 SkScalar t;
390 if (chopMonoCubicAtX(pts, clip.fRight, &t)) { 409 if (chopMonoCubicAtX(pts, clip.fRight, &t)) {
391 SkPoint tmp[7];
392 SkChopCubicAt(pts, tmp, t); 410 SkChopCubicAt(pts, tmp, t);
411 #else
412 if (SkChopMonoCubicAtX(pts, clip.fRight, tmp)) {
413 #endif
393 tmp[3].fX = clip.fRight; 414 tmp[3].fX = clip.fRight;
394 clamp_le(tmp[2].fX, clip.fRight); 415 clamp_le(tmp[2].fX, clip.fRight);
416 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER
395 clamp_le(tmp[1].fX, clip.fRight); 417 clamp_le(tmp[1].fX, clip.fRight);
418 #endif
396 419
397 this->appendCubic(tmp, reverse); 420 this->appendCubic(tmp, reverse);
398 this->appendVLine(clip.fRight, tmp[3].fY, tmp[6].fY, reverse); 421 this->appendVLine(clip.fRight, tmp[3].fY, tmp[6].fY, reverse);
399 } else { 422 } else {
400 // if chopMonoCubicAtX failed, then we may have hit inexact numerics 423 // if chopMonoCubicAtX failed, then we may have hit inexact numerics
401 // so we just clamp against the right 424 // so we just clamp against the right
402 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse); 425 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse);
403 } 426 }
404 } else { // wholly inside the clip 427 } else { // wholly inside the clip
405 this->appendCubic(pts, reverse); 428 this->appendCubic(pts, reverse);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 assert_monotonic(&pts[0].fY, count); 549 assert_monotonic(&pts[0].fY, count);
527 } 550 }
528 } 551 }
529 552
530 void sk_assert_monotonic_x(const SkPoint pts[], int count) { 553 void sk_assert_monotonic_x(const SkPoint pts[], int count) {
531 if (count > 1) { 554 if (count > 1) {
532 assert_monotonic(&pts[0].fX, count); 555 assert_monotonic(&pts[0].fX, count);
533 } 556 }
534 } 557 }
535 #endif 558 #endif
OLDNEW
« no previous file with comments | « no previous file | src/core/SkGeometry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698