1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/tests/gtest/TestRegion.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,285 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "gtest/gtest.h" 1.10 +#include "nsRegion.h" 1.11 + 1.12 +class TestLargestRegion { 1.13 +public: 1.14 + static void TestSingleRect(nsRect r) { 1.15 + nsRegion region(r); 1.16 + EXPECT_TRUE(region.GetLargestRectangle().IsEqualInterior(r)); 1.17 + } 1.18 + // Construct a rectangle, remove part of it, then check the remainder 1.19 + static void TestNonRectangular() { 1.20 + nsRegion r(nsRect(0, 0, 30, 30)); 1.21 + 1.22 + const int nTests = 19; 1.23 + struct { 1.24 + nsRect rect; 1.25 + int64_t expectedArea; 1.26 + } tests[nTests] = { 1.27 + // Remove a 20x10 chunk from the square 1.28 + { nsRect(0, 0, 20, 10), 600 }, 1.29 + { nsRect(10, 0, 20, 10), 600 }, 1.30 + { nsRect(10, 20, 20, 10), 600 }, 1.31 + { nsRect(0, 20, 20, 10), 600 }, 1.32 + // Remove a 10x20 chunk from the square 1.33 + { nsRect(0, 0, 10, 20), 600 }, 1.34 + { nsRect(20, 0, 10, 20), 600 }, 1.35 + { nsRect(20, 10, 10, 20), 600 }, 1.36 + { nsRect(0, 10, 10, 20), 600 }, 1.37 + // Remove the center 10x10 1.38 + { nsRect(10, 10, 10, 10), 300 }, 1.39 + // Remove the middle column 1.40 + { nsRect(10, 0, 10, 30), 300 }, 1.41 + // Remove the middle row 1.42 + { nsRect(0, 10, 30, 10), 300 }, 1.43 + // Remove the corners 10x10 1.44 + { nsRect(0, 0, 10, 10), 600 }, 1.45 + { nsRect(20, 20, 10, 10), 600 }, 1.46 + { nsRect(20, 0, 10, 10), 600 }, 1.47 + { nsRect(0, 20, 10, 10), 600 }, 1.48 + // Remove the corners 20x20 1.49 + { nsRect(0, 0, 20, 20), 300 }, 1.50 + { nsRect(10, 10, 20, 20), 300 }, 1.51 + { nsRect(10, 0, 20, 20), 300 }, 1.52 + { nsRect(0, 10, 20, 20), 300 } 1.53 + }; 1.54 + 1.55 + for (int32_t i = 0; i < nTests; i++) { 1.56 + nsRegion r2; 1.57 + r2.Sub(r, tests[i].rect); 1.58 + 1.59 + EXPECT_TRUE(r2.IsComplex()) << "nsRegion code got unexpectedly smarter!"; 1.60 + 1.61 + nsRect largest = r2.GetLargestRectangle(); 1.62 + EXPECT_TRUE(largest.width * largest.height == tests[i].expectedArea) << 1.63 + "Did not successfully find largest rectangle in non-rectangular region on iteration " << i; 1.64 + } 1.65 + 1.66 + } 1.67 + static void TwoRectTest() { 1.68 + nsRegion r(nsRect(0, 0, 100, 100)); 1.69 + const int nTests = 4; 1.70 + struct { 1.71 + nsRect rect1, rect2; 1.72 + int64_t expectedArea; 1.73 + } tests[nTests] = { 1.74 + { nsRect(0, 0, 75, 40), nsRect(0, 60, 75, 40), 2500 }, 1.75 + { nsRect(25, 0, 75, 40), nsRect(25, 60, 75, 40), 2500 }, 1.76 + { nsRect(25, 0, 75, 40), nsRect(0, 60, 75, 40), 2000 }, 1.77 + { nsRect(0, 0, 75, 40), nsRect(25, 60, 75, 40), 2000 }, 1.78 + }; 1.79 + for (int32_t i = 0; i < nTests; i++) { 1.80 + nsRegion r2; 1.81 + 1.82 + r2.Sub(r, tests[i].rect1); 1.83 + r2.Sub(r2, tests[i].rect2); 1.84 + 1.85 + EXPECT_TRUE(r2.IsComplex()) << "nsRegion code got unexpectedly smarter!"; 1.86 + 1.87 + nsRect largest = r2.GetLargestRectangle(); 1.88 + EXPECT_TRUE(largest.width * largest.height == tests[i].expectedArea) << 1.89 + "Did not successfully find largest rectangle in two-rect-subtract region on iteration " << i; 1.90 + } 1.91 + } 1.92 + static void TestContainsSpecifiedRect() { 1.93 + nsRegion r(nsRect(0, 0, 100, 100)); 1.94 + r.Or(r, nsRect(0, 300, 50, 50)); 1.95 + EXPECT_TRUE(r.GetLargestRectangle(nsRect(0, 300, 10, 10)).IsEqualInterior(nsRect(0, 300, 50, 50))) << 1.96 + "Chose wrong rectangle"; 1.97 + } 1.98 + static void TestContainsSpecifiedOverflowingRect() { 1.99 + nsRegion r(nsRect(0, 0, 100, 100)); 1.100 + r.Or(r, nsRect(0, 300, 50, 50)); 1.101 + EXPECT_TRUE(r.GetLargestRectangle(nsRect(0, 290, 10, 20)).IsEqualInterior(nsRect(0, 300, 50, 50))) << 1.102 + "Chose wrong rectangle"; 1.103 + } 1.104 +}; 1.105 + 1.106 +TEST(Gfx, RegionSingleRect) { 1.107 + TestLargestRegion::TestSingleRect(nsRect(0, 52, 720, 480)); 1.108 + TestLargestRegion::TestSingleRect(nsRect(-20, 40, 50, 20)); 1.109 + TestLargestRegion::TestSingleRect(nsRect(-20, 40, 10, 8)); 1.110 + TestLargestRegion::TestSingleRect(nsRect(-20, -40, 10, 8)); 1.111 + TestLargestRegion::TestSingleRect(nsRect(-10, -10, 20, 20)); 1.112 +} 1.113 + 1.114 +TEST(Gfx, RegionNonRectangular) { 1.115 + TestLargestRegion::TestNonRectangular(); 1.116 +} 1.117 + 1.118 +TEST(Gfx, RegionTwoRectTest) { 1.119 + TestLargestRegion::TwoRectTest(); 1.120 +} 1.121 + 1.122 +TEST(Gfx, RegionContainsSpecifiedRect) { 1.123 + TestLargestRegion::TestContainsSpecifiedRect(); 1.124 +} 1.125 + 1.126 +TEST(Gfx, RegionTestContainsSpecifiedOverflowingRect) { 1.127 + TestLargestRegion::TestContainsSpecifiedOverflowingRect(); 1.128 +} 1.129 + 1.130 +TEST(Gfx, RegionScaleToInside) { 1.131 + { // no rectangles 1.132 + nsRegion r; 1.133 + 1.134 + nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60); 1.135 + nsIntRegion result; 1.136 + 1.137 + EXPECT_TRUE(result.IsEqual(scaled)) << 1.138 + "scaled result incorrect"; 1.139 + } 1.140 + 1.141 + { // one rectangle 1.142 + nsRegion r(nsRect(0,44760,19096,264)); 1.143 + 1.144 + nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60); 1.145 + nsIntRegion result(nsIntRect(0,746,318,4)); 1.146 + 1.147 + EXPECT_TRUE(result.IsEqual(scaled)) << 1.148 + "scaled result incorrect"; 1.149 + } 1.150 + 1.151 + 1.152 + { // the first rectangle gets adjusted 1.153 + nsRegion r(nsRect(0,44760,19096,264)); 1.154 + r.Or(r, nsRect(0,45024,19360,1056)); 1.155 + 1.156 + nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60); 1.157 + nsIntRegion result(nsIntRect(0,746,318,5)); 1.158 + result.Or(result, nsIntRect(0,751,322,17)); 1.159 + 1.160 + EXPECT_TRUE(result.IsEqual(scaled)) << 1.161 + "scaled result incorrect"; 1.162 + } 1.163 + 1.164 + { // the second rectangle gets adjusted 1.165 + nsRegion r(nsRect(0,44760,19360,264)); 1.166 + r.Or(r, nsRect(0,45024,19096,1056)); 1.167 + 1.168 + nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60); 1.169 + nsIntRegion result(nsIntRect(0,746,322,4)); 1.170 + result.Or(result, nsIntRect(0,750,318,18)); 1.171 + 1.172 + EXPECT_TRUE(result.IsEqual(scaled)) << 1.173 + "scaled result incorrect"; 1.174 + } 1.175 + 1.176 +} 1.177 + 1.178 +TEST(Gfx, RegionSimplify) { 1.179 + { // ensure simplify works on a single rect 1.180 + nsRegion r(nsRect(0,100,200,100)); 1.181 + 1.182 + r.SimplifyOutwardByArea(100*100); 1.183 + 1.184 + nsRegion result(nsRect(0,100,200,100)); 1.185 + 1.186 + EXPECT_TRUE(r.IsEqual(result)) << 1.187 + "regions not the same"; 1.188 + } 1.189 + 1.190 + { // the rectangles will be merged 1.191 + nsRegion r(nsRect(0,100,200,100)); 1.192 + r.Or(r, nsRect(0,200,300,200)); 1.193 + 1.194 + r.SimplifyOutwardByArea(100*100); 1.195 + 1.196 + nsRegion result(nsRect(0,100,300,300)); 1.197 + 1.198 + EXPECT_TRUE(r.IsEqual(result)) << 1.199 + "regions not merged"; 1.200 + } 1.201 + 1.202 + { // two rectangle on the first span 1.203 + // one on the second 1.204 + nsRegion r(nsRect(0,100,200,100)); 1.205 + r.Or(r, nsRect(0,200,300,200)); 1.206 + r.Or(r, nsRect(250,100,50,100)); 1.207 + 1.208 + EXPECT_TRUE(r.GetNumRects() == 3) << 1.209 + "wrong number of rects"; 1.210 + 1.211 + r.SimplifyOutwardByArea(100*100); 1.212 + 1.213 + nsRegion result(nsRect(0,100,300,300)); 1.214 + 1.215 + EXPECT_TRUE(r.IsEqual(result)) << 1.216 + "regions not merged"; 1.217 + } 1.218 + 1.219 + { // the rectangles will be merged 1.220 + nsRegion r(nsRect(0,100,200,100)); 1.221 + r.Or(r, nsRect(0,200,300,200)); 1.222 + r.Or(r, nsRect(250,100,50,100)); 1.223 + r.Sub(r, nsRect(200,200,40,200)); 1.224 + 1.225 + EXPECT_TRUE(r.GetNumRects() == 4) << 1.226 + "wrong number of rects"; 1.227 + 1.228 + r.SimplifyOutwardByArea(100*100); 1.229 + 1.230 + nsRegion result(nsRect(0,100,300,300)); 1.231 + result.Sub(result, nsRect(200,100,40,300)); 1.232 + 1.233 + EXPECT_TRUE(r.IsEqual(result)) << 1.234 + "regions not merged"; 1.235 + } 1.236 + 1.237 + { // three spans of rectangles 1.238 + nsRegion r(nsRect(0,100,200,100)); 1.239 + r.Or(r, nsRect(0,200,300,200)); 1.240 + r.Or(r, nsRect(250,100,50,50)); 1.241 + r.Sub(r, nsRect(200,200,40,200)); 1.242 + 1.243 + r.SimplifyOutwardByArea(100*100); 1.244 + 1.245 + nsRegion result(nsRect(0,100,300,300)); 1.246 + result.Sub(result, nsRect(200,100,40,300)); 1.247 + 1.248 + EXPECT_TRUE(r.IsEqual(result)) << 1.249 + "regions not merged"; 1.250 + } 1.251 + 1.252 + { // three spans of rectangles and an unmerged rectangle 1.253 + nsRegion r(nsRect(0,100,200,100)); 1.254 + r.Or(r, nsRect(0,200,300,200)); 1.255 + r.Or(r, nsRect(250,100,50,50)); 1.256 + r.Sub(r, nsRect(200,200,40,200)); 1.257 + r.Or(r, nsRect(250,900,150,50)); 1.258 + 1.259 + r.SimplifyOutwardByArea(100*100); 1.260 + 1.261 + nsRegion result(nsRect(0,100,300,300)); 1.262 + result.Sub(result, nsRect(200,100,40,300)); 1.263 + result.Or(result, nsRect(250,900,150,50)); 1.264 + 1.265 + EXPECT_TRUE(r.IsEqual(result)) << 1.266 + "regions not merged"; 1.267 + } 1.268 + 1.269 + { // unmerged regions 1.270 + nsRegion r(nsRect(0,100,200,100)); 1.271 + r.Or(r, nsRect(0,200,300,200)); 1.272 + 1.273 + r.SimplifyOutwardByArea(100); 1.274 + 1.275 + nsRegion result(nsRect(0,100,200,100)); 1.276 + result.Or(result, nsRect(0,200,300,200)); 1.277 + 1.278 + EXPECT_TRUE(r.IsEqual(result)) << 1.279 + "regions not merged"; 1.280 + } 1.281 + 1.282 + { // empty region 1.283 + // just make sure this doesn't crash. 1.284 + nsRegion r; 1.285 + r.SimplifyOutwardByArea(100); 1.286 + } 1.287 + 1.288 +}