diff options
author | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-10-22 18:11:06 +0000 |
---|---|---|
committer | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-10-22 18:11:06 +0000 |
commit | 8481ccc199ba3ed03acb19b1f341394db5bcb834 (patch) | |
tree | b9ff3c578bb9e144e9fa5d04c4b1662c3da089b3 /src | |
parent | d6a5f4e2008d96a896c76ca031bece0723e16e3c (diff) |
fix quadclipper in the case that the chop function fails
If the chopper fails, then we've hit some numerical edge-case, which indicates
that the quad is just barely crossing the edge, so to handle that, we just
clamp the Y values to the edge. This distorts the quad, but only in the case
when 99% of the quad will not be affected.
git-svn-id: http://skia.googlecode.com/svn/trunk@404 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkQuadClipper.cpp | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/src/core/SkQuadClipper.cpp b/src/core/SkQuadClipper.cpp index c6add69745..7521bdc7fd 100644 --- a/src/core/SkQuadClipper.cpp +++ b/src/core/SkQuadClipper.cpp @@ -49,7 +49,7 @@ void SkQuadClipper::setClip(const SkIRect& clip) { bool SkQuadClipper::clipQuad(const SkPoint srcPts[3], SkPoint dst[3]) { bool reverse; - // we need the data to be monotonically descending in Y + // we need the data to be monotonically increasing in Y if (srcPts[0].fY > srcPts[2].fY) { dst[0] = srcPts[2]; dst[1] = srcPts[1]; @@ -71,19 +71,40 @@ bool SkQuadClipper::clipQuad(const SkPoint srcPts[3], SkPoint dst[3]) { SkPoint tmp[5]; // for SkChopQuadAt // are we partially above - if (dst[0].fY < ctop && chopMonoQuadAtY(dst, ctop, &t)) { - SkChopQuadAt(dst, tmp, t); - dst[0] = tmp[2]; - dst[1] = tmp[3]; + if (dst[0].fY < ctop) { + if (chopMonoQuadAtY(dst, ctop, &t)) { + // take the 2nd chopped quad + SkChopQuadAt(dst, tmp, t); + dst[0] = tmp[2]; + dst[1] = tmp[3]; + } else { + // if chopMonoQuadAtY failed, then we may have hit inexact numerics + // so we just clamp against the top + for (int i = 0; i < 3; i++) { + if (dst[i].fY < ctop) { + dst[i].fY = ctop; + } + } + } } // are we partially below - if (dst[2].fY > cbot && chopMonoQuadAtY(dst, cbot, &t)) { - SkChopQuadAt(dst, tmp, t); - dst[1] = tmp[1]; - dst[2] = tmp[2]; + if (dst[2].fY > cbot) { + if (chopMonoQuadAtY(dst, cbot, &t)) { + SkChopQuadAt(dst, tmp, t); + dst[1] = tmp[1]; + dst[2] = tmp[2]; + } else { + // if chopMonoQuadAtY failed, then we may have hit inexact numerics + // so we just clamp against the bottom + for (int i = 0; i < 3; i++) { + if (dst[i].fY > cbot) { + dst[i].fY = cbot; + } + } + } } - + if (reverse) { SkTSwap<SkPoint>(dst[0], dst[2]); } |