зеркало из https://github.com/mozilla/gecko-dev.git
588 строки
21 KiB
C++
588 строки
21 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#include <limits>
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "nsRect.h"
|
|
#include "gfxRect.h"
|
|
#include "mozilla/WritingModes.h"
|
|
#ifdef XP_WIN
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
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.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.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.IsZeroArea() && rect1.IsFinite() &&
|
|
!rect2.IsEmpty() && !rect2.IsZeroArea() && 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);
|
|
RectType rect2(rect1);
|
|
|
|
// Test the equality operator
|
|
EXPECT_TRUE(rect1 == rect2) <<
|
|
"[1] Test the equality operator";
|
|
|
|
EXPECT_FALSE(!rect1.IsEqualInterior(rect2)) <<
|
|
"[2] Test the inequality operator";
|
|
|
|
// Make sure that two empty rects are equal
|
|
rect1.SetEmpty();
|
|
rect2.SetEmpty();
|
|
EXPECT_TRUE(rect1 == rect2) <<
|
|
"[3] Make sure that two empty rects are equal";
|
|
|
|
return true;
|
|
}
|
|
|
|
template <class RectType>
|
|
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_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_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()) ||
|
|
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.MoveByX(-1);
|
|
EXPECT_FALSE(rect1.Contains(rect2)) <<
|
|
"[5] Test against a rect whose left edge (only) is outside of rect1";
|
|
rect2.MoveByX(1);
|
|
|
|
// Test against a rect whose top edge (only) is outside of rect1
|
|
rect2.MoveByY(-1);
|
|
EXPECT_FALSE(rect1.Contains(rect2)) <<
|
|
"[6] Test against a rect whose top edge (only) is outside of rect1";
|
|
rect2.MoveByY(1);
|
|
|
|
// Test against a rect whose right edge (only) is outside of rect1
|
|
rect2.MoveByX(1);
|
|
EXPECT_FALSE(rect1.Contains(rect2)) <<
|
|
"[7] Test against a rect whose right edge (only) is outside of rect1";
|
|
rect2.MoveByX(-1);
|
|
|
|
// Test against a rect whose bottom edge (only) is outside of rect1
|
|
rect2.MoveByY(1);
|
|
EXPECT_FALSE(rect1.Contains(rect2)) <<
|
|
"[8] Test against a rect whose bottom edge (only) is outside of rect1";
|
|
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
|
|
TestIntersects()
|
|
{
|
|
RectType rect1(10, 10, 50, 50);
|
|
RectType rect2(rect1);
|
|
|
|
// Test against a rect that's the same as rect1
|
|
EXPECT_FALSE(!rect1.Intersects(rect2)) <<
|
|
"[1] Test against a rect that's the same as rect1";
|
|
|
|
// Test against a rect that's enclosed by rect1
|
|
rect2.Inflate(-1, -1);
|
|
EXPECT_FALSE(!rect1.Contains(rect2) || !rect1.Intersects(rect2)) <<
|
|
"[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.MoveByX(-1);
|
|
EXPECT_FALSE(!rect1.Intersects(rect2)) <<
|
|
"[4] Test against a rect that overlaps the left edge of rect1";
|
|
rect2.MoveByX(1);
|
|
|
|
// Test against a rect that's outside of rect1 on the left
|
|
rect2.MoveByX(-rect2.Width());
|
|
EXPECT_FALSE(rect1.Intersects(rect2)) <<
|
|
"[5] Test against a rect that's outside of rect1 on the left";
|
|
rect2.MoveByX(rect2.Width());
|
|
|
|
// Test against a rect that overlaps the top edge of rect1
|
|
rect2.MoveByY(-1);
|
|
EXPECT_FALSE(!rect1.Intersects(rect2)) <<
|
|
"[6] Test against a rect that overlaps the top edge of rect1";
|
|
rect2.MoveByY(1);
|
|
|
|
// Test against a rect that's outside of rect1 on the top
|
|
rect2.MoveByY(-rect2.Height());
|
|
EXPECT_FALSE(rect1.Intersects(rect2)) <<
|
|
"[7] Test against a rect that's outside of rect1 on the top";
|
|
rect2.MoveByY(rect2.Height());
|
|
|
|
// Test against a rect that overlaps the right edge of rect1
|
|
rect2.MoveByX(1);
|
|
EXPECT_FALSE(!rect1.Intersects(rect2)) <<
|
|
"[8] Test against a rect that overlaps the right edge of rect1";
|
|
rect2.MoveByX(-1);
|
|
|
|
// Test against a rect that's outside of rect1 on the right
|
|
rect2.MoveByX(rect2.Width());
|
|
EXPECT_FALSE(rect1.Intersects(rect2)) <<
|
|
"[9] Test against a rect that's outside of rect1 on the right";
|
|
rect2.MoveByX(-rect2.Width());
|
|
|
|
// Test against a rect that overlaps the bottom edge of rect1
|
|
rect2.MoveByY(1);
|
|
EXPECT_FALSE(!rect1.Intersects(rect2)) <<
|
|
"[10] Test against a rect that overlaps the bottom edge of rect1";
|
|
rect2.MoveByY(-1);
|
|
|
|
// Test against a rect that's outside of rect1 on the bottom
|
|
rect2.MoveByY(rect2.Height());
|
|
EXPECT_FALSE(rect1.Intersects(rect2)) <<
|
|
"[11] Test against a rect that's outside of rect1 on the bottom";
|
|
rect2.MoveByY(-rect2.Height());
|
|
|
|
return true;
|
|
}
|
|
|
|
// Test the method that returns a boolean result and an intersection rect
|
|
template <class RectType>
|
|
static bool
|
|
TestIntersection()
|
|
{
|
|
RectType rect1(10, 10, 50, 50);
|
|
RectType rect2(rect1);
|
|
RectType dest;
|
|
|
|
// Test against a rect that's the same as rect1
|
|
EXPECT_FALSE(!dest.IntersectRect(rect1, rect2) || !(dest.IsEqualInterior(rect1))) <<
|
|
"[1] Test against a rect that's the same as rect1";
|
|
|
|
// 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.MoveByX(-1);
|
|
EXPECT_FALSE(!dest.IntersectRect(rect1, rect2) ||
|
|
!(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.MoveByX(1);
|
|
|
|
// Test against a rect that's outside of rect1 on the left
|
|
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_TRUE(dest.IsEmpty() && dest.IsZeroArea()) <<
|
|
"[4] Make sure an empty rect is returned";
|
|
EXPECT_TRUE(dest.IsFinite()) << "[4b] Should be finite";
|
|
rect2.MoveByX(rect2.Width());
|
|
|
|
// Test against a rect that overlaps the top edge of rect1
|
|
rect2.MoveByY(-1);
|
|
EXPECT_FALSE(!dest.IntersectRect(rect1, rect2) ||
|
|
!(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.MoveByY(1);
|
|
|
|
// Test against a rect that's outside of rect1 on the top
|
|
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_TRUE(dest.IsEmpty() && dest.IsZeroArea()) <<
|
|
"[6] Make sure an empty rect is returned";
|
|
EXPECT_TRUE(dest.IsFinite()) << "[6b] Should be finite";
|
|
rect2.MoveByY(rect2.Height());
|
|
|
|
// Test against a rect that overlaps the right edge of rect1
|
|
rect2.MoveByX(1);
|
|
EXPECT_FALSE(!dest.IntersectRect(rect1, rect2) ||
|
|
!(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.MoveByX(-1);
|
|
|
|
// Test against a rect that's outside of rect1 on the right
|
|
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_TRUE(dest.IsEmpty() && dest.IsZeroArea()) <<
|
|
"[8] Make sure an empty rect is returned";
|
|
EXPECT_TRUE(dest.IsFinite()) << "[8b] Should be finite";
|
|
rect2.MoveByX(-rect2.Width());
|
|
|
|
// Test against a rect that overlaps the bottom edge of rect1
|
|
rect2.MoveByY(1);
|
|
EXPECT_FALSE(!dest.IntersectRect(rect1, rect2) ||
|
|
!(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.MoveByY(-1);
|
|
|
|
// Test against a rect that's outside of rect1 on the bottom
|
|
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_TRUE(dest.IsEmpty() && dest.IsZeroArea()) <<
|
|
"[10] Make sure an empty rect is returned";
|
|
EXPECT_TRUE(dest.IsFinite()) << "[10b] Should be finite";
|
|
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_TRUE(!dest.IntersectRect(rect1, rect2) && dest.IsEmpty() && dest.IsZeroArea()) <<
|
|
"[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_TRUE(!dest.IntersectRect(rect1, rect2) && dest.IsEmpty() && dest.IsZeroArea()) <<
|
|
"[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_TRUE(!dest.IntersectRect(rect1, rect2) && dest.IsEmpty() && dest.IsZeroArea()) <<
|
|
"[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_TRUE(!dest.IntersectRect(rect1, rect2) && dest.IsEmpty() && dest.IsZeroArea()) <<
|
|
"[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
|
|
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_TRUE(!dest.IsEmpty() && !dest.IsZeroArea() && 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_TRUE(!dest.IsEmpty() && !dest.IsZeroArea() && 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_TRUE(dest.IsEmpty() && dest.IsZeroArea()) <<
|
|
"[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_TRUE(!dest.IsEmpty() && !dest.IsZeroArea() &&
|
|
(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_TRUE(!dest.IsEmpty() && !dest.IsZeroArea() &&
|
|
(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()
|
|
{
|
|
float posInf = std::numeric_limits<float>::infinity();
|
|
float negInf = -std::numeric_limits<float>::infinity();
|
|
float justNaN = std::numeric_limits<float>::quiet_NaN();
|
|
|
|
gfxFloat values[4] = {5.0, 10.0, 15.0, 20.0};
|
|
|
|
// Try the "non-finite" values for x, y, width, height, one at a time
|
|
for (int i=0; i<4; i+=1) {
|
|
values[i] = posInf;
|
|
gfxRect rectPosInf(values[0], values[1], values[2], values[3]);
|
|
EXPECT_FALSE(rectPosInf.IsFinite()) << "For +inf (" << values[0] << "," << values[1] << "," << values[2] << "," << values[3] << ")";
|
|
|
|
values[i] = negInf;
|
|
gfxRect rectNegInf(values[0], values[1], values[2], values[3]);
|
|
EXPECT_FALSE(rectNegInf.IsFinite()) << "For -inf (" << values[0] << "," << values[1] << "," << values[2] << "," << values[3] << ")";
|
|
|
|
values[i] = justNaN;
|
|
gfxRect rectNaN(values[0], values[1], values[2], values[3]);
|
|
EXPECT_FALSE(rectNaN.IsFinite()) << "For NaN (" << values[0] << "," << values[1] << "," << values[2] << "," << values[3] << ")";
|
|
|
|
// Reset to a finite value...
|
|
values[i] = 5.0*i;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// We want to test nsRect values that are still in range but where
|
|
// the implementation is at risk of overflowing
|
|
template <class RectType>
|
|
static bool
|
|
TestBug1135677()
|
|
{
|
|
RectType rect1(1073741344, 1073741344, 1073756696, 1073819936);
|
|
RectType rect2(1073741820, 1073741820, 14400, 77640);
|
|
RectType dest;
|
|
|
|
dest = rect1.Intersect(rect2);
|
|
|
|
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.IsEqualRect(1, 2, 3, 4));
|
|
rect.SetWidth(13);
|
|
EXPECT_TRUE(rect.IsEqualRect(1, 2, 13, 4));
|
|
rect.SetHeight(14);
|
|
EXPECT_TRUE(rect.IsEqualRect(1, 2, 13, 14));
|
|
rect.SizeTo(23, 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.IsEqualRect(1, 2, 3, 4));
|
|
rect.Swap();
|
|
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)
|
|
{
|
|
nsRect rect1(x1, y1, w1, h1);
|
|
nsRect rect2(x2, y2, w2, h2);
|
|
nsRect rectDebug;
|
|
EXPECT_TRUE(isNonEmpty == rectDebug.IntersectRect(rect1, rect2));
|
|
EXPECT_TRUE(rectDebug.IsEqualEdges(nsRect(xR, yR, wR, hR)));
|
|
|
|
mozilla::LogicalRect r1(mozilla::WritingMode(), rect1.X(), rect1.Y(), rect1.Width(), rect1.Height());
|
|
mozilla::LogicalRect r2(mozilla::WritingMode(), rect2.X(), rect2.Y(), rect2.Width(), rect2.Height());
|
|
EXPECT_TRUE(isNonEmpty == r1.IntersectRect(r1, r2));
|
|
EXPECT_TRUE(rectDebug.IsEqualEdges(nsRect(r1.IStart(WritingMode()), r1.BStart(WritingMode()),
|
|
r1.ISize(WritingMode()), r1.BSize(WritingMode()))));
|
|
|
|
mozilla::LogicalRect r3(mozilla::WritingMode(), rect1.X(), rect1.Y(), rect1.Width(), rect1.Height());
|
|
mozilla::LogicalRect r4(mozilla::WritingMode(), rect2.X(), rect2.Y(), rect2.Width(), rect2.Height());
|
|
EXPECT_TRUE(isNonEmpty == r4.IntersectRect(r3, r4));
|
|
EXPECT_TRUE(rectDebug.IsEqualEdges(nsRect(r4.IStart(WritingMode()), r4.BStart(WritingMode()),
|
|
r4.ISize(WritingMode()), r4.BSize(WritingMode()))));
|
|
|
|
mozilla::LogicalRect r5(mozilla::WritingMode(), rect1.X(), rect1.Y(), rect1.Width(), rect1.Height());
|
|
mozilla::LogicalRect r6(mozilla::WritingMode(), rect2.X(), rect2.Y(), rect2.Width(), rect2.Height());
|
|
mozilla::LogicalRect r7(mozilla::WritingMode(), 0, 0, 1, 1);
|
|
EXPECT_TRUE(isNonEmpty == r7.IntersectRect(r5, r6));
|
|
EXPECT_TRUE(rectDebug.IsEqualEdges(nsRect(r7.IStart(WritingMode()), r7.BStart(WritingMode()),
|
|
r7.ISize(WritingMode()), r7.BSize(WritingMode()))));
|
|
}
|
|
|
|
static void
|
|
TestIntersectionLogical(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)
|
|
{
|
|
TestIntersectionLogicalHelper(x1, y1, w1, h1, x2, y2, w2, h2, xR, yR, wR, hR, isNonEmpty);
|
|
TestIntersectionLogicalHelper(x2, y2, w2, h2, x1, y1, w1, h1, xR, yR, wR, hR, isNonEmpty);
|
|
}
|
|
|
|
TEST(Gfx, Logical)
|
|
{
|
|
TestIntersectionLogical(578, 0, 2650, 1152, 1036, 0, 2312, 1, 1036, 0, 2192, 1, true);
|
|
TestIntersectionLogical(0, 0, 1000, 1000, 500, 500, 1000, 1000, 500, 500, 500, 500, true);
|
|
TestIntersectionLogical(100, 200, 300, 400, 50, 250, 100, 100, 100, 250, 50, 100, true);
|
|
TestIntersectionLogical(0, 100, 200, 300, 300, 100, 100, 300, 300, 100, 0, 0, false);
|
|
}
|
|
|
|
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>();
|
|
}
|
|
|