Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.scene.layout;
027
028/**
029 * Defines the size of the area that a BackgroundImage should fill relative
030 * to the Region it is styling. There are several properties who's values
031 * take precedence over the others. In particular there are 4 key properties,
032 * {@code width}, {@code height}, {@code contain}, and {@code cover}. Both width
033 * and height are independent of each other, however both interact with
034 * contain and cover.
035 * <p>
036 * From the CSS Specification, {@code cover} is defined to:
037 * <blockquote>
038 * Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both
039 * its width and its height can completely cover the background positioning area.
040 * </blockquote>
041 * {@code contain} is defined to:
042 * <blockquote>
043 * Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its
044 * width and its height can fit inside the background positioning area.
045 * </blockquote>
046 * And width and height both specify (in absolute values or percentages) the size to use. These
047 * two properties only apply if both cover and contain are false. If both cover and contain are true,
048 * then {@code cover} will be used.
049 * <p>
050 * The width and height may also be set to {@code AUTO}, indicating that the area should be sized
051 * so as to use the image's intrinsic size, or if it cannot be determined, 100%.
052 */
053public final class BackgroundSize {
054    /**
055     * From the CSS Specification:
056     * <blockquote>
057     *   An "auto" value for one dimension is resolved by using the image's intrinsic ratio and the size of the other
058     *   dimension, or failing that, using the image's intrinsic size, or failing that, treating it as 100%.
059     *   <p>
060     *   If both values are "auto" then the intrinsic width and/or height of the image should be used, if any,
061     *   the missing dimension (if any) behaving as "auto" as described above. If the image has neither an intrinsic
062     *   width nor an intrinsic height, its size is determined as for "contain".
063     * </blockquote>
064     *
065     * When set to AUTO, the values for widthAsPercentage and heightAsPercentage are ignored.
066     */
067    public static final double AUTO = -1;
068
069    /**
070     * The default BackgroundSize used by BackgroundImages when an explicit size is not defined.
071     * By default, the BackgroundSize is AUTO, AUTO for the width and height, and is neither
072     * cover nor contain.
073     */
074    public static final BackgroundSize DEFAULT = new BackgroundSize(AUTO, AUTO, true, true, false, false);
075
076    /**
077     * The width of the area within the Region where the associated BackgroundImage should
078     * render. If set to AUTO, then {@code widthAsPercentage} is ignored. This value has
079     * no meaning if either {@code contain} or {@code cover} are specified. This value
080     * cannot be negative, except when set to the value of AUTO.
081     */
082    final double width;
083    public final double getWidth() { return width; }
084
085    /**
086     * The height of the area within the Region where the associated BackgroundImage should
087     * render. If set to AUTO, then {@code heightAsPercentage} is ignored. This value has
088     * no meaning if either {@code contain} or {@code cover} are specified. This value
089     * cannot be negative, except when set to the value of AUTO.
090     */
091    final double height;
092    public final double getHeight() { return height; }
093
094    /**
095     * Specifies whether the value contained in {@code width} should be interpreted
096     * as a percentage or as a normal value.
097     */
098    final boolean widthAsPercentage;
099    public final boolean isWidthAsPercentage() { return widthAsPercentage; }
100
101    /**
102     * Specifies whether the value contained in {@code height} should be interpreted
103     * as a percentage or as a normal value.
104     */
105    final boolean heightAsPercentage;
106    public final boolean isHeightAsPercentage() { return heightAsPercentage; }
107
108    /**
109     * If true, scale the image, while preserving its intrinsic aspect ratio (if any), to the
110     * largest size such that both its width and its height can fit inside the background
111     * positioning area.
112     */
113    final boolean contain;
114    public final boolean isContain() { return contain; }
115
116    /**
117     * If true, scale the image, while preserving its intrinsic aspect ratio (if any), to the
118     * smallest size such that both its width and its height can completely cover the background
119     * positioning area.
120     */
121    final boolean cover;
122    public final boolean isCover() { return cover; }
123
124    /**
125     * A cached hash code value
126     */
127    private final int hash;
128
129    /**
130     * Create a new BackgroundSize.
131     *
132     * @param width                 The width. Cannot be less than 0, except for the value of AUTO.
133     * @param height                The height. Cannot be less than 0, except for the value of AUTO.
134     * @param widthAsPercentage     Whether the width is to be interpreted as a percentage
135     * @param heightAsPercentage    Whether the height is to be interpreted as a percentage
136     * @param contain               Whether the image should be sized to fit within the Region maximally
137     * @param cover                 Whether the image should be sized to "cover" the Region
138     */
139    public BackgroundSize(double width, double height,
140                          boolean widthAsPercentage, boolean heightAsPercentage,
141                          boolean contain, boolean cover) {
142        // TODO Should deal with NaN and Infinity values as well
143        if (width < 0 && width != AUTO)
144            throw new IllegalArgumentException("Width cannot be < 0, except when AUTO");
145        if (height < 0 && height != AUTO)
146            throw new IllegalArgumentException("Height cannot be < 0, except when AUTO");
147
148        this.width = width;
149        this.height = height;
150        this.widthAsPercentage = widthAsPercentage;
151        this.heightAsPercentage = heightAsPercentage;
152        this.contain = contain;
153        this.cover = cover;
154
155        // Pre-compute the hash code. NOTE: all variables are prefixed with "this" so that we
156        // do not accidentally compute the hash based on the constructor arguments rather than
157        // based on the fields themselves!
158        int result;
159        long temp;
160        result = (this.widthAsPercentage ? 1 : 0);
161        result = 31 * result + (this.heightAsPercentage ? 1 : 0);
162        temp = this.width != +0.0d ? Double.doubleToLongBits(this.width) : 0L;
163        result = 31 * result + (int) (temp ^ (temp >>> 32));
164        temp = this.height != +0.0d ? Double.doubleToLongBits(this.height) : 0L;
165        result = 31 * result + (int) (temp ^ (temp >>> 32));
166        result = 31 * result + (this.cover ? 1 : 0);
167        result = 31 * result + (this.contain ? 1 : 0);
168        hash = result;
169    }
170
171    /**
172     * @inheritDoc
173     */
174    @Override public boolean equals(Object o) {
175        if (this == o) return true;
176        if (o == null || getClass() != o.getClass()) return false;
177        BackgroundSize that = (BackgroundSize) o;
178        // Because the hash is cached, this can be very fast
179        if (this.hash != that.hash) return false;
180        if (contain != that.contain) return false;
181        if (cover != that.cover) return false;
182        if (Double.compare(that.height, height) != 0) return false;
183        if (heightAsPercentage != that.heightAsPercentage) return false;
184        if (widthAsPercentage != that.widthAsPercentage) return false;
185        if (Double.compare(that.width, width) != 0) return false;
186
187        return true;
188    }
189
190    /**
191     * @inheritDoc
192     */
193    @Override public int hashCode() {
194        return hash;
195    }
196}