aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-11-07 14:23:42 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-11-07 14:23:42 +0000
commitbb094b947bb53374f5ad3df1b0cc71f41d43d9bf (patch)
tree7dfabffd5159e7026e45993bbfa2f72794e012fc
parent3302783ea7edf667794b088e5fc0656946b99816 (diff)
fix SkRegion::intersects(rect) where the part of the rgn that we intersect is
the last run. The old bug was that we did an early exit from the loop because we were comparing against the next rgn.bottom, instead of the current one. inspired and fixed by danakj http://code.google.com/p/skia/issues/detail?id=958 Review URL: https://codereview.appspot.com/6812099 git-svn-id: http://skia.googlecode.com/svn/trunk@6327 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/core/SkRegion.cpp21
-rw-r--r--tests/RegionTest.cpp7
2 files changed, 20 insertions, 8 deletions
diff --git a/src/core/SkRegion.cpp b/src/core/SkRegion.cpp
index f6fc2dc6c5..776f3e8d33 100644
--- a/src/core/SkRegion.cpp
+++ b/src/core/SkRegion.cpp
@@ -313,8 +313,8 @@ bool SkRegion::contains(int32_t x, int32_t y) const {
if (this->isRect()) {
return true;
}
-
SkASSERT(this->isComplex());
+
const RunType* runs = fRunHead->findScanline(y);
// Skip the Bottom and IntervalCount
@@ -371,17 +371,18 @@ bool SkRegion::contains(const SkIRect& r) const {
if (this->isRect()) {
return true;
}
-
SkASSERT(this->isComplex());
+
const RunType* scanline = fRunHead->findScanline(r.fTop);
- RunType bottom;
- do {
+ for (;;) {
if (!scanline_contains(scanline, r.fLeft, r.fRight)) {
return false;
}
- bottom = scanline_bottom(scanline);
+ if (r.fBottom <= scanline_bottom(scanline)) {
+ break;
+ }
scanline = scanline_next(scanline);
- } while (r.fBottom > bottom);
+ }
return true;
}
@@ -455,14 +456,18 @@ bool SkRegion::intersects(const SkIRect& r) const {
if (this->isRect()) {
return true;
}
+ SkASSERT(this->isComplex());
const RunType* scanline = fRunHead->findScanline(sect.fTop);
- do {
+ for (;;) {
if (scanline_intersects(scanline, sect.fLeft, sect.fRight)) {
return true;
}
+ if (sect.fBottom <= scanline_bottom(scanline)) {
+ break;
+ }
scanline = scanline_next(scanline);
- } while (sect.fBottom >= scanline[0]);
+ }
return false;
}
diff --git a/tests/RegionTest.cpp b/tests/RegionTest.cpp
index e629a9eb93..a8ce0e0db0 100644
--- a/tests/RegionTest.cpp
+++ b/tests/RegionTest.cpp
@@ -67,6 +67,13 @@ static void test_fromchrome(skiatest::Reporter* reporter) {
Union(&container, SkIRect::MakeXYWH(30, 20, 10, 20));
TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(0, 0, 10, 39));
TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(29, 0, 10, 39));
+
+ {
+ SkRegion rgn;
+ Union(&rgn, SkIRect::MakeXYWH(0, 0, 10, 10));
+ Union(&rgn, SkIRect::MakeLTRB(5, 10, 20, 20));
+ TEST_INTERSECT(rgn, SkIRect::MakeXYWH(15, 0, 5, 11));
+ }
}
static void test_empties(skiatest::Reporter* reporter) {