1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 * These tests are taken from 17 * https://cs.android.com/android/platform/superproject/+/master:cts/tests/tests/graphics/src/android/graphics/cts/RegionTest.java 18 */ 19 20 package org.robolectric.integrationtests.nativegraphics; 21 22 import static android.os.Build.VERSION_CODES.O; 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertFalse; 25 import static org.junit.Assert.assertNotSame; 26 import static org.junit.Assert.assertThrows; 27 import static org.junit.Assert.assertTrue; 28 29 import android.graphics.Path; 30 import android.graphics.Rect; 31 import android.graphics.Region; 32 import androidx.test.ext.junit.runners.AndroidJUnit4; 33 import org.junit.Before; 34 import org.junit.Test; 35 import org.junit.runner.RunWith; 36 import org.robolectric.annotation.Config; 37 38 @RunWith(AndroidJUnit4.class) 39 @Config(minSdk = O) 40 public class ShadowNativeRegionTest { 41 // DIFFERENCE 42 private static final int[][] DIFFERENCE_WITH1 = { 43 {0, 0}, {4, 4}, {10, 10}, {19, 19}, {19, 0}, {10, 4}, {4, 10}, {0, 19} 44 }; 45 private static final int[][] DIFFERENCE_WITHOUT1 = {{5, 5}, {9, 9}, {9, 5}, {5, 9}}; 46 47 private static final int[][] DIFFERENCE_WITH2 = { 48 {0, 0}, {19, 0}, {9, 9}, {19, 9}, {0, 19}, {9, 19} 49 }; 50 private static final int[][] DIFFERENCE_WITHOUT2 = { 51 {10, 10}, {19, 10}, {10, 19}, {19, 19}, {29, 10}, {29, 29}, {10, 29} 52 }; 53 54 private static final int[][] DIFFERENCE_WITH3 = {{0, 0}, {19, 0}, {0, 19}, {19, 19}}; 55 private static final int[][] DIFFERENCE_WITHOUT3 = {{40, 40}, {40, 59}, {59, 40}, {59, 59}}; 56 57 // INTERSECT 58 private static final int[][] INTERSECT_WITH1 = {{5, 5}, {9, 9}, {9, 5}, {5, 9}}; 59 private static final int[][] INTERSECT_WITHOUT1 = { 60 {0, 0}, {2, 2}, {4, 4}, {10, 10}, {19, 19}, {19, 0}, {10, 4}, {4, 10}, {0, 19} 61 }; 62 63 private static final int[][] INTERSECT_WITH2 = {{10, 10}, {19, 10}, {10, 19}, {19, 19}}; 64 private static final int[][] INTERSECT_WITHOUT2 = { 65 {0, 0}, {19, 0}, {9, 9}, {19, 9}, {0, 19}, {9, 19}, {29, 10}, {29, 29}, {10, 29} 66 }; 67 68 // UNION 69 private static final int[][] UNION_WITH1 = { 70 {0, 0}, {2, 2}, {4, 4}, {6, 6}, {10, 10}, {19, 19}, {19, 0}, {10, 4}, {4, 10}, {0, 19}, {5, 5}, 71 {9, 9}, {9, 5}, {5, 9} 72 }; 73 private static final int[][] UNION_WITHOUT1 = {{0, 20}, {20, 20}, {20, 0}}; 74 75 private static final int[][] UNION_WITH2 = { 76 {0, 0}, {2, 2}, {19, 0}, {9, 9}, {19, 9}, {0, 19}, {9, 19}, {21, 21}, {10, 10}, {19, 10}, 77 {10, 19}, {19, 19}, {29, 10}, {29, 29}, {10, 29} 78 }; 79 private static final int[][] UNION_WITHOUT2 = { 80 {0, 29}, {0, 20}, {9, 29}, {9, 20}, 81 {29, 0}, {20, 0}, {29, 9}, {20, 9} 82 }; 83 84 private static final int[][] UNION_WITH3 = { 85 {0, 0}, {2, 2}, {19, 0}, {0, 19}, {19, 19}, 86 {40, 40}, {41, 41}, {40, 59}, {59, 40}, {59, 59} 87 }; 88 private static final int[][] UNION_WITHOUT3 = {{20, 20}, {39, 39}}; 89 90 // XOR 91 private static final int[][] XOR_WITH1 = { 92 {0, 0}, {2, 2}, {4, 4}, {10, 10}, {19, 19}, {19, 0}, {10, 4}, {4, 10}, {0, 19} 93 }; 94 private static final int[][] XOR_WITHOUT1 = {{5, 5}, {6, 6}, {9, 9}, {9, 5}, {5, 9}}; 95 96 private static final int[][] XOR_WITH2 = { 97 {0, 0}, {2, 2}, {19, 0}, {9, 9}, {19, 9}, {0, 19}, {9, 19}, {21, 21}, {29, 10}, {10, 29}, 98 {20, 10}, {10, 20}, {20, 20}, {29, 29} 99 }; 100 private static final int[][] XOR_WITHOUT2 = {{10, 10}, {11, 11}, {19, 10}, {10, 19}, {19, 19}}; 101 102 private static final int[][] XOR_WITH3 = { 103 {0, 0}, {2, 2}, {19, 0}, {0, 19}, {19, 19}, 104 {40, 40}, {41, 41}, {40, 59}, {59, 40}, {59, 59} 105 }; 106 private static final int[][] XOR_WITHOUT3 = {{20, 20}, {39, 39}}; 107 108 // REVERSE_DIFFERENCE 109 private static final int[][] REVERSE_DIFFERENCE_WITH2 = { 110 {29, 10}, {10, 29}, {20, 10}, {10, 20}, {20, 20}, {29, 29}, {21, 21} 111 }; 112 private static final int[][] REVERSE_DIFFERENCE_WITHOUT2 = { 113 {0, 0}, {19, 0}, {0, 19}, {19, 19}, {2, 2}, {11, 11} 114 }; 115 116 private static final int[][] REVERSE_DIFFERENCE_WITH3 = { 117 {40, 40}, {40, 59}, {59, 40}, {59, 59}, {41, 41} 118 }; 119 private static final int[][] REVERSE_DIFFERENCE_WITHOUT3 = { 120 {0, 0}, {19, 0}, {0, 19}, {19, 19}, {20, 20}, {39, 39}, {2, 2} 121 }; 122 123 private Region region; 124 verifyPointsInsideRegion(int[][] area)125 private void verifyPointsInsideRegion(int[][] area) { 126 for (int i = 0; i < area.length; i++) { 127 assertTrue(region.contains(area[i][0], area[i][1])); 128 } 129 } 130 verifyPointsOutsideRegion(int[][] area)131 private void verifyPointsOutsideRegion(int[][] area) { 132 for (int i = 0; i < area.length; i++) { 133 assertFalse(region.contains(area[i][0], area[i][1])); 134 } 135 } 136 137 @Before setup()138 public void setup() { 139 region = new Region(); 140 } 141 142 @Test testConstructor()143 public void testConstructor() { 144 // We don't actually care about the result of quickContains in this function (tested later). 145 // We call it because in robolectric native runtime, it's not static and so if the constructor 146 // is set up incorrectly, it will crash trying to get the instance from mNativeRegion. 147 Rect rect = new Rect(); 148 149 // Test Region() 150 Region defaultRegion = new Region(); 151 defaultRegion.quickContains(rect); 152 153 // Test Region(Region) 154 Region oriRegion = new Region(); 155 Region copyRegion = new Region(oriRegion); 156 copyRegion.quickContains(rect); 157 158 // Test Region(Rect) 159 Region rectRegion = new Region(rect); 160 rectRegion.quickContains(rect); 161 162 // Test Region(int, int, int, int) 163 Region intRegion = new Region(0, 0, 100, 100); 164 intRegion.quickContains(rect); 165 } 166 167 @Test testSet1()168 public void testSet1() { 169 Rect rect = new Rect(1, 2, 3, 4); 170 Region oriRegion = new Region(rect); 171 assertTrue(region.set(oriRegion)); 172 assertEquals(1, region.getBounds().left); 173 assertEquals(2, region.getBounds().top); 174 assertEquals(3, region.getBounds().right); 175 assertEquals(4, region.getBounds().bottom); 176 } 177 178 @Test testSet2()179 public void testSet2() { 180 Rect rect = new Rect(1, 2, 3, 4); 181 assertTrue(region.set(rect)); 182 assertEquals(1, region.getBounds().left); 183 assertEquals(2, region.getBounds().top); 184 assertEquals(3, region.getBounds().right); 185 assertEquals(4, region.getBounds().bottom); 186 } 187 188 @Test testSet3()189 public void testSet3() { 190 assertTrue(region.set(1, 2, 3, 4)); 191 assertEquals(1, region.getBounds().left); 192 assertEquals(2, region.getBounds().top); 193 assertEquals(3, region.getBounds().right); 194 assertEquals(4, region.getBounds().bottom); 195 } 196 197 @Test testIsRect()198 public void testIsRect() { 199 assertFalse(region.isRect()); 200 region = new Region(1, 2, 3, 4); 201 assertTrue(region.isRect()); 202 } 203 204 @Test testIsComplex()205 public void testIsComplex() { 206 // Region is empty 207 assertFalse(region.isComplex()); 208 209 // Only one rectangle 210 region = new Region(); 211 region.set(1, 2, 3, 4); 212 assertFalse(region.isComplex()); 213 214 // More than one rectangle 215 region = new Region(); 216 region.set(1, 1, 2, 2); 217 region.union(new Rect(3, 3, 5, 5)); 218 assertTrue(region.isComplex()); 219 } 220 221 @Test testQuickContains1()222 public void testQuickContains1() { 223 Rect rect = new Rect(1, 2, 3, 4); 224 // This region not contains expected rectangle. 225 assertFalse(region.quickContains(rect)); 226 region.set(rect); 227 // This region contains only one rectangle and it is the expected one. 228 assertTrue(region.quickContains(rect)); 229 region.set(5, 6, 7, 8); 230 // This region contains more than one rectangle. 231 assertFalse(region.quickContains(rect)); 232 } 233 234 @Test testQuickContains2()235 public void testQuickContains2() { 236 // This region not contains expected rectangle. 237 assertFalse(region.quickContains(1, 2, 3, 4)); 238 region.set(1, 2, 3, 4); 239 // This region contains only one rectangle and it is the expected one. 240 assertTrue(region.quickContains(1, 2, 3, 4)); 241 region.set(5, 6, 7, 8); 242 // This region contains more than one rectangle. 243 assertFalse(region.quickContains(1, 2, 3, 4)); 244 } 245 246 @Test testUnion()247 public void testUnion() { 248 Rect rect1 = new Rect(); 249 Rect rect2 = new Rect(0, 0, 20, 20); 250 Rect rect3 = new Rect(5, 5, 10, 10); 251 Rect rect4 = new Rect(10, 10, 30, 30); 252 Rect rect5 = new Rect(40, 40, 60, 60); 253 254 // union (inclusive-or) the two regions 255 region.set(rect2); 256 // union null rectangle 257 assertTrue(region.contains(6, 6)); 258 assertTrue(region.union(rect1)); 259 assertTrue(region.contains(6, 6)); 260 261 // 1. union rectangle inside this region 262 region.set(rect2); 263 assertTrue(region.contains(2, 2)); 264 assertTrue(region.contains(6, 6)); 265 assertTrue(region.union(rect3)); 266 verifyPointsInsideRegion(UNION_WITH1); 267 verifyPointsOutsideRegion(UNION_WITHOUT1); 268 269 // 2. union rectangle overlap this region 270 region.set(rect2); 271 assertTrue(region.contains(2, 2)); 272 assertFalse(region.contains(21, 21)); 273 assertTrue(region.union(rect4)); 274 verifyPointsInsideRegion(UNION_WITH2); 275 verifyPointsOutsideRegion(UNION_WITHOUT2); 276 277 // 3. union rectangle out of this region 278 region.set(rect2); 279 assertTrue(region.contains(2, 2)); 280 assertFalse(region.contains(41, 41)); 281 assertTrue(region.union(rect5)); 282 verifyPointsInsideRegion(UNION_WITH3); 283 verifyPointsOutsideRegion(UNION_WITHOUT3); 284 } 285 286 @Test testContains()287 public void testContains() { 288 region.set(2, 2, 5, 5); 289 // Not contain (1, 1). 290 assertFalse(region.contains(1, 1)); 291 292 // Test point inside this region. 293 assertTrue(region.contains(3, 3)); 294 295 // Test left-top corner. 296 assertTrue(region.contains(2, 2)); 297 298 // Test left-bottom corner. 299 assertTrue(region.contains(2, 4)); 300 301 // Test right-top corner. 302 assertTrue(region.contains(4, 2)); 303 304 // Test right-bottom corner. 305 assertTrue(region.contains(4, 4)); 306 307 // Though you set 5, but 5 is not contained by this region. 308 assertFalse(region.contains(5, 5)); 309 assertFalse(region.contains(2, 5)); 310 assertFalse(region.contains(5, 2)); 311 312 // Set a new rectangle. 313 region.set(6, 6, 8, 8); 314 assertFalse(region.contains(3, 3)); 315 assertTrue(region.contains(7, 7)); 316 } 317 318 @Test testEmpty()319 public void testEmpty() { 320 assertTrue(region.isEmpty()); 321 region = null; 322 region = new Region(1, 2, 3, 4); 323 assertFalse(region.isEmpty()); 324 region.setEmpty(); 325 assertTrue(region.isEmpty()); 326 } 327 328 @Test testGetBoundsNull()329 public void testGetBoundsNull() { 330 assertThrows(NullPointerException.class, () -> region.getBounds(null)); 331 } 332 333 @Test testGetBounds()334 public void testGetBounds() { 335 // Normal, return true. 336 Rect rect1 = new Rect(1, 2, 3, 4); 337 region = new Region(rect1); 338 assertTrue(region.getBounds(rect1)); 339 340 region.setEmpty(); 341 Rect rect2 = new Rect(5, 6, 7, 8); 342 assertFalse(region.getBounds(rect2)); 343 } 344 345 @Test testOp1()346 public void testOp1() { 347 Rect rect1 = new Rect(); 348 Rect rect2 = new Rect(0, 0, 20, 20); 349 Rect rect3 = new Rect(5, 5, 10, 10); 350 Rect rect4 = new Rect(10, 10, 30, 30); 351 Rect rect5 = new Rect(40, 40, 60, 60); 352 353 verifyNullRegionOp1(rect1); 354 verifyDifferenceOp1(rect1, rect2, rect3, rect4, rect5); 355 verifyIntersectOp1(rect1, rect2, rect3, rect4, rect5); 356 verifyUnionOp1(rect1, rect2, rect3, rect4, rect5); 357 verifyXorOp1(rect1, rect2, rect3, rect4, rect5); 358 verifyReverseDifferenceOp1(rect1, rect2, rect3, rect4, rect5); 359 verifyReplaceOp1(rect1, rect2, rect3, rect4, rect5); 360 } 361 verifyNullRegionOp1(Rect rect1)362 private void verifyNullRegionOp1(Rect rect1) { 363 // Region without rectangle 364 region = new Region(); 365 assertFalse(region.op(rect1, Region.Op.DIFFERENCE)); 366 assertFalse(region.op(rect1, Region.Op.INTERSECT)); 367 assertFalse(region.op(rect1, Region.Op.UNION)); 368 assertFalse(region.op(rect1, Region.Op.XOR)); 369 assertFalse(region.op(rect1, Region.Op.REVERSE_DIFFERENCE)); 370 assertFalse(region.op(rect1, Region.Op.REPLACE)); 371 } 372 verifyDifferenceOp1(Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5)373 private void verifyDifferenceOp1(Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5) { 374 // DIFFERENCE, Region with rectangle 375 // subtract the op region from the first region 376 region = new Region(); 377 // subtract null rectangle 378 region.set(rect2); 379 assertTrue(region.op(rect1, Region.Op.DIFFERENCE)); 380 381 // 1. subtract rectangle inside this region 382 region.set(rect2); 383 assertTrue(region.contains(6, 6)); 384 assertTrue(region.op(rect3, Region.Op.DIFFERENCE)); 385 verifyPointsInsideRegion(DIFFERENCE_WITH1); 386 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT1); 387 388 // 2. subtract rectangle overlap this region 389 region.set(rect2); 390 assertTrue(region.contains(11, 11)); 391 assertTrue(region.op(rect4, Region.Op.DIFFERENCE)); 392 verifyPointsInsideRegion(DIFFERENCE_WITH2); 393 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT2); 394 395 // 3. subtract rectangle out of this region 396 region.set(rect2); 397 assertTrue(region.op(rect5, Region.Op.DIFFERENCE)); 398 verifyPointsInsideRegion(DIFFERENCE_WITH3); 399 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT3); 400 } 401 verifyIntersectOp1(Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5)402 private void verifyIntersectOp1(Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5) { 403 // INTERSECT, Region with rectangle 404 // intersect the two regions 405 region = new Region(); 406 // intersect null rectangle 407 region.set(rect2); 408 assertFalse(region.op(rect1, Region.Op.INTERSECT)); 409 410 // 1. intersect rectangle inside this region 411 region.set(rect2); 412 assertTrue(region.contains(2, 2)); 413 assertTrue(region.op(rect3, Region.Op.INTERSECT)); 414 verifyPointsInsideRegion(INTERSECT_WITH1); 415 verifyPointsOutsideRegion(INTERSECT_WITHOUT1); 416 417 // 2. intersect rectangle overlap this region 418 region.set(rect2); 419 assertTrue(region.contains(9, 9)); 420 assertTrue(region.op(rect4, Region.Op.INTERSECT)); 421 verifyPointsInsideRegion(INTERSECT_WITH2); 422 verifyPointsOutsideRegion(INTERSECT_WITHOUT2); 423 424 // 3. intersect rectangle out of this region 425 region.set(rect2); 426 assertFalse(region.op(rect5, Region.Op.INTERSECT)); 427 } 428 verifyUnionOp1(Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5)429 private void verifyUnionOp1(Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5) { 430 // UNION, Region with rectangle 431 // union (inclusive-or) the two regions 432 region = new Region(); 433 region.set(rect2); 434 // union null rectangle 435 assertTrue(region.contains(6, 6)); 436 assertTrue(region.op(rect1, Region.Op.UNION)); 437 assertTrue(region.contains(6, 6)); 438 439 // 1. union rectangle inside this region 440 region.set(rect2); 441 assertTrue(region.contains(2, 2)); 442 assertTrue(region.contains(6, 6)); 443 assertTrue(region.op(rect3, Region.Op.UNION)); 444 verifyPointsInsideRegion(UNION_WITH1); 445 verifyPointsOutsideRegion(UNION_WITHOUT1); 446 447 // 2. union rectangle overlap this region 448 region.set(rect2); 449 assertTrue(region.contains(2, 2)); 450 assertFalse(region.contains(21, 21)); 451 assertTrue(region.op(rect4, Region.Op.UNION)); 452 verifyPointsInsideRegion(UNION_WITH2); 453 verifyPointsOutsideRegion(UNION_WITHOUT2); 454 455 // 3. union rectangle out of this region 456 region.set(rect2); 457 assertTrue(region.contains(2, 2)); 458 assertFalse(region.contains(41, 41)); 459 assertTrue(region.op(rect5, Region.Op.UNION)); 460 verifyPointsInsideRegion(UNION_WITH3); 461 verifyPointsOutsideRegion(UNION_WITHOUT3); 462 } 463 verifyXorOp1(Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5)464 private void verifyXorOp1(Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5) { 465 // XOR, Region with rectangle 466 // exclusive-or the two regions 467 region = new Region(); 468 // xor null rectangle 469 region.set(rect2); 470 assertTrue(region.op(rect1, Region.Op.XOR)); 471 472 // 1. xor rectangle inside this region 473 region.set(rect2); 474 assertTrue(region.contains(2, 2)); 475 assertTrue(region.contains(6, 6)); 476 assertTrue(region.op(rect3, Region.Op.XOR)); 477 verifyPointsInsideRegion(XOR_WITH1); 478 verifyPointsOutsideRegion(XOR_WITHOUT1); 479 480 // 2. xor rectangle overlap this region 481 region.set(rect2); 482 assertTrue(region.contains(2, 2)); 483 assertTrue(region.contains(11, 11)); 484 assertFalse(region.contains(21, 21)); 485 assertTrue(region.op(rect4, Region.Op.XOR)); 486 verifyPointsInsideRegion(XOR_WITH2); 487 verifyPointsOutsideRegion(XOR_WITHOUT2); 488 489 // 3. xor rectangle out of this region 490 region.set(rect2); 491 assertTrue(region.contains(2, 2)); 492 assertFalse(region.contains(41, 41)); 493 assertTrue(region.op(rect5, Region.Op.XOR)); 494 verifyPointsInsideRegion(XOR_WITH3); 495 verifyPointsOutsideRegion(XOR_WITHOUT3); 496 } 497 verifyReverseDifferenceOp1( Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5)498 private void verifyReverseDifferenceOp1( 499 Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5) { 500 // REVERSE_DIFFERENCE, Region with rectangle 501 // reverse difference the first region from the op region 502 region = new Region(); 503 region.set(rect2); 504 // reverse difference null rectangle 505 assertFalse(region.op(rect1, Region.Op.REVERSE_DIFFERENCE)); 506 507 // 1. reverse difference rectangle inside this region 508 region.set(rect2); 509 assertTrue(region.contains(2, 2)); 510 assertTrue(region.contains(6, 6)); 511 assertFalse(region.op(rect3, Region.Op.REVERSE_DIFFERENCE)); 512 513 // 2. reverse difference rectangle overlap this region 514 region.set(rect2); 515 assertTrue(region.contains(2, 2)); 516 assertTrue(region.contains(11, 11)); 517 assertFalse(region.contains(21, 21)); 518 assertTrue(region.op(rect4, Region.Op.REVERSE_DIFFERENCE)); 519 verifyPointsInsideRegion(REVERSE_DIFFERENCE_WITH2); 520 verifyPointsOutsideRegion(REVERSE_DIFFERENCE_WITHOUT2); 521 522 // 3. reverse difference rectangle out of this region 523 region.set(rect2); 524 assertTrue(region.contains(2, 2)); 525 assertFalse(region.contains(41, 41)); 526 assertTrue(region.op(rect5, Region.Op.REVERSE_DIFFERENCE)); 527 verifyPointsInsideRegion(REVERSE_DIFFERENCE_WITH3); 528 verifyPointsOutsideRegion(REVERSE_DIFFERENCE_WITHOUT3); 529 } 530 verifyReplaceOp1(Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5)531 private void verifyReplaceOp1(Rect rect1, Rect rect2, Rect rect3, Rect rect4, Rect rect5) { 532 // REPLACE, Region with rectangle 533 // replace the dst region with the op region 534 region = new Region(); 535 region.set(rect2); 536 // subtract null rectangle 537 assertFalse(region.op(rect1, Region.Op.REPLACE)); 538 // subtract rectangle inside this region 539 region.set(rect2); 540 assertEquals(rect2, region.getBounds()); 541 assertTrue(region.op(rect3, Region.Op.REPLACE)); 542 assertNotSame(rect2, region.getBounds()); 543 assertEquals(rect3, region.getBounds()); 544 // subtract rectangle overlap this region 545 region.set(rect2); 546 assertEquals(rect2, region.getBounds()); 547 assertTrue(region.op(rect4, Region.Op.REPLACE)); 548 assertNotSame(rect2, region.getBounds()); 549 assertEquals(rect4, region.getBounds()); 550 // subtract rectangle out of this region 551 region.set(rect2); 552 assertEquals(rect2, region.getBounds()); 553 assertTrue(region.op(rect5, Region.Op.REPLACE)); 554 assertNotSame(rect2, region.getBounds()); 555 assertEquals(rect5, region.getBounds()); 556 } 557 558 @Test testOp2()559 public void testOp2() { 560 Rect rect2 = new Rect(0, 0, 20, 20); 561 Rect rect3 = new Rect(5, 5, 10, 10); 562 Rect rect4 = new Rect(10, 10, 30, 30); 563 Rect rect5 = new Rect(40, 40, 60, 60); 564 565 verifyNullRegionOp2(); 566 verifyDifferenceOp2(rect2); 567 verifyIntersectOp2(rect2); 568 verifyUnionOp2(rect2); 569 verifyXorOp2(rect2); 570 verifyReverseDifferenceOp2(rect2); 571 verifyReplaceOp2(rect2, rect3, rect4, rect5); 572 } 573 verifyNullRegionOp2()574 private void verifyNullRegionOp2() { 575 // Region without rectangle 576 region = new Region(); 577 assertFalse(region.op(0, 0, 0, 0, Region.Op.DIFFERENCE)); 578 assertFalse(region.op(0, 0, 0, 0, Region.Op.INTERSECT)); 579 assertFalse(region.op(0, 0, 0, 0, Region.Op.UNION)); 580 assertFalse(region.op(0, 0, 0, 0, Region.Op.XOR)); 581 assertFalse(region.op(0, 0, 0, 0, Region.Op.REVERSE_DIFFERENCE)); 582 assertFalse(region.op(0, 0, 0, 0, Region.Op.REPLACE)); 583 } 584 verifyDifferenceOp2(Rect rect2)585 private void verifyDifferenceOp2(Rect rect2) { 586 // DIFFERENCE, Region with rectangle 587 // subtract the op region from the first region 588 region = new Region(); 589 // subtract null rectangle 590 region.set(rect2); 591 assertTrue(region.op(0, 0, 0, 0, Region.Op.DIFFERENCE)); 592 593 // 1. subtract rectangle inside this region 594 region.set(rect2); 595 assertTrue(region.contains(6, 6)); 596 assertTrue(region.op(5, 5, 10, 10, Region.Op.DIFFERENCE)); 597 verifyPointsInsideRegion(DIFFERENCE_WITH1); 598 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT1); 599 600 // 2. subtract rectangle overlap this region 601 region.set(rect2); 602 assertTrue(region.contains(11, 11)); 603 assertTrue(region.op(10, 10, 30, 30, Region.Op.DIFFERENCE)); 604 verifyPointsInsideRegion(DIFFERENCE_WITH2); 605 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT2); 606 607 // 3. subtract rectangle out of this region 608 region.set(rect2); 609 assertTrue(region.op(40, 40, 60, 60, Region.Op.DIFFERENCE)); 610 verifyPointsInsideRegion(DIFFERENCE_WITH3); 611 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT3); 612 } 613 verifyIntersectOp2(Rect rect2)614 private void verifyIntersectOp2(Rect rect2) { 615 // INTERSECT, Region with rectangle 616 // intersect the two regions 617 region = new Region(); 618 // intersect null rectangle 619 region.set(rect2); 620 assertFalse(region.op(0, 0, 0, 0, Region.Op.INTERSECT)); 621 622 // 1. intersect rectangle inside this region 623 region.set(rect2); 624 assertTrue(region.contains(2, 2)); 625 assertTrue(region.op(5, 5, 10, 10, Region.Op.INTERSECT)); 626 verifyPointsInsideRegion(INTERSECT_WITH1); 627 verifyPointsOutsideRegion(INTERSECT_WITHOUT1); 628 629 // 2. intersect rectangle overlap this region 630 region.set(rect2); 631 assertTrue(region.contains(9, 9)); 632 assertTrue(region.op(10, 10, 30, 30, Region.Op.INTERSECT)); 633 verifyPointsInsideRegion(INTERSECT_WITH2); 634 verifyPointsOutsideRegion(INTERSECT_WITHOUT2); 635 636 // 3. intersect rectangle out of this region 637 region.set(rect2); 638 assertFalse(region.op(40, 40, 60, 60, Region.Op.INTERSECT)); 639 } 640 verifyUnionOp2(Rect rect2)641 private void verifyUnionOp2(Rect rect2) { 642 // UNION, Region with rectangle 643 // union (inclusive-or) the two regions 644 region = new Region(); 645 region.set(rect2); 646 // union null rectangle 647 assertTrue(region.contains(6, 6)); 648 assertTrue(region.op(0, 0, 0, 0, Region.Op.UNION)); 649 assertTrue(region.contains(6, 6)); 650 651 // 1. union rectangle inside this region 652 region.set(rect2); 653 assertTrue(region.contains(2, 2)); 654 assertTrue(region.contains(6, 6)); 655 assertTrue(region.op(5, 5, 10, 10, Region.Op.UNION)); 656 verifyPointsInsideRegion(UNION_WITH1); 657 verifyPointsOutsideRegion(UNION_WITHOUT1); 658 659 // 2. union rectangle overlap this region 660 region.set(rect2); 661 assertTrue(region.contains(2, 2)); 662 assertFalse(region.contains(21, 21)); 663 assertTrue(region.op(10, 10, 30, 30, Region.Op.UNION)); 664 verifyPointsInsideRegion(UNION_WITH2); 665 verifyPointsOutsideRegion(UNION_WITHOUT2); 666 667 // 3. union rectangle out of this region 668 region.set(rect2); 669 assertTrue(region.contains(2, 2)); 670 assertFalse(region.contains(41, 41)); 671 assertTrue(region.op(40, 40, 60, 60, Region.Op.UNION)); 672 verifyPointsInsideRegion(UNION_WITH3); 673 verifyPointsOutsideRegion(UNION_WITHOUT3); 674 } 675 verifyXorOp2(Rect rect2)676 private void verifyXorOp2(Rect rect2) { 677 // XOR, Region with rectangle 678 // exclusive-or the two regions 679 region = new Region(); 680 region.set(rect2); 681 // xor null rectangle 682 assertTrue(region.op(0, 0, 0, 0, Region.Op.XOR)); 683 684 // 1. xor rectangle inside this region 685 region.set(rect2); 686 assertTrue(region.contains(2, 2)); 687 assertTrue(region.contains(6, 6)); 688 assertTrue(region.op(5, 5, 10, 10, Region.Op.XOR)); 689 verifyPointsInsideRegion(XOR_WITH1); 690 verifyPointsOutsideRegion(XOR_WITHOUT1); 691 692 // 2. xor rectangle overlap this region 693 region.set(rect2); 694 assertTrue(region.contains(2, 2)); 695 assertTrue(region.contains(11, 11)); 696 assertFalse(region.contains(21, 21)); 697 assertTrue(region.op(10, 10, 30, 30, Region.Op.XOR)); 698 verifyPointsInsideRegion(XOR_WITH2); 699 verifyPointsOutsideRegion(XOR_WITHOUT2); 700 701 // 3. xor rectangle out of this region 702 region.set(rect2); 703 assertTrue(region.contains(2, 2)); 704 assertFalse(region.contains(41, 41)); 705 assertTrue(region.op(40, 40, 60, 60, Region.Op.XOR)); 706 verifyPointsInsideRegion(XOR_WITH3); 707 verifyPointsOutsideRegion(XOR_WITHOUT3); 708 } 709 verifyReverseDifferenceOp2(Rect rect2)710 private void verifyReverseDifferenceOp2(Rect rect2) { 711 // REVERSE_DIFFERENCE, Region with rectangle 712 // reverse difference the first region from the op region 713 region = new Region(); 714 region.set(rect2); 715 // reverse difference null rectangle 716 assertFalse(region.op(0, 0, 0, 0, Region.Op.REVERSE_DIFFERENCE)); 717 // reverse difference rectangle inside this region 718 region.set(rect2); 719 assertTrue(region.contains(2, 2)); 720 assertTrue(region.contains(6, 6)); 721 assertFalse(region.op(5, 5, 10, 10, Region.Op.REVERSE_DIFFERENCE)); 722 // reverse difference rectangle overlap this region 723 region.set(rect2); 724 assertTrue(region.contains(2, 2)); 725 assertTrue(region.contains(11, 11)); 726 assertFalse(region.contains(21, 21)); 727 assertTrue(region.op(10, 10, 30, 30, Region.Op.REVERSE_DIFFERENCE)); 728 verifyPointsInsideRegion(REVERSE_DIFFERENCE_WITH2); 729 verifyPointsOutsideRegion(REVERSE_DIFFERENCE_WITHOUT2); 730 // reverse difference rectangle out of this region 731 region.set(rect2); 732 assertTrue(region.contains(2, 2)); 733 assertFalse(region.contains(41, 41)); 734 assertTrue(region.op(40, 40, 60, 60, Region.Op.REVERSE_DIFFERENCE)); 735 verifyPointsInsideRegion(REVERSE_DIFFERENCE_WITH3); 736 verifyPointsOutsideRegion(REVERSE_DIFFERENCE_WITHOUT3); 737 } 738 verifyReplaceOp2(Rect rect2, Rect rect3, Rect rect4, Rect rect5)739 private void verifyReplaceOp2(Rect rect2, Rect rect3, Rect rect4, Rect rect5) { 740 // REPLACE, Region w1ith rectangle 741 // replace the dst region with the op region 742 region = new Region(); 743 region.set(rect2); 744 // subtract null rectangle 745 assertFalse(region.op(0, 0, 0, 0, Region.Op.REPLACE)); 746 // subtract rectangle inside this region 747 region.set(rect2); 748 assertEquals(rect2, region.getBounds()); 749 assertTrue(region.op(5, 5, 10, 10, Region.Op.REPLACE)); 750 assertNotSame(rect2, region.getBounds()); 751 assertEquals(rect3, region.getBounds()); 752 // subtract rectangle overlap this region 753 region.set(rect2); 754 assertEquals(rect2, region.getBounds()); 755 assertTrue(region.op(10, 10, 30, 30, Region.Op.REPLACE)); 756 assertNotSame(rect2, region.getBounds()); 757 assertEquals(rect4, region.getBounds()); 758 // subtract rectangle out of this region 759 region.set(rect2); 760 assertEquals(rect2, region.getBounds()); 761 assertTrue(region.op(40, 40, 60, 60, Region.Op.REPLACE)); 762 assertNotSame(rect2, region.getBounds()); 763 assertEquals(rect5, region.getBounds()); 764 } 765 766 @Test testOp3()767 public void testOp3() { 768 Region region1 = new Region(); 769 Region region2 = new Region(0, 0, 20, 20); 770 Region region3 = new Region(5, 5, 10, 10); 771 Region region4 = new Region(10, 10, 30, 30); 772 Region region5 = new Region(40, 40, 60, 60); 773 774 verifyNullRegionOp3(region1); 775 verifyDifferenceOp3(region1, region2, region3, region4, region5); 776 verifyIntersectOp3(region1, region2, region3, region4, region5); 777 verifyUnionOp3(region1, region2, region3, region4, region5); 778 verifyXorOp3(region1, region2, region3, region4, region5); 779 verifyReverseDifferenceOp3(region1, region2, region3, region4, region5); 780 verifyReplaceOp3(region1, region2, region3, region4, region5); 781 } 782 verifyNullRegionOp3(Region region1)783 private void verifyNullRegionOp3(Region region1) { 784 // Region without rectangle 785 region = new Region(); 786 assertFalse(region.op(region1, Region.Op.DIFFERENCE)); 787 assertFalse(region.op(region1, Region.Op.INTERSECT)); 788 assertFalse(region.op(region1, Region.Op.UNION)); 789 assertFalse(region.op(region1, Region.Op.XOR)); 790 assertFalse(region.op(region1, Region.Op.REVERSE_DIFFERENCE)); 791 assertFalse(region.op(region1, Region.Op.REPLACE)); 792 } 793 verifyDifferenceOp3( Region region1, Region region2, Region region3, Region region4, Region region5)794 private void verifyDifferenceOp3( 795 Region region1, Region region2, Region region3, Region region4, Region region5) { 796 // DIFFERENCE, Region with rectangle 797 // subtract the op region from the first region 798 region = new Region(); 799 // subtract null rectangle 800 region.set(region2); 801 assertTrue(region.op(region1, Region.Op.DIFFERENCE)); 802 803 // 1. subtract rectangle inside this region 804 region.set(region2); 805 assertTrue(region.contains(6, 6)); 806 assertTrue(region.op(region3, Region.Op.DIFFERENCE)); 807 verifyPointsInsideRegion(DIFFERENCE_WITH1); 808 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT1); 809 810 // 2. subtract rectangle overlap this region 811 region.set(region2); 812 assertTrue(region.contains(11, 11)); 813 assertTrue(region.op(region4, Region.Op.DIFFERENCE)); 814 verifyPointsInsideRegion(DIFFERENCE_WITH2); 815 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT2); 816 817 // 3. subtract rectangle out of this region 818 region.set(region2); 819 assertTrue(region.op(region5, Region.Op.DIFFERENCE)); 820 verifyPointsInsideRegion(DIFFERENCE_WITH3); 821 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT3); 822 } 823 verifyIntersectOp3( Region region1, Region region2, Region region3, Region region4, Region region5)824 private void verifyIntersectOp3( 825 Region region1, Region region2, Region region3, Region region4, Region region5) { 826 // INTERSECT, Region with rectangle 827 // intersect the two regions 828 region = new Region(); 829 region.set(region2); 830 // intersect null rectangle 831 assertFalse(region.op(region1, Region.Op.INTERSECT)); 832 833 // 1. intersect rectangle inside this region 834 region.set(region2); 835 assertTrue(region.contains(2, 2)); 836 assertTrue(region.op(region3, Region.Op.INTERSECT)); 837 verifyPointsInsideRegion(INTERSECT_WITH1); 838 verifyPointsOutsideRegion(INTERSECT_WITHOUT1); 839 840 // 2. intersect rectangle overlap this region 841 region.set(region2); 842 assertTrue(region.contains(9, 9)); 843 assertTrue(region.op(region4, Region.Op.INTERSECT)); 844 verifyPointsInsideRegion(INTERSECT_WITH2); 845 verifyPointsOutsideRegion(INTERSECT_WITHOUT2); 846 847 // 3. intersect rectangle out of this region 848 region.set(region2); 849 assertFalse(region.op(region5, Region.Op.INTERSECT)); 850 } 851 verifyUnionOp3( Region region1, Region region2, Region region3, Region region4, Region region5)852 private void verifyUnionOp3( 853 Region region1, Region region2, Region region3, Region region4, Region region5) { 854 // UNION, Region with rectangle 855 // union (inclusive-or) the two regions 856 region = new Region(); 857 // union null rectangle 858 region.set(region2); 859 assertTrue(region.contains(6, 6)); 860 assertTrue(region.op(region1, Region.Op.UNION)); 861 assertTrue(region.contains(6, 6)); 862 863 // 1. union rectangle inside this region 864 region.set(region2); 865 assertTrue(region.contains(2, 2)); 866 assertTrue(region.contains(6, 6)); 867 assertTrue(region.op(region3, Region.Op.UNION)); 868 verifyPointsInsideRegion(UNION_WITH1); 869 verifyPointsOutsideRegion(UNION_WITHOUT1); 870 871 // 2. union rectangle overlap this region 872 region.set(region2); 873 assertTrue(region.contains(2, 2)); 874 assertFalse(region.contains(21, 21)); 875 assertTrue(region.op(region4, Region.Op.UNION)); 876 verifyPointsInsideRegion(UNION_WITH2); 877 verifyPointsOutsideRegion(UNION_WITHOUT2); 878 879 // 3. union rectangle out of this region 880 region.set(region2); 881 assertTrue(region.contains(2, 2)); 882 assertFalse(region.contains(41, 41)); 883 assertTrue(region.op(region5, Region.Op.UNION)); 884 verifyPointsInsideRegion(UNION_WITH3); 885 verifyPointsOutsideRegion(UNION_WITHOUT3); 886 } 887 verifyXorOp3( Region region1, Region region2, Region region3, Region region4, Region region5)888 private void verifyXorOp3( 889 Region region1, Region region2, Region region3, Region region4, Region region5) { 890 // XOR, Region with rectangle 891 // exclusive-or the two regions 892 region = new Region(); 893 // xor null rectangle 894 region.set(region2); 895 assertTrue(region.op(region1, Region.Op.XOR)); 896 897 // 1. xor rectangle inside this region 898 region.set(region2); 899 assertTrue(region.contains(2, 2)); 900 assertTrue(region.contains(6, 6)); 901 assertTrue(region.op(region3, Region.Op.XOR)); 902 verifyPointsInsideRegion(XOR_WITH1); 903 verifyPointsOutsideRegion(XOR_WITHOUT1); 904 905 // 2. xor rectangle overlap this region 906 region.set(region2); 907 assertTrue(region.contains(2, 2)); 908 assertTrue(region.contains(11, 11)); 909 assertFalse(region.contains(21, 21)); 910 assertTrue(region.op(region4, Region.Op.XOR)); 911 verifyPointsInsideRegion(XOR_WITH2); 912 verifyPointsOutsideRegion(XOR_WITHOUT2); 913 914 // 3. xor rectangle out of this region 915 region.set(region2); 916 assertTrue(region.contains(2, 2)); 917 assertFalse(region.contains(41, 41)); 918 assertTrue(region.op(region5, Region.Op.XOR)); 919 verifyPointsInsideRegion(XOR_WITH3); 920 verifyPointsOutsideRegion(XOR_WITHOUT3); 921 } 922 verifyReverseDifferenceOp3( Region region1, Region region2, Region region3, Region region4, Region region5)923 private void verifyReverseDifferenceOp3( 924 Region region1, Region region2, Region region3, Region region4, Region region5) { 925 // REVERSE_DIFFERENCE, Region with rectangle 926 // reverse difference the first region from the op region 927 region = new Region(); 928 // reverse difference null rectangle 929 region.set(region2); 930 assertFalse(region.op(region1, Region.Op.REVERSE_DIFFERENCE)); 931 932 // 1. reverse difference rectangle inside this region 933 region.set(region2); 934 assertTrue(region.contains(2, 2)); 935 assertTrue(region.contains(6, 6)); 936 assertFalse(region.op(region3, Region.Op.REVERSE_DIFFERENCE)); 937 938 // 2. reverse difference rectangle overlap this region 939 region.set(region2); 940 assertTrue(region.contains(2, 2)); 941 assertTrue(region.contains(11, 11)); 942 assertFalse(region.contains(21, 21)); 943 assertTrue(region.op(region4, Region.Op.REVERSE_DIFFERENCE)); 944 verifyPointsInsideRegion(REVERSE_DIFFERENCE_WITH2); 945 verifyPointsOutsideRegion(REVERSE_DIFFERENCE_WITHOUT2); 946 947 // 3. reverse difference rectangle out of this region 948 region.set(region2); 949 assertTrue(region.contains(2, 2)); 950 assertFalse(region.contains(41, 41)); 951 assertTrue(region.op(region5, Region.Op.REVERSE_DIFFERENCE)); 952 verifyPointsInsideRegion(REVERSE_DIFFERENCE_WITH3); 953 verifyPointsOutsideRegion(REVERSE_DIFFERENCE_WITHOUT3); 954 } 955 verifyReplaceOp3( Region region1, Region region2, Region region3, Region region4, Region region5)956 private void verifyReplaceOp3( 957 Region region1, Region region2, Region region3, Region region4, Region region5) { 958 // REPLACE, Region with rectangle 959 // replace the dst region with the op region 960 region = new Region(); 961 region.set(region2); 962 // subtract null rectangle 963 assertFalse(region.op(region1, Region.Op.REPLACE)); 964 // subtract rectangle inside this region 965 region.set(region2); 966 assertEquals(region2.getBounds(), region.getBounds()); 967 assertTrue(region.op(region3, Region.Op.REPLACE)); 968 assertNotSame(region2.getBounds(), region.getBounds()); 969 assertEquals(region3.getBounds(), region.getBounds()); 970 // subtract rectangle overlap this region 971 region.set(region2); 972 assertEquals(region2.getBounds(), region.getBounds()); 973 assertTrue(region.op(region4, Region.Op.REPLACE)); 974 assertNotSame(region2.getBounds(), region.getBounds()); 975 assertEquals(region4.getBounds(), region.getBounds()); 976 // subtract rectangle out of this region 977 region.set(region2); 978 assertEquals(region2.getBounds(), region.getBounds()); 979 assertTrue(region.op(region5, Region.Op.REPLACE)); 980 assertNotSame(region2.getBounds(), region.getBounds()); 981 assertEquals(region5.getBounds(), region.getBounds()); 982 } 983 984 @Test testOp4()985 public void testOp4() { 986 Rect rect1 = new Rect(); 987 Rect rect2 = new Rect(0, 0, 20, 20); 988 989 Region region1 = new Region(); 990 Region region2 = new Region(0, 0, 20, 20); 991 Region region3 = new Region(5, 5, 10, 10); 992 Region region4 = new Region(10, 10, 30, 30); 993 Region region5 = new Region(40, 40, 60, 60); 994 995 verifyNullRegionOp4(rect1, region1); 996 verifyDifferenceOp4(rect1, rect2, region1, region3, region4, region5); 997 verifyIntersectOp4(rect1, rect2, region1, region3, region4, region5); 998 verifyUnionOp4(rect1, rect2, region1, region3, region4, region5); 999 verifyXorOp4(rect1, rect2, region1, region3, region4, region5); 1000 verifyReverseDifferenceOp4(rect1, rect2, region1, region3, region4, region5); 1001 verifyReplaceOp4(rect1, rect2, region1, region2, region3, region4, region5); 1002 } 1003 verifyNullRegionOp4(Rect rect1, Region region1)1004 private void verifyNullRegionOp4(Rect rect1, Region region1) { 1005 // Region without rectangle 1006 region = new Region(); 1007 assertFalse(region.op(rect1, region1, Region.Op.DIFFERENCE)); 1008 assertFalse(region.op(rect1, region1, Region.Op.INTERSECT)); 1009 assertFalse(region.op(rect1, region1, Region.Op.UNION)); 1010 1011 assertFalse(region.op(rect1, region1, Region.Op.XOR)); 1012 assertFalse(region.op(rect1, region1, Region.Op.REVERSE_DIFFERENCE)); 1013 assertFalse(region.op(rect1, region1, Region.Op.REPLACE)); 1014 } 1015 verifyDifferenceOp4( Rect rect1, Rect rect2, Region region1, Region region3, Region region4, Region region5)1016 private void verifyDifferenceOp4( 1017 Rect rect1, Rect rect2, Region region1, Region region3, Region region4, Region region5) { 1018 // DIFFERENCE, Region with rectangle 1019 // subtract the op region from the first region 1020 region = new Region(); 1021 // subtract null rectangle 1022 assertTrue(region.op(rect2, region1, Region.Op.DIFFERENCE)); 1023 1024 // 1. subtract rectangle inside this region 1025 region.set(rect1); 1026 assertTrue(region.op(rect2, region3, Region.Op.DIFFERENCE)); 1027 verifyPointsInsideRegion(DIFFERENCE_WITH1); 1028 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT1); 1029 1030 // 2. subtract rectangle overlap this region 1031 region.set(rect1); 1032 assertTrue(region.op(rect2, region4, Region.Op.DIFFERENCE)); 1033 verifyPointsInsideRegion(DIFFERENCE_WITH2); 1034 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT2); 1035 1036 // 3. subtract rectangle out of this region 1037 region.set(rect1); 1038 assertTrue(region.op(rect2, region5, Region.Op.DIFFERENCE)); 1039 verifyPointsInsideRegion(DIFFERENCE_WITH3); 1040 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT3); 1041 } 1042 verifyIntersectOp4( Rect rect1, Rect rect2, Region region1, Region region3, Region region4, Region region5)1043 private void verifyIntersectOp4( 1044 Rect rect1, Rect rect2, Region region1, Region region3, Region region4, Region region5) { 1045 // INTERSECT, Region with rectangle 1046 // intersect the two regions 1047 region = new Region(); 1048 // intersect null rectangle 1049 region.set(rect1); 1050 assertFalse(region.op(rect2, region1, Region.Op.INTERSECT)); 1051 1052 // 1. intersect rectangle inside this region 1053 region.set(rect1); 1054 assertTrue(region.op(rect2, region3, Region.Op.INTERSECT)); 1055 verifyPointsInsideRegion(INTERSECT_WITH1); 1056 verifyPointsOutsideRegion(INTERSECT_WITHOUT1); 1057 1058 // 2. intersect rectangle overlap this region 1059 region.set(rect1); 1060 assertTrue(region.op(rect2, region4, Region.Op.INTERSECT)); 1061 verifyPointsInsideRegion(INTERSECT_WITH2); 1062 verifyPointsOutsideRegion(INTERSECT_WITHOUT2); 1063 1064 // 3. intersect rectangle out of this region 1065 region.set(rect1); 1066 assertFalse(region.op(rect2, region5, Region.Op.INTERSECT)); 1067 } 1068 verifyUnionOp4( Rect rect1, Rect rect2, Region region1, Region region3, Region region4, Region region5)1069 private void verifyUnionOp4( 1070 Rect rect1, Rect rect2, Region region1, Region region3, Region region4, Region region5) { 1071 // UNION, Region with rectangle 1072 // union (inclusive-or) the two regions 1073 region = new Region(); 1074 // union null rectangle 1075 region.set(rect1); 1076 assertTrue(region.op(rect2, region1, Region.Op.UNION)); 1077 assertTrue(region.contains(6, 6)); 1078 1079 // 1. union rectangle inside this region 1080 region.set(rect1); 1081 assertTrue(region.op(rect2, region3, Region.Op.UNION)); 1082 verifyPointsInsideRegion(UNION_WITH1); 1083 verifyPointsOutsideRegion(UNION_WITHOUT1); 1084 1085 // 2. union rectangle overlap this region 1086 region.set(rect1); 1087 assertTrue(region.op(rect2, region4, Region.Op.UNION)); 1088 verifyPointsInsideRegion(UNION_WITH2); 1089 verifyPointsOutsideRegion(UNION_WITHOUT2); 1090 1091 // 3. union rectangle out of this region 1092 region.set(rect1); 1093 assertTrue(region.op(rect2, region5, Region.Op.UNION)); 1094 verifyPointsInsideRegion(UNION_WITH3); 1095 verifyPointsOutsideRegion(UNION_WITHOUT3); 1096 } 1097 verifyXorOp4( Rect rect1, Rect rect2, Region region1, Region region3, Region region4, Region region5)1098 private void verifyXorOp4( 1099 Rect rect1, Rect rect2, Region region1, Region region3, Region region4, Region region5) { 1100 // XOR, Region with rectangle 1101 // exclusive-or the two regions 1102 region = new Region(); 1103 // xor null rectangle 1104 region.set(rect1); 1105 assertTrue(region.op(rect2, region1, Region.Op.XOR)); 1106 1107 // 1. xor rectangle inside this region 1108 region.set(rect1); 1109 assertTrue(region.op(rect2, region3, Region.Op.XOR)); 1110 verifyPointsInsideRegion(XOR_WITH1); 1111 verifyPointsOutsideRegion(XOR_WITHOUT1); 1112 1113 // 2. xor rectangle overlap this region 1114 region.set(rect1); 1115 assertTrue(region.op(rect2, region4, Region.Op.XOR)); 1116 verifyPointsInsideRegion(XOR_WITH2); 1117 verifyPointsOutsideRegion(XOR_WITHOUT2); 1118 1119 // 3. xor rectangle out of this region 1120 region.set(rect1); 1121 assertTrue(region.op(rect2, region5, Region.Op.XOR)); 1122 verifyPointsInsideRegion(XOR_WITH3); 1123 verifyPointsOutsideRegion(XOR_WITHOUT3); 1124 } 1125 verifyReverseDifferenceOp4( Rect rect1, Rect rect2, Region region1, Region region3, Region region4, Region region5)1126 private void verifyReverseDifferenceOp4( 1127 Rect rect1, Rect rect2, Region region1, Region region3, Region region4, Region region5) { 1128 // REVERSE_DIFFERENCE, Region with rectangle 1129 // reverse difference the first region from the op region 1130 region = new Region(); 1131 // reverse difference null rectangle 1132 region.set(rect1); 1133 assertFalse(region.op(rect2, region1, Region.Op.REVERSE_DIFFERENCE)); 1134 1135 // 1. reverse difference rectangle inside this region 1136 region.set(rect1); 1137 assertFalse(region.op(rect2, region3, Region.Op.REVERSE_DIFFERENCE)); 1138 1139 // 2. reverse difference rectangle overlap this region 1140 region.set(rect1); 1141 assertTrue(region.op(rect2, region4, Region.Op.REVERSE_DIFFERENCE)); 1142 verifyPointsInsideRegion(REVERSE_DIFFERENCE_WITH2); 1143 verifyPointsOutsideRegion(REVERSE_DIFFERENCE_WITHOUT2); 1144 1145 // 3. reverse difference rectangle out of this region 1146 region.set(rect1); 1147 assertTrue(region.op(rect2, region5, Region.Op.REVERSE_DIFFERENCE)); 1148 verifyPointsInsideRegion(REVERSE_DIFFERENCE_WITH3); 1149 verifyPointsOutsideRegion(REVERSE_DIFFERENCE_WITHOUT3); 1150 } 1151 verifyReplaceOp4( Rect rect1, Rect rect2, Region region1, Region region2, Region region3, Region region4, Region region5)1152 private void verifyReplaceOp4( 1153 Rect rect1, 1154 Rect rect2, 1155 Region region1, 1156 Region region2, 1157 Region region3, 1158 Region region4, 1159 Region region5) { 1160 // REPLACE, Region with rectangle 1161 // replace the dst region with the op region 1162 region = new Region(); 1163 // subtract null rectangle 1164 region.set(rect1); 1165 assertFalse(region.op(rect2, region1, Region.Op.REPLACE)); 1166 // subtract rectangle inside this region 1167 region.set(rect1); 1168 assertTrue(region.op(rect2, region3, Region.Op.REPLACE)); 1169 assertNotSame(region2.getBounds(), region.getBounds()); 1170 assertEquals(region3.getBounds(), region.getBounds()); 1171 // subtract rectangle overlap this region 1172 region.set(rect1); 1173 assertTrue(region.op(rect2, region4, Region.Op.REPLACE)); 1174 assertNotSame(region2.getBounds(), region.getBounds()); 1175 assertEquals(region4.getBounds(), region.getBounds()); 1176 // subtract rectangle out of this region 1177 region.set(rect1); 1178 assertTrue(region.op(rect2, region5, Region.Op.REPLACE)); 1179 assertNotSame(region2.getBounds(), region.getBounds()); 1180 assertEquals(region5.getBounds(), region.getBounds()); 1181 } 1182 1183 @Test testOp5()1184 public void testOp5() { 1185 Region region1 = new Region(); 1186 Region region2 = new Region(0, 0, 20, 20); 1187 Region region3 = new Region(5, 5, 10, 10); 1188 Region region4 = new Region(10, 10, 30, 30); 1189 Region region5 = new Region(40, 40, 60, 60); 1190 1191 verifyNullRegionOp5(region1); 1192 verifyDifferenceOp5(region1, region2, region3, region4, region5); 1193 verifyIntersectOp5(region1, region2, region3, region4, region5); 1194 verifyUnionOp5(region1, region2, region3, region4, region5); 1195 verifyXorOp5(region1, region2, region3, region4, region5); 1196 verifyReverseDifferenceOp5(region1, region2, region3, region4, region5); 1197 verifyReplaceOp5(region1, region2, region3, region4, region5); 1198 } 1199 verifyNullRegionOp5(Region region1)1200 private void verifyNullRegionOp5(Region region1) { 1201 // Region without rectangle 1202 region = new Region(); 1203 assertFalse(region.op(region, region1, Region.Op.DIFFERENCE)); 1204 assertFalse(region.op(region, region1, Region.Op.INTERSECT)); 1205 assertFalse(region.op(region, region1, Region.Op.UNION)); 1206 assertFalse(region.op(region, region1, Region.Op.XOR)); 1207 assertFalse(region.op(region, region1, Region.Op.REVERSE_DIFFERENCE)); 1208 assertFalse(region.op(region, region1, Region.Op.REPLACE)); 1209 } 1210 verifyDifferenceOp5( Region region1, Region region2, Region region3, Region region4, Region region5)1211 private void verifyDifferenceOp5( 1212 Region region1, Region region2, Region region3, Region region4, Region region5) { 1213 // DIFFERENCE, Region with rectangle 1214 // subtract the op region from the first region 1215 region = new Region(); 1216 // subtract null rectangle 1217 region.set(region1); 1218 assertTrue(region.op(region2, region1, Region.Op.DIFFERENCE)); 1219 1220 // 1. subtract rectangle inside this region 1221 region.set(region1); 1222 assertTrue(region.op(region2, region3, Region.Op.DIFFERENCE)); 1223 verifyPointsInsideRegion(DIFFERENCE_WITH1); 1224 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT1); 1225 1226 // 2. subtract rectangle overlap this region 1227 region.set(region1); 1228 assertTrue(region.op(region2, region4, Region.Op.DIFFERENCE)); 1229 verifyPointsInsideRegion(DIFFERENCE_WITH2); 1230 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT2); 1231 1232 // 3. subtract rectangle out of this region 1233 region.set(region1); 1234 assertTrue(region.op(region2, region5, Region.Op.DIFFERENCE)); 1235 verifyPointsInsideRegion(DIFFERENCE_WITH3); 1236 verifyPointsOutsideRegion(DIFFERENCE_WITHOUT3); 1237 } 1238 verifyIntersectOp5( Region region1, Region region2, Region region3, Region region4, Region region5)1239 private void verifyIntersectOp5( 1240 Region region1, Region region2, Region region3, Region region4, Region region5) { 1241 // INTERSECT, Region with rectangle 1242 // intersect the two regions 1243 region = new Region(); 1244 // intersect null rectangle 1245 region.set(region1); 1246 assertFalse(region.op(region2, region1, Region.Op.INTERSECT)); 1247 1248 // 1. intersect rectangle inside this region 1249 region.set(region1); 1250 assertTrue(region.op(region2, region3, Region.Op.INTERSECT)); 1251 verifyPointsInsideRegion(INTERSECT_WITH1); 1252 verifyPointsOutsideRegion(INTERSECT_WITHOUT1); 1253 1254 // 2. intersect rectangle overlap this region 1255 region.set(region1); 1256 assertTrue(region.op(region2, region4, Region.Op.INTERSECT)); 1257 verifyPointsInsideRegion(INTERSECT_WITH2); 1258 verifyPointsOutsideRegion(INTERSECT_WITHOUT2); 1259 1260 // 3. intersect rectangle out of this region 1261 region.set(region1); 1262 assertFalse(region.op(region2, region5, Region.Op.INTERSECT)); 1263 } 1264 verifyUnionOp5( Region region1, Region region2, Region region3, Region region4, Region region5)1265 private void verifyUnionOp5( 1266 Region region1, Region region2, Region region3, Region region4, Region region5) { 1267 // UNION, Region with rectangle 1268 // union (inclusive-or) the two regions 1269 region = new Region(); 1270 // union null rectangle 1271 region.set(region1); 1272 assertTrue(region.op(region2, region1, Region.Op.UNION)); 1273 assertTrue(region.contains(6, 6)); 1274 1275 // 1. union rectangle inside this region 1276 region.set(region1); 1277 assertTrue(region.op(region2, region3, Region.Op.UNION)); 1278 verifyPointsInsideRegion(UNION_WITH1); 1279 verifyPointsOutsideRegion(UNION_WITHOUT1); 1280 1281 // 2. union rectangle overlap this region 1282 region.set(region1); 1283 assertTrue(region.op(region2, region4, Region.Op.UNION)); 1284 verifyPointsInsideRegion(UNION_WITH2); 1285 verifyPointsOutsideRegion(UNION_WITHOUT2); 1286 1287 // 3. union rectangle out of this region 1288 region.set(region1); 1289 assertTrue(region.op(region2, region5, Region.Op.UNION)); 1290 verifyPointsInsideRegion(UNION_WITH3); 1291 verifyPointsOutsideRegion(UNION_WITHOUT3); 1292 } 1293 verifyXorOp5( Region region1, Region region2, Region region3, Region region4, Region region5)1294 private void verifyXorOp5( 1295 Region region1, Region region2, Region region3, Region region4, Region region5) { 1296 // XOR, Region with rectangle 1297 // exclusive-or the two regions 1298 region = new Region(); 1299 // xor null rectangle 1300 region.set(region1); 1301 assertTrue(region.op(region2, region1, Region.Op.XOR)); 1302 1303 // 1. xor rectangle inside this region 1304 region.set(region1); 1305 assertTrue(region.op(region2, region3, Region.Op.XOR)); 1306 verifyPointsInsideRegion(XOR_WITH1); 1307 verifyPointsOutsideRegion(XOR_WITHOUT1); 1308 1309 // 2. xor rectangle overlap this region 1310 region.set(region1); 1311 assertTrue(region.op(region2, region4, Region.Op.XOR)); 1312 verifyPointsInsideRegion(XOR_WITH2); 1313 verifyPointsOutsideRegion(XOR_WITHOUT2); 1314 1315 // 3. xor rectangle out of this region 1316 region.set(region1); 1317 assertTrue(region.op(region2, region5, Region.Op.XOR)); 1318 verifyPointsInsideRegion(XOR_WITH3); 1319 verifyPointsOutsideRegion(XOR_WITHOUT3); 1320 } 1321 verifyReverseDifferenceOp5( Region region1, Region region2, Region region3, Region region4, Region region5)1322 private void verifyReverseDifferenceOp5( 1323 Region region1, Region region2, Region region3, Region region4, Region region5) { 1324 // REVERSE_DIFFERENCE, Region with rectangle 1325 // reverse difference the first region from the op region 1326 region = new Region(); 1327 // reverse difference null rectangle 1328 region.set(region1); 1329 assertFalse(region.op(region2, region1, Region.Op.REVERSE_DIFFERENCE)); 1330 1331 // 1. reverse difference rectangle inside this region 1332 region.set(region1); 1333 assertFalse(region.op(region2, region3, Region.Op.REVERSE_DIFFERENCE)); 1334 1335 // 2. reverse difference rectangle overlap this region 1336 region.set(region1); 1337 assertTrue(region.op(region2, region4, Region.Op.REVERSE_DIFFERENCE)); 1338 verifyPointsInsideRegion(REVERSE_DIFFERENCE_WITH2); 1339 verifyPointsOutsideRegion(REVERSE_DIFFERENCE_WITHOUT2); 1340 1341 // 3. reverse difference rectangle out of this region 1342 region.set(region1); 1343 assertTrue(region.op(region2, region5, Region.Op.REVERSE_DIFFERENCE)); 1344 verifyPointsInsideRegion(REVERSE_DIFFERENCE_WITH3); 1345 verifyPointsOutsideRegion(REVERSE_DIFFERENCE_WITHOUT3); 1346 } 1347 verifyReplaceOp5( Region region1, Region region2, Region region3, Region region4, Region region5)1348 private void verifyReplaceOp5( 1349 Region region1, Region region2, Region region3, Region region4, Region region5) { 1350 // REPLACE, Region with rectangle 1351 // replace the dst region with the op region 1352 region = new Region(); 1353 // subtract null rectangle 1354 region.set(region1); 1355 assertFalse(region.op(region2, region1, Region.Op.REPLACE)); 1356 // subtract rectangle inside this region 1357 region.set(region1); 1358 assertTrue(region.op(region2, region3, Region.Op.REPLACE)); 1359 assertNotSame(region2.getBounds(), region.getBounds()); 1360 assertEquals(region3.getBounds(), region.getBounds()); 1361 // subtract rectangle overlap this region 1362 region.set(region1); 1363 assertTrue(region.op(region2, region4, Region.Op.REPLACE)); 1364 assertNotSame(region2.getBounds(), region.getBounds()); 1365 assertEquals(region4.getBounds(), region.getBounds()); 1366 // subtract rectangle out of this region 1367 region.set(region1); 1368 assertTrue(region.op(region2, region5, Region.Op.REPLACE)); 1369 assertNotSame(region2.getBounds(), region.getBounds()); 1370 assertEquals(region5.getBounds(), region.getBounds()); 1371 } 1372 1373 @Test testGetBoundaryPath1()1374 public void testGetBoundaryPath1() { 1375 assertTrue(region.getBoundaryPath().isEmpty()); 1376 1377 // Both clip and path are non-null. 1378 Region clip = new Region(0, 0, 10, 10); 1379 Path path = new Path(); 1380 path.addRect(0, 0, 10, 10, Path.Direction.CW); 1381 assertTrue(region.setPath(path, clip)); 1382 assertFalse(region.getBoundaryPath().isEmpty()); 1383 } 1384 1385 @Test testGetBoundaryPath2()1386 public void testGetBoundaryPath2() { 1387 Path path = new Path(); 1388 assertFalse(region.getBoundaryPath(path)); 1389 1390 // path is null 1391 region = new Region(0, 0, 10, 10); 1392 path = new Path(); 1393 assertTrue(region.getBoundaryPath(path)); 1394 1395 // region is null 1396 region = new Region(); 1397 path = new Path(); 1398 path.addRect(0, 0, 10, 10, Path.Direction.CW); 1399 assertFalse(region.getBoundaryPath(path)); 1400 1401 // both path and region are non-null 1402 region = new Region(0, 0, 10, 10); 1403 path = new Path(); 1404 path.addRect(0, 0, 5, 5, Path.Direction.CW); 1405 assertTrue(region.getBoundaryPath(path)); 1406 } 1407 1408 @Test testSetPath()1409 public void testSetPath() { 1410 // Both clip and path are null. 1411 Region clip = new Region(); 1412 Path path = new Path(); 1413 assertFalse(region.setPath(path, clip)); 1414 1415 // Only path is null. 1416 path = new Path(); 1417 clip = new Region(0, 0, 10, 10); 1418 assertFalse(region.setPath(path, clip)); 1419 1420 // Only clip is null. 1421 clip = new Region(); 1422 path = new Path(); 1423 path.addRect(0, 0, 10, 10, Path.Direction.CW); 1424 assertFalse(region.setPath(path, clip)); 1425 1426 // Both clip and path are non-null. 1427 path = new Path(); 1428 clip = new Region(0, 0, 10, 10); 1429 path.addRect(0, 0, 10, 10, Path.Direction.CW); 1430 assertTrue(region.setPath(path, clip)); 1431 1432 // Both clip and path are non-null. 1433 path = new Path(); 1434 clip = new Region(0, 0, 5, 5); 1435 path.addRect(0, 0, 10, 10, Path.Direction.CW); 1436 assertTrue(region.setPath(path, clip)); 1437 Rect expected = new Rect(0, 0, 5, 5); 1438 Rect unexpected = new Rect(0, 0, 10, 10); 1439 Rect actual = region.getBounds(); 1440 assertEquals(expected.right, actual.right); 1441 assertNotSame(unexpected.right, actual.right); 1442 1443 // Both clip and path are non-null. 1444 path = new Path(); 1445 clip = new Region(0, 0, 10, 10); 1446 path.addRect(0, 0, 5, 5, Path.Direction.CW); 1447 assertTrue(region.setPath(path, clip)); 1448 expected = new Rect(0, 0, 5, 5); 1449 unexpected = new Rect(0, 0, 10, 10); 1450 actual = region.getBounds(); 1451 assertEquals(expected.right, actual.right); 1452 assertNotSame(unexpected.right, actual.right); 1453 } 1454 1455 @Test testTranslate1()1456 public void testTranslate1() { 1457 Rect rect1 = new Rect(0, 0, 20, 20); 1458 Rect rect2 = new Rect(10, 10, 30, 30); 1459 region = new Region(0, 0, 20, 20); 1460 region.translate(10, 10); 1461 assertNotSame(rect1, region.getBounds()); 1462 assertEquals(rect2, region.getBounds()); 1463 } 1464 1465 @Test testTranslate2()1466 public void testTranslate2() { 1467 Region dst = new Region(); 1468 Rect rect1 = new Rect(0, 0, 20, 20); 1469 Rect rect2 = new Rect(10, 10, 30, 30); 1470 region = new Region(0, 0, 20, 20); 1471 region.translate(10, 10, dst); 1472 assertEquals(rect1, region.getBounds()); 1473 assertNotSame(rect2, region.getBounds()); 1474 assertNotSame(rect1, dst.getBounds()); 1475 assertEquals(rect2, dst.getBounds()); 1476 } 1477 1478 @Test testDescribeContents()1479 public void testDescribeContents() { 1480 int actual = region.describeContents(); 1481 assertEquals(0, actual); 1482 } 1483 1484 @Test testQuickReject1()1485 public void testQuickReject1() { 1486 Rect oriRect = new Rect(0, 0, 20, 20); 1487 Rect rect1 = new Rect(); 1488 Rect rect2 = new Rect(40, 40, 60, 60); 1489 Rect rect3 = new Rect(0, 0, 10, 10); 1490 Rect rect4 = new Rect(10, 10, 30, 30); 1491 1492 // Return true if the region is empty 1493 assertTrue(region.quickReject(rect1)); 1494 region.set(oriRect); 1495 assertTrue(region.quickReject(rect2)); 1496 region.set(oriRect); 1497 assertFalse(region.quickReject(rect3)); 1498 region.set(oriRect); 1499 assertFalse(region.quickReject(rect4)); 1500 } 1501 1502 @Test testQuickReject2()1503 public void testQuickReject2() { 1504 // Return true if the region is empty 1505 assertTrue(region.quickReject(0, 0, 0, 0)); 1506 region.set(0, 0, 20, 20); 1507 assertTrue(region.quickReject(40, 40, 60, 60)); 1508 region.set(0, 0, 20, 20); 1509 assertFalse(region.quickReject(0, 0, 10, 10)); 1510 region.set(0, 0, 20, 20); 1511 assertFalse(region.quickReject(10, 10, 30, 30)); 1512 } 1513 1514 @Test testQuickReject3()1515 public void testQuickReject3() { 1516 Region oriRegion = new Region(0, 0, 20, 20); 1517 Region region1 = new Region(); 1518 Region region2 = new Region(40, 40, 60, 60); 1519 Region region3 = new Region(0, 0, 10, 10); 1520 Region region4 = new Region(10, 10, 30, 30); 1521 1522 // Return true if the region is empty 1523 assertTrue(region.quickReject(region1)); 1524 region.set(oriRegion); 1525 assertTrue(region.quickReject(region2)); 1526 region.set(oriRegion); 1527 assertFalse(region.quickReject(region3)); 1528 region.set(oriRegion); 1529 assertFalse(region.quickReject(region4)); 1530 } 1531 } 1532