1 /*
   2  * Copyright (c) 2012, 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 test.javafx.scene.layout;
  27 
  28 import javafx.geometry.Insets;
  29 import javafx.geometry.Side;
  30 import javafx.scene.image.Image;
  31 import javafx.scene.layout.Background;
  32 import javafx.scene.layout.BackgroundFill;
  33 import javafx.scene.layout.BackgroundImage;
  34 import javafx.scene.layout.BackgroundPosition;
  35 import javafx.scene.layout.BackgroundShim;
  36 import javafx.scene.layout.CornerRadii;
  37 import javafx.scene.paint.Color;
  38 import org.junit.Test;
  39 
  40 import static javafx.scene.layout.BackgroundRepeat.*;
  41 import static org.junit.Assert.*;
  42 
  43 /**
  44  */
  45 public class BackgroundTest {
  46     private static final BackgroundFill[] FILLS_1 = new BackgroundFill[] {
  47             new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY),
  48     };
  49     private static final BackgroundFill[] FILLS_2 = new BackgroundFill[] {
  50             new BackgroundFill(Color.GREEN, new CornerRadii(3), new Insets(4)),
  51             new BackgroundFill(Color.BLUE, new CornerRadii(6), new Insets(8)),
  52     };
  53 
  54     private static final Image IMAGE_1 = new Image("test/javafx/scene/layout/red.png");
  55     private static final Image IMAGE_2 = new Image("test/javafx/scene/layout/blue.png");
  56     private static final Image IMAGE_3 = new Image("test/javafx/scene/layout/green.png");
  57     private static final Image IMAGE_4 = new Image("test/javafx/scene/layout/yellow.png");
  58 
  59     private static final BackgroundImage[] IMAGES_1 = new BackgroundImage[] {
  60             new BackgroundImage(IMAGE_1, null, null, null, null)
  61     };
  62 
  63     private static final BackgroundImage[] IMAGES_2 = new BackgroundImage[] {
  64             new BackgroundImage(IMAGE_2, SPACE, SPACE, null, null),
  65             new BackgroundImage(IMAGE_3, ROUND, ROUND, null, null),
  66             new BackgroundImage(IMAGE_4, NO_REPEAT, NO_REPEAT, null, null)
  67     };
  68 
  69     @Test public void instanceCreation() {
  70         Background b = new Background(FILLS_1, IMAGES_1);
  71         assertEquals(FILLS_1.length, b.getFills().size(), 0);
  72         assertEquals(FILLS_1[0], b.getFills().get(0));
  73         assertEquals(IMAGES_1.length, b.getImages().size(), 0);
  74         assertEquals(IMAGES_1[0], b.getImages().get(0));
  75     }
  76 
  77     @Test public void instanceCreation2() {
  78         Background b = new Background(FILLS_2, IMAGES_2);
  79         assertEquals(FILLS_2.length, b.getFills().size(), 0);
  80         assertEquals(FILLS_2[0], b.getFills().get(0));
  81         assertEquals(FILLS_2[1], b.getFills().get(1));
  82         assertEquals(IMAGES_2.length, b.getImages().size(), 0);
  83         assertEquals(IMAGES_2[0], b.getImages().get(0));
  84         assertEquals(IMAGES_2[1], b.getImages().get(1));
  85         assertEquals(IMAGES_2[2], b.getImages().get(2));
  86     }
  87 
  88     @Test public void instanceCreationNullFills() {
  89         Background b = new Background(null, IMAGES_1);
  90         assertEquals(0, b.getFills().size(), 0);
  91         assertEquals(IMAGES_1.length, b.getImages().size(), 0);
  92         assertEquals(IMAGES_1[0], b.getImages().get(0));
  93     }
  94 
  95     @Test public void instanceCreationEmptyFills() {
  96         Background b = new Background(new BackgroundFill[0], IMAGES_1);
  97         assertEquals(0, b.getFills().size(), 0);
  98         assertEquals(IMAGES_1.length, b.getImages().size(), 0);
  99         assertEquals(IMAGES_1[0], b.getImages().get(0));
 100     }
 101 
 102     @Test public void instanceCreationNullImages() {
 103         Background b = new Background(FILLS_1, null);
 104         assertEquals(FILLS_1.length, b.getFills().size(), 0);
 105         assertEquals(FILLS_1[0], b.getFills().get(0));
 106         assertEquals(0, b.getImages().size(), 0);
 107     }
 108 
 109     @Test public void instanceCreationEmptyImages() {
 110         Background b = new Background(FILLS_1, new BackgroundImage[0]);
 111         assertEquals(FILLS_1.length, b.getFills().size(), 0);
 112         assertEquals(FILLS_1[0], b.getFills().get(0));
 113         assertEquals(0, b.getImages().size(), 0);
 114     }
 115 
 116     @Test public void instanceCreationWithNullsInTheFillArray() {
 117         final BackgroundFill[] fills = new BackgroundFill[] {
 118                 null,
 119                 new BackgroundFill(Color.GREEN, new CornerRadii(3), new Insets(4)),
 120                 new BackgroundFill(Color.BLUE, new CornerRadii(6), new Insets(8)),
 121         };
 122         Background b = new Background(fills, null);
 123         assertEquals(FILLS_2.length, b.getFills().size(), 0);
 124         assertEquals(FILLS_2[0], b.getFills().get(0));
 125         assertEquals(FILLS_2[1], b.getFills().get(1));
 126     }
 127 
 128     @Test public void instanceCreationWithNullsInTheFillArray2() {
 129         final BackgroundFill[] fills = new BackgroundFill[] {
 130                 new BackgroundFill(Color.GREEN, new CornerRadii(3), new Insets(4)),
 131                 null,
 132                 new BackgroundFill(Color.BLUE, new CornerRadii(6), new Insets(8)),
 133         };
 134         Background b = new Background(fills, null);
 135         assertEquals(FILLS_2.length, b.getFills().size(), 0);
 136         assertEquals(FILLS_2[0], b.getFills().get(0));
 137         assertEquals(FILLS_2[1], b.getFills().get(1));
 138     }
 139 
 140     @Test public void instanceCreationWithNullsInTheFillArray3() {
 141         final BackgroundFill[] fills = new BackgroundFill[] {
 142                 new BackgroundFill(Color.GREEN, new CornerRadii(3), new Insets(4)),
 143                 new BackgroundFill(Color.BLUE, new CornerRadii(6), new Insets(8)),
 144                 null
 145         };
 146         Background b = new Background(fills, null);
 147         assertEquals(FILLS_2.length, b.getFills().size(), 0);
 148         assertEquals(FILLS_2[0], b.getFills().get(0));
 149         assertEquals(FILLS_2[1], b.getFills().get(1));
 150     }
 151 
 152     @Test public void instanceCreationWithNullsInTheFillArray4() {
 153         final BackgroundFill[] fills = new BackgroundFill[] {
 154                 null
 155         };
 156         Background b = new Background(fills, null);
 157         assertEquals(0, b.getFills().size(), 0);
 158     }
 159 
 160     @Test public void instanceCreationWithNullsInTheImageArray() {
 161         final BackgroundImage[] images = new BackgroundImage[] {
 162                 null,
 163                 new BackgroundImage(IMAGE_2, SPACE, SPACE, null, null),
 164                 new BackgroundImage(IMAGE_3, ROUND, ROUND, null, null),
 165                 new BackgroundImage(IMAGE_4, NO_REPEAT, NO_REPEAT, null, null)
 166         };
 167         Background b = new Background(null, images);
 168         assertEquals(IMAGES_2.length, b.getImages().size(), 0);
 169         assertEquals(IMAGES_2[0], b.getImages().get(0));
 170         assertEquals(IMAGES_2[1], b.getImages().get(1));
 171         assertEquals(IMAGES_2[2], b.getImages().get(2));
 172     }
 173 
 174     @Test public void instanceCreationWithNullsInTheImageArray2() {
 175         final BackgroundImage[] images = new BackgroundImage[] {
 176                 new BackgroundImage(IMAGE_2, SPACE, SPACE, null, null),
 177                 null,
 178                 new BackgroundImage(IMAGE_3, ROUND, ROUND, null, null),
 179                 new BackgroundImage(IMAGE_4, NO_REPEAT, NO_REPEAT, null, null)
 180         };
 181         Background b = new Background(null, images);
 182         assertEquals(IMAGES_2.length, b.getImages().size(), 0);
 183         assertEquals(IMAGES_2[0], b.getImages().get(0));
 184         assertEquals(IMAGES_2[1], b.getImages().get(1));
 185         assertEquals(IMAGES_2[2], b.getImages().get(2));
 186     }
 187 
 188     @Test public void instanceCreationWithNullsInTheImageArray3() {
 189         final BackgroundImage[] images = new BackgroundImage[] {
 190                 new BackgroundImage(IMAGE_2, SPACE, SPACE, null, null),
 191                 new BackgroundImage(IMAGE_3, ROUND, ROUND, null, null),
 192                 new BackgroundImage(IMAGE_4, NO_REPEAT, NO_REPEAT, null, null),
 193                 null
 194         };
 195         Background b = new Background(null, images);
 196         assertEquals(IMAGES_2.length, b.getImages().size(), 0);
 197         assertEquals(IMAGES_2[0], b.getImages().get(0));
 198         assertEquals(IMAGES_2[1], b.getImages().get(1));
 199         assertEquals(IMAGES_2[2], b.getImages().get(2));
 200     }
 201 
 202     @Test public void instanceCreationWithNullsInTheImageArray4() {
 203         final BackgroundImage[] images = new BackgroundImage[] {
 204                 null
 205         };
 206         Background b = new Background(null, images);
 207         assertEquals(0, b.getImages().size(), 0);
 208     }
 209 
 210     @Test public void suppliedBackgroundFillsMutatedLaterDoNotChangeFills() {
 211         final BackgroundFill fill = new BackgroundFill(Color.GREEN, new CornerRadii(3), new Insets(4));
 212         final BackgroundFill[] fills = new BackgroundFill[] { fill };
 213         Background b = new Background(fills, null);
 214         Background b2 = new Background(fills);
 215         fills[0] = null;
 216         assertEquals(1, b.getFills().size());
 217         assertEquals(1, b2.getFills().size());
 218         assertSame(fill, b.getFills().get(0));
 219         assertSame(fill, b2.getFills().get(0));
 220     }
 221 
 222     @Test public void suppliedBackgroundImagesMutatedLaterDoNotChangeImages() {
 223         final BackgroundImage image = new BackgroundImage(IMAGE_2, SPACE, SPACE, null, null);
 224         final BackgroundImage[] images = new BackgroundImage[] { image };
 225         Background b = new Background(null, images);
 226         Background b2 = new Background(images);
 227         images[0] = null;
 228         assertEquals(1, b.getImages().size());
 229         assertEquals(1, b2.getImages().size());
 230         assertSame(image, b.getImages().get(0));
 231         assertSame(image, b2.getImages().get(0));
 232     }
 233 
 234     @Test(expected = UnsupportedOperationException.class)
 235     public void fillsIsUnmodifiable() {
 236         final BackgroundFill fill = new BackgroundFill(Color.GREEN, new CornerRadii(3), new Insets(4));
 237         final BackgroundFill[] fills = new BackgroundFill[] { fill };
 238         Background b = new Background(fills);
 239         b.getFills().add(new BackgroundFill(Color.BLUE, new CornerRadii(6), new Insets(8)));
 240     }
 241 
 242     @Test(expected = UnsupportedOperationException.class)
 243     public void imagesIsUnmodifiable() {
 244         final BackgroundImage image = new BackgroundImage(IMAGE_2, SPACE, SPACE, null, null);
 245         final BackgroundImage[] images = new BackgroundImage[] { image };
 246         Background b = new Background(images);
 247         b.getImages().add(new BackgroundImage(IMAGE_3, ROUND, ROUND, null, null));
 248     }
 249 
 250     @Test public void backgroundOutsetsAreDefinedByFills() {
 251         final BackgroundFill[] fills = new BackgroundFill[] {
 252                 new BackgroundFill(Color.RED, new CornerRadii(3), new Insets(-1, 5, 5, 5)),
 253                 new BackgroundFill(Color.GREEN, new CornerRadii(6), new Insets(8)),
 254                 new BackgroundFill(Color.BLUE, new CornerRadii(6), new Insets(2, -1, 3, 5)),
 255                 new BackgroundFill(Color.MAGENTA, new CornerRadii(6), new Insets(-7, -2, 4, 4)),
 256                 new BackgroundFill(Color.CYAN, new CornerRadii(6), new Insets(0, 0, -8, 0)),
 257                 new BackgroundFill(Color.YELLOW, new CornerRadii(6), new Insets(4, -1, 3, 5)),
 258                 new BackgroundFill(Color.BLACK, new CornerRadii(6), new Insets(0, 0, 0, -8))
 259         };
 260 
 261         Background b = new Background(fills, null);
 262         assertEquals(new Insets(7, 2, 8, 8), b.getOutsets());
 263     }
 264 
 265     @Test public void backgroundImagesDoNotContributeToOutsets() {
 266         final BackgroundImage[] images = new BackgroundImage[] {
 267                 new BackgroundImage(IMAGE_1, null, null,
 268                         new BackgroundPosition(Side.LEFT, -10, false, Side.TOP, -10, false),
 269                         null)
 270         };
 271 
 272         Background b = new Background(null, images);
 273         assertEquals(Insets.EMPTY, b.getOutsets());
 274     }
 275 
 276     @Test public void equivalent() {
 277         Background a = new Background((BackgroundFill[])null, null);
 278         Background b = new Background((BackgroundFill[])null, null);
 279         assertEquals(a, b);
 280     }
 281 
 282     @Test public void equivalent2() {
 283         Background a = new Background(FILLS_2, null);
 284         Background b = new Background(FILLS_2, null);
 285         assertEquals(a, b);
 286     }
 287 
 288     @Test public void equivalent3() {
 289         Background a = new Background(null, IMAGES_2);
 290         Background b = new Background(null, IMAGES_2);
 291         assertEquals(a, b);
 292     }
 293 
 294     @Test public void equivalentHasSameHashCode() {
 295         Background a = new Background((BackgroundFill[])null, null);
 296         Background b = new Background((BackgroundFill[])null, null);
 297         assertEquals(a.hashCode(), b.hashCode());
 298     }
 299 
 300     @Test public void equivalentHasSameHashCode2() {
 301         Background a = new Background(FILLS_2, null);
 302         Background b = new Background(FILLS_2, null);
 303         assertEquals(a.hashCode(), b.hashCode());
 304     }
 305 
 306     @Test public void equivalentHasSameHashCode3() {
 307         Background a = new Background(null, IMAGES_2);
 308         Background b = new Background(null, IMAGES_2);
 309         assertEquals(a.hashCode(), b.hashCode());
 310     }
 311 
 312     @Test public void notEqual() {
 313         Background a = new Background(FILLS_1, null);
 314         Background b = new Background((BackgroundFill[])null, null);
 315         assertFalse(a.equals(b));
 316     }
 317 
 318     @Test public void notEqual2() {
 319         Background a = new Background((BackgroundFill[])null, null);
 320         Background b = new Background(FILLS_2, null);
 321         assertFalse(a.equals(b));
 322     }
 323 
 324     @Test public void notEqual3() {
 325         Background a = new Background(null, IMAGES_1);
 326         Background b = new Background((BackgroundFill[])null, null);
 327         assertFalse(a.equals(b));
 328     }
 329 
 330     @Test public void notEqual4() {
 331         Background a = new Background((BackgroundFill[])null, null);
 332         Background b = new Background(null, IMAGES_2);
 333         assertFalse(a.equals(b));
 334     }
 335 
 336     @Test public void notEqualWithNull() {
 337         Background a = new Background((BackgroundFill[])null, null);
 338         assertFalse(a.equals(null));
 339     }
 340 
 341     @Test public void notEqualWithRandom() {
 342         Background a = new Background((BackgroundFill[])null, null);
 343         assertFalse(a.equals("Some random String"));
 344     }
 345 
 346     /**************************************************************************
 347      *                                                                        *
 348      * Tests for getting the computed opaque insets. Like normal insets,      *
 349      * these are positive going inwards.                                      *
 350      *                                                                        *
 351      *************************************************************************/
 352 
 353     @Test public void opaqueInsets_nullFillsResultsInNaN() {
 354         Background b = new Background((BackgroundFill[])null, null);
 355         final double[] trbl = new double[4];
 356         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 357         assertTrue(Double.isNaN(trbl[0]));
 358         assertTrue(Double.isNaN(trbl[1]));
 359         assertTrue(Double.isNaN(trbl[2]));
 360         assertTrue(Double.isNaN(trbl[3]));
 361     }
 362 
 363     @Test public void opaqueInsets_transparentFillsResultsInNaN() {
 364         BackgroundFill f = new BackgroundFill(Color.TRANSPARENT, null, null);
 365         Background b = new Background(new BackgroundFill[] { f }, null);
 366         final double[] trbl = new double[4];
 367         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 368         assertTrue(Double.isNaN(trbl[0]));
 369         assertTrue(Double.isNaN(trbl[1]));
 370         assertTrue(Double.isNaN(trbl[2]));
 371         assertTrue(Double.isNaN(trbl[3]));
 372     }
 373 
 374     @Test public void opaqueInsets_transparentFillsResultsInNaN2() {
 375         BackgroundFill f = new BackgroundFill(Color.rgb(255, 0, 0, 0), null, null);
 376         Background b = new Background(new BackgroundFill[] { f }, null);
 377         final double[] trbl = new double[4];
 378         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 379         assertTrue(Double.isNaN(trbl[0]));
 380         assertTrue(Double.isNaN(trbl[1]));
 381         assertTrue(Double.isNaN(trbl[2]));
 382         assertTrue(Double.isNaN(trbl[3]));
 383     }
 384 
 385     @Test public void opaqueInsets_transparentFillsResultsInNaN3() {
 386         BackgroundFill f = new BackgroundFill(Color.TRANSPARENT, null, null);
 387         BackgroundFill f2 = new BackgroundFill(Color.rgb(255, 0, 0, 0), null, null);
 388         Background b = new Background(new BackgroundFill[] { f, f2 }, null);
 389         final double[] trbl = new double[4];
 390         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 391         assertTrue(Double.isNaN(trbl[0]));
 392         assertTrue(Double.isNaN(trbl[1]));
 393         assertTrue(Double.isNaN(trbl[2]));
 394         assertTrue(Double.isNaN(trbl[3]));
 395     }
 396 
 397     @Test public void opaqueInsets_transparentFillsMixedWithNonTransparentFills() {
 398         BackgroundFill f = new BackgroundFill(Color.TRANSPARENT, null, null);
 399         BackgroundFill f2 = new BackgroundFill(Color.RED, null, new Insets(1));
 400         Background b = new Background(new BackgroundFill[] { f, f2 }, null);
 401         final double[] trbl = new double[4];
 402         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 403         assertEquals(1, trbl[0], 0);
 404         assertEquals(1, trbl[1], 0);
 405         assertEquals(1, trbl[2], 0);
 406         assertEquals(1, trbl[3], 0);
 407     }
 408 
 409     @Test public void opaqueInsets_transparentFillsMixedWithNonTransparentFills2() {
 410         BackgroundFill f = new BackgroundFill(Color.TRANSPARENT, null, null);
 411         BackgroundFill f2 = new BackgroundFill(Color.RED, null, new Insets(-1));
 412         Background b = new Background(new BackgroundFill[] { f, f2 }, null);
 413         final double[] trbl = new double[4];
 414         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 415         assertEquals(-1, trbl[0], 0);
 416         assertEquals(-1, trbl[1], 0);
 417         assertEquals(-1, trbl[2], 0);
 418         assertEquals(-1, trbl[3], 0);
 419     }
 420 
 421     @Test public void opaqueInsets_nestedOpaqueRectangles_LargestRectangleUsed() {
 422         BackgroundFill f = new BackgroundFill(Color.RED, null, new Insets(0));
 423         BackgroundFill f2 = new BackgroundFill(Color.GREEN, null, new Insets(1));
 424         BackgroundFill f3 = new BackgroundFill(Color.BLUE, null, new Insets(2));
 425         Background b = new Background(new BackgroundFill[] { f, f2, f3 }, null);
 426         final double[] trbl = new double[4];
 427         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 428         assertEquals(0, trbl[0], 0);
 429         assertEquals(0, trbl[1], 0);
 430         assertEquals(0, trbl[2], 0);
 431         assertEquals(0, trbl[3], 0);
 432     }
 433 
 434     @Test public void opaqueInsets_nestedOpaqueRectangles_LargestRectangleUsed2() {
 435         BackgroundFill f = new BackgroundFill(Color.RED, null, new Insets(-1));
 436         BackgroundFill f2 = new BackgroundFill(Color.GREEN, null, new Insets(0));
 437         BackgroundFill f3 = new BackgroundFill(Color.BLUE, null, new Insets(1));
 438         Background b = new Background(new BackgroundFill[] { f, f2, f3 }, null);
 439         final double[] trbl = new double[4];
 440         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 441         assertEquals(-1, trbl[0], 0);
 442         assertEquals(-1, trbl[1], 0);
 443         assertEquals(-1, trbl[2], 0);
 444         assertEquals(-1, trbl[3], 0);
 445     }
 446 
 447     @Test public void opaqueInsets_nestedOpaqueRectangles_LargestRectangleUsed3() {
 448         BackgroundFill f = new BackgroundFill(Color.RED, null, new Insets(10));
 449         BackgroundFill f2 = new BackgroundFill(Color.GREEN, null, new Insets(1));
 450         BackgroundFill f3 = new BackgroundFill(Color.BLUE, null, new Insets(2));
 451         Background b = new Background(new BackgroundFill[] { f, f2, f3 }, null);
 452         final double[] trbl = new double[4];
 453         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 454         assertEquals(1, trbl[0], 0);
 455         assertEquals(1, trbl[1], 0);
 456         assertEquals(1, trbl[2], 0);
 457         assertEquals(1, trbl[3], 0);
 458     }
 459 
 460     @Test public void opaqueInsets_nestedOpaqueRectangles_LargestRectangleUsed4() {
 461         BackgroundFill f = new BackgroundFill(Color.RED, null, new Insets(0));
 462         BackgroundFill f2 = new BackgroundFill(Color.GREEN, null, new Insets(1));
 463         BackgroundFill f3 = new BackgroundFill(Color.BLUE, null, new Insets(-2));
 464         Background b = new Background(new BackgroundFill[] { f, f2, f3 }, null);
 465         final double[] trbl = new double[4];
 466         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 467         assertEquals(-2, trbl[0], 0);
 468         assertEquals(-2, trbl[1], 0);
 469         assertEquals(-2, trbl[2], 0);
 470         assertEquals(-2, trbl[3], 0);
 471     }
 472 
 473     @Test public void opaqueInsets_offsetOpaqueRectangles_completelyContained_LargestRectangleUsed() {
 474         BackgroundFill f = new BackgroundFill(Color.RED, null, new Insets(0));
 475         BackgroundFill f2 = new BackgroundFill(Color.GREEN, null, new Insets(1, 0, 0, 0));
 476         BackgroundFill f3 = new BackgroundFill(Color.BLUE, null, new Insets(0, 1, 0, 0));
 477         BackgroundFill f4 = new BackgroundFill(Color.YELLOW, null, new Insets(0, 0, 1, 0));
 478         BackgroundFill f5 = new BackgroundFill(Color.CYAN, null, new Insets(0, 0, 0, 1));
 479         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4, f5 }, null);
 480         final double[] trbl = new double[4];
 481         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 482         assertEquals(0, trbl[0], 0);
 483         assertEquals(0, trbl[1], 0);
 484         assertEquals(0, trbl[2], 0);
 485         assertEquals(0, trbl[3], 0);
 486     }
 487 
 488     // Even when the big rectangle is not the first, does it still work?
 489     @Test public void opaqueInsets_offsetOpaqueRectangles_completelyContained_LargestRectangleUsed2() {
 490         BackgroundFill f = new BackgroundFill(Color.YELLOW, null, new Insets(0, 0, 1, 0));
 491         BackgroundFill f2 = new BackgroundFill(Color.GREEN, null, new Insets(1, 0, 0, 0));
 492         BackgroundFill f3 = new BackgroundFill(Color.BLUE, null, new Insets(0, 1, 0, 0));
 493         BackgroundFill f4 = new BackgroundFill(Color.RED, null, new Insets(0));
 494         BackgroundFill f5 = new BackgroundFill(Color.CYAN, null, new Insets(0, 0, 0, 1));
 495         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4, f5 }, null);
 496         final double[] trbl = new double[4];
 497         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 498         assertEquals(0, trbl[0], 0);
 499         assertEquals(0, trbl[1], 0);
 500         assertEquals(0, trbl[2], 0);
 501         assertEquals(0, trbl[3], 0);
 502     }
 503 
 504     @Test public void opaqueInsets_offsetOpaqueRectangles_UnionUsed() {
 505         BackgroundFill f = new BackgroundFill(Color.RED, null, new Insets(10, 0, 0, 0));
 506         BackgroundFill f2 = new BackgroundFill(Color.GREEN, null, new Insets(0, 10, 0, 0));
 507         BackgroundFill f3 = new BackgroundFill(Color.BLUE, null, new Insets(0, 0, 10, 0));
 508         BackgroundFill f4 = new BackgroundFill(Color.YELLOW, null, new Insets(0, 0, 0, 10));
 509         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4 }, null);
 510         final double[] trbl = new double[4];
 511         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 512         assertEquals(0, trbl[0], 0);
 513         assertEquals(0, trbl[1], 0);
 514         assertEquals(0, trbl[2], 0);
 515         assertEquals(0, trbl[3], 0);
 516     }
 517 
 518     @Test public void opaqueInsets_offsetOpaqueRectangles_UnionUsed2() {
 519         BackgroundFill f = new BackgroundFill(Color.RED, null, new Insets(10, 0, 0, 0));
 520         BackgroundFill f2 = new BackgroundFill(Color.GREEN, null, new Insets(10, 10, 0, 0));
 521         BackgroundFill f3 = new BackgroundFill(Color.BLUE, null, new Insets(10, 10, 10, 0));
 522         BackgroundFill f4 = new BackgroundFill(Color.YELLOW, null, new Insets(10, 10, 10, 10));
 523         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4 }, null);
 524         final double[] trbl = new double[4];
 525         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 526         assertEquals(10, trbl[0], 0);
 527         assertEquals(0, trbl[1], 0);
 528         assertEquals(0, trbl[2], 0);
 529         assertEquals(0, trbl[3], 0);
 530     }
 531 
 532     // There are actually 3 possible outcomes from this test, and the one being tested is
 533     // the one currently being used. We could use the bounds of f, the bounds of f2, or the
 534     // intersection of the bounds of f and f2. It turns out in this case, the intersection
 535     // would be smaller, but the bounds of f and f2 are equal in size.
 536     @Test public void opaqueInsets_offsetOpaqueRectangles_LargestUsed() {
 537         BackgroundFill f = new BackgroundFill(Color.RED, null, new Insets(10));
 538         BackgroundFill f2 = new BackgroundFill(Color.GREEN, null, new Insets(20, 0, 0, 20));
 539         Background b = new Background(new BackgroundFill[] { f, f2 }, null);
 540         final double[] trbl = new double[4];
 541         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 542         assertEquals(10, trbl[0], 0);
 543         assertEquals(10, trbl[1], 0);
 544         assertEquals(10, trbl[2], 0);
 545         assertEquals(10, trbl[3], 0);
 546     }
 547 
 548     // NOTE: For these corner radii tests, I only need to know that the opaque region
 549     // of a single fill is correct for any given set of corner radii, because after
 550     // the opaque region for a single fill is computed, thereafter the rest of the
 551     // implementation is all the same
 552     @Test public void opaqueInsets_uniformCornerRadii() {
 553         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(3), null);
 554         Background b = new Background(new BackgroundFill[] { f }, null);
 555         final double[] trbl = new double[4];
 556         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 557         assertEquals(1.5, trbl[0], 0);
 558         assertEquals(1.5, trbl[1], 0);
 559         assertEquals(1.5, trbl[2], 0);
 560         assertEquals(1.5, trbl[3], 0);
 561     }
 562 
 563     @Test public void opaqueInsets_nonUniformCornerRadii() {
 564         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(1, 2, 3, 4, false), null);
 565         Background b = new Background(new BackgroundFill[] { f }, null);
 566         final double[] trbl = new double[4];
 567         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 568         assertEquals(1, trbl[0], 0);
 569         assertEquals(1.5, trbl[1], 0);
 570         assertEquals(2, trbl[2], 0);
 571         assertEquals(2, trbl[3], 0);
 572     }
 573 
 574     @Test public void opaqueInsets_nonUniformCornerRadii2() {
 575         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(1, 2, 3, 4, 5, 6, 7, 8,
 576                                                                          false, false, false, false,
 577                                                                          false, false, false, false), null);
 578         Background b = new Background(new BackgroundFill[] { f }, null);
 579         final double[] trbl = new double[4];
 580         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 581         assertEquals(1.5, trbl[0], 0);
 582         assertEquals(2.5, trbl[1], 0);
 583         assertEquals(3.5, trbl[2], 0);
 584         assertEquals(4, trbl[3], 0);
 585     }
 586 
 587     @Test public void opaqueInsetsPercent_uniformCornerRadii() {
 588         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(.1, true), null);
 589         Background b = new Background(new BackgroundFill[] { f }, null);
 590         final double[] trbl = new double[4];
 591         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 592         assertEquals(2.5, trbl[0], 0);
 593         assertEquals(5, trbl[1], 0);
 594         assertEquals(2.5, trbl[2], 0);
 595         assertEquals(5, trbl[3], 0);
 596     }
 597 
 598     @Test public void opaqueInsetsPercent_nonUniformCornerRadii() {
 599         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(.1, .2, .3, .4, true), null);
 600         Background b = new Background(new BackgroundFill[] { f }, null);
 601         final double[] trbl = new double[4];
 602         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 603         assertEquals(5, trbl[0], 0); // top-left-vertical is 2.5, but top-right-vertical is 5
 604         assertEquals(15, trbl[1], 0); // top-right-horizontal is 5, but bottom-right-horizontal is 15
 605         assertEquals(10, trbl[2], 0); // bottom-right-vertical is 7.5, but bottom-left-vertical is 10
 606         assertEquals(20, trbl[3], 0); // bottom-left-horizontal dominates at 20
 607     }
 608 
 609     @Test public void opaqueInsetsPercent_nonUniformCornerRadii2() {
 610         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(.1, .15, .2, .25, .3, .35, .4, .45,
 611                                                                          true, true, true, true,
 612                                                                          true, true, true, true), null);
 613         Background b = new Background(new BackgroundFill[] { f }, null);
 614         final double[] trbl = new double[4];
 615         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 616         assertEquals(5, trbl[0], 0); // top-left-vertical is 3.75, but top-right-vertical is 5
 617         assertEquals(15, trbl[1], 0); // top-right-horizontal is 12.5, but bottom-right-horizontal is 15
 618         assertEquals(10, trbl[2], 0); // bottom-right-vertical is 8.75, but bottom-left-vertical is 10
 619         assertEquals(22.5, trbl[3], 0); // bottom-left-horizontal dominates at 22.5
 620     }
 621 
 622     @Test public void opaqueInsetsPercent_nonUniformCornerRadii3() {
 623         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(.1, 15, .2, 25, .3, 35, .4, 45,
 624                                                                          true, false, true, false,
 625                                                                          true, false, true, false), null);
 626         Background b = new Background(new BackgroundFill[] { f }, null);
 627         final double[] trbl = new double[4];
 628         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 629         assertEquals(7.5, trbl[0], 0); // top-left-vertical is 7.5, and top-right-vertical is 5
 630         assertEquals(15, trbl[1], 0); // top-right-horizontal is 12.5, but bottom-right-horizontal is 15
 631         assertEquals(17.5, trbl[2], 0); // bottom-right-vertical is 17.5, and bottom-left-vertical is 10
 632         assertEquals(22.5, trbl[3], 0); // bottom-left-horizontal dominates at 22.5
 633     }
 634 
 635     @Test public void opaqueInsetsPercent_nonUniformCornerRadii4() {
 636         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(10, .15, 20, .25, 30, .35, 40, .45,
 637                                                                          false, true, false, true,
 638                                                                          false, true, false, true), null);
 639         Background b = new Background(new BackgroundFill[] { f }, null);
 640         final double[] trbl = new double[4];
 641         BackgroundShim.computeOpaqueInsets(b, 100, 50, trbl);
 642         assertEquals(10, trbl[0], 0); // top-left-vertical is 3.75, but top-right-vertical is 10
 643         assertEquals(15, trbl[1], 0); // top-right-horizontal is 12.5, but bottom-right-horizontal is 15
 644         assertEquals(20, trbl[2], 0); // bottom-right-vertical is 8.75, but bottom-left-vertical is 20
 645         assertEquals(22.5, trbl[3], 0); // bottom-left-horizontal dominates at 22.5
 646     }
 647 
 648     @Test public void backgroundFillsArePercentageBased_AllPercentageBased() {
 649         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(.5, true), new Insets(10, 0, 0, 0));
 650         BackgroundFill f2 = new BackgroundFill(Color.GREEN, new CornerRadii(.4, true), new Insets(0, 10, 0, 0));
 651         BackgroundFill f3 = new BackgroundFill(Color.BLUE, new CornerRadii(.3, true), new Insets(0, 0, 10, 0));
 652         BackgroundFill f4 = new BackgroundFill(Color.YELLOW, new CornerRadii(.2, true), new Insets(0, 0, 0, 10));
 653         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4 }, null);
 654         assertTrue(b.isFillPercentageBased());
 655     }
 656 
 657     @Test public void backgroundFillsArePercentageBased_OnePercentageBased() {
 658         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(5), new Insets(10, 0, 0, 0));
 659         BackgroundFill f2 = new BackgroundFill(Color.GREEN, new CornerRadii(4), new Insets(0, 10, 0, 0));
 660         BackgroundFill f3 = new BackgroundFill(Color.BLUE, new CornerRadii(.3, true), new Insets(0, 0, 10, 0));
 661         BackgroundFill f4 = new BackgroundFill(Color.YELLOW, new CornerRadii(2), new Insets(0, 0, 0, 10));
 662         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4 }, null);
 663         assertTrue(b.isFillPercentageBased());
 664     }
 665 
 666     @Test public void backgroundFillsArePercentageBased_OneCornerOfOne() {
 667         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(5, 5, .5, 5, 5, 5, 5, 5,
 668                 false, false, true, false, false, false, false, false), new Insets(10, 0, 0, 0));
 669         BackgroundFill f2 = new BackgroundFill(Color.GREEN, new CornerRadii(4), new Insets(0, 10, 0, 0));
 670         BackgroundFill f3 = new BackgroundFill(Color.BLUE, new CornerRadii(3), new Insets(0, 0, 10, 0));
 671         BackgroundFill f4 = new BackgroundFill(Color.YELLOW, new CornerRadii(2), new Insets(0, 0, 0, 10));
 672         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4 }, null);
 673         assertTrue(b.isFillPercentageBased());
 674     }
 675 
 676     @Test public void backgroundFillsAreNotPercentageBased() {
 677         BackgroundFill f = new BackgroundFill(Color.RED, new CornerRadii(5), new Insets(10, 0, 0, 0));
 678         BackgroundFill f2 = new BackgroundFill(Color.GREEN, new CornerRadii(4), new Insets(0, 10, 0, 0));
 679         BackgroundFill f3 = new BackgroundFill(Color.BLUE, new CornerRadii(3), new Insets(0, 0, 10, 0));
 680         BackgroundFill f4 = new BackgroundFill(Color.YELLOW, new CornerRadii(2), new Insets(0, 0, 0, 10));
 681         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4 }, null);
 682         assertFalse(b.isFillPercentageBased());
 683     }
 684 
 685     @Test public void backgroundFillsAreNotPercentageBased_NoFills() {
 686         Background b = new Background(new BackgroundFill[0]);
 687         assertFalse(b.isFillPercentageBased());
 688     }
 689 
 690     @Test public void backgroundFillsAreNotPercentageBased_NullRadii() {
 691         BackgroundFill f = new BackgroundFill(Color.RED, null, new Insets(10, 0, 0, 0));
 692         BackgroundFill f2 = new BackgroundFill(Color.GREEN, null, new Insets(0, 10, 0, 0));
 693         BackgroundFill f3 = new BackgroundFill(Color.BLUE, null, new Insets(0, 0, 10, 0));
 694         BackgroundFill f4 = new BackgroundFill(Color.YELLOW, null, new Insets(0, 0, 0, 10));
 695         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4 }, null);
 696         assertFalse(b.isFillPercentageBased());
 697     }
 698 
 699     @Test public void backgroundFillsAreNotPercentageBased_OneEmpty() {
 700         BackgroundFill f = new BackgroundFill(Color.RED, CornerRadii.EMPTY, new Insets(10, 0, 0, 0));
 701         BackgroundFill f2 = new BackgroundFill(Color.GREEN, new CornerRadii(4), new Insets(0, 10, 0, 0));
 702         BackgroundFill f3 = new BackgroundFill(Color.BLUE, new CornerRadii(3), new Insets(0, 0, 10, 0));
 703         BackgroundFill f4 = new BackgroundFill(Color.YELLOW, new CornerRadii(2), new Insets(0, 0, 0, 10));
 704         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4 }, null);
 705         assertFalse(b.isFillPercentageBased());
 706     }
 707 
 708     @Test public void backgroundFillsAreNotPercentageBased_AllEmpty() {
 709         BackgroundFill f = new BackgroundFill(Color.RED, CornerRadii.EMPTY, new Insets(10, 0, 0, 0));
 710         BackgroundFill f2 = new BackgroundFill(Color.GREEN, CornerRadii.EMPTY, new Insets(0, 10, 0, 0));
 711         BackgroundFill f3 = new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, new Insets(0, 0, 10, 0));
 712         BackgroundFill f4 = new BackgroundFill(Color.YELLOW, CornerRadii.EMPTY, new Insets(0, 0, 0, 10));
 713         Background b = new Background(new BackgroundFill[] { f, f2, f3, f4 }, null);
 714         assertFalse(b.isFillPercentageBased());
 715     }
 716 
 717     // TODO: What happens if the corner radii become so big that we would end up with a negative opaque
 718     // inset in one dimension?
 719 
 720     // TODO: What happens if the insets are so big that they cross in either dimension?
 721 
 722     // TODO: Test having insets on images, and a combination of insets on images and fills
 723 }