--- a/gfx/2d/BaseRect.h
+++ b/gfx/2d/BaseRect.h
@@ -347,22 +347,26 @@ struct BaseRect {
MOZ_CRASH("GFX: Incomplete switch");
}
Point Center() const { return Point(x, y) + Point(width, height)/2; }
SizeT Size() const { return SizeT(width, height); }
T Area() const { return width * height; }
// Helper methods for computing the extents
- T X() const { return x; }
- T Y() const { return y; }
- T Width() const { return width; }
- T Height() const { return height; }
- T XMost() const { return x + width; }
- T YMost() const { return y + height; }
+ MOZ_ALWAYS_INLINE T X() const { return x; }
+ MOZ_ALWAYS_INLINE T Y() const { return y; }
+ MOZ_ALWAYS_INLINE T Width() const { return width; }
+ MOZ_ALWAYS_INLINE T Height() const { return height; }
+ MOZ_ALWAYS_INLINE T XMost() const { return x + width; }
+ MOZ_ALWAYS_INLINE T YMost() const { return y + height; }
+
+ // Set width and height. SizeTo() sets them together.
+ MOZ_ALWAYS_INLINE void SetWidth(T aWidth) { width = aWidth; }
+ MOZ_ALWAYS_INLINE void SetHeight(T aHeight) { height = aHeight; }
// Get the coordinate of the edge on the given side.
T Edge(mozilla::Side aSide) const
{
switch (aSide) {
case eSideTop: return Y();
case eSideRight: return XMost();
case eSideBottom: return YMost();
@@ -385,16 +389,20 @@ struct BaseRect {
MOZ_ASSERT(aY <= YMost());
height = YMost() - aY;
y = aY;
}
void SetBottomEdge(T aYMost) {
MOZ_ASSERT(aYMost >= y);
height = aYMost - y;
}
+ void Swap() {
+ std::swap(x, y);
+ std::swap(width, height);
+ }
// Round the rectangle edges to integer coordinates, such that the rounded
// rectangle has the same set of pixel centers as the original rectangle.
// Edges at offset 0.5 round up.
// Suitable for most places where integral device coordinates
// are needed, but note that any translation should be applied first to
// avoid pixel rounding errors.
// Note that this is *not* rounding to nearest integer if the values are negative.
--- a/gfx/tests/gtest/TestRect.cpp
+++ b/gfx/tests/gtest/TestRect.cpp
@@ -16,25 +16,25 @@ 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) <<
+ rect1.Width() == 30 && rect1.Height() == 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) <<
+ rect2.Width() == rect2.Width() && rect2.Height() == rect2.Height()) <<
"[2] Make sure the rectangle was properly initialized with copy constructor";
EXPECT_TRUE(!rect1.IsEmpty() && rect1.IsFinite() &&
!rect2.IsEmpty() && rect2.IsFinite()) <<
"[3] These rectangles are not empty and are finite";
return true;
@@ -68,17 +68,17 @@ 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_FALSE(!rect1.Contains(rect1.x + rect1.Width()/2, rect1.y + rect1.Height()/2)) <<
"[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)) <<
"[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())) <<
@@ -144,56 +144,56 @@ TestIntersects()
// Test against a rect that overlaps the left edge of rect1
rect2.x--;
EXPECT_FALSE(!rect1.Intersects(rect2)) <<
"[4] Test against a rect that overlaps the left edge of rect1";
rect2.x++;
// Test against a rect that's outside of rect1 on the left
- rect2.x -= rect2.width;
+ rect2.x -= 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.x += rect2.Width();
// Test against a rect that overlaps the top edge of rect1
rect2.y--;
EXPECT_FALSE(!rect1.Intersects(rect2)) <<
"[6] Test against a rect that overlaps the top edge of rect1";
rect2.y++;
// Test against a rect that's outside of rect1 on the top
- rect2.y -= rect2.height;
+ rect2.y -= 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.y += rect2.Height();
// Test against a rect that overlaps the right edge of rect1
rect2.x++;
EXPECT_FALSE(!rect1.Intersects(rect2)) <<
"[8] Test against a rect that overlaps the right edge of rect1";
rect2.x--;
// Test against a rect that's outside of rect1 on the right
- rect2.x += rect2.width;
+ rect2.x += 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.x -= rect2.Width();
// Test against a rect that overlaps the bottom edge of rect1
rect2.y++;
EXPECT_FALSE(!rect1.Intersects(rect2)) <<
"[10] Test against a rect that overlaps the bottom edge of rect1";
rect2.y--;
// Test against a rect that's outside of rect1 on the bottom
- rect2.y += rect2.height;
+ rect2.y += 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.y -= rect2.Height();
return true;
}
// Test the method that returns a boolean result and an intersection rect
template <class RectType>
static bool
TestIntersection()
@@ -210,82 +210,82 @@ TestIntersection()
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--;
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++;
// Test against a rect that's outside of rect1 on the left
- rect2.x -= rect2.width;
+ rect2.x -= 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()) <<
"[4] Make sure an empty rect is returned";
EXPECT_TRUE(dest.IsFinite()) << "[4b] Should be finite";
- rect2.x += rect2.width;
+ rect2.x += rect2.Width();
// Test against a rect that overlaps the top edge of rect1
rect2.y--;
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++;
// Test against a rect that's outside of rect1 on the top
- rect2.y -= rect2.height;
+ rect2.y -= 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()) <<
"[6] Make sure an empty rect is returned";
EXPECT_TRUE(dest.IsFinite()) << "[6b] Should be finite";
- rect2.y += rect2.height;
+ rect2.y += rect2.Height();
// Test against a rect that overlaps the right edge of rect1
rect2.x++;
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--;
// Test against a rect that's outside of rect1 on the right
- rect2.x += rect2.width;
+ rect2.x += 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()) <<
"[8] Make sure an empty rect is returned";
EXPECT_TRUE(dest.IsFinite()) << "[8b] Should be finite";
- rect2.x -= rect2.width;
+ rect2.x -= rect2.Width();
// Test against a rect that overlaps the bottom edge of rect1
rect2.y++;
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--;
// Test against a rect that's outside of rect1 on the bottom
- rect2.y += rect2.height;
+ rect2.y += 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()) <<
"[10] Make sure an empty rect is returned";
EXPECT_TRUE(dest.IsFinite()) << "[10b] Should be finite";
- rect2.y -= rect2.height;
+ rect2.y -= 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()) <<
"[11] Intersection of rects with zero width or height should be empty";
EXPECT_TRUE(dest.IsFinite()) << "[11b] Should be finite";
@@ -407,44 +407,78 @@ 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) <<
+ dest.Width() == 14400 && dest.Height() == 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);
+ rect.SetWidth(13);
+ EXPECT_TRUE(rect.X() == 1 && rect.Y() == 2 && rect.Width() == 13 && rect.Height() == 4);
+ rect.SetHeight(14);
+ EXPECT_TRUE(rect.X() == 1 && rect.Y() == 2 && rect.Width() == 13 && rect.Height() == 14);
+ rect.SizeTo(23, 24);
+ EXPECT_TRUE(rect.X() == 1 && rect.Y() == 2 && rect.Width() == 23 && rect.Height() == 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);
+ rect.Swap();
+ EXPECT_TRUE(rect.X() == 2 && rect.Y() == 1 && rect.Width() == 4 && rect.Height() == 3);
+ return true;
+}
+
+
+
TEST(Gfx, nsRect) {
TestConstructors<nsRect>();
TestEqualityOperator<nsRect>();
TestContainment<nsRect>();
TestIntersects<nsRect>();
TestIntersection<nsRect>();
TestUnion<nsRect>();
TestBug1135677<nsRect>();
+ TestSetWH<nsRect>();
+ TestSwap<nsRect>();
}
TEST(Gfx, nsIntRect) {
TestConstructors<nsIntRect>();
TestEqualityOperator<nsIntRect>();
TestContainment<nsIntRect>();
TestIntersects<nsIntRect>();
TestIntersection<nsIntRect>();
TestUnion<nsIntRect>();
TestBug1135677<nsIntRect>();
+ TestSetWH<nsIntRect>();
+ TestSwap<nsIntRect>();
}
TEST(Gfx, gfxRect) {
TestConstructors<gfxRect>();
// Skip TestEqualityOperator<gfxRect>(); as gfxRect::operator== is private
TestContainment<gfxRect>();
TestIntersects<gfxRect>();
TestIntersection<gfxRect>();
TestUnion<gfxRect>();
TestBug1135677<gfxRect>();
TestFiniteGfx();
+ TestSetWH<gfxRect>();
+ TestSwap<gfxRect>();
}