| 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 |