blob: 0793eaa8af9764d3522bf177dd073b2b59b36a40 [file] [log] [blame]
/*
* Copyright (C) 2014-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <WebCore/FloatRect.h>
#include <WebCore/IntPoint.h>
#include <WebCore/IntRect.h>
#include <WebCore/IntSize.h>
#if USE(CG)
#include <CoreGraphics/CoreGraphics.h>
#endif
#if PLATFORM(WIN)
#include <d2d1.h>
#endif
namespace TestWebKitAPI {
static void testGetAndSet(WebCore::IntRect rect)
{
rect.setX(1);
EXPECT_EQ(1, rect.x());
rect.setY(2);
EXPECT_EQ(2, rect.y());
rect.setWidth(203);
EXPECT_EQ(203, rect.width());
rect.setHeight(73);
EXPECT_EQ(73, rect.height());
}
static void testEmptyRect(const WebCore::IntRect& rect)
{
EXPECT_EQ(0, rect.x());
EXPECT_EQ(0, rect.y());
EXPECT_EQ(0, rect.width());
EXPECT_EQ(0, rect.height());
EXPECT_EQ(0, rect.maxX());
EXPECT_EQ(0, rect.maxY());
EXPECT_TRUE(rect.isEmpty());
}
TEST(IntRect, DefaultConstruction)
{
WebCore::IntRect test;
testEmptyRect(test);
testGetAndSet(test);
auto location = test.location();
EXPECT_EQ(0, location.x());
EXPECT_EQ(0, location.y());
auto size = test.size();
EXPECT_EQ(0, size.width());
EXPECT_EQ(0, size.height());
}
TEST(IntRect, ValueConstruction)
{
WebCore::IntRect test(10, 20, 100, 50);
EXPECT_EQ(10, test.x());
EXPECT_EQ(20, test.y());
EXPECT_EQ(100, test.width());
EXPECT_EQ(50, test.height());
EXPECT_EQ(110, test.maxX());
EXPECT_EQ(70, test.maxY());
EXPECT_FALSE(test.isEmpty());
auto location = test.location();
EXPECT_EQ(10, location.x());
EXPECT_EQ(20, location.y());
auto size = test.size();
EXPECT_EQ(100, size.width());
EXPECT_EQ(50, size.height());
}
TEST(IntRect, PointSizeConstruction)
{
WebCore::IntPoint location(20, 30);
WebCore::IntSize size(100, 50);
WebCore::IntRect test(location, size);
EXPECT_EQ(20, test.x());
EXPECT_EQ(30, test.y());
EXPECT_EQ(100, test.width());
EXPECT_EQ(50, test.height());
EXPECT_EQ(120, test.maxX());
EXPECT_EQ(80, test.maxY());
EXPECT_FALSE(test.isEmpty());
auto location2 = test.location();
EXPECT_EQ(20, location2.x());
EXPECT_EQ(30, location2.y());
auto size2 = test.size();
EXPECT_EQ(100, size2.width());
EXPECT_EQ(50, size2.height());
}
TEST(IntRect, FloatRectConstruction)
{
WebCore::FloatRect rect(20.0f, 30.0f, 150.0f, 300.0f);
WebCore::IntRect test(rect);
EXPECT_EQ(20, test.x());
EXPECT_EQ(30, test.y());
EXPECT_EQ(150, test.width());
EXPECT_EQ(300, test.height());
EXPECT_EQ(170, test.maxX());
EXPECT_EQ(330, test.maxY());
EXPECT_FALSE(test.isEmpty());
auto location = test.location();
EXPECT_EQ(20, location.x());
EXPECT_EQ(30, location.y());
auto size = test.size();
EXPECT_EQ(150, size.width());
EXPECT_EQ(300, size.height());
}
TEST(IntRect, SetLocationAndSize)
{
WebCore::IntRect rect;
testEmptyRect(rect);
WebCore::IntPoint location(10, 20);
rect.setLocation(location);
EXPECT_EQ(10, rect.x());
EXPECT_EQ(20, rect.y());
EXPECT_EQ(0, rect.width());
EXPECT_EQ(0, rect.height());
EXPECT_EQ(10, rect.maxX());
EXPECT_EQ(20, rect.maxY());
EXPECT_TRUE(rect.isEmpty());
WebCore::IntSize size(100, 200);
rect.setSize(size);
EXPECT_EQ(10, rect.x());
EXPECT_EQ(20, rect.y());
EXPECT_EQ(100, rect.width());
EXPECT_EQ(200, rect.height());
EXPECT_EQ(110, rect.maxX());
EXPECT_EQ(220, rect.maxY());
EXPECT_FALSE(rect.isEmpty());
}
TEST(IntRect, Center)
{
WebCore::IntRect rect(20, 40, 100, 200);
auto center = rect.center();
EXPECT_EQ(70, center.x());
EXPECT_EQ(140, center.y());
}
TEST(IntRect, Move)
{
WebCore::IntRect rect(20, 30, 100, 200);
WebCore::IntSize delta(10, 20);
rect.move(delta);
EXPECT_EQ(30, rect.x());
EXPECT_EQ(50, rect.y());
WebCore::IntPoint deltaPoint(-20, -40);
rect.moveBy(deltaPoint);
EXPECT_EQ(10, rect.x());
EXPECT_EQ(10, rect.y());
rect.move(-10, 22);
EXPECT_EQ(0, rect.x());
EXPECT_EQ(32, rect.y());
}
TEST(IntRect, Expand)
{
WebCore::IntRect rect(20, 30, 100, 200);
WebCore::IntSize size(100, 100);
rect.expand(size);
EXPECT_EQ(200, rect.width());
EXPECT_EQ(300, rect.height());
rect.expand(55, 22);
EXPECT_EQ(255, rect.width());
EXPECT_EQ(322, rect.height());
WebCore::IntSize size2(-10, -20);
rect.expand(size2);
EXPECT_EQ(245, rect.width());
EXPECT_EQ(302, rect.height());
rect.expand(-5, -2);
EXPECT_EQ(240, rect.width());
EXPECT_EQ(300, rect.height());
}
TEST(IntRect, Contract)
{
WebCore::IntRect rect(20, 30, 100, 200);
WebCore::IntSize size(50, 100);
rect.contract(size);
EXPECT_EQ(50, rect.width());
EXPECT_EQ(100, rect.height());
rect.contract(25, 22);
EXPECT_EQ(25, rect.width());
EXPECT_EQ(78, rect.height());
WebCore::IntSize size2(-10, -20);
rect.contract(size2);
EXPECT_EQ(35, rect.width());
EXPECT_EQ(98, rect.height());
rect.contract(-5, -2);
EXPECT_EQ(40, rect.width());
EXPECT_EQ(100, rect.height());
}
TEST(IntRect, ShiftXEdge)
{
WebCore::IntRect rect(20, 30, 100, 200);
rect.shiftXEdgeTo(77);
EXPECT_EQ(77, rect.x());
EXPECT_EQ(120, rect.maxX());
EXPECT_EQ(30, rect.y());
EXPECT_EQ(230, rect.maxY());
EXPECT_EQ(43, rect.width());
EXPECT_EQ(200, rect.height());
rect.shiftMaxXEdgeTo(200);
EXPECT_EQ(77, rect.x());
EXPECT_EQ(200, rect.maxX());
EXPECT_EQ(30, rect.y());
EXPECT_EQ(230, rect.maxY());
EXPECT_EQ(123, rect.width());
EXPECT_EQ(200, rect.height());
}
TEST(IntRect, ShiftYEdge)
{
WebCore::IntRect rect(20, 30, 100, 200);
rect.shiftYEdgeTo(59.0f);
EXPECT_EQ(20, rect.x());
EXPECT_EQ(120, rect.maxX());
EXPECT_EQ(59, rect.y());
EXPECT_EQ(230, rect.maxY());
EXPECT_EQ(100, rect.width());
EXPECT_EQ(171, rect.height());
rect.shiftMaxYEdgeTo(270.0f);
EXPECT_EQ(20, rect.x());
EXPECT_EQ(120, rect.maxX());
EXPECT_EQ(59, rect.y());
EXPECT_EQ(270, rect.maxY());
EXPECT_EQ(100, rect.width());
EXPECT_EQ(211, rect.height());
}
TEST(IntRect, Inflate)
{
WebCore::IntRect rect(20, 30, 100, 200);
rect.inflateX(5);
EXPECT_EQ(15, rect.x());
EXPECT_EQ(125, rect.maxX());
rect.inflateY(4);
EXPECT_EQ(26, rect.y());
EXPECT_EQ(234, rect.maxY());
rect.inflate(10);
EXPECT_EQ(5, rect.x());
EXPECT_EQ(135, rect.maxX());
EXPECT_EQ(16, rect.y());
EXPECT_EQ(244, rect.maxY());
}
TEST(IntRect, Corners)
{
WebCore::IntRect rect(20, 30, 100, 200);
WebCore::FloatPoint topLeft = rect.minXMinYCorner();
EXPECT_EQ(20, topLeft.x());
EXPECT_EQ(30, topLeft.y());
WebCore::FloatPoint topRight = rect.maxXMinYCorner();
EXPECT_EQ(120, topRight.x());
EXPECT_EQ(30, topRight.y());
WebCore::FloatPoint bottomLeft = rect.minXMaxYCorner();
EXPECT_EQ(20, bottomLeft.x());
EXPECT_EQ(230, bottomLeft.y());
WebCore::FloatPoint bottomRight = rect.maxXMaxYCorner();
EXPECT_EQ(120, bottomRight.x());
EXPECT_EQ(230, bottomRight.y());
}
TEST(IntRect, Contains)
{
WebCore::IntRect rect(20, 30, 100, 200);
WebCore::IntRect contained(30, 40, 50, 100);
ASSERT_TRUE(rect.contains(contained));
WebCore::IntRect outside(120, 230, 50, 100);
ASSERT_FALSE(rect.contains(outside));
WebCore::IntRect intersects(10, 20, 90, 180);
ASSERT_FALSE(rect.contains(intersects));
WebCore::IntPoint pointInside(60, 70);
ASSERT_TRUE(rect.contains(pointInside));
WebCore::IntPoint pointOutside(160, 270);
ASSERT_FALSE(rect.contains(pointOutside));
WebCore::IntPoint pointOnLine(20, 30);
ASSERT_TRUE(rect.contains(pointOnLine));
ASSERT_TRUE(rect.contains(60, 70));
ASSERT_FALSE(rect.contains(160, 270));
}
TEST(IntRect, Intersects)
{
WebCore::IntRect rect(20, 30, 100, 200);
WebCore::IntRect contained(30, 40, 50, 100);
ASSERT_TRUE(rect.intersects(contained));
WebCore::IntRect outside(120, 230, 50, 100);
ASSERT_FALSE(rect.intersects(outside));
WebCore::IntRect intersects(10, 20, 90, 180);
ASSERT_TRUE(rect.intersects(intersects));
}
static void testIntersectResult(const WebCore::IntRect& rect)
{
EXPECT_EQ(70, rect.x());
EXPECT_EQ(120, rect.maxX());
EXPECT_EQ(80, rect.y());
EXPECT_EQ(230, rect.maxY());
}
TEST(IntRect, Intersect)
{
WebCore::IntRect rectA(20, 30, 100, 200);
WebCore::IntRect rectB(70, 80, 100, 200);
rectA.intersect(rectB);
testIntersectResult(rectA);
WebCore::IntRect rectC(20, 30, 100, 200);
auto intersected = WebCore::intersection(rectC, rectB);
testIntersectResult(intersected);
}
static void testUnitedRects(const WebCore::IntRect& united)
{
EXPECT_EQ(20, united.x());
EXPECT_EQ(170, united.maxX());
EXPECT_EQ(30, united.y());
EXPECT_EQ(280, united.maxY());
}
TEST(IntRect, Unite)
{
WebCore::IntRect rectA(20, 30, 100, 200);
WebCore::IntRect rectB(70, 80, 100, 200);
rectA.unite(rectB);
testUnitedRects(rectA);
WebCore::IntRect rectC(20, 30, 100, 200);
auto united = WebCore::unionRect(rectC, rectB);
testUnitedRects(united);
}
TEST(IntRect, Scale)
{
WebCore::IntRect rect(20, 30, 100, 200);
rect.scale(2.0f);
EXPECT_EQ(40, rect.x());
EXPECT_EQ(240, rect.maxX());
EXPECT_EQ(60, rect.y());
EXPECT_EQ(460, rect.maxY());
}
TEST(IntRect, Transpose)
{
WebCore::IntRect rect(20, 30, 100, 200);
auto transposed = rect.transposedRect();
EXPECT_EQ(30, transposed.x());
EXPECT_EQ(230, transposed.maxX());
EXPECT_EQ(20, transposed.y());
EXPECT_EQ(120, transposed.maxY());
}
#if USE(CG) || PLATFORM(WIN)
static void checkCastRect(const WebCore::IntRect& rect)
{
EXPECT_EQ(10, rect.x());
EXPECT_EQ(40, rect.maxX());
EXPECT_EQ(20, rect.y());
EXPECT_EQ(60, rect.maxY());
EXPECT_EQ(30, rect.width());
EXPECT_EQ(40, rect.height());
}
#endif
TEST(IntRect, Casting)
{
WebCore::IntRect rect(10, 20, 30, 40);
#if USE(CG)
CGRect cgRect = CGRectMake(10.0, 20.0, 30.0, 40.0);
WebCore::IntRect rectFromCGRect(cgRect);
checkCastRect(rectFromCGRect);
#endif
#if PLATFORM(WIN)
RECT gdiRect = rect;
EXPECT_EQ(10, gdiRect.left);
EXPECT_EQ(20, gdiRect.top);
EXPECT_EQ(40, gdiRect.right);
EXPECT_EQ(60, gdiRect.bottom);
WebCore::IntRect rectFromGDIRect(gdiRect);
checkCastRect(rectFromGDIRect);
D2D1_RECT_U d2dRectU = rect;
EXPECT_EQ(10, d2dRectU.left);
EXPECT_EQ(20, d2dRectU.top);
EXPECT_EQ(40, d2dRectU.right);
EXPECT_EQ(60, d2dRectU.bottom);
WebCore::IntRect rectFromD2DRectU(d2dRectU);
checkCastRect(rectFromD2DRectU);
D2D1_RECT_F d2dRectF = rect;
EXPECT_FLOAT_EQ(10.0f, d2dRectF.left);
EXPECT_FLOAT_EQ(20.0f, d2dRectF.top);
EXPECT_FLOAT_EQ(40.0f, d2dRectF.right);
EXPECT_FLOAT_EQ(60.0f, d2dRectF.bottom);
WebCore::IntRect rectFromD2DRectF(d2dRectF);
checkCastRect(rectFromD2DRectF);
#endif
}
static void checkSubtractionResult1(const WebCore::IntRect& rect)
{
EXPECT_EQ(-10, rect.x());
EXPECT_EQ(90, rect.maxX());
EXPECT_EQ(-10, rect.y());
EXPECT_EQ(90, rect.maxY());
EXPECT_EQ(100, rect.width());
EXPECT_EQ(100, rect.height());
}
static void checkSubtractionResult2(const WebCore::IntRect& rect)
{
EXPECT_EQ(-40, rect.x());
EXPECT_EQ(60, rect.maxX());
EXPECT_EQ(-50, rect.y());
EXPECT_EQ(50, rect.maxY());
EXPECT_EQ(100, rect.width());
EXPECT_EQ(100, rect.height());
}
TEST(IntRect, Subtraction)
{
WebCore::IntRect rect(10, 20, 100, 100);
WebCore::IntPoint rightSide(20, 30);
rect -= rightSide;
checkSubtractionResult1(rect);
auto rect2 = rect - WebCore::IntPoint(30, 40);
checkSubtractionResult2(rect2);
}
TEST(IntRect, Equality)
{
WebCore::IntRect rect(10, 20, 100, 100);
WebCore::IntRect rect2(10, 20, 100, 100);
WebCore::IntRect rightSide(110, 20, 20, 100);
ASSERT_TRUE(rect == rect2);
ASSERT_FALSE(rect != rect2);
ASSERT_TRUE(rect != rightSide);
ASSERT_FALSE(rect == rightSide);
}
#if USE(CG)
static void checkEnclosingIntRect(const WebCore::IntRect& rect)
{
EXPECT_EQ(10, rect.x());
EXPECT_EQ(41, rect.maxX());
EXPECT_EQ(21, rect.y());
EXPECT_EQ(62, rect.maxY());
EXPECT_EQ(31, rect.width());
EXPECT_EQ(41, rect.height());
}
#endif
TEST(IntRect, EnclosingIntRect)
{
#if USE(CG)
CGRect cgRect = CGRectMake(10.5, 21.3, 30.1, 40.0);
WebCore::IntRect enclosingCG = WebCore::enclosingIntRect(cgRect);
checkEnclosingIntRect(enclosingCG);
#endif
}
TEST(IntRect, AreaAndDistances)
{
WebCore::IntRect rect(10, 20, 100, 100);
EXPECT_EQ(10000U, rect.area().unsafeGet());
}
}