| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 The Android Open Source Project | 3 * Copyright 2011 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 "SkScan.h" | 10 #include "SkScan.h" |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 istart += 1; | 581 istart += 1; |
| 582 int fullSpans = istop - istart - (scaleStop > 0); | 582 int fullSpans = istop - istart - (scaleStop > 0); |
| 583 if (fullSpans > 0) { | 583 if (fullSpans > 0) { |
| 584 fstart = hairBlitter->drawLine(istart, istart + fullSpans, fstart, slope
); | 584 fstart = hairBlitter->drawLine(istart, istart + fullSpans, fstart, slope
); |
| 585 } | 585 } |
| 586 if (scaleStop > 0) { | 586 if (scaleStop > 0) { |
| 587 hairBlitter->drawCap(istop - 1, fstart, slope, scaleStop); | 587 hairBlitter->drawCap(istop - 1, fstart, slope, scaleStop); |
| 588 } | 588 } |
| 589 } | 589 } |
| 590 | 590 |
| 591 void SkScan::AntiHairLineRgn(SkPoint pt0, SkPoint pt1, const SkRegion* clip, SkB
litter* blitter) { | 591 void SkScan::AntiHairLineRgn(const SkPoint array[], int arrayCount, const SkRegi
on* clip, |
| 592 SkBlitter* blitter) { |
| 592 if (clip && clip->isEmpty()) { | 593 if (clip && clip->isEmpty()) { |
| 593 return; | 594 return; |
| 594 } | 595 } |
| 595 | 596 |
| 596 SkASSERT(clip == NULL || !clip->getBounds().isEmpty()); | 597 SkASSERT(clip == NULL || !clip->getBounds().isEmpty()); |
| 597 | 598 |
| 598 #ifdef TEST_GAMMA | 599 #ifdef TEST_GAMMA |
| 599 build_gamma_table(); | 600 build_gamma_table(); |
| 600 #endif | 601 #endif |
| 601 | 602 |
| 602 SkPoint pts[2] = { pt0, pt1 }; | 603 const SkScalar max = SkIntToScalar(32767); |
| 604 const SkRect fixedBounds = SkRect::MakeLTRB(-max, -max, max, max); |
| 603 | 605 |
| 604 // We have to pre-clip the line to fit in a SkFixed, so we just chop | 606 SkRect clipBounds; |
| 605 // the line. TODO find a way to actually draw beyond that range. | 607 if (clip) { |
| 606 { | 608 clipBounds.set(clip->getBounds()); |
| 607 SkRect fixedBounds; | 609 /* We perform integral clipping later on, but we do a scalar clip first |
| 608 const SkScalar max = SkIntToScalar(32767); | 610 to ensure that our coordinates are expressible in fixed/integers. |
| 609 fixedBounds.set(-max, -max, max, max); | 611 |
| 610 if (!SkLineClipper::IntersectLine(pts, fixedBounds, pts)) { | 612 antialiased hairlines can draw up to 1/2 of a pixel outside of |
| 611 return; | 613 their bounds, so we need to outset the clip before calling the |
| 612 } | 614 clipper. To make the numerics safer, we outset by a whole pixel, |
| 615 since the 1/2 pixel boundary is important to the antihair blitter, |
| 616 we don't want to risk numerical fate by chopping on that edge. |
| 617 */ |
| 618 clipBounds.outset(SK_Scalar1, SK_Scalar1); |
| 613 } | 619 } |
| 614 | 620 |
| 615 if (clip) { | 621 for (int i = 0; i < arrayCount - 1; ++i) { |
| 616 SkRect clipBounds; | 622 SkPoint pts[2]; |
| 617 clipBounds.set(clip->getBounds()); | |
| 618 /* We perform integral clipping later on, but we do a scalar clip first | |
| 619 to ensure that our coordinates are expressible in fixed/integers. | |
| 620 | 623 |
| 621 antialiased hairlines can draw up to 1/2 of a pixel outside of | 624 // We have to pre-clip the line to fit in a SkFixed, so we just chop |
| 622 their bounds, so we need to outset the clip before calling the | 625 // the line. TODO find a way to actually draw beyond that range. |
| 623 clipper. To make the numerics safer, we outset by a whole pixel, | 626 if (!SkLineClipper::IntersectLine(&array[i], fixedBounds, pts)) { |
| 624 since the 1/2 pixel boundary is important to the antihair blitter, | 627 continue; |
| 625 we don't want to risk numerical fate by chopping on that edge. | 628 } |
| 626 */ | |
| 627 clipBounds.outset(SK_Scalar1, SK_Scalar1); | |
| 628 | 629 |
| 629 if (!SkLineClipper::IntersectLine(pts, clipBounds, pts)) { | 630 if (clip && !SkLineClipper::IntersectLine(pts, clipBounds, pts)) { |
| 630 return; | 631 continue; |
| 631 } | 632 } |
| 633 |
| 634 SkFDot6 x0 = SkScalarToFDot6(pts[0].fX); |
| 635 SkFDot6 y0 = SkScalarToFDot6(pts[0].fY); |
| 636 SkFDot6 x1 = SkScalarToFDot6(pts[1].fX); |
| 637 SkFDot6 y1 = SkScalarToFDot6(pts[1].fY); |
| 638 |
| 639 if (clip) { |
| 640 SkFDot6 left = SkMin32(x0, x1); |
| 641 SkFDot6 top = SkMin32(y0, y1); |
| 642 SkFDot6 right = SkMax32(x0, x1); |
| 643 SkFDot6 bottom = SkMax32(y0, y1); |
| 644 SkIRect ir; |
| 645 |
| 646 ir.set( SkFDot6Floor(left) - 1, |
| 647 SkFDot6Floor(top) - 1, |
| 648 SkFDot6Ceil(right) + 1, |
| 649 SkFDot6Ceil(bottom) + 1); |
| 650 |
| 651 if (clip->quickReject(ir)) { |
| 652 continue; |
| 653 } |
| 654 if (!clip->quickContains(ir)) { |
| 655 SkRegion::Cliperator iter(*clip, ir); |
| 656 const SkIRect* r = &iter.rect(); |
| 657 |
| 658 while (!iter.done()) { |
| 659 do_anti_hairline(x0, y0, x1, y1, r, blitter); |
| 660 iter.next(); |
| 661 } |
| 662 continue; |
| 663 } |
| 664 // fall through to no-clip case |
| 665 } |
| 666 do_anti_hairline(x0, y0, x1, y1, NULL, blitter); |
| 632 } | 667 } |
| 633 | |
| 634 SkFDot6 x0 = SkScalarToFDot6(pts[0].fX); | |
| 635 SkFDot6 y0 = SkScalarToFDot6(pts[0].fY); | |
| 636 SkFDot6 x1 = SkScalarToFDot6(pts[1].fX); | |
| 637 SkFDot6 y1 = SkScalarToFDot6(pts[1].fY); | |
| 638 | |
| 639 if (clip) { | |
| 640 SkFDot6 left = SkMin32(x0, x1); | |
| 641 SkFDot6 top = SkMin32(y0, y1); | |
| 642 SkFDot6 right = SkMax32(x0, x1); | |
| 643 SkFDot6 bottom = SkMax32(y0, y1); | |
| 644 SkIRect ir; | |
| 645 | |
| 646 ir.set( SkFDot6Floor(left) - 1, | |
| 647 SkFDot6Floor(top) - 1, | |
| 648 SkFDot6Ceil(right) + 1, | |
| 649 SkFDot6Ceil(bottom) + 1); | |
| 650 | |
| 651 if (clip->quickReject(ir)) { | |
| 652 return; | |
| 653 } | |
| 654 if (!clip->quickContains(ir)) { | |
| 655 SkRegion::Cliperator iter(*clip, ir); | |
| 656 const SkIRect* r = &iter.rect(); | |
| 657 | |
| 658 while (!iter.done()) { | |
| 659 do_anti_hairline(x0, y0, x1, y1, r, blitter); | |
| 660 iter.next(); | |
| 661 } | |
| 662 return; | |
| 663 } | |
| 664 // fall through to no-clip case | |
| 665 } | |
| 666 do_anti_hairline(x0, y0, x1, y1, NULL, blitter); | |
| 667 } | 668 } |
| 668 | 669 |
| 669 void SkScan::AntiHairRect(const SkRect& rect, const SkRasterClip& clip, | 670 void SkScan::AntiHairRect(const SkRect& rect, const SkRasterClip& clip, |
| 670 SkBlitter* blitter) { | 671 SkBlitter* blitter) { |
| 671 SkPoint p0, p1; | 672 SkPoint pts[5]; |
| 672 | 673 |
| 673 p0.set(rect.fLeft, rect.fTop); | 674 pts[0].set(rect.fLeft, rect.fTop); |
| 674 p1.set(rect.fRight, rect.fTop); | 675 pts[1].set(rect.fRight, rect.fTop); |
| 675 SkScan::AntiHairLine(p0, p1, clip, blitter); | 676 pts[2].set(rect.fRight, rect.fBottom); |
| 676 p0.set(rect.fRight, rect.fBottom); | 677 pts[3].set(rect.fLeft, rect.fBottom); |
| 677 SkScan::AntiHairLine(p0, p1, clip, blitter); | 678 pts[4] = pts[0]; |
| 678 p1.set(rect.fLeft, rect.fBottom); | 679 SkScan::AntiHairLine(pts, 5, clip, blitter); |
| 679 SkScan::AntiHairLine(p0, p1, clip, blitter); | |
| 680 p0.set(rect.fLeft, rect.fTop); | |
| 681 SkScan::AntiHairLine(p0, p1, clip, blitter); | |
| 682 } | 680 } |
| 683 | 681 |
| 684 /////////////////////////////////////////////////////////////////////////////// | 682 /////////////////////////////////////////////////////////////////////////////// |
| 685 | 683 |
| 686 typedef int FDot8; // 24.8 integer fixed point | 684 typedef int FDot8; // 24.8 integer fixed point |
| 687 | 685 |
| 688 static inline FDot8 SkFixedToFDot8(SkFixed x) { | 686 static inline FDot8 SkFixedToFDot8(SkFixed x) { |
| 689 return (x + 0x80) >> 8; | 687 return (x + 0x80) >> 8; |
| 690 } | 688 } |
| 691 | 689 |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1064 | 1062 |
| 1065 void SkScan::AntiFrameRect(const SkRect& r, const SkPoint& strokeSize, | 1063 void SkScan::AntiFrameRect(const SkRect& r, const SkPoint& strokeSize, |
| 1066 const SkRasterClip& clip, SkBlitter* blitter) { | 1064 const SkRasterClip& clip, SkBlitter* blitter) { |
| 1067 if (clip.isBW()) { | 1065 if (clip.isBW()) { |
| 1068 AntiFrameRect(r, strokeSize, &clip.bwRgn(), blitter); | 1066 AntiFrameRect(r, strokeSize, &clip.bwRgn(), blitter); |
| 1069 } else { | 1067 } else { |
| 1070 SkAAClipBlitterWrapper wrap(clip, blitter); | 1068 SkAAClipBlitterWrapper wrap(clip, blitter); |
| 1071 AntiFrameRect(r, strokeSize, &wrap.getRgn(), wrap.getBlitter()); | 1069 AntiFrameRect(r, strokeSize, &wrap.getRgn(), wrap.getBlitter()); |
| 1072 } | 1070 } |
| 1073 } | 1071 } |
| OLD | NEW |