Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Side by Side Diff: src/core/SkScan_Path.cpp

Issue 1544873002: handle halfway case in scan converter (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add more comments Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/core/SkRect.h ('k') | tests/DrawPathTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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. Also rounds top and left using double, flooring when the fraction is exactly 0.5f.
579 *
580 * e.g.
581 * SkScalar left = 0.5f;
582 * int ileft = SkScalarRoundToInt(left);
583 * SkASSERT(0 == ileft); // <--- fails
584 * int ileft = round_down_to_int(left);
585 * SkASSERT(0 == ileft); // <--- succeeds
586 * SkScalar right = 0.49999997f;
587 * int iright = SkScalarRoundToInt(right);
588 * SkASSERT(0 == iright); // <--- fails
589 * iright = SkDScalarRoundToInt(right);
590 * SkASSERT(0 == iright); // <--- succeeds
591 */
592 static void round_asymmetric_to_int(const SkRect& src, SkIRect* dst) {
593 SkASSERT(dst);
594 dst->set(round_down_to_int(src.fLeft), round_down_to_int(src.fTop),
595 SkDScalarRoundToInt(src.fRight), SkDScalarRoundToInt(src.fBottom));
596 }
597
562 void SkScan::FillPath(const SkPath& path, const SkRegion& origClip, 598 void SkScan::FillPath(const SkPath& path, const SkRegion& origClip,
563 SkBlitter* blitter) { 599 SkBlitter* blitter) {
564 if (origClip.isEmpty()) { 600 if (origClip.isEmpty()) {
565 return; 601 return;
566 } 602 }
567 603
568 // Our edges are fixed-point, and don't like the bounds of the clip to 604 // 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 605 // exceed that. Here we trim the clip just so we don't overflow later on
570 const SkRegion* clipPtr = &origClip; 606 const SkRegion* clipPtr = &origClip;
571 SkRegion finiteClip; 607 SkRegion finiteClip;
572 if (clip_to_limit(origClip, &finiteClip)) { 608 if (clip_to_limit(origClip, &finiteClip)) {
573 if (finiteClip.isEmpty()) { 609 if (finiteClip.isEmpty()) {
574 return; 610 return;
575 } 611 }
576 clipPtr = &finiteClip; 612 clipPtr = &finiteClip;
577 } 613 }
578 // don't reference "origClip" any more, just use clipPtr 614 // don't reference "origClip" any more, just use clipPtr
579 615
580 SkIRect ir; 616 SkIRect ir;
581 // We deliberately call dround() instead of round(), since we can't afford t o generate a 617 // We deliberately call round_asymmetric_to_int() instead of round(), since we can't afford
582 // bounds that is tighter than the corresponding SkEdges. The edge code basi cally converts 618 // to generate a bounds that is tighter than the corresponding SkEdges. The edge code basically
583 // the floats to fixed, and then "rounds". If we called round() instead of d round() here, 619 // converts the floats to fixed, and then "rounds". If we called round() ins tead of
584 // we could generate the wrong ir for values like 0.4999997. 620 // round_asymmetric_to_int() here, we could generate the wrong ir for values like 0.4999997.
585 path.getBounds().dround(&ir); 621 round_asymmetric_to_int(path.getBounds(), &ir);
586 if (ir.isEmpty()) { 622 if (ir.isEmpty()) {
587 if (path.isInverseFillType()) { 623 if (path.isInverseFillType()) {
588 blitter->blitRegion(*clipPtr); 624 blitter->blitRegion(*clipPtr);
589 } 625 }
590 return; 626 return;
591 } 627 }
592 628
593 SkScanClipper clipper(blitter, clipPtr, ir, path.isInverseFillType()); 629 SkScanClipper clipper(blitter, clipPtr, ir, path.isInverseFillType());
594 630
595 blitter = clipper.getBlitter(); 631 blitter = clipper.getBlitter();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 clipRgn = &wrap.getRgn(); 736 clipRgn = &wrap.getRgn();
701 blitter = wrap.getBlitter(); 737 blitter = wrap.getBlitter();
702 } 738 }
703 739
704 SkScanClipper clipper(blitter, clipRgn, ir); 740 SkScanClipper clipper(blitter, clipRgn, ir);
705 blitter = clipper.getBlitter(); 741 blitter = clipper.getBlitter();
706 if (blitter) { 742 if (blitter) {
707 sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir); 743 sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir);
708 } 744 }
709 } 745 }
OLDNEW
« no previous file with comments | « include/core/SkRect.h ('k') | tests/DrawPathTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698