/* * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javafx.scene.layout; /** * Defines the size of the area that a BackgroundImage should fill relative * to the Region it is styling. There are several properties who's values * take precedence over the others. In particular there are 4 key properties, * {@code width}, {@code height}, {@code contain}, and {@code cover}. Both width * and height are independent of each other, however both interact with * contain and cover. *

* From the CSS Specification, {@code cover} is defined to: *

* Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both * its width and its height can completely cover the background positioning area. *
* {@code contain} is defined to: *
* Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its * width and its height can fit inside the background positioning area. *
* And width and height both specify (in absolute values or percentages) the size to use. These * two properties only apply if both cover and contain are false. If both cover and contain are true, * then {@code cover} will be used. *

* The width and height may also be set to {@code AUTO}, indicating that the area should be sized * so as to use the image's intrinsic size, or if it cannot be determined, 100%. */ public final class BackgroundSize { /** * From the CSS Specification: *

* An ‘auto’ value for one dimension is resolved by using the image's intrinsic ratio and the size of the other * dimension, or failing that, using the image's intrinsic size, or failing that, treating it as 100%. *

* If both values are ‘auto’ then the intrinsic width and/or height of the image should be used, if any, * the missing dimension (if any) behaving as ‘auto’ as described above. If the image has neither an intrinsic * width nor an intrinsic height, its size is determined as for ‘contain’. *

* * When set to AUTO, the values for widthAsPercentage and heightAsPercentage are ignored. */ public static final double AUTO = -1; /** * The default BackgroundSize used by BackgroundImages when an explicit size is not defined. * By default, the BackgroundSize is AUTO, AUTO for the width and height, and is neither * cover nor contain. */ public static final BackgroundSize DEFAULT = new BackgroundSize(AUTO, AUTO, true, true, false, false); /** * The width of the area within the Region where the associated BackgroundImage should * render. If set to AUTO, then {@code widthAsPercentage} is ignored. This value has * no meaning if either {@code contain} or {@code cover} are specified. This value * cannot be negative, except when set to the value of AUTO. */ final double width; public final double getWidth() { return width; } /** * The height of the area within the Region where the associated BackgroundImage should * render. If set to AUTO, then {@code heightAsPercentage} is ignored. This value has * no meaning if either {@code contain} or {@code cover} are specified. This value * cannot be negative, except when set to the value of AUTO. */ final double height; public final double getHeight() { return height; } /** * Specifies whether the value contained in {@code width} should be interpreted * as a percentage or as a normal value. */ final boolean widthAsPercentage; public final boolean isWidthAsPercentage() { return widthAsPercentage; } /** * Specifies whether the value contained in {@code height} should be interpreted * as a percentage or as a normal value. */ final boolean heightAsPercentage; public final boolean isHeightAsPercentage() { return heightAsPercentage; } /** * If true, scale the image, while preserving its intrinsic aspect ratio (if any), to the * largest size such that both its width and its height can fit inside the background * positioning area. */ final boolean contain; public final boolean isContain() { return contain; } /** * If true, scale the image, while preserving its intrinsic aspect ratio (if any), to the * smallest size such that both its width and its height can completely cover the background * positioning area. */ final boolean cover; public final boolean isCover() { return cover; } /** * A cached hash code value */ private int hash = 0; /** * Create a new BackgroundSize. * * @param width The width. Cannot be less than 0, except for the value of AUTO. * @param height The height. Cannot be less than 0, except for the value of AUTO. * @param widthAsPercentage Whether the width is to be interpreted as a percentage * @param heightAsPercentage Whether the height is to be interpreted as a percentage * @param contain Whether the image should be sized to fit within the Region maximally * @param cover Whether the image should be sized to "cover" the Region */ public BackgroundSize(double width, double height, boolean widthAsPercentage, boolean heightAsPercentage, boolean contain, boolean cover) { // TODO Should deal with NaN and Infinity values as well if (width < 0 && width != AUTO) throw new IllegalArgumentException("Width cannot be < 0, except when AUTO"); if (height < 0 && height != AUTO) throw new IllegalArgumentException("Height cannot be < 0, except when AUTO"); this.width = width; this.height = height; this.widthAsPercentage = widthAsPercentage; this.heightAsPercentage = heightAsPercentage; this.contain = contain; this.cover = cover; } /** * @inheritDoc */ @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; // Because the hash is cached, this can be very fast if (hashCode() != o.hashCode()) return false; BackgroundSize that = (BackgroundSize) o; if (contain != that.contain) return false; if (cover != that.cover) return false; if (Double.compare(that.height, height) != 0) return false; if (heightAsPercentage != that.heightAsPercentage) return false; if (widthAsPercentage != that.widthAsPercentage) return false; if (Double.compare(that.width, width) != 0) return false; return true; } /** * @inheritDoc */ @Override public int hashCode() { if (hash == 0) { // Please note: I have to compute into a temporary result variable // before making the final assignment, or the hash code could // come out wrong in a multi-threaded scenario. int result; long temp; result = (widthAsPercentage ? 1 : 0); result = 31 * result + (heightAsPercentage ? 1 : 0); temp = width != +0.0d ? Double.doubleToLongBits(width) : 0L; result = 31 * result + (int) (temp ^ (temp >>> 32)); temp = height != +0.0d ? Double.doubleToLongBits(height) : 0L; result = 31 * result + (int) (temp ^ (temp >>> 32)); result = 31 * result + (cover ? 1 : 0); result = 31 * result + (contain ? 1 : 0); hash = result; } return hash; } }