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 "SkScanPriv.h" | 8 #include "SkScanPriv.h" |
9 #include "SkBlitter.h" | 9 #include "SkBlitter.h" |
10 #include "SkEdge.h" | 10 #include "SkEdge.h" |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 | 552 |
553 SkIRect limitR; | 553 SkIRect limitR; |
554 limitR.set(-limit, -limit, limit, limit); | 554 limitR.set(-limit, -limit, limit, limit); |
555 if (limitR.contains(orig.getBounds())) { | 555 if (limitR.contains(orig.getBounds())) { |
556 return false; | 556 return false; |
557 } | 557 } |
558 reduced->op(orig, limitR, SkRegion::kIntersect_Op); | 558 reduced->op(orig, limitR, SkRegion::kIntersect_Op); |
559 return true; | 559 return true; |
560 } | 560 } |
561 | 561 |
562 /** | |
563 * Variant of SkScalarRoundToInt, identical to SkDScalarRoundToInt except when the input fraction | |
564 * is 0.5. In this case only, round the value down. This is used to round the t op and left | |
565 * of a rectangle, and corresponds to the way the scan converter treats the top and left edges. | |
566 */ | |
567 static inline int round_down_to_int(SkScalar x) { | |
568 double xx = x; | |
569 xx += 0.5; | |
570 double floorXX = floor(xx); | |
571 return (int)floorXX - (xx == floorXX); | |
572 } | |
573 | |
574 /** | |
575 * Variant of SkRect::round() that explicitly performs the rounding step (i.e. floor(x + 0.5)) | |
576 * using double instead of SkScalar (float). It does this by calling SkDScalar RoundToInt(), | |
577 * which may be slower than calling SkScalarRountToInt(), but gives slightly m ore accurate | |
578 * results. | |
579 * | |
580 * e.g. | |
581 * SkScalar x = 0.49999997f; | |
reed1
2016/01/04 19:43:39
I think the comment block needs to be expanded, no
caryclark
2016/01/04 20:58:42
Done.
| |
582 * int ix = SkScalarRoundToInt(x); | |
583 * SkASSERT(0 == ix); // <--- fails | |
584 * ix = SkDScalarRoundToInt(x); | |
585 * SkASSERT(0 == ix); // <--- succeeds | |
586 */ | |
587 static void round_out(const SkRect& src, SkIRect* dst) { | |
reed1
2016/01/04 19:43:39
SkRect uses "out" to mean we floor/ceiling the val
caryclark
2016/01/04 20:58:42
Done.
| |
588 SkASSERT(dst); | |
589 dst->set(round_down_to_int(src.fLeft), round_down_to_int(src.fTop), | |
590 SkDScalarRoundToInt(src.fRight), SkDScalarRoundToInt(src.fBottom)); | |
591 } | |
592 | |
562 void SkScan::FillPath(const SkPath& path, const SkRegion& origClip, | 593 void SkScan::FillPath(const SkPath& path, const SkRegion& origClip, |
563 SkBlitter* blitter) { | 594 SkBlitter* blitter) { |
564 if (origClip.isEmpty()) { | 595 if (origClip.isEmpty()) { |
565 return; | 596 return; |
566 } | 597 } |
567 | 598 |
568 // Our edges are fixed-point, and don't like the bounds of the clip to | 599 // Our edges are fixed-point, and don't like the bounds of the clip to |
569 // exceed that. Here we trim the clip just so we don't overflow later on | 600 // exceed that. Here we trim the clip just so we don't overflow later on |
570 const SkRegion* clipPtr = &origClip; | 601 const SkRegion* clipPtr = &origClip; |
571 SkRegion finiteClip; | 602 SkRegion finiteClip; |
572 if (clip_to_limit(origClip, &finiteClip)) { | 603 if (clip_to_limit(origClip, &finiteClip)) { |
573 if (finiteClip.isEmpty()) { | 604 if (finiteClip.isEmpty()) { |
574 return; | 605 return; |
575 } | 606 } |
576 clipPtr = &finiteClip; | 607 clipPtr = &finiteClip; |
577 } | 608 } |
578 // don't reference "origClip" any more, just use clipPtr | 609 // don't reference "origClip" any more, just use clipPtr |
579 | 610 |
580 SkIRect ir; | 611 SkIRect ir; |
581 // We deliberately call dround() instead of round(), since we can't afford t o generate a | 612 // We deliberately call dround() instead of round(), since we can't afford t o generate a |
582 // bounds that is tighter than the corresponding SkEdges. The edge code basi cally converts | 613 // bounds that is tighter than the corresponding SkEdges. The edge code basi cally converts |
583 // the floats to fixed, and then "rounds". If we called round() instead of d round() here, | 614 // the floats to fixed, and then "rounds". If we called round() instead of d round() here, |
584 // we could generate the wrong ir for values like 0.4999997. | 615 // we could generate the wrong ir for values like 0.4999997. |
585 path.getBounds().dround(&ir); | 616 round_out(path.getBounds(), &ir); |
586 if (ir.isEmpty()) { | 617 if (ir.isEmpty()) { |
587 if (path.isInverseFillType()) { | 618 if (path.isInverseFillType()) { |
588 blitter->blitRegion(*clipPtr); | 619 blitter->blitRegion(*clipPtr); |
589 } | 620 } |
590 return; | 621 return; |
591 } | 622 } |
592 | 623 |
593 SkScanClipper clipper(blitter, clipPtr, ir, path.isInverseFillType()); | 624 SkScanClipper clipper(blitter, clipPtr, ir, path.isInverseFillType()); |
594 | 625 |
595 blitter = clipper.getBlitter(); | 626 blitter = clipper.getBlitter(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
700 clipRgn = &wrap.getRgn(); | 731 clipRgn = &wrap.getRgn(); |
701 blitter = wrap.getBlitter(); | 732 blitter = wrap.getBlitter(); |
702 } | 733 } |
703 | 734 |
704 SkScanClipper clipper(blitter, clipRgn, ir); | 735 SkScanClipper clipper(blitter, clipRgn, ir); |
705 blitter = clipper.getBlitter(); | 736 blitter = clipper.getBlitter(); |
706 if (blitter) { | 737 if (blitter) { |
707 sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir); | 738 sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir); |
708 } | 739 } |
709 } | 740 } |
OLD | NEW |