Bug 1040986 - Add a Contains(x,y) method to nsRegion. r=jrmuizel
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 22 Jul 2014 13:33:46 -0400
changeset 195581 17e28bbaaac8c49f29841192d92e939de78288c5
parent 195580 24f3cfb76bf07f8453c24eeaf97622dbcc498d89
child 195582 4301c7932cfd647c3bea48a06def1df4eee3b3fe
push id27188
push usercbook@mozilla.com
push dateWed, 23 Jul 2014 13:53:43 +0000
treeherdermozilla-central@785acfd2ae48 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1040986
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1040986 - Add a Contains(x,y) method to nsRegion. r=jrmuizel
gfx/src/nsRegion.h
gfx/tests/gtest/TestRegion.cpp
--- a/gfx/src/nsRegion.h
+++ b/gfx/src/nsRegion.h
@@ -197,16 +197,25 @@ public:
     return Sub(nsRegion(aRect), aRegion);
   }
   nsRegion& Sub(const nsRect& aRect1, const nsRect& aRect2)
   {
     Copy(aRect1);
     return Sub(*this, aRect2);
   }
 
+  /**
+   * Returns true iff the given point is inside the region. A region
+   * created from a rect (x=0, y=0, w=100, h=100) will NOT contain
+   * the point x=100, y=100.
+   */
+  bool Contains (int aX, int aY) const
+  {
+    return pixman_region32_contains_point(Impl(), aX, aY, nullptr);
+  }
   bool Contains (const nsRect& aRect) const
   {
     pixman_box32_t box = RectToBox(aRect);
     return pixman_region32_contains_rectangle(Impl(), &box) == PIXMAN_REGION_IN;
   }
   bool Contains (const nsRegion& aRgn) const;
   bool Intersects (const nsRect& aRect) const;
 
@@ -568,19 +577,24 @@ public:
     return Sub (nsIntRegion (aRect), aRegion);
   }
   nsIntRegion& Sub  (const nsIntRect& aRect1, const nsIntRect& aRect2)
   {
     mImpl = ToRect (aRect1);
     return Sub (*this, aRect2);
   }
 
+  /**
+   * Returns true iff the given point is inside the region. A region
+   * created from a rect (x=0, y=0, w=100, h=100) will NOT contain
+   * the point x=100, y=100.
+   */
   bool Contains (int aX, int aY) const
   {
-    return Contains(nsIntRect(aX, aY, 1, 1));
+    return mImpl.Contains(aX, aY);
   }
   bool Contains (const nsIntRect& aRect) const
   {
     return mImpl.Contains (ToRect (aRect));
   }
   bool Contains (const nsIntRegion& aRgn) const
   {
     return mImpl.Contains (aRgn.mImpl);
--- a/gfx/tests/gtest/TestRegion.cpp
+++ b/gfx/tests/gtest/TestRegion.cpp
@@ -283,16 +283,89 @@ TEST(Gfx, RegionSimplify) {
 
   { // empty region
     // just make sure this doesn't crash.
     nsRegion r;
     r.SimplifyOutwardByArea(100);
   }
 }
 
+TEST(Gfx, RegionContains)
+{
+  { // ensure Contains works on a simple region
+    nsRegion r(nsRect(0, 0, 100, 100));
+
+    EXPECT_TRUE(r.Contains(0, 0));
+    EXPECT_TRUE(r.Contains(0, 99));
+    EXPECT_TRUE(r.Contains(99, 0));
+    EXPECT_TRUE(r.Contains(99, 99));
+
+    EXPECT_FALSE(r.Contains(-1, 50));
+    EXPECT_FALSE(r.Contains(100, 50));
+    EXPECT_FALSE(r.Contains(50, -1));
+    EXPECT_FALSE(r.Contains(50, 100));
+
+    EXPECT_TRUE(r.Contains(nsRect(0, 0, 100, 100)));
+    EXPECT_TRUE(r.Contains(nsRect(99, 99, 1, 1)));
+
+    EXPECT_FALSE(r.Contains(nsRect(100, 100, 1, 1)));
+    EXPECT_FALSE(r.Contains(nsRect(100, 100, 0, 0)));
+  }
+
+  { // empty regions contain nothing
+    nsRegion r(nsRect(100, 100, 0, 0));
+
+    EXPECT_FALSE(r.Contains(0, 0));
+    EXPECT_FALSE(r.Contains(100, 100));
+    EXPECT_FALSE(r.Contains(nsRect(100, 100, 0, 0)));
+    EXPECT_FALSE(r.Contains(nsRect(100, 100, 1, 1)));
+  }
+
+  { // complex region contain tests
+    // The region looks like this, with two squares that overlap.
+    // (hard to do accurately with ASCII art)
+    // +------+
+    // |      |
+    // |      +--+
+    // |         |
+    // +--+      |
+    //    |      |
+    //    +------+
+    nsRegion r(nsRect(0, 0, 100, 100));
+    r.OrWith(nsRect(50, 50, 100, 100));
+
+    EXPECT_TRUE(r.Contains(0, 0));
+    EXPECT_TRUE(r.Contains(99, 99));
+    EXPECT_TRUE(r.Contains(50, 100));
+    EXPECT_TRUE(r.Contains(100, 50));
+    EXPECT_TRUE(r.Contains(149, 149));
+
+    EXPECT_FALSE(r.Contains(49, 100));
+    EXPECT_FALSE(r.Contains(100, 49));
+    EXPECT_FALSE(r.Contains(150, 150));
+
+    EXPECT_TRUE(r.Contains(nsRect(100, 100, 1, 1)));
+    EXPECT_FALSE(r.Contains(nsRect(49, 99, 2, 2)));
+  }
+
+  { // region with a hole
+    nsRegion r(nsRect(0, 0, 100, 100));
+    r.SubOut(nsRect(40, 40, 10, 10));
+
+    EXPECT_TRUE(r.Contains(0, 0));
+    EXPECT_TRUE(r.Contains(39, 39));
+    EXPECT_FALSE(r.Contains(40, 40));
+    EXPECT_FALSE(r.Contains(49, 49));
+    EXPECT_TRUE(r.Contains(50, 50));
+
+    EXPECT_FALSE(r.Contains(nsRect(40, 40, 10, 10)));
+    EXPECT_FALSE(r.Contains(nsRect(39, 39, 2, 2)));
+  }
+}
+
 #define DILATE_VALUE 0x88
 #define REGION_VALUE 0xff
 
 struct RegionBitmap {
   RegionBitmap(unsigned char *bitmap, int width, int height) : bitmap(bitmap), width(width), height(height) {}
 
   void clear() {
     for (int y = 0; y < height; y++) {