Bug 1423919: Additional methods for BaseRect for convinient modifications/testing of the member variable values. Force inline some commonly used methods. r?bas.schouten draft
authorMilan Sreckovic <milan@mozilla.com>
Thu, 07 Dec 2017 14:14:04 -0500
changeset 709248 9e6835b2617109fe28b2131ac1488ecc6cdc1d85
parent 709018 e30c06a1074c2455f47e0bafb9bb84ec1a09d682
child 743361 033f4d959ef49462720a70b233fca5807e4a5880
push id92577
push userbmo:milan@mozilla.com
push dateThu, 07 Dec 2017 19:34:19 +0000
reviewersbas.schouten
bugs1423919
milestone59.0a1
Bug 1423919: Additional methods for BaseRect for convinient modifications/testing of the member variable values. Force inline some commonly used methods. r?bas.schouten MozReview-Commit-ID: 8zALRpsKLXx
gfx/2d/BaseRect.h
gfx/tests/gtest/TestRect.cpp
gfx/tests/gtest/TestRegion.cpp
--- a/gfx/2d/BaseRect.h
+++ b/gfx/2d/BaseRect.h
@@ -53,18 +53,20 @@ struct BaseRect {
   {
   }
   BaseRect(T aX, T aY, T aWidth, T aHeight) :
       x(aX), y(aY), width(aWidth), height(aHeight)
   {
   }
 
   // Emptiness. An empty rect is one that has no area, i.e. its height or width
-  // is <= 0
-  bool IsEmpty() const { return height <= 0 || width <= 0; }
+  // is <= 0.  Zero rect is the one with height and width set to zero.  Note
+  // that SetEmpty() may change a rectangle that identified as IsEmpty().
+  MOZ_ALWAYS_INLINE bool IsZero() const { return height == 0 || width == 0; }
+  MOZ_ALWAYS_INLINE bool IsEmpty() const { return height <= 0 || width <= 0; }
   void SetEmpty() { width = height = 0; }
 
   // "Finite" means not inf and not NaN
   bool IsFinite() const
   {
     typedef typename mozilla::Conditional<mozilla::IsSame<T, float>::value, float, double>::Type FloatType;
     return (mozilla::IsFinite(FloatType(x)) &&
             mozilla::IsFinite(FloatType(y)) &&
@@ -79,21 +81,29 @@ struct BaseRect {
   {
     return aRect.IsEmpty() ||
            (x <= aRect.x && aRect.XMost() <= XMost() &&
             y <= aRect.y && aRect.YMost() <= YMost());
   }
   // Returns true if this rectangle contains the point. Points are considered
   // in the rectangle if they are on the left or top edge, but outside if they
   // are on the right or bottom edge.
-  bool Contains(T aX, T aY) const
+  MOZ_ALWAYS_INLINE bool Contains(T aX, T aY) const
   {
     return x <= aX && aX < XMost() &&
            y <= aY && aY < YMost();
   }
+  MOZ_ALWAYS_INLINE bool ContainsX(T aX) const
+  {
+    return x <= aX && aX < XMost();
+  }
+  MOZ_ALWAYS_INLINE bool ContainsY(T aY) const
+  {
+    return y <= aY && aY < YMost();
+  }
   // Returns true if this rectangle contains the point. Points are considered
   // in the rectangle if they are on the left or top edge, but outside if they
   // are on the right or bottom edge.
   bool Contains(const Point& aPoint) const { return Contains(aPoint.x, aPoint.y); }
 
   // Intersection. Returns TRUE if the receiver's area has non-empty
   // intersection with aRect's area, and FALSE otherwise.
   // Always returns false if aRect is empty or 'this' is empty.
@@ -194,35 +204,59 @@ struct BaseRect {
     if (aPoint.y < y) {
       height = YMost() - aPoint.y;
       y = aPoint.y;
     } else if (aPoint.y > YMost()) {
       height = aPoint.y - y;
     }
   }
 
-  void SetRect(T aX, T aY, T aWidth, T aHeight)
+  MOZ_ALWAYS_INLINE void SetRect(T aX, T aY, T aWidth, T aHeight)
   {
     x = aX; y = aY; width = aWidth; height = aHeight;
   }
+  MOZ_ALWAYS_INLINE void SetRectX(T aX, T aWidth)
+  {
+    x = aX; width = aWidth;
+  }
+  MOZ_ALWAYS_INLINE void SetRectY(T aY, T aHeight)
+  {
+    y = aY; height = aHeight;
+  }
+  MOZ_ALWAYS_INLINE void SetBox(T aX, T aY, T aXMost, T aYMost)
+  {
+    x = aX; y = aY; width = aXMost - aX; height = aYMost - aY;
+  }
+  MOZ_ALWAYS_INLINE void SetBoxX(T aX, T aXMost)
+  {
+    x = aX; width = aXMost - aX;
+  }
+  MOZ_ALWAYS_INLINE void SetBoxY(T aY, T aYMost)
+  {
+    y = aY; height = aYMost - aY;
+  }
   void SetRect(const Point& aPt, const SizeT& aSize)
   {
     SetRect(aPt.x, aPt.y, aSize.width, aSize.height);
   }
-  void GetRect(T* aX, T* aY, T* aWidth, T* aHeight)
+  MOZ_ALWAYS_INLINE void GetRect(T* aX, T* aY, T* aWidth, T* aHeight)
   {
     *aX = x; *aY = y; *aWidth = width; *aHeight = height;
   }
 
-  void MoveTo(T aX, T aY) { x = aX; y = aY; }
-  void MoveTo(const Point& aPoint) { x = aPoint.x; y = aPoint.y; }
-  void MoveBy(T aDx, T aDy) { x += aDx; y += aDy; }
-  void MoveBy(const Point& aPoint) { x += aPoint.x; y += aPoint.y; }
-  void SizeTo(T aWidth, T aHeight) { width = aWidth; height = aHeight; }
-  void SizeTo(const SizeT& aSize) { width = aSize.width; height = aSize.height; }
+  MOZ_ALWAYS_INLINE void MoveTo(T aX, T aY) { x = aX; y = aY; }
+  MOZ_ALWAYS_INLINE void MoveToX(T aX) { x = aX; }
+  MOZ_ALWAYS_INLINE void MoveToY(T aY) { y = aY; }
+  MOZ_ALWAYS_INLINE void MoveTo(const Point& aPoint) { x = aPoint.x; y = aPoint.y; }
+  MOZ_ALWAYS_INLINE void MoveBy(T aDx, T aDy) { x += aDx; y += aDy; }
+  MOZ_ALWAYS_INLINE void MoveByX(T aDx) { x += aDx; }
+  MOZ_ALWAYS_INLINE void MoveByY(T aDy) { y += aDy; }
+  MOZ_ALWAYS_INLINE void MoveBy(const Point& aPoint) { x += aPoint.x; y += aPoint.y; }
+  MOZ_ALWAYS_INLINE void SizeTo(T aWidth, T aHeight) { width = aWidth; height = aHeight; }
+  MOZ_ALWAYS_INLINE void SizeTo(const SizeT& aSize) { width = aSize.width; height = aSize.height; }
 
   void Inflate(T aD) { Inflate(aD, aD); }
   void Inflate(T aDx, T aDy)
   {
     x -= aDx;
     y -= aDy;
     width += 2 * aDx;
     height += 2 * aDy;
@@ -257,16 +291,30 @@ struct BaseRect {
   // points on the edges.
   // Use when we care about the exact x/y/width/height values being
   // equal (i.e. we care about differences in empty rectangles).
   bool IsEqualEdges(const Sub& aRect) const
   {
     return x == aRect.x && y == aRect.y &&
            width == aRect.width && height == aRect.height;
   }
+  MOZ_ALWAYS_INLINE bool IsEqualRect(T aX, T aY, T aW, T aH)
+  {
+    return x == aX && y == aY && width == aW && height == aH;
+  }
+  MOZ_ALWAYS_INLINE bool IsEqualXY(T aX, T aY)
+  {
+    return x == aX && y == aY;
+  }
+
+  MOZ_ALWAYS_INLINE bool IsEqualSize(T aW, T aH)
+  {
+    return width == aW && height == aH;
+  }
+
   // Return true if the rectangles contain the same area of the plane.
   // Use when we do not care about differences in empty rectangles.
   bool IsEqualInterior(const Sub& aRect) const
   {
     return IsEqualEdges(aRect) || (IsEmpty() && aRect.IsEmpty());
   }
 
   friend Sub operator+(Sub aSub, const Point& aPoint)
--- a/gfx/tests/gtest/TestRect.cpp
+++ b/gfx/tests/gtest/TestRect.cpp
@@ -17,33 +17,80 @@
 template <class RectType>
 static bool
 TestConstructors()
 {
   // Create a rectangle
   RectType  rect1(10, 20, 30, 40);
 
   // Make sure the rectangle was properly initialized
-  EXPECT_TRUE(rect1.x == 10 && rect1.y == 20 &&
-    rect1.Width() == 30 && rect1.Height() == 40) <<
+  EXPECT_TRUE(rect1.IsEqualRect(10, 20, 30, 40) &&
+              rect1.IsEqualXY(10, 20) && rect1.IsEqualSize(30, 40)) <<
     "[1] Make sure the rectangle was properly initialized with constructor";
 
   // Create a second rect using the copy constructor
   RectType  rect2(rect1);
 
   // Make sure the rectangle was properly initialized
-  EXPECT_TRUE(rect2.x == rect1.x && rect2.y == rect2.y &&
-    rect2.Width() == rect2.Width() && rect2.Height() == rect2.Height()) <<
+  EXPECT_TRUE(rect2.IsEqualEdges(rect1) &&
+              rect2.IsEqualXY(rect1.X(), rect1.Y()) &&
+              rect2.IsEqualSize(rect1.Width(), rect1.Height())) <<
     "[2] Make sure the rectangle was properly initialized with copy constructor";
 
 
-  EXPECT_TRUE(!rect1.IsEmpty() && rect1.IsFinite() &&
-      !rect2.IsEmpty() && rect2.IsFinite()) <<
+  EXPECT_TRUE(!rect1.IsEmpty() && !rect1.IsZero() && rect1.IsFinite() &&
+              !rect2.IsEmpty() && !rect2.IsZero() && rect2.IsFinite()) <<
     "[3] These rectangles are not empty and are finite";
 
+
+  rect1.SetRect(1, 2, 30, 40);
+  EXPECT_TRUE(rect1.X() == 1 && rect1.Y() == 2 &&
+              rect1.Width() == 30 && rect1.Height() == 40 &&
+              rect1.XMost() == 31 && rect1.YMost() == 42);
+
+  rect1.SetRectX(11, 50);
+  EXPECT_TRUE(rect1.X() == 11 && rect1.Y() == 2 &&
+              rect1.Width() == 50 && rect1.Height() == 40 &&
+              rect1.XMost() == 61 && rect1.YMost() == 42);
+
+  rect1.SetRectY(22, 60);
+  EXPECT_TRUE(rect1.X() == 11 && rect1.Y() == 22 &&
+              rect1.Width() == 50 && rect1.Height() == 60 &&
+              rect1.XMost() == 61 && rect1.YMost() == 82);
+
+  rect1.SetBox(1, 2, 31, 42);
+  EXPECT_TRUE(rect1.X() == 1 && rect1.Y() == 2 &&
+              rect1.Width() == 30 && rect1.Height() == 40 &&
+              rect1.XMost() == 31 && rect1.YMost() == 42);
+
+  rect1.SetBoxX(11, 61);
+  EXPECT_TRUE(rect1.X() == 11 && rect1.Y() == 2 &&
+              rect1.Width() == 50 && rect1.Height() == 40 &&
+              rect1.XMost() == 61 && rect1.YMost() == 42);
+
+  rect1.SetBoxY(22, 82);
+  EXPECT_TRUE(rect1.X() == 11 && rect1.Y() == 22 &&
+              rect1.Width() == 50 && rect1.Height() == 60 &&
+              rect1.XMost() == 61 && rect1.YMost() == 82);
+
+  rect1.SetRect(1, 2, 30, 40);
+  EXPECT_TRUE(rect1.X() == 1 && rect1.Y() == 2 &&
+              rect1.Width() == 30 && rect1.Height() == 40 &&
+              rect1.XMost() == 31 && rect1.YMost() == 42);
+
+  rect1.MoveByX(10);
+  EXPECT_TRUE(rect1.X() == 11 && rect1.Y() == 2 &&
+              rect1.Width() == 30 && rect1.Height() == 40 &&
+              rect1.XMost() == 41 && rect1.YMost() == 42);
+
+  rect1.MoveByY(20);
+  EXPECT_TRUE(rect1.X() == 11 && rect1.Y() == 22 &&
+              rect1.Width() == 30 && rect1.Height() == 40 &&
+              rect1.XMost() == 41 && rect1.YMost() == 62);
+
   return true;
 }
 
 template <class RectType>
 static bool
 TestEqualityOperator()
 {
   RectType  rect1(10, 20, 30, 40);
@@ -70,58 +117,64 @@ static bool
 TestContainment()
 {
   RectType  rect1(10, 10, 50, 50);
 
   // Test the point containment methods
   //
 
   // Basic test of a point in the middle of the rect
-  EXPECT_FALSE(!rect1.Contains(rect1.x + rect1.Width()/2, rect1.y + rect1.Height()/2)) <<
+  EXPECT_TRUE(rect1.Contains(rect1.Center()) &&
+              rect1.ContainsX(rect1.Center().x) &&
+              rect1.ContainsY(rect1.Center().y)) <<
     "[1] Basic test of a point in the middle of the rect";
 
   // Test against a point at the left/top edges
-  EXPECT_FALSE(!rect1.Contains(rect1.x, rect1.y)) <<
+  EXPECT_TRUE(rect1.Contains(rect1.X(), rect1.Y()) &&
+              rect1.ContainsX(rect1.X()) &&
+              rect1.ContainsY(rect1.Y())) <<
     "[2] Test against a point at the left/top edges";
 
   // Test against a point at the right/bottom extents
-  EXPECT_FALSE(rect1.Contains(rect1.XMost(), rect1.YMost())) <<
+  EXPECT_FALSE(rect1.Contains(rect1.XMost(), rect1.YMost()) ||
+               rect1.ContainsX(rect1.XMost()) ||
+               rect1.ContainsY(rect1.YMost())) <<
     "[3] Test against a point at the right/bottom extents";
 
   // Test the rect containment methods
   //
   RectType  rect2(rect1);
 
   // Test against a rect that's the same as rect1
   EXPECT_FALSE(!rect1.Contains(rect2)) <<
     "[4] Test against a rect that's the same as rect1";
 
   // Test against a rect whose left edge (only) is outside of rect1
-  rect2.x--;
+  rect2.MoveByX(-1);
   EXPECT_FALSE(rect1.Contains(rect2)) <<
     "[5] Test against a rect whose left edge (only) is outside of rect1";
-  rect2.x++;
+  rect2.MoveByX(1);
 
   // Test against a rect whose top edge (only) is outside of rect1
-  rect2.y--;
+  rect2.MoveByY(-1);
   EXPECT_FALSE(rect1.Contains(rect2)) <<
     "[6] Test against a rect whose top edge (only) is outside of rect1";
-  rect2.y++;
+  rect2.MoveByY(1);
 
   // Test against a rect whose right edge (only) is outside of rect1
-  rect2.x++;
+  rect2.MoveByX(1);
   EXPECT_FALSE(rect1.Contains(rect2)) <<
     "[7] Test against a rect whose right edge (only) is outside of rect1";
-  rect2.x--;
+  rect2.MoveByX(-1);
 
   // Test against a rect whose bottom edge (only) is outside of rect1
-  rect2.y++;
+  rect2.MoveByY(1);
   EXPECT_FALSE(rect1.Contains(rect2)) <<
     "[8] Test against a rect whose bottom edge (only) is outside of rect1";
-  rect2.y--;
+  rect2.MoveByY(-1);
 
   return true;
 }
 
 // Test the method that returns a boolean result but doesn't return a
 // a rectangle
 template <class RectType>
 static bool
@@ -140,62 +193,62 @@ TestIntersects()
     "[2] Test against a rect that's enclosed by rect1";
   rect2.Inflate(1, 1);
 
   // Make sure inflate and deflate worked correctly
   EXPECT_TRUE(rect1.IsEqualInterior(rect2)) <<
     "[3] Make sure inflate and deflate worked correctly";
 
   // Test against a rect that overlaps the left edge of rect1
-  rect2.x--;
+  rect2.MoveByX(-1);
   EXPECT_FALSE(!rect1.Intersects(rect2)) <<
     "[4] Test against a rect that overlaps the left edge of rect1";
-  rect2.x++;
+  rect2.MoveByX(1);
 
   // Test against a rect that's outside of rect1 on the left
-  rect2.x -= rect2.Width();
+  rect2.MoveByX(-rect2.Width());
   EXPECT_FALSE(rect1.Intersects(rect2)) <<
     "[5] Test against a rect that's outside of rect1 on the left";
-  rect2.x += rect2.Width();
+  rect2.MoveByX(rect2.Width());
 
   // Test against a rect that overlaps the top edge of rect1
-  rect2.y--;
+  rect2.MoveByY(-1);
   EXPECT_FALSE(!rect1.Intersects(rect2)) <<
     "[6] Test against a rect that overlaps the top edge of rect1";
-  rect2.y++;
+  rect2.MoveByY(1);
 
   // Test against a rect that's outside of rect1 on the top
-  rect2.y -= rect2.Height();
+  rect2.MoveByY(-rect2.Height());
   EXPECT_FALSE(rect1.Intersects(rect2)) <<
     "[7] Test against a rect that's outside of rect1 on the top";
-  rect2.y += rect2.Height();
+  rect2.MoveByY(rect2.Height());
 
   // Test against a rect that overlaps the right edge of rect1
-  rect2.x++;
+  rect2.MoveByX(1);
   EXPECT_FALSE(!rect1.Intersects(rect2)) <<
     "[8] Test against a rect that overlaps the right edge of rect1";
-  rect2.x--;
+  rect2.MoveByX(-1);
 
   // Test against a rect that's outside of rect1 on the right
-  rect2.x += rect2.Width();
+  rect2.MoveByX(rect2.Width());
   EXPECT_FALSE(rect1.Intersects(rect2)) <<
     "[9] Test against a rect that's outside of rect1 on the right";
-  rect2.x -= rect2.Width();
+  rect2.MoveByX(-rect2.Width());
 
   // Test against a rect that overlaps the bottom edge of rect1
-  rect2.y++;
+  rect2.MoveByY(1);
   EXPECT_FALSE(!rect1.Intersects(rect2)) <<
     "[10] Test against a rect that overlaps the bottom edge of rect1";
-  rect2.y--;
+  rect2.MoveByY(-1);
 
   // Test against a rect that's outside of rect1 on the bottom
-  rect2.y += rect2.Height();
+  rect2.MoveByY(rect2.Height());
   EXPECT_FALSE(rect1.Intersects(rect2)) <<
     "[11] Test against a rect that's outside of rect1 on the bottom";
-  rect2.y -= rect2.Height();
+  rect2.MoveByY(-rect2.Height());
 
   return true;
 }
 
 // Test the method that returns a boolean result and an intersection rect
 template <class RectType>
 static bool
 TestIntersection()
@@ -210,114 +263,114 @@ TestIntersection()
 
   // Test against a rect that's enclosed by rect1
   rect2.Inflate(-1, -1);
   EXPECT_FALSE(!dest.IntersectRect(rect1, rect2) || !(dest.IsEqualInterior(rect2))) <<
     "[2] Test against a rect that's enclosed by rect1";
   rect2.Inflate(1, 1);
 
   // Test against a rect that overlaps the left edge of rect1
-  rect2.x--;
+  rect2.MoveByX(-1);
   EXPECT_FALSE(!dest.IntersectRect(rect1, rect2) ||
-    !(dest.IsEqualInterior(RectType(rect1.x, rect1.y, rect1.Width() - 1, rect1.Height())))) <<
+    !(dest.IsEqualInterior(RectType(rect1.X(), rect1.Y(), rect1.Width() - 1, rect1.Height())))) <<
     "[3] Test against a rect that overlaps the left edge of rect1";
-  rect2.x++;
+  rect2.MoveByX(1);
 
   // Test against a rect that's outside of rect1 on the left
-  rect2.x -= rect2.Width();
+  rect2.MoveByX(-rect2.Width());
   EXPECT_FALSE(dest.IntersectRect(rect1, rect2)) <<
     "[4] Test against a rect that's outside of rect1 on the left";
   // Make sure an empty rect is returned
-  EXPECT_FALSE(!dest.IsEmpty()) <<
+  EXPECT_TRUE(dest.IsEmpty() && dest.IsZero()) <<
     "[4] Make sure an empty rect is returned";
   EXPECT_TRUE(dest.IsFinite()) << "[4b] Should be finite";
-  rect2.x += rect2.Width();
+  rect2.MoveByX(rect2.Width());
 
   // Test against a rect that overlaps the top edge of rect1
-  rect2.y--;
+  rect2.MoveByY(-1);
   EXPECT_FALSE(!dest.IntersectRect(rect1, rect2) ||
-    !(dest.IsEqualInterior(RectType(rect1.x, rect1.y, rect1.Width(), rect1.Height() - 1)))) <<
+    !(dest.IsEqualInterior(RectType(rect1.X(), rect1.Y(), rect1.Width(), rect1.Height() - 1)))) <<
     "[5] Test against a rect that overlaps the top edge of rect1";
   EXPECT_TRUE(dest.IsFinite()) << "[5b] Should be finite";
-  rect2.y++;
+  rect2.MoveByY(1);
 
   // Test against a rect that's outside of rect1 on the top
-  rect2.y -= rect2.Height();
+  rect2.MoveByY(-rect2.Height());
   EXPECT_FALSE(dest.IntersectRect(rect1, rect2)) <<
     "[6] Test against a rect that's outside of rect1 on the top";
   // Make sure an empty rect is returned
-  EXPECT_FALSE(!dest.IsEmpty()) <<
+  EXPECT_TRUE(dest.IsEmpty() && dest.IsZero()) <<
     "[6] Make sure an empty rect is returned";
   EXPECT_TRUE(dest.IsFinite()) << "[6b] Should be finite";
-  rect2.y += rect2.Height();
+  rect2.MoveByY(rect2.Height());
 
   // Test against a rect that overlaps the right edge of rect1
-  rect2.x++;
+  rect2.MoveByX(1);
   EXPECT_FALSE(!dest.IntersectRect(rect1, rect2) ||
-    !(dest.IsEqualInterior(RectType(rect1.x + 1, rect1.y, rect1.Width() - 1, rect1.Height())))) <<
+    !(dest.IsEqualInterior(RectType(rect1.X() + 1, rect1.Y(), rect1.Width() - 1, rect1.Height())))) <<
     "[7] Test against a rect that overlaps the right edge of rect1";
-  rect2.x--;
+  rect2.MoveByX(-1);
 
   // Test against a rect that's outside of rect1 on the right
-  rect2.x += rect2.Width();
+  rect2.MoveByX(rect2.Width());
   EXPECT_FALSE(dest.IntersectRect(rect1, rect2)) <<
     "[8] Test against a rect that's outside of rect1 on the right";
   // Make sure an empty rect is returned
-  EXPECT_FALSE(!dest.IsEmpty()) <<
+  EXPECT_TRUE(dest.IsEmpty() && dest.IsZero()) <<
     "[8] Make sure an empty rect is returned";
   EXPECT_TRUE(dest.IsFinite()) << "[8b] Should be finite";
-  rect2.x -= rect2.Width();
+  rect2.MoveByX(-rect2.Width());
 
   // Test against a rect that overlaps the bottom edge of rect1
-  rect2.y++;
+  rect2.MoveByY(1);
   EXPECT_FALSE(!dest.IntersectRect(rect1, rect2) ||
-    !(dest.IsEqualInterior(RectType(rect1.x, rect1.y + 1, rect1.Width(), rect1.Height() - 1)))) <<
+    !(dest.IsEqualInterior(RectType(rect1.X(), rect1.Y() + 1, rect1.Width(), rect1.Height() - 1)))) <<
     "[9] Test against a rect that overlaps the bottom edge of rect1";
   EXPECT_TRUE(dest.IsFinite()) << "[9b] Should be finite";
-  rect2.y--;
+  rect2.MoveByY(-1);
 
   // Test against a rect that's outside of rect1 on the bottom
-  rect2.y += rect2.Height();
+  rect2.MoveByY(rect2.Height());
   EXPECT_FALSE(dest.IntersectRect(rect1, rect2)) <<
     "[10] Test against a rect that's outside of rect1 on the bottom";
   // Make sure an empty rect is returned
-  EXPECT_FALSE(!dest.IsEmpty()) <<
+  EXPECT_TRUE(dest.IsEmpty() && dest.IsZero()) <<
     "[10] Make sure an empty rect is returned";
   EXPECT_TRUE(dest.IsFinite()) << "[10b] Should be finite";
-  rect2.y -= rect2.Height();
+  rect2.MoveByY(-rect2.Height());
 
   // Test against a rect with zero width or height
   rect1.SetRect(100, 100, 100, 100);
   rect2.SetRect(150, 100, 0, 100);
-  EXPECT_FALSE(dest.IntersectRect(rect1, rect2) || !dest.IsEmpty()) <<
+  EXPECT_TRUE(!dest.IntersectRect(rect1, rect2) && dest.IsEmpty() && dest.IsZero()) <<
     "[11] Intersection of rects with zero width or height should be empty";
   EXPECT_TRUE(dest.IsFinite()) << "[11b] Should be finite";
 
   // Tests against a rect with negative width or height
   //
 
   // Test against a rect with negative width
   rect1.SetRect(100, 100, 100, 100);
   rect2.SetRect(100, 100, -100, 100);
-  EXPECT_FALSE(dest.IntersectRect(rect1, rect2) || !dest.IsEmpty()) <<
+  EXPECT_TRUE(!dest.IntersectRect(rect1, rect2) && dest.IsEmpty() && dest.IsZero()) <<
     "[12] Intersection of rects with negative width or height should be empty";
   EXPECT_TRUE(dest.IsFinite()) << "[12b] Should be finite";
 
   // Those two rects exactly overlap in some way...
   // but we still want to return an empty rect
   rect1.SetRect(100, 100, 100, 100);
   rect2.SetRect(200, 200, -100, -100);
-  EXPECT_FALSE(dest.IntersectRect(rect1, rect2) || !dest.IsEmpty()) <<
+  EXPECT_TRUE(!dest.IntersectRect(rect1, rect2) && dest.IsEmpty() && dest.IsZero()) <<
     "[13] Intersection of rects with negative width or height should be empty";
   EXPECT_TRUE(dest.IsFinite()) << "[13b] Should be finite";
 
   // Test against two identical rects with negative height
   rect1.SetRect(100, 100, 100, -100);
   rect2.SetRect(100, 100, 100, -100);
-  EXPECT_FALSE(dest.IntersectRect(rect1, rect2) || !dest.IsEmpty()) <<
+  EXPECT_TRUE(!dest.IntersectRect(rect1, rect2) && dest.IsEmpty() && dest.IsZero()) <<
     "[14] Intersection of rects with negative width or height should be empty";
   EXPECT_TRUE(dest.IsFinite()) << "[14b] Should be finite";
 
   return true;
 }
 
 template <class RectType>
 static bool
@@ -325,51 +378,51 @@ TestUnion()
 {
   RectType  rect1;
   RectType  rect2(10, 10, 50, 50);
   RectType  dest;
 
   // Check the case where the receiver is an empty rect
   rect1.SetEmpty();
   dest.UnionRect(rect1, rect2);
-  EXPECT_FALSE(dest.IsEmpty() || !dest.IsEqualInterior(rect2)) <<
+  EXPECT_TRUE(!dest.IsEmpty() && !dest.IsZero() && dest.IsEqualInterior(rect2)) <<
     "[1] Check the case where the receiver is an empty rect";
   EXPECT_TRUE(dest.IsFinite()) << "[1b] Should be finite";
 
   // Check the case where the source rect is an empty rect
   rect1 = rect2;
   rect2.SetEmpty();
   dest.UnionRect(rect1, rect2);
-  EXPECT_FALSE(dest.IsEmpty() || !dest.IsEqualInterior(rect1)) <<
+  EXPECT_TRUE(!dest.IsEmpty() && !dest.IsZero() && dest.IsEqualInterior(rect1)) <<
     "[2] Check the case where the source rect is an empty rect";
   EXPECT_TRUE(dest.IsFinite()) << "[2b] Should be finite";
 
   // Test the case where both rects are empty
   rect1.SetEmpty();
   rect2.SetEmpty();
   dest.UnionRect(rect1, rect2);
-  EXPECT_FALSE(!dest.IsEmpty()) <<
+  EXPECT_TRUE(dest.IsEmpty() && dest.IsZero()) <<
     "[3] Test the case where both rects are empty";
   EXPECT_TRUE(dest.IsFinite()) << "[3b] Should be finite";
 
   // Test union case where the two rects don't overlap at all
   rect1.SetRect(10, 10, 50, 50);
   rect2.SetRect(100, 100, 50, 50);
   dest.UnionRect(rect1, rect2);
-  EXPECT_FALSE(dest.IsEmpty() ||
-     !(dest.IsEqualInterior(RectType(rect1.x, rect1.y, rect2.XMost() - rect1.x, rect2.YMost() - rect1.y)))) <<
+  EXPECT_TRUE(!dest.IsEmpty() && !dest.IsZero() &&
+    (dest.IsEqualInterior(RectType(rect1.X(), rect1.Y(), rect2.XMost() - rect1.X(), rect2.YMost() - rect1.Y())))) <<
     "[4] Test union case where the two rects don't overlap at all";
   EXPECT_TRUE(dest.IsFinite()) << "[4b] Should be finite";
 
   // Test union case where the two rects overlap
   rect1.SetRect(30, 30, 50, 50);
   rect2.SetRect(10, 10, 50, 50);
   dest.UnionRect(rect1, rect2);
-  EXPECT_FALSE(dest.IsEmpty() ||
-      !(dest.IsEqualInterior(RectType(rect2.x, rect2.y, rect1.XMost() - rect2.x, rect1.YMost() - rect2.y)))) <<
+  EXPECT_TRUE(!dest.IsEmpty() && !dest.IsZero() &&
+    (dest.IsEqualInterior(RectType(rect2.X(), rect2.Y(), rect1.XMost() - rect2.X(), rect1.YMost() - rect2.Y())))) <<
     "[5] Test union case where the two rects overlap";
   EXPECT_TRUE(dest.IsFinite()) << "[5b] Should be finite";
 
   return true;
 }
 
 static bool
 TestFiniteGfx()
@@ -408,46 +461,45 @@ static bool
 TestBug1135677()
 {
   RectType  rect1(1073741344, 1073741344, 1073756696, 1073819936);
   RectType  rect2(1073741820, 1073741820, 14400, 77640);
   RectType  dest;
 
   dest = rect1.Intersect(rect2);
 
-  EXPECT_TRUE(dest.x == 1073741820 && dest.y == 1073741820 &&
-              dest.Width() == 14400 && dest.Height() == 77640) <<
+  EXPECT_TRUE(dest.IsEqualRect(1073741820, 1073741820, 14400, 77640)) <<
               "[1] Operation should not overflow internally.";
 
   return true;
 }
 
 template <class RectType>
 static bool
 TestSetWH()
 {
   RectType  rect(1, 2, 3, 4);
-  EXPECT_TRUE(rect.X() == 1 && rect.Y() == 2 && rect.Width() == 3 && rect.Height() == 4);
+  EXPECT_TRUE(rect.IsEqualRect(1, 2, 3, 4));
   rect.SetWidth(13);
-  EXPECT_TRUE(rect.X() == 1 && rect.Y() == 2 && rect.Width() == 13 && rect.Height() == 4);
+  EXPECT_TRUE(rect.IsEqualRect(1, 2, 13, 4));
   rect.SetHeight(14);
-  EXPECT_TRUE(rect.X() == 1 && rect.Y() == 2 && rect.Width() == 13 && rect.Height() == 14);
+  EXPECT_TRUE(rect.IsEqualRect(1, 2, 13, 14));
   rect.SizeTo(23, 24);
-  EXPECT_TRUE(rect.X() == 1 && rect.Y() == 2 && rect.Width() == 23 && rect.Height() == 24);
+  EXPECT_TRUE(rect.IsEqualRect(1, 2, 23, 24));
   return true;
 }
 
 template <class RectType>
 static bool
 TestSwap()
 {
   RectType  rect(1, 2, 3, 4);
-  EXPECT_TRUE(rect.X() == 1 && rect.Y() == 2 && rect.Width() == 3 && rect.Height() == 4);
+  EXPECT_TRUE(rect.IsEqualRect(1, 2, 3, 4));
   rect.Swap();
-  EXPECT_TRUE(rect.X() == 2 && rect.Y() == 1 && rect.Width() == 4 && rect.Height() == 3);
+  EXPECT_TRUE(rect.IsEqualRect(2, 1, 4, 3));
   return true;
 }
 
 static void
 TestIntersectionLogicalHelper(nscoord x1, nscoord y1, nscoord w1, nscoord h1,
                               nscoord x2, nscoord y2, nscoord w2, nscoord h2,
                               nscoord xR, nscoord yR, nscoord wR, nscoord hR,
                               bool isNonEmpty)
--- a/gfx/tests/gtest/TestRegion.cpp
+++ b/gfx/tests/gtest/TestRegion.cpp
@@ -380,18 +380,18 @@ struct RegionBitmap {
       }
     }
   }
 
   void set(nsRegion &region) {
     clear();
     for (auto iter = region.RectIter(); !iter.Done(); iter.Next()) {
       const nsRect& r = iter.Get();
-      for (int y = r.y; y < r.YMost(); y++) {
-        for (int x = r.x; x < r.XMost(); x++) {
+      for (int y = r.Y(); y < r.YMost(); y++) {
+        for (int x = r.X(); x < r.XMost(); x++) {
           bitmap[x + y * width] = REGION_VALUE;
         }
       }
     }
   }
 
   void dilate() {
     for (int y = 0; y < height; y++) {