gfx/tests/gtest/TestRegion.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "gtest/gtest.h"
michael@0 7 #include "nsRegion.h"
michael@0 8
michael@0 9 class TestLargestRegion {
michael@0 10 public:
michael@0 11 static void TestSingleRect(nsRect r) {
michael@0 12 nsRegion region(r);
michael@0 13 EXPECT_TRUE(region.GetLargestRectangle().IsEqualInterior(r));
michael@0 14 }
michael@0 15 // Construct a rectangle, remove part of it, then check the remainder
michael@0 16 static void TestNonRectangular() {
michael@0 17 nsRegion r(nsRect(0, 0, 30, 30));
michael@0 18
michael@0 19 const int nTests = 19;
michael@0 20 struct {
michael@0 21 nsRect rect;
michael@0 22 int64_t expectedArea;
michael@0 23 } tests[nTests] = {
michael@0 24 // Remove a 20x10 chunk from the square
michael@0 25 { nsRect(0, 0, 20, 10), 600 },
michael@0 26 { nsRect(10, 0, 20, 10), 600 },
michael@0 27 { nsRect(10, 20, 20, 10), 600 },
michael@0 28 { nsRect(0, 20, 20, 10), 600 },
michael@0 29 // Remove a 10x20 chunk from the square
michael@0 30 { nsRect(0, 0, 10, 20), 600 },
michael@0 31 { nsRect(20, 0, 10, 20), 600 },
michael@0 32 { nsRect(20, 10, 10, 20), 600 },
michael@0 33 { nsRect(0, 10, 10, 20), 600 },
michael@0 34 // Remove the center 10x10
michael@0 35 { nsRect(10, 10, 10, 10), 300 },
michael@0 36 // Remove the middle column
michael@0 37 { nsRect(10, 0, 10, 30), 300 },
michael@0 38 // Remove the middle row
michael@0 39 { nsRect(0, 10, 30, 10), 300 },
michael@0 40 // Remove the corners 10x10
michael@0 41 { nsRect(0, 0, 10, 10), 600 },
michael@0 42 { nsRect(20, 20, 10, 10), 600 },
michael@0 43 { nsRect(20, 0, 10, 10), 600 },
michael@0 44 { nsRect(0, 20, 10, 10), 600 },
michael@0 45 // Remove the corners 20x20
michael@0 46 { nsRect(0, 0, 20, 20), 300 },
michael@0 47 { nsRect(10, 10, 20, 20), 300 },
michael@0 48 { nsRect(10, 0, 20, 20), 300 },
michael@0 49 { nsRect(0, 10, 20, 20), 300 }
michael@0 50 };
michael@0 51
michael@0 52 for (int32_t i = 0; i < nTests; i++) {
michael@0 53 nsRegion r2;
michael@0 54 r2.Sub(r, tests[i].rect);
michael@0 55
michael@0 56 EXPECT_TRUE(r2.IsComplex()) << "nsRegion code got unexpectedly smarter!";
michael@0 57
michael@0 58 nsRect largest = r2.GetLargestRectangle();
michael@0 59 EXPECT_TRUE(largest.width * largest.height == tests[i].expectedArea) <<
michael@0 60 "Did not successfully find largest rectangle in non-rectangular region on iteration " << i;
michael@0 61 }
michael@0 62
michael@0 63 }
michael@0 64 static void TwoRectTest() {
michael@0 65 nsRegion r(nsRect(0, 0, 100, 100));
michael@0 66 const int nTests = 4;
michael@0 67 struct {
michael@0 68 nsRect rect1, rect2;
michael@0 69 int64_t expectedArea;
michael@0 70 } tests[nTests] = {
michael@0 71 { nsRect(0, 0, 75, 40), nsRect(0, 60, 75, 40), 2500 },
michael@0 72 { nsRect(25, 0, 75, 40), nsRect(25, 60, 75, 40), 2500 },
michael@0 73 { nsRect(25, 0, 75, 40), nsRect(0, 60, 75, 40), 2000 },
michael@0 74 { nsRect(0, 0, 75, 40), nsRect(25, 60, 75, 40), 2000 },
michael@0 75 };
michael@0 76 for (int32_t i = 0; i < nTests; i++) {
michael@0 77 nsRegion r2;
michael@0 78
michael@0 79 r2.Sub(r, tests[i].rect1);
michael@0 80 r2.Sub(r2, tests[i].rect2);
michael@0 81
michael@0 82 EXPECT_TRUE(r2.IsComplex()) << "nsRegion code got unexpectedly smarter!";
michael@0 83
michael@0 84 nsRect largest = r2.GetLargestRectangle();
michael@0 85 EXPECT_TRUE(largest.width * largest.height == tests[i].expectedArea) <<
michael@0 86 "Did not successfully find largest rectangle in two-rect-subtract region on iteration " << i;
michael@0 87 }
michael@0 88 }
michael@0 89 static void TestContainsSpecifiedRect() {
michael@0 90 nsRegion r(nsRect(0, 0, 100, 100));
michael@0 91 r.Or(r, nsRect(0, 300, 50, 50));
michael@0 92 EXPECT_TRUE(r.GetLargestRectangle(nsRect(0, 300, 10, 10)).IsEqualInterior(nsRect(0, 300, 50, 50))) <<
michael@0 93 "Chose wrong rectangle";
michael@0 94 }
michael@0 95 static void TestContainsSpecifiedOverflowingRect() {
michael@0 96 nsRegion r(nsRect(0, 0, 100, 100));
michael@0 97 r.Or(r, nsRect(0, 300, 50, 50));
michael@0 98 EXPECT_TRUE(r.GetLargestRectangle(nsRect(0, 290, 10, 20)).IsEqualInterior(nsRect(0, 300, 50, 50))) <<
michael@0 99 "Chose wrong rectangle";
michael@0 100 }
michael@0 101 };
michael@0 102
michael@0 103 TEST(Gfx, RegionSingleRect) {
michael@0 104 TestLargestRegion::TestSingleRect(nsRect(0, 52, 720, 480));
michael@0 105 TestLargestRegion::TestSingleRect(nsRect(-20, 40, 50, 20));
michael@0 106 TestLargestRegion::TestSingleRect(nsRect(-20, 40, 10, 8));
michael@0 107 TestLargestRegion::TestSingleRect(nsRect(-20, -40, 10, 8));
michael@0 108 TestLargestRegion::TestSingleRect(nsRect(-10, -10, 20, 20));
michael@0 109 }
michael@0 110
michael@0 111 TEST(Gfx, RegionNonRectangular) {
michael@0 112 TestLargestRegion::TestNonRectangular();
michael@0 113 }
michael@0 114
michael@0 115 TEST(Gfx, RegionTwoRectTest) {
michael@0 116 TestLargestRegion::TwoRectTest();
michael@0 117 }
michael@0 118
michael@0 119 TEST(Gfx, RegionContainsSpecifiedRect) {
michael@0 120 TestLargestRegion::TestContainsSpecifiedRect();
michael@0 121 }
michael@0 122
michael@0 123 TEST(Gfx, RegionTestContainsSpecifiedOverflowingRect) {
michael@0 124 TestLargestRegion::TestContainsSpecifiedOverflowingRect();
michael@0 125 }
michael@0 126
michael@0 127 TEST(Gfx, RegionScaleToInside) {
michael@0 128 { // no rectangles
michael@0 129 nsRegion r;
michael@0 130
michael@0 131 nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
michael@0 132 nsIntRegion result;
michael@0 133
michael@0 134 EXPECT_TRUE(result.IsEqual(scaled)) <<
michael@0 135 "scaled result incorrect";
michael@0 136 }
michael@0 137
michael@0 138 { // one rectangle
michael@0 139 nsRegion r(nsRect(0,44760,19096,264));
michael@0 140
michael@0 141 nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
michael@0 142 nsIntRegion result(nsIntRect(0,746,318,4));
michael@0 143
michael@0 144 EXPECT_TRUE(result.IsEqual(scaled)) <<
michael@0 145 "scaled result incorrect";
michael@0 146 }
michael@0 147
michael@0 148
michael@0 149 { // the first rectangle gets adjusted
michael@0 150 nsRegion r(nsRect(0,44760,19096,264));
michael@0 151 r.Or(r, nsRect(0,45024,19360,1056));
michael@0 152
michael@0 153 nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
michael@0 154 nsIntRegion result(nsIntRect(0,746,318,5));
michael@0 155 result.Or(result, nsIntRect(0,751,322,17));
michael@0 156
michael@0 157 EXPECT_TRUE(result.IsEqual(scaled)) <<
michael@0 158 "scaled result incorrect";
michael@0 159 }
michael@0 160
michael@0 161 { // the second rectangle gets adjusted
michael@0 162 nsRegion r(nsRect(0,44760,19360,264));
michael@0 163 r.Or(r, nsRect(0,45024,19096,1056));
michael@0 164
michael@0 165 nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
michael@0 166 nsIntRegion result(nsIntRect(0,746,322,4));
michael@0 167 result.Or(result, nsIntRect(0,750,318,18));
michael@0 168
michael@0 169 EXPECT_TRUE(result.IsEqual(scaled)) <<
michael@0 170 "scaled result incorrect";
michael@0 171 }
michael@0 172
michael@0 173 }
michael@0 174
michael@0 175 TEST(Gfx, RegionSimplify) {
michael@0 176 { // ensure simplify works on a single rect
michael@0 177 nsRegion r(nsRect(0,100,200,100));
michael@0 178
michael@0 179 r.SimplifyOutwardByArea(100*100);
michael@0 180
michael@0 181 nsRegion result(nsRect(0,100,200,100));
michael@0 182
michael@0 183 EXPECT_TRUE(r.IsEqual(result)) <<
michael@0 184 "regions not the same";
michael@0 185 }
michael@0 186
michael@0 187 { // the rectangles will be merged
michael@0 188 nsRegion r(nsRect(0,100,200,100));
michael@0 189 r.Or(r, nsRect(0,200,300,200));
michael@0 190
michael@0 191 r.SimplifyOutwardByArea(100*100);
michael@0 192
michael@0 193 nsRegion result(nsRect(0,100,300,300));
michael@0 194
michael@0 195 EXPECT_TRUE(r.IsEqual(result)) <<
michael@0 196 "regions not merged";
michael@0 197 }
michael@0 198
michael@0 199 { // two rectangle on the first span
michael@0 200 // one on the second
michael@0 201 nsRegion r(nsRect(0,100,200,100));
michael@0 202 r.Or(r, nsRect(0,200,300,200));
michael@0 203 r.Or(r, nsRect(250,100,50,100));
michael@0 204
michael@0 205 EXPECT_TRUE(r.GetNumRects() == 3) <<
michael@0 206 "wrong number of rects";
michael@0 207
michael@0 208 r.SimplifyOutwardByArea(100*100);
michael@0 209
michael@0 210 nsRegion result(nsRect(0,100,300,300));
michael@0 211
michael@0 212 EXPECT_TRUE(r.IsEqual(result)) <<
michael@0 213 "regions not merged";
michael@0 214 }
michael@0 215
michael@0 216 { // the rectangles will be merged
michael@0 217 nsRegion r(nsRect(0,100,200,100));
michael@0 218 r.Or(r, nsRect(0,200,300,200));
michael@0 219 r.Or(r, nsRect(250,100,50,100));
michael@0 220 r.Sub(r, nsRect(200,200,40,200));
michael@0 221
michael@0 222 EXPECT_TRUE(r.GetNumRects() == 4) <<
michael@0 223 "wrong number of rects";
michael@0 224
michael@0 225 r.SimplifyOutwardByArea(100*100);
michael@0 226
michael@0 227 nsRegion result(nsRect(0,100,300,300));
michael@0 228 result.Sub(result, nsRect(200,100,40,300));
michael@0 229
michael@0 230 EXPECT_TRUE(r.IsEqual(result)) <<
michael@0 231 "regions not merged";
michael@0 232 }
michael@0 233
michael@0 234 { // three spans of rectangles
michael@0 235 nsRegion r(nsRect(0,100,200,100));
michael@0 236 r.Or(r, nsRect(0,200,300,200));
michael@0 237 r.Or(r, nsRect(250,100,50,50));
michael@0 238 r.Sub(r, nsRect(200,200,40,200));
michael@0 239
michael@0 240 r.SimplifyOutwardByArea(100*100);
michael@0 241
michael@0 242 nsRegion result(nsRect(0,100,300,300));
michael@0 243 result.Sub(result, nsRect(200,100,40,300));
michael@0 244
michael@0 245 EXPECT_TRUE(r.IsEqual(result)) <<
michael@0 246 "regions not merged";
michael@0 247 }
michael@0 248
michael@0 249 { // three spans of rectangles and an unmerged rectangle
michael@0 250 nsRegion r(nsRect(0,100,200,100));
michael@0 251 r.Or(r, nsRect(0,200,300,200));
michael@0 252 r.Or(r, nsRect(250,100,50,50));
michael@0 253 r.Sub(r, nsRect(200,200,40,200));
michael@0 254 r.Or(r, nsRect(250,900,150,50));
michael@0 255
michael@0 256 r.SimplifyOutwardByArea(100*100);
michael@0 257
michael@0 258 nsRegion result(nsRect(0,100,300,300));
michael@0 259 result.Sub(result, nsRect(200,100,40,300));
michael@0 260 result.Or(result, nsRect(250,900,150,50));
michael@0 261
michael@0 262 EXPECT_TRUE(r.IsEqual(result)) <<
michael@0 263 "regions not merged";
michael@0 264 }
michael@0 265
michael@0 266 { // unmerged regions
michael@0 267 nsRegion r(nsRect(0,100,200,100));
michael@0 268 r.Or(r, nsRect(0,200,300,200));
michael@0 269
michael@0 270 r.SimplifyOutwardByArea(100);
michael@0 271
michael@0 272 nsRegion result(nsRect(0,100,200,100));
michael@0 273 result.Or(result, nsRect(0,200,300,200));
michael@0 274
michael@0 275 EXPECT_TRUE(r.IsEqual(result)) <<
michael@0 276 "regions not merged";
michael@0 277 }
michael@0 278
michael@0 279 { // empty region
michael@0 280 // just make sure this doesn't crash.
michael@0 281 nsRegion r;
michael@0 282 r.SimplifyOutwardByArea(100);
michael@0 283 }
michael@0 284
michael@0 285 }

mercurial