OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkScan.h" | 8 #include "SkScan.h" |
9 #include "SkBlitter.h" | 9 #include "SkBlitter.h" |
10 #include "SkRasterClip.h" | 10 #include "SkRasterClip.h" |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 if (SkPath::kMove_Verb == prevVerb) { | 421 if (SkPath::kMove_Verb == prevVerb) { |
422 SkPoint* first = pts; | 422 SkPoint* first = pts; |
423 SkPoint* ctrl = first; | 423 SkPoint* ctrl = first; |
424 int controls = ptCount - 1; | 424 int controls = ptCount - 1; |
425 SkVector tangent; | 425 SkVector tangent; |
426 do { | 426 do { |
427 tangent = *first - *++ctrl; | 427 tangent = *first - *++ctrl; |
428 } while (tangent.isZero() && --controls > 0); | 428 } while (tangent.isZero() && --controls > 0); |
429 if (tangent.isZero()) { | 429 if (tangent.isZero()) { |
430 tangent.set(1, 0); | 430 tangent.set(1, 0); |
| 431 controls = ptCount - 1; // If all points are equal, move all but on
e |
431 } else { | 432 } else { |
432 tangent.normalize(); | 433 tangent.normalize(); |
433 } | 434 } |
434 first->fX += tangent.fX * capOutset; | 435 do { // If the end point and control points are equal, loop to move t
hem in tandem. |
435 first->fY += tangent.fY * capOutset; | 436 first->fX += tangent.fX * capOutset; |
| 437 first->fY += tangent.fY * capOutset; |
| 438 ++first; |
| 439 } while (++controls < ptCount); |
436 } | 440 } |
437 if (SkPath::kMove_Verb == nextVerb || SkPath::kDone_Verb == nextVerb) { | 441 if (SkPath::kMove_Verb == nextVerb || SkPath::kDone_Verb == nextVerb) { |
438 SkPoint* last = &pts[ptCount - 1]; | 442 SkPoint* last = &pts[ptCount - 1]; |
439 SkPoint* ctrl = last; | 443 SkPoint* ctrl = last; |
440 int controls = ptCount - 1; | 444 int controls = ptCount - 1; |
441 SkVector tangent; | 445 SkVector tangent; |
442 do { | 446 do { |
443 tangent = *last - *--ctrl; | 447 tangent = *last - *--ctrl; |
444 } while (tangent.isZero() && --controls > 0); | 448 } while (tangent.isZero() && --controls > 0); |
445 if (tangent.isZero()) { | 449 if (tangent.isZero()) { |
446 tangent.set(-1, 0); | 450 tangent.set(-1, 0); |
| 451 controls = ptCount - 1; |
447 } else { | 452 } else { |
448 tangent.normalize(); | 453 tangent.normalize(); |
449 } | 454 } |
450 last->fX += tangent.fX * capOutset; | 455 do { |
451 last->fY += tangent.fY * capOutset; | 456 last->fX += tangent.fX * capOutset; |
| 457 last->fY += tangent.fY * capOutset; |
| 458 --last; |
| 459 } while (++controls < ptCount); |
452 } | 460 } |
453 } | 461 } |
454 | 462 |
455 template <SkPaint::Cap capStyle> | 463 template <SkPaint::Cap capStyle> |
456 void hair_path(const SkPath& path, const SkRasterClip& rclip, SkBlitter* blitter
, | 464 void hair_path(const SkPath& path, const SkRasterClip& rclip, SkBlitter* blitter
, |
457 SkScan::HairRgnProc lineproc) { | 465 SkScan::HairRgnProc lineproc) { |
458 if (path.isEmpty()) { | 466 if (path.isEmpty()) { |
459 return; | 467 return; |
460 } | 468 } |
461 | 469 |
462 SkAAClipBlitterWrapper wrap; | 470 SkAAClipBlitterWrapper wrap; |
463 const SkRegion* clip = nullptr; | 471 const SkRegion* clip = nullptr; |
464 SkRect insetStorage, outsetStorage; | 472 SkRect insetStorage, outsetStorage; |
465 const SkRect* insetClip = nullptr; | 473 const SkRect* insetClip = nullptr; |
466 const SkRect* outsetClip = nullptr; | 474 const SkRect* outsetClip = nullptr; |
467 | 475 |
468 { | 476 { |
469 const SkIRect ibounds = path.getBounds().roundOut().makeOutset(1, 1); | 477 const int capOut = SkPaint::kButt_Cap == capStyle ? 1 : 2; |
470 | 478 const SkIRect ibounds = path.getBounds().roundOut().makeOutset(capOut, c
apOut); |
471 if (rclip.quickReject(ibounds)) { | 479 if (rclip.quickReject(ibounds)) { |
472 return; | 480 return; |
473 } | 481 } |
474 if (!rclip.quickContains(ibounds)) { | 482 if (!rclip.quickContains(ibounds)) { |
475 if (rclip.isBW()) { | 483 if (rclip.isBW()) { |
476 clip = &rclip.bwRgn(); | 484 clip = &rclip.bwRgn(); |
477 } else { | 485 } else { |
478 wrap.init(rclip, blitter); | 486 wrap.init(rclip, blitter); |
479 blitter = wrap.getBlitter(); | 487 blitter = wrap.getBlitter(); |
480 clip = &wrap.getRgn(); | 488 clip = &wrap.getRgn(); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 | 681 |
674 SkAAClipBlitterWrapper wrap; | 682 SkAAClipBlitterWrapper wrap; |
675 if (!clip.quickContains(r.roundOut().makeOutset(1, 1))) { | 683 if (!clip.quickContains(r.roundOut().makeOutset(1, 1))) { |
676 wrap.init(clip, blitter); | 684 wrap.init(clip, blitter); |
677 blitter = wrap.getBlitter(); | 685 blitter = wrap.getBlitter(); |
678 clipRgn = &wrap.getRgn(); | 686 clipRgn = &wrap.getRgn(); |
679 } | 687 } |
680 AntiHairLineRgn(pts, count, clipRgn, blitter); | 688 AntiHairLineRgn(pts, count, clipRgn, blitter); |
681 } | 689 } |
682 } | 690 } |
OLD | NEW |