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

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

Issue 15924003: don't overclamp cubics (see skbug.com/1316) (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « gm/cubicpaths.cpp ('k') | no next file » | 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 // Modify pts[] in place so that it is clipped in Y to the clip rect 276 // Modify pts[] in place so that it is clipped in Y to the clip rect
277 static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) { 277 static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {
278 278
279 // are we partially above 279 // are we partially above
280 if (pts[0].fY < clip.fTop) { 280 if (pts[0].fY < clip.fTop) {
281 SkScalar t; 281 SkScalar t;
282 if (chopMonoCubicAtY(pts, clip.fTop, &t)) { 282 if (chopMonoCubicAtY(pts, clip.fTop, &t)) {
283 SkPoint tmp[7]; 283 SkPoint tmp[7];
284 SkChopCubicAt(pts, tmp, t); 284 SkChopCubicAt(pts, tmp, t);
285 285
286 // tmp[3, 4, 5].fY should all be to the below clip.fTop, and 286 // tmp[3, 4, 5].fY should all be to the below clip.fTop.
287 // still be monotonic in Y. Since we can't trust the numerics of 287 // Since we can't trust the numerics of
288 // the chopper, we force those conditions now 288 // the chopper, we force those conditions now
289 tmp[3].fY = clip.fTop; 289 tmp[3].fY = clip.fTop;
290 clamp_ge(tmp[4].fY, clip.fTop); 290 clamp_ge(tmp[4].fY, clip.fTop);
291 clamp_ge(tmp[5].fY, tmp[4].fY); 291 clamp_ge(tmp[5].fY, clip.fTop);
292 292
293 pts[0] = tmp[3]; 293 pts[0] = tmp[3];
294 pts[1] = tmp[4]; 294 pts[1] = tmp[4];
295 pts[2] = tmp[5]; 295 pts[2] = tmp[5];
296 } else { 296 } else {
297 // if chopMonoCubicAtY failed, then we may have hit inexact numerics 297 // if chopMonoCubicAtY failed, then we may have hit inexact numerics
298 // so we just clamp against the top 298 // so we just clamp against the top
299 for (int i = 0; i < 4; i++) { 299 for (int i = 0; i < 4; i++) {
300 clamp_ge(pts[i].fY, clip.fTop); 300 clamp_ge(pts[i].fY, clip.fTop);
301 } 301 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 } 355 }
356 356
357 // are we partially to the left 357 // are we partially to the left
358 if (pts[0].fX < clip.fLeft) { 358 if (pts[0].fX < clip.fLeft) {
359 SkScalar t; 359 SkScalar t;
360 if (chopMonoCubicAtX(pts, clip.fLeft, &t)) { 360 if (chopMonoCubicAtX(pts, clip.fLeft, &t)) {
361 SkPoint tmp[7]; 361 SkPoint tmp[7];
362 SkChopCubicAt(pts, tmp, t); 362 SkChopCubicAt(pts, tmp, t);
363 this->appendVLine(clip.fLeft, tmp[0].fY, tmp[3].fY, reverse); 363 this->appendVLine(clip.fLeft, tmp[0].fY, tmp[3].fY, reverse);
364 364
365 // tmp[3, 4, 5].fX should all be to the right of clip.fLeft, and 365 // tmp[3, 4, 5].fX should all be to the right of clip.fLeft.
366 // still be monotonic in X. Since we can't trust the numerics of 366 // Since we can't trust the numerics of
367 // the chopper, we force those conditions now 367 // the chopper, we force those conditions now
368 tmp[3].fX = clip.fLeft; 368 tmp[3].fX = clip.fLeft;
369 clamp_ge(tmp[4].fX, clip.fLeft); 369 clamp_ge(tmp[4].fX, clip.fLeft);
370 clamp_ge(tmp[5].fX, tmp[4].fX); 370 clamp_ge(tmp[5].fX, clip.fLeft);
371 371
372 pts[0] = tmp[3]; 372 pts[0] = tmp[3];
373 pts[1] = tmp[4]; 373 pts[1] = tmp[4];
374 pts[2] = tmp[5]; 374 pts[2] = tmp[5];
375 } else { 375 } else {
376 // if chopMonocubicAtY failed, then we may have hit inexact numerics 376 // if chopMonocubicAtY failed, then we may have hit inexact numerics
377 // so we just clamp against the left 377 // so we just clamp against the left
378 this->appendVLine(clip.fLeft, pts[0].fY, pts[3].fY, reverse); 378 this->appendVLine(clip.fLeft, pts[0].fY, pts[3].fY, reverse);
379 return; 379 return;
380 } 380 }
381 } 381 }
382 382
383 // are we partially to the right 383 // are we partially to the right
384 if (pts[3].fX > clip.fRight) { 384 if (pts[3].fX > clip.fRight) {
385 SkScalar t; 385 SkScalar t;
386 if (chopMonoCubicAtX(pts, clip.fRight, &t)) { 386 if (chopMonoCubicAtX(pts, clip.fRight, &t)) {
387 SkPoint tmp[7]; 387 SkPoint tmp[7];
388 SkChopCubicAt(pts, tmp, t); 388 SkChopCubicAt(pts, tmp, t);
389 tmp[3].fX = clip.fRight; 389 tmp[3].fX = clip.fRight;
390 clamp_le(tmp[2].fX, clip.fRight); 390 clamp_le(tmp[2].fX, clip.fRight);
391 clamp_le(tmp[1].fX, tmp[2].fX); 391 clamp_le(tmp[1].fX, clip.fRight);
392 392
393 this->appendCubic(tmp, reverse); 393 this->appendCubic(tmp, reverse);
394 this->appendVLine(clip.fRight, tmp[3].fY, tmp[6].fY, reverse); 394 this->appendVLine(clip.fRight, tmp[3].fY, tmp[6].fY, reverse);
395 } else { 395 } else {
396 // if chopMonoCubicAtX failed, then we may have hit inexact numerics 396 // if chopMonoCubicAtX failed, then we may have hit inexact numerics
397 // so we just clamp against the right 397 // so we just clamp against the right
398 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse); 398 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse);
399 } 399 }
400 } else { // wholly inside the clip 400 } else { // wholly inside the clip
401 this->appendCubic(pts, reverse); 401 this->appendCubic(pts, reverse);
402 } 402 }
403 } 403 }
404 404
405 bool SkEdgeClipper::clipCubic(const SkPoint srcPts[4], const SkRect& clip) { 405 bool SkEdgeClipper::clipCubic(const SkPoint srcPts[4], const SkRect& clip) {
406 fCurrPoint = fPoints; 406 fCurrPoint = fPoints;
407 fCurrVerb = fVerbs; 407 fCurrVerb = fVerbs;
408 408
409 SkRect bounds; 409 SkRect bounds;
410 bounds.set(srcPts, 4); 410 bounds.set(srcPts, 4);
411 411
412 if (!quick_reject(bounds, clip)) { 412 if (!quick_reject(bounds, clip)) {
413 SkPoint monoY[10]; 413 SkPoint monoY[10];
414 int countY = SkChopCubicAtYExtrema(srcPts, monoY); 414 int countY = SkChopCubicAtYExtrema(srcPts, monoY);
415 for (int y = 0; y <= countY; y++) { 415 for (int y = 0; y <= countY; y++) {
416 // sk_assert_monotonic_y(&monoY[y * 3], 4);
417 SkPoint monoX[10]; 416 SkPoint monoX[10];
418 int countX = SkChopCubicAtXExtrema(&monoY[y * 3], monoX); 417 int countX = SkChopCubicAtXExtrema(&monoY[y * 3], monoX);
419 for (int x = 0; x <= countX; x++) { 418 for (int x = 0; x <= countX; x++) {
420 // sk_assert_monotonic_y(&monoX[x * 3], 4);
421 // sk_assert_monotonic_x(&monoX[x * 3], 4);
422 this->clipMonoCubic(&monoX[x * 3], clip); 419 this->clipMonoCubic(&monoX[x * 3], clip);
423 SkASSERT(fCurrVerb - fVerbs < kMaxVerbs); 420 SkASSERT(fCurrVerb - fVerbs < kMaxVerbs);
424 SkASSERT(fCurrPoint - fPoints <= kMaxPoints); 421 SkASSERT(fCurrPoint - fPoints <= kMaxPoints);
425 } 422 }
426 } 423 }
427 } 424 }
428 425
429 *fCurrVerb = SkPath::kDone_Verb; 426 *fCurrVerb = SkPath::kDone_Verb;
430 fCurrPoint = fPoints; 427 fCurrPoint = fPoints;
431 fCurrVerb = fVerbs; 428 fCurrVerb = fVerbs;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 assert_monotonic(&pts[0].fY, count); 522 assert_monotonic(&pts[0].fY, count);
526 } 523 }
527 } 524 }
528 525
529 void sk_assert_monotonic_x(const SkPoint pts[], int count) { 526 void sk_assert_monotonic_x(const SkPoint pts[], int count) {
530 if (count > 1) { 527 if (count > 1) {
531 assert_monotonic(&pts[0].fX, count); 528 assert_monotonic(&pts[0].fX, count);
532 } 529 }
533 } 530 }
534 #endif 531 #endif
OLDNEW
« no previous file with comments | « gm/cubicpaths.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698