1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.scene.layout;
  27 
  28 import javafx.geometry.Insets;
  29 import javafx.scene.paint.Color;
  30 import org.junit.Before;
  31 import org.junit.Test;
  32 
  33 import static org.junit.Assert.*;
  34 
  35 /**
  36  * Tests for Region picking. By default, Region has pickOnBounds set to true, so picking
  37  * anything within the bounds of the region will return true, anything outside the bounds
  38  * false. However, due to RT-25066, the bounds of a region defined by a shape will be 0x0,
  39  * in which case it will never be picked.
  40  *
  41  * If pickOnBounds is false, then an entire different code path is executed. We don't care
  42  * whether a fill is transparent or not (transparent fills can still cause the region to
  43  * pick), but we do care about picking within the "shape" and picking within the rounded
  44  * rectangle which is created as a result of background fills / background images.
  45  *
  46  * In the case of background images, we don't care about whether we are picking a transparent
  47  * pixel or not, but just based on the insets etc (since we don't have a good means for testing
  48  * the image pixel value).
  49  */
  50 public class RegionPickTest {
  51     private static final double X = 0;
  52     private static final double Y = 0;
  53     private static final double WIDTH = 100;
  54     private static final double HEIGHT = 100;
  55     private static final double CENTER_X = X + (WIDTH / 2.0);
  56     private static final double CENTER_Y = Y + (HEIGHT / 2.0);
  57     private static final double LEFT_OF = X - 10;
  58     private static final double ABOVE = Y - 10;
  59     private static final double RIGHT_OF = X + WIDTH + 10;
  60     private static final double BELOW = Y + HEIGHT + 10;
  61 
  62     private Region region;
  63 
  64     @Before public void setup() {
  65         region = new Region();
  66         region.resizeRelocate(X, Y, WIDTH, HEIGHT);
  67         region.setPickOnBounds(false);
  68     }
  69 
  70     /**************************************************************************
  71      *                                                                        *
  72      * Set of tests to ensure that picking within / without a region with     *
  73      * pickOnBounds set to true (the normal default) results in expected      *
  74      * behavior (pick when within bounds, not when without bounds)            *
  75      *                                                                        *
  76      *************************************************************************/
  77 
  78     @Test public void pickingNormalRegion() {
  79         region.setPickOnBounds(true);
  80         assertFalse(region.contains(LEFT_OF, CENTER_Y));
  81         assertFalse(region.contains(CENTER_X, ABOVE));
  82         assertFalse(region.contains(RIGHT_OF, CENTER_Y));
  83         assertFalse(region.contains(CENTER_X, BELOW));
  84         assertTrue(region.contains(CENTER_X, CENTER_Y));
  85     }
  86 
  87     /**************************************************************************
  88      *                                                                        *
  89      * Test for a Region which has no fills of any kind, but has              *
  90      * pickOnBounds set to false. Such a Region should never pick.            *
  91      *                                                                        *
  92      *************************************************************************/
  93 
  94     @Test public void pickingEmptyRegionDoesNotWork() {
  95         assertFalse(region.contains(LEFT_OF, CENTER_Y));
  96         assertFalse(region.contains(CENTER_X, ABOVE));
  97         assertFalse(region.contains(RIGHT_OF, CENTER_Y));
  98         assertFalse(region.contains(CENTER_X, BELOW));
  99         assertFalse(region.contains(CENTER_X, CENTER_Y));
 100     }
 101 
 102     /**************************************************************************
 103      *                                                                        *
 104      * Test behavior when picking a region with fills, but no shape or border *
 105      * or images.                                                             *
 106      *                                                                        *
 107      *************************************************************************/
 108 
 109     @Test public void pickingRectangularFillWorks() {
 110         region.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
 111         assertFalse(region.contains(LEFT_OF, CENTER_Y));
 112         assertFalse(region.contains(CENTER_X, ABOVE));
 113         assertFalse(region.contains(RIGHT_OF, CENTER_Y));
 114         assertFalse(region.contains(CENTER_X, BELOW));
 115         assertTrue(region.contains(CENTER_X, CENTER_Y));
 116     }
 117 
 118     @Test public void pickingRectangularFillWithInsetsWorks() {
 119         // With insets of 10, we ought to not pick inside the region until we get to position 10
 120         region.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, new Insets(10))));
 121         assertFalse(region.contains(X + 9, CENTER_Y));
 122         assertFalse(region.contains(CENTER_X, Y + 9));
 123         assertFalse(region.contains(X + WIDTH - 9, CENTER_Y));
 124         assertFalse(region.contains(CENTER_X, Y + HEIGHT - 9));
 125         assertTrue(region.contains(X + 10, CENTER_Y));
 126         assertTrue(region.contains(CENTER_X, Y + 10));
 127         assertTrue(region.contains(X + WIDTH - 10, CENTER_Y));
 128         assertTrue(region.contains(CENTER_X, Y + HEIGHT - 10));
 129         assertTrue(region.contains(CENTER_X, CENTER_Y));
 130     }
 131 
 132     @Test public void pickingRectangularFillWithUniformRadiusWorks() {
 133         region.setBackground(new Background(new BackgroundFill(Color.RED, new CornerRadii(10), Insets.EMPTY)));
 134         // Check points in the top-left corner area
 135         assertTrue(region.contains(X, Y + 10));
 136         assertTrue(region.contains(X + 10, Y));
 137         assertTrue(region.contains(X + 10 - (10 * Math.cos(45)), Y + 10 - (10 * Math.sin(45))));
 138         assertTrue(region.contains(X + 10 - (9 * Math.cos(45)), Y + 10 - (9 * Math.sin(45))));
 139         assertFalse(region.contains(X + 10 - (11 * Math.cos(45)), Y + 10 - (11 * Math.sin(45))));
 140         // Check points in the top-right corner area
 141         assertTrue(region.contains(X + WIDTH, Y + 10));
 142         assertTrue(region.contains(X + WIDTH - 10, Y));
 143         assertTrue(region.contains(X + WIDTH - 10 + (10 * Math.cos(45)), Y + 10 - (10 * Math.sin(45))));
 144         assertTrue(region.contains(X + WIDTH - 10 + (9 * Math.cos(45)), Y + 10 - (9 * Math.sin(45))));
 145         assertFalse(region.contains(X + WIDTH - 10 + (11 * Math.cos(45)), Y + 10 - (11 * Math.sin(45))));
 146         // Check points in the bottom-right corner area
 147         assertTrue(region.contains(X + WIDTH, Y + HEIGHT - 10));
 148         assertTrue(region.contains(X + WIDTH - 10, Y + HEIGHT));
 149         assertTrue(region.contains(X + WIDTH - 10 + (10 * Math.cos(45)), Y + HEIGHT - 10 + (10 * Math.sin(45))));
 150         assertTrue(region.contains(X + WIDTH - 10 + (9 * Math.cos(45)), Y + HEIGHT - 10 + (9 * Math.sin(45))));
 151         assertFalse(region.contains(X + WIDTH - 10 + (11 * Math.cos(45)), Y + HEIGHT - 10 + (11 * Math.sin(45))));
 152         // Check points in the bottom-left corner area
 153         assertTrue(region.contains(X, Y + HEIGHT - 10));
 154         assertTrue(region.contains(X + 10, Y + HEIGHT));
 155         assertTrue(region.contains(X + 10 - (10 * Math.cos(45)), Y + HEIGHT - 10 + (10 * Math.sin(45))));
 156         assertTrue(region.contains(X + 10 - (9 * Math.cos(45)), Y + HEIGHT - 10 + (9 * Math.sin(45))));
 157         assertFalse(region.contains(X + 10 - (11 * Math.cos(45)), Y + HEIGHT - 10 + (11 * Math.sin(45))));
 158         // Check the center
 159         assertTrue(region.contains(CENTER_X, CENTER_Y));
 160     }
 161 
 162     @Test public void pickingRectangularFillWithUniformRadiusWithInsetsWorks() {
 163         region.setBackground(new Background(new BackgroundFill(Color.RED, new CornerRadii(10), new Insets(10))));
 164         // Check points in the top-left corner area
 165         assertTrue(region.contains(X + 10, Y + 20));
 166         assertTrue(region.contains(X + 20, Y + 10));
 167         assertTrue(region.contains(X + 20 - (10 * Math.cos(45)), Y + 20 - (10 * Math.sin(45))));
 168         assertTrue(region.contains(X + 20 - (9 * Math.cos(45)), Y + 20 - (9 * Math.sin(45))));
 169         assertFalse(region.contains(X + 20 - (11 * Math.cos(45)), Y + 20 - (11 * Math.sin(45))));
 170         // Check points in the top-right corner area
 171         assertTrue(region.contains(X + WIDTH - 10, Y + 20));
 172         assertTrue(region.contains(X + WIDTH - 20, Y + 10));
 173         assertTrue(region.contains(X + WIDTH - 20 + (10 * Math.cos(45)), Y + 20 - (10 * Math.sin(45))));
 174         assertTrue(region.contains(X + WIDTH - 20 + (9 * Math.cos(45)), Y + 20 - (9 * Math.sin(45))));
 175         assertFalse(region.contains(X + WIDTH - 20 + (11 * Math.cos(45)), Y + 20 - (11 * Math.sin(45))));
 176         // Check points in the bottom-right corner area
 177         assertTrue(region.contains(X + WIDTH - 10, Y + HEIGHT - 20));
 178         assertTrue(region.contains(X + WIDTH - 20, Y + HEIGHT - 10));
 179         assertTrue(region.contains(X + WIDTH - 20 + (10 * Math.cos(45)), Y + HEIGHT - 20 + (10 * Math.sin(45))));
 180         assertTrue(region.contains(X + WIDTH - 20 + (9 * Math.cos(45)), Y + HEIGHT - 20 + (9 * Math.sin(45))));
 181         assertFalse(region.contains(X + WIDTH - 20 + (11 * Math.cos(45)), Y + HEIGHT - 20 + (11 * Math.sin(45))));
 182         // Check points in the bottom-left corner area
 183         assertTrue(region.contains(X + 10, Y + HEIGHT - 20));
 184         assertTrue(region.contains(X + 20, Y + HEIGHT - 10));
 185         assertTrue(region.contains(X + 20 - (10 * Math.cos(45)), Y + HEIGHT - 20 + (10 * Math.sin(45))));
 186         assertTrue(region.contains(X + 20 - (9 * Math.cos(45)), Y + HEIGHT - 20 + (9 * Math.sin(45))));
 187         assertFalse(region.contains(X + 20 - (11 * Math.cos(45)), Y + HEIGHT - 20 + (11 * Math.sin(45))));
 188         // Check the center
 189         assertTrue(region.contains(CENTER_X, CENTER_Y));
 190     }
 191 
 192     // test with really really large corner radius
 193     @Test public void pickingRectangularFillWithUniformVERYLARGERadiusWorks() {
 194         region.setBackground(new Background(new BackgroundFill(Color.RED, new CornerRadii(10000000), Insets.EMPTY)));
 195         // This produces an effective radius of 50 due to my width/height being 100x100
 196         // Check points in the top-left corner area
 197         assertTrue(region.contains(X, Y + 50));
 198         assertTrue(region.contains(X + 50, Y));
 199         assertTrue(region.contains(X + 50 - (50 * Math.cos(45)), Y + 50 - (50 * Math.sin(45))));
 200         assertTrue(region.contains(X + 50 - (49 * Math.cos(45)), Y + 50 - (49 * Math.sin(45))));
 201         assertFalse(region.contains(X + 50 - (51 * Math.cos(45)), Y + 50 - (51 * Math.sin(45))));
 202         // Check points in the top-right corner area
 203         assertTrue(region.contains(X + WIDTH, Y + 50));
 204         assertTrue(region.contains(X + WIDTH - 50, Y));
 205         assertTrue(region.contains(X + WIDTH - 50 + (50 * Math.cos(45)), Y + 50 - (50 * Math.sin(45))));
 206         assertTrue(region.contains(X + WIDTH - 50 + (49 * Math.cos(45)), Y + 50 - (49 * Math.sin(45))));
 207         assertFalse(region.contains(X + WIDTH - 50 + (51 * Math.cos(45)), Y + 50 - (51 * Math.sin(45))));
 208         // Check points in the bottom-right corner area
 209         assertTrue(region.contains(X + WIDTH, Y + HEIGHT - 50));
 210         assertTrue(region.contains(X + WIDTH - 50, Y + HEIGHT));
 211         assertTrue(region.contains(X + WIDTH - 50 + (50 * Math.cos(45)), Y + HEIGHT - 50 + (50 * Math.sin(45))));
 212         assertTrue(region.contains(X + WIDTH - 50 + (49 * Math.cos(45)), Y + HEIGHT - 50 + (49 * Math.sin(45))));
 213         assertFalse(region.contains(X + WIDTH - 50 + (51 * Math.cos(45)), Y + HEIGHT - 50 + (51 * Math.sin(45))));
 214         // Check points in the bottom-left corner area
 215         assertTrue(region.contains(X, Y + HEIGHT - 50));
 216         assertTrue(region.contains(X + 50, Y + HEIGHT));
 217         assertTrue(region.contains(X + 50 - (50 * Math.cos(45)), Y + HEIGHT - 50 + (50 * Math.sin(45))));
 218         assertTrue(region.contains(X + 50 - (49 * Math.cos(45)), Y + HEIGHT - 50 + (49 * Math.sin(45))));
 219         assertFalse(region.contains(X + 50 - (51 * Math.cos(45)), Y + HEIGHT - 50 + (51 * Math.sin(45))));
 220         // Check the center
 221         assertTrue(region.contains(CENTER_X, CENTER_Y));
 222     }
 223 
 224     @Test public void pickingRectangularFillWithIndependentRadiusWorks() {
 225         region.setBackground(new Background(new BackgroundFill(Color.RED, new CornerRadii(1, 2, 3, 4, false),
 226                                                                Insets.EMPTY)));
 227         // Check points in the top-left corner area
 228         assertTrue(region.contains(X, Y + 1));
 229         assertTrue(region.contains(X + 1, Y));
 230         assertTrue(region.contains(X + 1 - (1 * Math.cos(45)), Y + 1 - (1 * Math.sin(45))));
 231         assertTrue(region.contains(X + 1 - (.5 * Math.cos(45)), Y + 1 - (.5 * Math.sin(45))));
 232         assertFalse(region.contains(X + 1 - (2 * Math.cos(45)), Y + 1 - (2 * Math.sin(45))));
 233         // Check points in the top-right corner area
 234         assertTrue(region.contains(X + WIDTH, Y + 2));
 235         assertTrue(region.contains(X + WIDTH - 2, Y));
 236         assertTrue(region.contains(X + WIDTH - 2 + (2 * Math.cos(45)), Y + 2 - (2 * Math.sin(45))));
 237         assertTrue(region.contains(X + WIDTH - 2 + (1 * Math.cos(45)), Y + 2 - (1 * Math.sin(45))));
 238         assertFalse(region.contains(X + WIDTH - 2 + (3 * Math.cos(45)), Y + 2 - (3 * Math.sin(45))));
 239         // Check points in the bottom-right corner area
 240         assertTrue(region.contains(X + WIDTH, Y + HEIGHT - 3));
 241         assertTrue(region.contains(X + WIDTH - 3, Y + HEIGHT));
 242         assertTrue(region.contains(X + WIDTH - 3 + (3 * Math.cos(45)), Y + HEIGHT - 3 + (3 * Math.sin(45))));
 243         assertTrue(region.contains(X + WIDTH - 3 + (2 * Math.cos(45)), Y + HEIGHT - 3 + (2 * Math.sin(45))));
 244         assertFalse(region.contains(X + WIDTH - 3 + (4 * Math.cos(45)), Y + HEIGHT - 3 + (4 * Math.sin(45))));
 245         // Check points in the bottom-left corner area
 246         assertTrue(region.contains(X, Y + HEIGHT - 4));
 247         assertTrue(region.contains(X + 4, Y + HEIGHT));
 248         assertTrue(region.contains(X + 4 - (4 * Math.cos(45)), Y + HEIGHT - 4 + (4 * Math.sin(45))));
 249         assertTrue(region.contains(X + 4 - (3 * Math.cos(45)), Y + HEIGHT - 4 + (3 * Math.sin(45))));
 250         assertFalse(region.contains(X + 4 - (5 * Math.cos(45)), Y + HEIGHT - 4 + (5 * Math.sin(45))));
 251         // Check the center
 252         assertTrue(region.contains(CENTER_X, CENTER_Y));
 253     }
 254 
 255     @Test public void pickingRectangularFillWithIndependentRadiusWorks2() {
 256         region.setBackground(new Background(new BackgroundFill(Color.RED,
 257             new CornerRadii(1, 2, 3, 4, 5, 6, 7, 8, false, false, false, false, false, false, false, false),
 258             Insets.EMPTY)));
 259         // Check points in the top-left corner area
 260         assertTrue(region.contains(X, Y + 2));
 261         assertTrue(region.contains(X + 1, Y));
 262         assertTrue(region.contains(X + 1 - (1 * Math.cos(45)), Y + 2 - (2 * Math.sin(45))));
 263         assertTrue(region.contains(X + 1 - (.5 * Math.cos(45)), Y + 2 - (1 * Math.sin(45))));
 264         assertFalse(region.contains(X + 1 - (2 * Math.cos(45)), Y + 2 - (3 * Math.sin(45))));
 265         // Check points in the top-right corner area
 266         assertTrue(region.contains(X + WIDTH, Y + 3));
 267         assertTrue(region.contains(X + WIDTH - 4, Y));
 268         assertTrue(region.contains(X + WIDTH - 4 + (4 * Math.cos(45)), Y + 3 - (3 * Math.sin(45))));
 269         assertTrue(region.contains(X + WIDTH - 4 + (3 * Math.cos(45)), Y + 3 - (2 * Math.sin(45))));
 270         assertFalse(region.contains(X + WIDTH - 4 + (5 * Math.cos(45)), Y + 3 - (4 * Math.sin(45))));
 271         // Check points in the bottom-right corner area
 272         assertTrue(region.contains(X + WIDTH, Y + HEIGHT - 6));
 273         assertTrue(region.contains(X + WIDTH - 5, Y + HEIGHT));
 274         assertTrue(region.contains(X + WIDTH - 5 + (5 * Math.cos(45)), Y + HEIGHT - 6 + (6 * Math.sin(45))));
 275         assertTrue(region.contains(X + WIDTH - 5 + (4 * Math.cos(45)), Y + HEIGHT - 6 + (5 * Math.sin(45))));
 276         assertFalse(region.contains(X + WIDTH - 5 + (6 * Math.cos(45)), Y + HEIGHT - 6 + (7 * Math.sin(45))));
 277         // Check points in the bottom-left corner area
 278         assertTrue(region.contains(X, Y + HEIGHT - 7));
 279         assertTrue(region.contains(X + 8, Y + HEIGHT));
 280         assertTrue(region.contains(X + 8 - (8 * Math.cos(45)), Y + HEIGHT - 7 + (7 * Math.sin(45))));
 281         assertTrue(region.contains(X + 8 - (7 * Math.cos(45)), Y + HEIGHT - 7 + (6 * Math.sin(45))));
 282         assertFalse(region.contains(X + 8 - (9 * Math.cos(45)), Y + HEIGHT - 7 + (8 * Math.sin(45))));
 283         // Check the center
 284         assertTrue(region.contains(CENTER_X, CENTER_Y));
 285     }
 286 
 287     @Test public void pickingRectangularFillWithIndependentRadiusWithInsetsWorks() {
 288         region.setBackground(new Background(new BackgroundFill(Color.RED,
 289             new CornerRadii(1, 2, 3, 4, 5, 6, 7, 8, false, false, false, false, false, false, false, false),
 290             new Insets(4, 3, 2, 1))));
 291         // Check points in the top-left corner area
 292         assertTrue(region.contains(X + 1, Y + 2 + 4));
 293         assertTrue(region.contains(X + 1 + 1, Y + 4));
 294         assertTrue(region.contains(X + 1 + 1 - (1 * Math.cos(45)), Y + 2 + 4 - (2 * Math.sin(45))));
 295         assertTrue(region.contains(X + 1 + 1 - (.5 * Math.cos(45)), Y + 2 + 4 - (1 * Math.sin(45))));
 296         assertFalse(region.contains(X + 1 + 1 - (2 * Math.cos(45)), Y + 2 + 4 - (3 * Math.sin(45))));
 297         // Check points in the top-right corner area
 298         assertTrue(region.contains(X + WIDTH - 3, Y + 3 + 4));
 299         assertTrue(region.contains(X + WIDTH - 4 - 3, Y + 4));
 300         assertTrue(region.contains(X + WIDTH - 4 - 3 + (4 * Math.cos(45)), Y + 4 + 3 - (3 * Math.sin(45))));
 301         assertTrue(region.contains(X + WIDTH - 4 - 3 + (3 * Math.cos(45)), Y + 4 + 3 - (2 * Math.sin(45))));
 302         assertFalse(region.contains(X + WIDTH - 4 - 3 + (5 * Math.cos(45)), Y + 4 + 3 - (4 * Math.sin(45))));
 303         // Check points in the bottom-right corner area
 304         assertTrue(region.contains(X + WIDTH - 3, Y + HEIGHT - 2 - 6));
 305         assertTrue(region.contains(X + WIDTH - 3 - 5, Y + HEIGHT - 2));
 306         assertTrue(region.contains(X + WIDTH - 3 - 5 + (5 * Math.cos(45)), Y + HEIGHT - 2 - 6 + (6 * Math.sin(45))));
 307         assertTrue(region.contains(X + WIDTH - 3 - 5 + (4 * Math.cos(45)), Y + HEIGHT - 2 - 6 + (5 * Math.sin(45))));
 308         assertFalse(region.contains(X + WIDTH - 3 - 5 + (6 * Math.cos(45)), Y + HEIGHT - 2 - 6 + (7 * Math.sin(45))));
 309         // Check points in the bottom-left corner area
 310         assertTrue(region.contains(X + 1, Y + HEIGHT - 2 - 7));
 311         assertTrue(region.contains(X + 1 + 8, Y + HEIGHT - 2));
 312         assertTrue(region.contains(X + 1 + 8 - (8 * Math.cos(45)), Y + HEIGHT - 2 - 7 + (7 * Math.sin(45))));
 313         assertTrue(region.contains(X + 1 + 8 - (7 * Math.cos(45)), Y + HEIGHT - 2 - 7 + (6 * Math.sin(45))));
 314         assertFalse(region.contains(X + 1 + 8 - (9 * Math.cos(45)), Y + HEIGHT - 2 - 7 + (8 * Math.sin(45))));
 315         // Check the center
 316         assertTrue(region.contains(CENTER_X, CENTER_Y));
 317     }
 318 
 319     // TODO test with really really large corner radius
 320 
 321     /**************************************************************************
 322      *                                                                        *
 323      * Test behavior when picking a region with borders, but no shape or      *
 324      * or images.                                                             *
 325      *                                                                        *
 326      *************************************************************************/
 327 
 328     @Test public void pickingRectangularBorderWorks() {
 329         region.setBorder(new Border(new BorderStroke(Color.GREEN, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
 330                                                      new BorderWidths(1))));
 331         assertFalse(region.contains(LEFT_OF, CENTER_Y));
 332         assertFalse(region.contains(CENTER_X, ABOVE));
 333         assertFalse(region.contains(RIGHT_OF, CENTER_Y));
 334         assertFalse(region.contains(CENTER_X, BELOW));
 335         // Note that the center is empty and should not be picked
 336         assertFalse(region.contains(CENTER_X, CENTER_Y));
 337     }
 338 
 339     @Test public void pickingRectangularBorderWithThickBorder() {
 340         region.setBorder(new Border(new BorderStroke(Color.GREEN, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
 341                                                      new BorderWidths(10))));
 342         assertFalse(region.contains(LEFT_OF, CENTER_Y));
 343         assertFalse(region.contains(CENTER_X, ABOVE));
 344         assertFalse(region.contains(RIGHT_OF, CENTER_Y));
 345         assertFalse(region.contains(CENTER_X, BELOW));
 346         assertFalse(region.contains(CENTER_X, CENTER_Y));
 347 
 348         assertTrue(region.contains(X, Y));
 349         assertTrue(region.contains(X+5, Y+5));
 350         assertFalse(region.contains(X+10, Y+10));
 351     }
 352 
 353     @Test public void pickingRectangularBorderWithIndependentBorderWidths() {
 354         region.setBorder(new Border(new BorderStroke(Color.GREEN, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
 355                                                      new BorderWidths(5, 10, 15, 20))));
 356         assertFalse(region.contains(LEFT_OF, CENTER_Y));
 357         assertFalse(region.contains(CENTER_X, ABOVE));
 358         assertFalse(region.contains(RIGHT_OF, CENTER_Y));
 359         assertFalse(region.contains(CENTER_X, BELOW));
 360         assertFalse(region.contains(CENTER_X, CENTER_Y));
 361 
 362         // Top. Test first and last pixels, and one-past
 363         assertTrue(region.contains(CENTER_X, Y));
 364         assertTrue(region.contains(CENTER_X, Y + 4));
 365         assertFalse(region.contains(CENTER_X, Y + 5));
 366 
 367         // Right. Test first and last pixels, and one-past
 368         assertTrue(region.contains(WIDTH, CENTER_Y));
 369         assertTrue(region.contains(WIDTH - 9, CENTER_Y));
 370         assertFalse(region.contains(WIDTH - 10, CENTER_Y));
 371 
 372         // Bottom. Test first and last pixels, and one-past
 373         assertTrue(region.contains(CENTER_X, HEIGHT));
 374         assertTrue(region.contains(CENTER_X, HEIGHT - 14));
 375         assertFalse(region.contains(CENTER_X, HEIGHT - 15));
 376 
 377         // Left. Test first and last pixels, and one-past
 378         assertTrue(region.contains(X, CENTER_Y));
 379         assertTrue(region.contains(X + 19, CENTER_Y));
 380         assertFalse(region.contains(X + 20, CENTER_Y));
 381     }
 382 
 383     @Test public void pickingRectangularBorderWithIndependentPercentageBorderWidths() {
 384         region.setBorder(new Border(new BorderStroke(Color.GREEN, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
 385                                                      new BorderWidths(.05, .10, .15, .20, true, true, true, true))));
 386         assertFalse(region.contains(LEFT_OF, CENTER_Y));
 387         assertFalse(region.contains(CENTER_X, ABOVE));
 388         assertFalse(region.contains(RIGHT_OF, CENTER_Y));
 389         assertFalse(region.contains(CENTER_X, BELOW));
 390         assertFalse(region.contains(CENTER_X, CENTER_Y));
 391 
 392         // Top. Test first and last pixels, and one-past
 393         assertTrue(region.contains(CENTER_X, Y));
 394         assertTrue(region.contains(CENTER_X, Y + 4));
 395         assertFalse(region.contains(CENTER_X, Y + 5));
 396 
 397         // Right. Test first and last pixels, and one-past
 398         assertTrue(region.contains(WIDTH, CENTER_Y));
 399         assertTrue(region.contains(WIDTH - 9, CENTER_Y));
 400         assertFalse(region.contains(WIDTH - 10, CENTER_Y));
 401 
 402         // Bottom. Test first and last pixels, and one-past
 403         assertTrue(region.contains(CENTER_X, HEIGHT));
 404         assertTrue(region.contains(CENTER_X, HEIGHT - 14));
 405         assertFalse(region.contains(CENTER_X, HEIGHT - 15));
 406 
 407         // Left. Test first and last pixels, and one-past
 408         assertTrue(region.contains(X, CENTER_Y));
 409         assertTrue(region.contains(X + 19, CENTER_Y));
 410         assertFalse(region.contains(X + 20, CENTER_Y));
 411     }
 412 
 413     @Test public void pickingRectangularBorderWithIndependentBorderWidthsAndInsets() {
 414         region.setBorder(new Border(new BorderStroke(Color.GREEN, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
 415                                                      new BorderWidths(5, 10, 15, 20), new Insets(1, 2, 3, 4))));
 416         // Top. Test first and last pixels, and one-past
 417         assertFalse(region.contains(CENTER_X, Y));
 418         assertTrue(region.contains(CENTER_X, Y+1));
 419         assertTrue(region.contains(CENTER_X, Y+1 + 4));
 420         assertFalse(region.contains(CENTER_X, Y+1 + 5));
 421 
 422         // Right. Test first and last pixels, and one-past
 423         assertFalse(region.contains(WIDTH-1, CENTER_Y));
 424         assertTrue(region.contains(WIDTH-2, CENTER_Y));
 425         assertTrue(region.contains(WIDTH-2 - 9, CENTER_Y));
 426         assertFalse(region.contains(WIDTH-2 - 10, CENTER_Y));
 427 
 428         // Bottom. Test first and last pixels, and one-past
 429         assertFalse(region.contains(CENTER_X, HEIGHT-2));
 430         assertTrue(region.contains(CENTER_X, HEIGHT-3));
 431         assertTrue(region.contains(CENTER_X, HEIGHT-3 - 14));
 432         assertFalse(region.contains(CENTER_X, HEIGHT-3 - 15));
 433 
 434         // Left. Test first and last pixels, and one-past
 435         assertFalse(region.contains(X+3, CENTER_Y));
 436         assertTrue(region.contains(X+4, CENTER_Y));
 437         assertTrue(region.contains(X+4 + 19, CENTER_Y));
 438         assertFalse(region.contains(X+4 + 20, CENTER_Y));
 439     }
 440 
 441     @Test public void pickingRectangularBorderWithIndependentRadiusWithInsetsWorks() {
 442         region.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID,
 443             new CornerRadii(1, 2, 3, 4, 5, 6, 7, 8, false, false, false, false, false, false, false, false),
 444             new BorderWidths(5, 10, 15, 20), new Insets(4, 3, 2, 1))));
 445         // Check points in the top-left corner area
 446         assertTrue(region.contains(X + 1, Y + 2 + 4));
 447         assertTrue(region.contains(X + 1 + 1, Y + 4));
 448         assertTrue(region.contains(X + 1 + 1 - (1 * Math.cos(45)), Y + 2 + 4 - (2 * Math.sin(45))));
 449         assertTrue(region.contains(X + 1 + 1 - (.5 * Math.cos(45)), Y + 2 + 4 - (1 * Math.sin(45))));
 450         assertFalse(region.contains(X + 1 + 1 - (2 * Math.cos(45)), Y + 2 + 4 - (3 * Math.sin(45))));
 451         // Check points in the top-right corner area
 452         assertTrue(region.contains(X + WIDTH - 3, Y + 3 + 4));
 453         assertTrue(region.contains(X + WIDTH - 4 - 3, Y + 4));
 454         assertTrue(region.contains(X + WIDTH - 4 - 3 + (4 * Math.cos(45)), Y + 4 + 3 - (3 * Math.sin(45))));
 455         assertTrue(region.contains(X + WIDTH - 4 - 3 + (3 * Math.cos(45)), Y + 4 + 3 - (2 * Math.sin(45))));
 456         assertFalse(region.contains(X + WIDTH - 4 - 3 + (5 * Math.cos(45)), Y + 4 + 3 - (4 * Math.sin(45))));
 457         // Check points in the bottom-right corner area
 458         assertTrue(region.contains(X + WIDTH - 3, Y + HEIGHT - 2 - 6));
 459         assertTrue(region.contains(X + WIDTH - 3 - 5, Y + HEIGHT - 2));
 460         assertTrue(region.contains(X + WIDTH - 3 - 5 + (5 * Math.cos(45)), Y + HEIGHT - 2 - 6 + (6 * Math.sin(45))));
 461         assertTrue(region.contains(X + WIDTH - 3 - 5 + (4 * Math.cos(45)), Y + HEIGHT - 2 - 6 + (5 * Math.sin(45))));
 462         assertFalse(region.contains(X + WIDTH - 3 - 5 + (6 * Math.cos(45)), Y + HEIGHT - 2 - 6 + (7 * Math.sin(45))));
 463         // Check points in the bottom-left corner area
 464         assertTrue(region.contains(X + 1, Y + HEIGHT - 2 - 7));
 465         assertTrue(region.contains(X + 1 + 8, Y + HEIGHT - 2));
 466         assertTrue(region.contains(X + 1 + 8 - (8 * Math.cos(45)), Y + HEIGHT - 2 - 7 + (7 * Math.sin(45))));
 467         assertTrue(region.contains(X + 1 + 8 - (7 * Math.cos(45)), Y + HEIGHT - 2 - 7 + (6 * Math.sin(45))));
 468         assertFalse(region.contains(X + 1 + 8 - (9 * Math.cos(45)), Y + HEIGHT - 2 - 7 + (8 * Math.sin(45))));
 469         // Check the center
 470         assertFalse(region.contains(CENTER_X, CENTER_Y));
 471         // TODO Could stand to have more tests testing the inside hit edge
 472     }
 473 
 474     @Test public void pickingRectangularBorderWithIndependentPercentageRadiusWithInsetsWorks() {
 475         region.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID,
 476             new CornerRadii(.01, .02, .03, .04, .05, .06, .07, .08, true, true, true, true, true, true, true, true),
 477             new BorderWidths(5, 10, 15, 20), new Insets(4, 3, 2, 1))));
 478         // Check points in the top-left corner area
 479         assertTrue(region.contains(X + 1, Y + 2 + 4));
 480         assertTrue(region.contains(X + 1 + 1, Y + 4));
 481         assertTrue(region.contains(X + 1 + 1 - (1 * Math.cos(45)), Y + 2 + 4 - (2 * Math.sin(45))));
 482         assertTrue(region.contains(X + 1 + 1 - (.5 * Math.cos(45)), Y + 2 + 4 - (1 * Math.sin(45))));
 483         assertFalse(region.contains(X + 1 + 1 - (2 * Math.cos(45)), Y + 2 + 4 - (3 * Math.sin(45))));
 484         // Check points in the top-right corner area
 485         assertTrue(region.contains(X + WIDTH - 3, Y + 3 + 4));
 486         assertTrue(region.contains(X + WIDTH - 4 - 3, Y + 4));
 487         assertTrue(region.contains(X + WIDTH - 4 - 3 + (4 * Math.cos(45)), Y + 4 + 3 - (3 * Math.sin(45))));
 488         assertTrue(region.contains(X + WIDTH - 4 - 3 + (3 * Math.cos(45)), Y + 4 + 3 - (2 * Math.sin(45))));
 489         assertFalse(region.contains(X + WIDTH - 4 - 3 + (5 * Math.cos(45)), Y + 4 + 3 - (4 * Math.sin(45))));
 490         // Check points in the bottom-right corner area
 491         assertTrue(region.contains(X + WIDTH - 3, Y + HEIGHT - 2 - 6));
 492         assertTrue(region.contains(X + WIDTH - 3 - 5, Y + HEIGHT - 2));
 493         assertTrue(region.contains(X + WIDTH - 3 - 5 + (5 * Math.cos(45)), Y + HEIGHT - 2 - 6 + (6 * Math.sin(45))));
 494         assertTrue(region.contains(X + WIDTH - 3 - 5 + (4 * Math.cos(45)), Y + HEIGHT - 2 - 6 + (5 * Math.sin(45))));
 495         assertFalse(region.contains(X + WIDTH - 3 - 5 + (6 * Math.cos(45)), Y + HEIGHT - 2 - 6 + (7 * Math.sin(45))));
 496         // Check points in the bottom-left corner area
 497         assertTrue(region.contains(X + 1, Y + HEIGHT - 2 - 7));
 498         assertTrue(region.contains(X + 1 + 8, Y + HEIGHT - 2));
 499         assertTrue(region.contains(X + 1 + 8 - (8 * Math.cos(45)), Y + HEIGHT - 2 - 7 + (7 * Math.sin(45))));
 500         assertTrue(region.contains(X + 1 + 8 - (7 * Math.cos(45)), Y + HEIGHT - 2 - 7 + (6 * Math.sin(45))));
 501         assertFalse(region.contains(X + 1 + 8 - (9 * Math.cos(45)), Y + HEIGHT - 2 - 7 + (8 * Math.sin(45))));
 502         // Check the center
 503         assertFalse(region.contains(CENTER_X, CENTER_Y));
 504         // TODO Could stand to have more tests testing the inside hit edge
 505     }
 506 
 507     /**************************************************************************
 508      *                                                                        *
 509      * Test behavior when picking a shaped region. We have to test all the    *
 510      * positionShape / scaleShape variants to make sure we are always picking *
 511      * based on the perceived (rendered) shape                                *
 512      *                                                                        *
 513      *************************************************************************/
 514 
 515     // TODO implement along with fix for RT-27775
 516 }