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

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: delete from public headers 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.
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
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 }
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