aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-10-22 18:11:06 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-10-22 18:11:06 +0000
commit8481ccc199ba3ed03acb19b1f341394db5bcb834 (patch)
treeb9ff3c578bb9e144e9fa5d04c4b1662c3da089b3 /src
parentd6a5f4e2008d96a896c76ca031bece0723e16e3c (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.cpp41
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]);
}