OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |