/* |
|
* Copyright (c) 1995, 2013, 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 java.awt; |
|
import java.beans.ConstructorProperties; |
|
import java.awt.image.ColorModel; |
|
import java.awt.geom.AffineTransform; |
|
import java.awt.geom.Rectangle2D; |
|
import java.awt.color.ColorSpace; |
|
/** |
|
* The <code>Color</code> class is used to encapsulate colors in the default |
|
* sRGB color space or colors in arbitrary color spaces identified by a |
|
* {@link ColorSpace}. Every color has an implicit alpha value of 1.0 or |
|
* an explicit one provided in the constructor. The alpha value |
|
* defines the transparency of a color and can be represented by |
|
* a float value in the range 0.0 - 1.0 or 0 - 255. |
|
* An alpha value of 1.0 or 255 means that the color is completely |
|
* opaque and an alpha value of 0 or 0.0 means that the color is |
|
* completely transparent. |
|
* When constructing a <code>Color</code> with an explicit alpha or |
|
* getting the color/alpha components of a <code>Color</code>, the color |
|
* components are never premultiplied by the alpha component. |
|
* <p> |
|
* The default color space for the Java 2D(tm) API is sRGB, a proposed |
|
* standard RGB color space. For further information on sRGB, |
|
* see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html"> |
|
* http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html |
|
* </A>. |
|
* <p> |
|
* @version 10 Feb 1997 |
|
* @author Sami Shaio |
|
* @author Arthur van Hoff |
|
* @see ColorSpace |
|
* @see AlphaComposite |
|
*/ |
|
public class Color implements Paint, java.io.Serializable { |
|
/** |
|
* The color white. In the default sRGB space. |
|
*/ |
|
public final static Color white = new Color(255, 255, 255); |
|
/** |
|
* The color white. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color WHITE = white; |
|
/** |
|
* The color light gray. In the default sRGB space. |
|
*/ |
|
public final static Color lightGray = new Color(192, 192, 192); |
|
/** |
|
* The color light gray. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color LIGHT_GRAY = lightGray; |
|
/** |
|
* The color gray. In the default sRGB space. |
|
*/ |
|
public final static Color gray = new Color(128, 128, 128); |
|
/** |
|
* The color gray. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color GRAY = gray; |
|
/** |
|
* The color dark gray. In the default sRGB space. |
|
*/ |
|
public final static Color darkGray = new Color(64, 64, 64); |
|
/** |
|
* The color dark gray. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color DARK_GRAY = darkGray; |
|
/** |
|
* The color black. In the default sRGB space. |
|
*/ |
|
public final static Color black = new Color(0, 0, 0); |
|
/** |
|
* The color black. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color BLACK = black; |
|
/** |
|
* The color red. In the default sRGB space. |
|
*/ |
|
public final static Color red = new Color(255, 0, 0); |
|
/** |
|
* The color red. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color RED = red; |
|
/** |
|
* The color pink. In the default sRGB space. |
|
*/ |
|
public final static Color pink = new Color(255, 175, 175); |
|
/** |
|
* The color pink. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color PINK = pink; |
|
/** |
|
* The color orange. In the default sRGB space. |
|
*/ |
|
public final static Color orange = new Color(255, 200, 0); |
|
/** |
|
* The color orange. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color ORANGE = orange; |
|
/** |
|
* The color yellow. In the default sRGB space. |
|
*/ |
|
public final static Color yellow = new Color(255, 255, 0); |
|
/** |
|
* The color yellow. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color YELLOW = yellow; |
|
/** |
|
* The color green. In the default sRGB space. |
|
*/ |
|
public final static Color green = new Color(0, 255, 0); |
|
/** |
|
* The color green. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color GREEN = green; |
|
/** |
|
* The color magenta. In the default sRGB space. |
|
*/ |
|
public final static Color magenta = new Color(255, 0, 255); |
|
/** |
|
* The color magenta. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color MAGENTA = magenta; |
|
/** |
|
* The color cyan. In the default sRGB space. |
|
*/ |
|
public final static Color cyan = new Color(0, 255, 255); |
|
/** |
|
* The color cyan. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color CYAN = cyan; |
|
/** |
|
* The color blue. In the default sRGB space. |
|
*/ |
|
public final static Color blue = new Color(0, 0, 255); |
|
/** |
|
* The color blue. In the default sRGB space. |
|
* @since 1.4 |
|
*/ |
|
public final static Color BLUE = blue; |
|
/** |
|
* The color value. |
|
* @serial |
|
* @see #getRGB |
|
*/ |
|
int value; |
|
/** |
|
* The color value in the default sRGB <code>ColorSpace</code> as |
|
* <code>float</code> components (no alpha). |
|
* If <code>null</code> after object construction, this must be an |
|
* sRGB color constructed with 8-bit precision, so compute from the |
|
* <code>int</code> color value. |
|
* @serial |
|
* @see #getRGBColorComponents |
|
* @see #getRGBComponents |
|
*/ |
|
private float frgbvalue[] = null; |
|
/** |
|
* The color value in the native <code>ColorSpace</code> as |
|
* <code>float</code> components (no alpha). |
|
* If <code>null</code> after object construction, this must be an |
|
* sRGB color constructed with 8-bit precision, so compute from the |
|
* <code>int</code> color value. |
|
* @serial |
|
* @see #getRGBColorComponents |
|
* @see #getRGBComponents |
|
*/ |
|
private float fvalue[] = null; |
|
/** |
|
* The alpha value as a <code>float</code> component. |
|
* If <code>frgbvalue</code> is <code>null</code>, this is not valid |
|
* data, so compute from the <code>int</code> color value. |
|
* @serial |
|
* @see #getRGBComponents |
|
* @see #getComponents |
|
*/ |
|
private float falpha = 0.0f; |
|
/** |
|
* The <code>ColorSpace</code>. If <code>null</code>, then it's |
|
* default is sRGB. |
|
* @serial |
|
* @see #getColor |
|
* @see #getColorSpace |
|
* @see #getColorComponents |
|
*/ |
|
private ColorSpace cs = null; |
|
/* |
|
* JDK 1.1 serialVersionUID |
|
*/ |
|
private static final long serialVersionUID = 118526816881161077L; |
|
/** |
|
* Initialize JNI field and method IDs |
|
*/ |
|
private static native void initIDs(); |
|
static { |
|
/** 4112352 - Calling getDefaultToolkit() |
|
** here can cause this class to be accessed before it is fully |
|
** initialized. DON'T DO IT!!! |
|
** |
|
** Toolkit.getDefaultToolkit(); |
|
**/ |
|
/* ensure that the necessary native libraries are loaded */ |
|
Toolkit.loadLibraries(); |
|
if (!GraphicsEnvironment.isHeadless()) { |
|
initIDs(); |
|
} |
|
} |
|
/** |
|
* Checks the color integer components supplied for validity. |
|
* Throws an {@link IllegalArgumentException} if the value is out of |
|
* range. |
|
* @param r the Red component |
|
* @param g the Green component |
|
* @param b the Blue component |
|
**/ |
|
private static void testColorValueRange(int r, int g, int b, int a) { |
|
boolean rangeError = false; |
|
String badComponentString = ""; |
|
if ( a < 0 || a > 255) { |
|
rangeError = true; |
|
badComponentString = badComponentString + " Alpha"; |
|
} |
|
if ( r < 0 || r > 255) { |
|
rangeError = true; |
|
badComponentString = badComponentString + " Red"; |
|
} |
|
if ( g < 0 || g > 255) { |
|
rangeError = true; |
|
badComponentString = badComponentString + " Green"; |
|
} |
|
if ( b < 0 || b > 255) { |
|
rangeError = true; |
|
badComponentString = badComponentString + " Blue"; |
|
} |
|
if ( rangeError == true ) { |
|
throw new IllegalArgumentException("Color parameter outside of expected range:" |
|
+ badComponentString); |
|
} |
|
} |
|
/** |
|
* Checks the color <code>float</code> components supplied for |
|
* validity. |
|
* Throws an <code>IllegalArgumentException</code> if the value is out |
|
* of range. |
|
* @param r the Red component |
|
* @param g the Green component |
|
* @param b the Blue component |
|
**/ |
|
private static void testColorValueRange(float r, float g, float b, float a) { |
|
boolean rangeError = false; |
|
String badComponentString = ""; |
|
if ( a < 0.0 || a > 1.0) { |
|
rangeError = true; |
|
badComponentString = badComponentString + " Alpha"; |
|
} |
|
if ( r < 0.0 || r > 1.0) { |
|
rangeError = true; |
|
badComponentString = badComponentString + " Red"; |
|
} |
|
if ( g < 0.0 || g > 1.0) { |
|
rangeError = true; |
|
badComponentString = badComponentString + " Green"; |
|
} |
|
if ( b < 0.0 || b > 1.0) { |
|
rangeError = true; |
|
badComponentString = badComponentString + " Blue"; |
|
} |
|
if ( rangeError == true ) { |
|
throw new IllegalArgumentException("Color parameter outside of expected range:" |
|
+ badComponentString); |
|
} |
|
} |
|
/** |
|
* Creates an opaque sRGB color with the specified red, green, |
|
* and blue values in the range (0 - 255). |
|
* The actual color used in rendering depends |
|
* on finding the best match given the color space |
|
* available for a given output device. |
|
* Alpha is defaulted to 255. |
|
* |
|
* @throws IllegalArgumentException if <code>r</code>, <code>g</code> |
|
* or <code>b</code> are outside of the range |
|
* 0 to 255, inclusive |
|
* @param r the red component |
|
* @param g the green component |
|
* @param b the blue component |
|
* @see #getRed |
|
* @see #getGreen |
|
* @see #getBlue |
|
* @see #getRGB |
|
*/ |
|
public Color(int r, int g, int b) { |
|
this(r, g, b, 255); |
|
} |
|
/** |
|
* Creates an sRGB color with the specified red, green, blue, and alpha |
|
* values in the range (0 - 255). |
|
* |
|
* @throws IllegalArgumentException if <code>r</code>, <code>g</code>, |
|
* <code>b</code> or <code>a</code> are outside of the range |
|
* 0 to 255, inclusive |
|
* @param r the red component |
|
* @param g the green component |
|
* @param b the blue component |
|
* @param a the alpha component |
|
* @see #getRed |
|
* @see #getGreen |
|
* @see #getBlue |
|
* @see #getAlpha |
|
* @see #getRGB |
|
*/ |
|
@ConstructorProperties({"red", "green", "blue", "alpha"}) |
|
public Color(int r, int g, int b, int a) { |
|
value = ((a & 0xFF) << 24) | |
|
((r & 0xFF) << 16) | |
|
((g & 0xFF) << 8) | |
|
((b & 0xFF) << 0); |
|
testColorValueRange(r,g,b,a); |
|
} |
|
/** |
|
* Creates an opaque sRGB color with the specified combined RGB value |
|
* consisting of the red component in bits 16-23, the green component |
|
* in bits 8-15, and the blue component in bits 0-7. The actual color |
|
* used in rendering depends on finding the best match given the |
|
* color space available for a particular output device. Alpha is |
|
* defaulted to 255. |
|
* |
|
* @param rgb the combined RGB components |
|
* @see java.awt.image.ColorModel#getRGBdefault |
|
* @see #getRed |
|
* @see #getGreen |
|
* @see #getBlue |
|
* @see #getRGB |
|
*/ |
|
public Color(int rgb) { |
|
value = 0xff000000 | rgb; |
|
} |
|
/** |
|
* Creates an sRGB color with the specified combined RGBA value consisting |
|
* of the alpha component in bits 24-31, the red component in bits 16-23, |
|
* the green component in bits 8-15, and the blue component in bits 0-7. |
|
* If the <code>hasalpha</code> argument is <code>false</code>, alpha |
|
* is defaulted to 255. |
|
* |
|
* @param rgba the combined RGBA components |
|
* @param hasalpha <code>true</code> if the alpha bits are valid; |
|
* <code>false</code> otherwise |
|
* @see java.awt.image.ColorModel#getRGBdefault |
|
* @see #getRed |
|
* @see #getGreen |
|
* @see #getBlue |
|
* @see #getAlpha |
|
* @see #getRGB |
|
*/ |
|
public Color(int rgba, boolean hasalpha) { |
|
if (hasalpha) { |
|
value = rgba; |
|
} else { |
|
value = 0xff000000 | rgba; |
|
} |
|
} |
|
/** |
|
* Creates an opaque sRGB color with the specified red, green, and blue |
|
* values in the range (0.0 - 1.0). Alpha is defaulted to 1.0. The |
|
* actual color used in rendering depends on finding the best |
|
* match given the color space available for a particular output |
|
* device. |
|
* |
|
* @throws IllegalArgumentException if <code>r</code>, <code>g</code> |
|
* or <code>b</code> are outside of the range |
|
* 0.0 to 1.0, inclusive |
|
* @param r the red component |
|
* @param g the green component |
|
* @param b the blue component |
|
* @see #getRed |
|
* @see #getGreen |
|
* @see #getBlue |
|
* @see #getRGB |
|
*/ |
|
public Color(float r, float g, float b) { |
|
this( (int) (r*255+0.5), (int) (g*255+0.5), (int) (b*255+0.5)); |
|
testColorValueRange(r,g,b,1.0f); |
|
frgbvalue = new float[3]; |
|
frgbvalue[0] = r; |
|
frgbvalue[1] = g; |
|
frgbvalue[2] = b; |
|
falpha = 1.0f; |
|
fvalue = frgbvalue; |
|
} |
|
/** |
|
* Creates an sRGB color with the specified red, green, blue, and |
|
* alpha values in the range (0.0 - 1.0). The actual color |
|
* used in rendering depends on finding the best match given the |
|
* color space available for a particular output device. |
|
* @throws IllegalArgumentException if <code>r</code>, <code>g</code> |
|
* <code>b</code> or <code>a</code> are outside of the range |
|
* 0.0 to 1.0, inclusive |
|
* @param r the red component |
|
* @param g the green component |
|
* @param b the blue component |
|
* @param a the alpha component |
|
* @see #getRed |
|
* @see #getGreen |
|
* @see #getBlue |
|
* @see #getAlpha |
|
* @see #getRGB |
|
*/ |
|
public Color(float r, float g, float b, float a) { |
|
this((int)(r*255+0.5), (int)(g*255+0.5), (int)(b*255+0.5), (int)(a*255+0.5)); |
|
frgbvalue = new float[3]; |
|
frgbvalue[0] = r; |
|
frgbvalue[1] = g; |
|
frgbvalue[2] = b; |
|
falpha = a; |
|
fvalue = frgbvalue; |
|
} |
|
/** |
|
* Creates a color in the specified <code>ColorSpace</code> |
|
* with the color components specified in the <code>float</code> |
|
* array and the specified alpha. The number of components is |
|
* determined by the type of the <code>ColorSpace</code>. For |
|
* example, RGB requires 3 components, but CMYK requires 4 |
|
* components. |
|
* @param cspace the <code>ColorSpace</code> to be used to |
|
* interpret the components |
|
* @param components an arbitrary number of color components |
|
* that is compatible with the <code>ColorSpace</code> |
|
* @param alpha alpha value |
|
* @throws IllegalArgumentException if any of the values in the |
|
* <code>components</code> array or <code>alpha</code> is |
|
* outside of the range 0.0 to 1.0 |
|
* @see #getComponents |
|
* @see #getColorComponents |
|
*/ |
|
public Color(ColorSpace cspace, float components[], float alpha) { |
|
boolean rangeError = false; |
|
String badComponentString = ""; |
|
int n = cspace.getNumComponents(); |
|
fvalue = new float[n]; |
|
for (int i = 0; i < n; i++) { |
|
if (components[i] < 0.0 || components[i] > 1.0) { |
|
rangeError = true; |
|
badComponentString = badComponentString + "Component " + i |
|
+ " "; |
|
} else { |
|
fvalue[i] = components[i]; |
|
} |
|
} |
|
if (alpha < 0.0 || alpha > 1.0) { |
|
rangeError = true; |
|
badComponentString = badComponentString + "Alpha"; |
|
} else { |
|
falpha = alpha; |
|
} |
|
if (rangeError) { |
|
throw new IllegalArgumentException( |
|
"Color parameter outside of expected range: " + |
|
badComponentString); |
|
} |
|
frgbvalue = cspace.toRGB(fvalue); |
|
cs = cspace; |
|
value = ((((int)(falpha*255)) & 0xFF) << 24) | |
|
((((int)(frgbvalue[0]*255)) & 0xFF) << 16) | |
|
((((int)(frgbvalue[1]*255)) & 0xFF) << 8) | |
|
((((int)(frgbvalue[2]*255)) & 0xFF) << 0); |
|
} |
|
/** |
|
* Returns the red component in the range 0-255 in the default sRGB |
|
* space. |
|
* @return the red component. |
|
* @see #getRGB |
|
*/ |
|
public int getRed() { |
|
return (getRGB() >> 16) & 0xFF; |
|
} |
|
/** |
|
* Returns the green component in the range 0-255 in the default sRGB |
|
* space. |
|
* @return the green component. |
|
* @see #getRGB |
|
*/ |
|
public int getGreen() { |
|
return (getRGB() >> 8) & 0xFF; |
|
} |
|
/** |
|
* Returns the blue component in the range 0-255 in the default sRGB |
|
* space. |
|
* @return the blue component. |
|
* @see #getRGB |
|
*/ |
|
public int getBlue() { |
|
return (getRGB() >> 0) & 0xFF; |
|
} |
|
/** |
|
* Returns the alpha component in the range 0-255. |
|
* @return the alpha component. |
|
* @see #getRGB |
|
*/ |
|
public int getAlpha() { |
|
return (getRGB() >> 24) & 0xff; |
|
} |
|
/** |
|
* Returns the RGB value representing the color in the default sRGB |
|
* {@link ColorModel}. |
|
* (Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are |
|
* blue). |
|
* @return the RGB value of the color in the default sRGB |
|
* <code>ColorModel</code>. |
|
* @see java.awt.image.ColorModel#getRGBdefault |
|
* @see #getRed |
|
* @see #getGreen |
|
* @see #getBlue |
|
* @since JDK1.0 |
|
*/ |
|
public int getRGB() { |
|
return value; |
|
} |
|
private static final double FACTOR = 0.7; |
|
/** |
|
* Creates a new <code>Color</code> that is a brighter version of this |
|
* <code>Color</code>. |
|
* <p> |
|
* This method applies an arbitrary scale factor to each of the three RGB |
|
* components of this <code>Color</code> to create a brighter version |
|
* of this <code>Color</code>. |
|
* The {@code alpha} value is preserved. |
|
* Although <code>brighter</code> and |
|
* <code>darker</code> are inverse operations, the results of a |
|
* series of invocations of these two methods might be inconsistent |
|
* because of rounding errors. |
|
* @return a new <code>Color</code> object that is |
|
* a brighter version of this <code>Color</code> |
|
* with the same {@code alpha} value. |
|
* @see java.awt.Color#darker |
|
* @since JDK1.0 |
|
*/ |
|
public Color brighter() { |
|
int r = getRed(); |
|
int g = getGreen(); |
|
int b = getBlue(); |
|
int alpha = getAlpha(); |
|
/* From 2D group: |
|
* 1. black.brighter() should return grey |
|
* 2. applying brighter to blue will always return blue, brighter |
|
* 3. non pure color (non zero rgb) will eventually return white |
|
*/ |
|
int i = (int)(1.0/(1.0-FACTOR)); |
|
if ( r == 0 && g == 0 && b == 0) { |
|
return new Color(i, i, i, alpha); |
|
} |
|
if ( r > 0 && r < i ) r = i; |
|
if ( g > 0 && g < i ) g = i; |
|
if ( b > 0 && b < i ) b = i; |
|
return new Color(Math.min((int)(r/FACTOR), 255), |
|
Math.min((int)(g/FACTOR), 255), |
|
Math.min((int)(b/FACTOR), 255), |
|
alpha); |
|
} |
|
/** |
|
* Creates a new <code>Color</code> that is a darker version of this |
|
* <code>Color</code>. |
|
* <p> |
|
* This method applies an arbitrary scale factor to each of the three RGB |
|
* components of this <code>Color</code> to create a darker version of |
|
* this <code>Color</code>. |
|
* The {@code alpha} value is preserved. |
|
* Although <code>brighter</code> and |
|
* <code>darker</code> are inverse operations, the results of a series |
|
* of invocations of these two methods might be inconsistent because |
|
* of rounding errors. |
|
* @return a new <code>Color</code> object that is |
|
* a darker version of this <code>Color</code> |
|
* with the same {@code alpha} value. |
|
* @see java.awt.Color#brighter |
|
* @since JDK1.0 |
|
*/ |
|
public Color darker() { |
|
return new Color(Math.max((int)(getRed() *FACTOR), 0), |
|
Math.max((int)(getGreen()*FACTOR), 0), |
|
Math.max((int)(getBlue() *FACTOR), 0), |
|
getAlpha()); |
|
} |
|
/** |
|
* Computes the hash code for this <code>Color</code>. |
|
* @return a hash code value for this object. |
|
* @since JDK1.0 |
|
*/ |
|
public int hashCode() { |
|
return value; |
|
} |
|
/** |
|
* Determines whether another object is equal to this |
|
* <code>Color</code>. |
|
* <p> |
|
* The result is <code>true</code> if and only if the argument is not |
|
* <code>null</code> and is a <code>Color</code> object that has the same |
|
* red, green, blue, and alpha values as this object. |
|
* @param obj the object to test for equality with this |
|
* <code>Color</code> |
|
* @return <code>true</code> if the objects are the same; |
|
* <code>false</code> otherwise. |
|
* @since JDK1.0 |
|
*/ |
|
public boolean equals(Object obj) { |
|
return obj instanceof Color && ((Color)obj).getRGB() == this.getRGB(); |
|
} |
|
/** |
|
* Returns a string representation of this <code>Color</code>. This |
|
* method is intended to be used only for debugging purposes. The |
|
* content and format of the returned string might vary between |
|
* implementations. The returned string might be empty but cannot |
|
* be <code>null</code>. |
|
* |
|
* @return a string representation of this <code>Color</code>. |
|
*/ |
|
public String toString() { |
|
return getClass().getName() + "[r=" + getRed() + ",g=" + getGreen() + ",b=" + getBlue() + "]"; |
|
} |
|
/** |
|
* Converts a <code>String</code> to an integer and returns the |
|
* specified opaque <code>Color</code>. This method handles string |
|
* formats that are used to represent octal and hexadecimal numbers. |
|
* @param nm a <code>String</code> that represents |
|
* an opaque color as a 24-bit integer |
|
* @return the new <code>Color</code> object. |
|
* @see java.lang.Integer#decode |
|
* @exception NumberFormatException if the specified string cannot |
|
* be interpreted as a decimal, |
|
* octal, or hexadecimal integer. |
|
* @since JDK1.1 |
|
*/ |
|
public static Color decode(String nm) throws NumberFormatException { |
|
Integer intval = Integer.decode(nm); |
|
int i = intval.intValue(); |
|
return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF); |
|
} |
|
/** |
|
* Finds a color in the system properties. |
|
* <p> |
|
* The argument is treated as the name of a system property to |
|
* be obtained. The string value of this property is then interpreted |
|
* as an integer which is then converted to a <code>Color</code> |
|
* object. |
|
* <p> |
|
* If the specified property is not found or could not be parsed as |
|
* an integer then <code>null</code> is returned. |
|
* @param nm the name of the color property |
|
* @return the <code>Color</code> converted from the system |
|
* property. |
|
* @see java.lang.System#getProperty(java.lang.String) |
|
* @see java.lang.Integer#getInteger(java.lang.String) |
|
* @see java.awt.Color#Color(int) |
|
* @since JDK1.0 |
|
*/ |
|
public static Color getColor(String nm) { |
|
return getColor(nm, null); |
|
} |
|
/** |
|
* Finds a color in the system properties. |
|
* <p> |
|
* The first argument is treated as the name of a system property to |
|
* be obtained. The string value of this property is then interpreted |
|
* as an integer which is then converted to a <code>Color</code> |
|
* object. |
|
* <p> |
|
* If the specified property is not found or cannot be parsed as |
|
* an integer then the <code>Color</code> specified by the second |
|
* argument is returned instead. |
|
* @param nm the name of the color property |
|
* @param v the default <code>Color</code> |
|
* @return the <code>Color</code> converted from the system |
|
* property, or the specified <code>Color</code>. |
|
* @see java.lang.System#getProperty(java.lang.String) |
|
* @see java.lang.Integer#getInteger(java.lang.String) |
|
* @see java.awt.Color#Color(int) |
|
* @since JDK1.0 |
|
*/ |
|
public static Color getColor(String nm, Color v) { |
|
Integer intval = Integer.getInteger(nm); |
|
if (intval == null) { |
|
return v; |
|
} |
|
int i = intval.intValue(); |
|
return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF); |
|
} |
|
/** |
|
* Finds a color in the system properties. |
|
* <p> |
|
* The first argument is treated as the name of a system property to |
|
* be obtained. The string value of this property is then interpreted |
|
* as an integer which is then converted to a <code>Color</code> |
|
* object. |
|
* <p> |
|
* If the specified property is not found or could not be parsed as |
|
* an integer then the integer value <code>v</code> is used instead, |
|
* and is converted to a <code>Color</code> object. |
|
* @param nm the name of the color property |
|
* @param v the default color value, as an integer |
|
* @return the <code>Color</code> converted from the system |
|
* property or the <code>Color</code> converted from |
|
* the specified integer. |
|
* @see java.lang.System#getProperty(java.lang.String) |
|
* @see java.lang.Integer#getInteger(java.lang.String) |
|
* @see java.awt.Color#Color(int) |
|
* @since JDK1.0 |
|
*/ |
|
public static Color getColor(String nm, int v) { |
|
Integer intval = Integer.getInteger(nm); |
|
int i = (intval != null) ? intval.intValue() : v; |
|
return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, (i >> 0) & 0xFF); |
|
} |
|
/** |
|
* Converts the components of a color, as specified by the HSB |
|
* model, to an equivalent set of values for the default RGB model. |
|
* <p> |
|
* The <code>saturation</code> and <code>brightness</code> components |
|
* should be floating-point values between zero and one |
|
* (numbers in the range 0.0-1.0). The <code>hue</code> component |
|
* can be any floating-point number. The floor of this number is |
|
* subtracted from it to create a fraction between 0 and 1. This |
|
* fractional number is then multiplied by 360 to produce the hue |
|
* angle in the HSB color model. |
|
* <p> |
|
* The integer that is returned by <code>HSBtoRGB</code> encodes the |
|
* value of a color in bits 0-23 of an integer value that is the same |
|
* format used by the method {@link #getRGB() getRGB}. |
|
* This integer can be supplied as an argument to the |
|
* <code>Color</code> constructor that takes a single integer argument. |
|
* @param hue the hue component of the color |
|
* @param saturation the saturation of the color |
|
* @param brightness the brightness of the color |
|
* @return the RGB value of the color with the indicated hue, |
|
* saturation, and brightness. |
|
* @see java.awt.Color#getRGB() |
|
* @see java.awt.Color#Color(int) |
|
* @see java.awt.image.ColorModel#getRGBdefault() |
|
* @since JDK1.0 |
|
*/ |
|
public static int HSBtoRGB(float hue, float saturation, float brightness) { |
|
int r = 0, g = 0, b = 0; |
|
if (saturation == 0) { |
|
r = g = b = (int) (brightness * 255.0f + 0.5f); |
|
} else { |
|
float h = (hue - (float)Math.floor(hue)) * 6.0f; |
|
float f = h - (float)java.lang.Math.floor(h); |
|
float p = brightness * (1.0f - saturation); |
|
float q = brightness * (1.0f - saturation * f); |
|
float t = brightness * (1.0f - (saturation * (1.0f - f))); |
|
switch ((int) h) { |
|
case 0: |
|
r = (int) (brightness * 255.0f + 0.5f); |
|
g = (int) (t * 255.0f + 0.5f); |
|
b = (int) (p * 255.0f + 0.5f); |
|
break; |
|
case 1: |
|
r = (int) (q * 255.0f + 0.5f); |
|
g = (int) (brightness * 255.0f + 0.5f); |
|
b = (int) (p * 255.0f + 0.5f); |
|
break; |
|
case 2: |
|
r = (int) (p * 255.0f + 0.5f); |
|
g = (int) (brightness * 255.0f + 0.5f); |
|
b = (int) (t * 255.0f + 0.5f); |
|
break; |
|
case 3: |
|
r = (int) (p * 255.0f + 0.5f); |
|
g = (int) (q * 255.0f + 0.5f); |
|
b = (int) (brightness * 255.0f + 0.5f); |
|
break; |
|
case 4: |
|
r = (int) (t * 255.0f + 0.5f); |
|
g = (int) (p * 255.0f + 0.5f); |
|
b = (int) (brightness * 255.0f + 0.5f); |
|
break; |
|
case 5: |
|
r = (int) (brightness * 255.0f + 0.5f); |
|
g = (int) (p * 255.0f + 0.5f); |
|
b = (int) (q * 255.0f + 0.5f); |
|
break; |
|
} |
|
} |
|
return 0xff000000 | (r << 16) | (g << 8) | (b << 0); |
|
} |
|
/** |
|
* Converts the components of a color, as specified by the default RGB |
|
* model, to an equivalent set of values for hue, saturation, and |
|
* brightness that are the three components of the HSB model. |
|
* <p> |
|
* If the <code>hsbvals</code> argument is <code>null</code>, then a |
|
* new array is allocated to return the result. Otherwise, the method |
|
* returns the array <code>hsbvals</code>, with the values put into |
|
* that array. |
|
* @param r the red component of the color |
|
* @param g the green component of the color |
|
* @param b the blue component of the color |
|
* @param hsbvals the array used to return the |
|
* three HSB values, or <code>null</code> |
|
* @return an array of three elements containing the hue, saturation, |
|
* and brightness (in that order), of the color with |
|
* the indicated red, green, and blue components. |
|
* @see java.awt.Color#getRGB() |
|
* @see java.awt.Color#Color(int) |
|
* @see java.awt.image.ColorModel#getRGBdefault() |
|
* @since JDK1.0 |
|
*/ |
|
public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) { |
|
float hue, saturation, brightness; |
|
if (hsbvals == null) { |
|
hsbvals = new float[3]; |
|
} |
|
int cmax = (r > g) ? r : g; |
|
if (b > cmax) cmax = b; |
|
int cmin = (r < g) ? r : g; |
|
if (b < cmin) cmin = b; |
|
brightness = ((float) cmax) / 255.0f; |
|
if (cmax != 0) |
|
saturation = ((float) (cmax - cmin)) / ((float) cmax); |
|
else |
|
saturation = 0; |
|
if (saturation == 0) |
|
hue = 0; |
|
else { |
|
float redc = ((float) (cmax - r)) / ((float) (cmax - cmin)); |
|
float greenc = ((float) (cmax - g)) / ((float) (cmax - cmin)); |
|
float bluec = ((float) (cmax - b)) / ((float) (cmax - cmin)); |
|
if (r == cmax) |
|
hue = bluec - greenc; |
|
else if (g == cmax) |
|
hue = 2.0f + redc - bluec; |
|
else |
|
hue = 4.0f + greenc - redc; |
|
hue = hue / 6.0f; |
|
if (hue < 0) |
|
hue = hue + 1.0f; |
|
} |
|
hsbvals[0] = hue; |
|
hsbvals[1] = saturation; |
|
hsbvals[2] = brightness; |
|
return hsbvals; |
|
} |
|
/** |
|
* Creates a <code>Color</code> object based on the specified values |
|
* for the HSB color model. |
|
* <p> |
|
* The <code>s</code> and <code>b</code> components should be |
|
* floating-point values between zero and one |
|
* (numbers in the range 0.0-1.0). The <code>h</code> component |
|
* can be any floating-point number. The floor of this number is |
|
* subtracted from it to create a fraction between 0 and 1. This |
|
* fractional number is then multiplied by 360 to produce the hue |
|
* angle in the HSB color model. |
|
* @param h the hue component |
|
* @param s the saturation of the color |
|
* @param b the brightness of the color |
|
* @return a <code>Color</code> object with the specified hue, |
|
* saturation, and brightness. |
|
* @since JDK1.0 |
|
*/ |
|
public static Color getHSBColor(float h, float s, float b) { |
|
return new Color(HSBtoRGB(h, s, b)); |
|
} |
|
/** |
|
* Returns a <code>float</code> array containing the color and alpha |
|
* components of the <code>Color</code>, as represented in the default |
|
* sRGB color space. |
|
* If <code>compArray</code> is <code>null</code>, an array of length |
|
* 4 is created for the return value. Otherwise, |
|
* <code>compArray</code> must have length 4 or greater, |
|
* and it is filled in with the components and returned. |
|
* @param compArray an array that this method fills with |
|
* color and alpha components and returns |
|
* @return the RGBA components in a <code>float</code> array. |
|
*/ |
|
public float[] getRGBComponents(float[] compArray) { |
|
float[] f; |
|
if (compArray == null) { |
|
f = new float[4]; |
|
} else { |
|
f = compArray; |
|
} |
|
if (frgbvalue == null) { |
|
f[0] = ((float)getRed())/255f; |
|
f[1] = ((float)getGreen())/255f; |
|
f[2] = ((float)getBlue())/255f; |
|
f[3] = ((float)getAlpha())/255f; |
|
} else { |
|
f[0] = frgbvalue[0]; |
|
f[1] = frgbvalue[1]; |
|
f[2] = frgbvalue[2]; |
|
f[3] = falpha; |
|
} |
|
return f; |
|
} |
|
/** |
|
* Returns a <code>float</code> array containing only the color |
|
* components of the <code>Color</code>, in the default sRGB color |
|
* space. If <code>compArray</code> is <code>null</code>, an array of |
|
* length 3 is created for the return value. Otherwise, |
|
* <code>compArray</code> must have length 3 or greater, and it is |
|
* filled in with the components and returned. |
|
* @param compArray an array that this method fills with color |
|
* components and returns |
|
* @return the RGB components in a <code>float</code> array. |
|
*/ |
|
public float[] getRGBColorComponents(float[] compArray) { |
|
float[] f; |
|
if (compArray == null) { |
|
f = new float[3]; |
|
} else { |
|
f = compArray; |
|
} |
|
if (frgbvalue == null) { |
|
f[0] = ((float)getRed())/255f; |
|
f[1] = ((float)getGreen())/255f; |
|
f[2] = ((float)getBlue())/255f; |
|
} else { |
|
f[0] = frgbvalue[0]; |
|
f[1] = frgbvalue[1]; |
|
f[2] = frgbvalue[2]; |
|
} |
|
return f; |
|
} |
|
/** |
|
* Returns a <code>float</code> array containing the color and alpha |
|
* components of the <code>Color</code>, in the |
|
* <code>ColorSpace</code> of the <code>Color</code>. |
|
* If <code>compArray</code> is <code>null</code>, an array with |
|
* length equal to the number of components in the associated |
|
* <code>ColorSpace</code> plus one is created for |
|
* the return value. Otherwise, <code>compArray</code> must have at |
|
* least this length and it is filled in with the components and |
|
* returned. |
|
* @param compArray an array that this method fills with the color and |
|
* alpha components of this <code>Color</code> in its |
|
* <code>ColorSpace</code> and returns |
|
* @return the color and alpha components in a <code>float</code> |
|
* array. |
|
*/ |
|
public float[] getComponents(float[] compArray) { |
|
if (fvalue == null) |
|
return getRGBComponents(compArray); |
|
float[] f; |
|
int n = fvalue.length; |
|
if (compArray == null) { |
|
f = new float[n + 1]; |
|
} else { |
|
f = compArray; |
|
} |
|
for (int i = 0; i < n; i++) { |
|
f[i] = fvalue[i]; |
|
} |
|
f[n] = falpha; |
|
return f; |
|
} |
|
/** |
|
* Returns a <code>float</code> array containing only the color |
|
* components of the <code>Color</code>, in the |
|
* <code>ColorSpace</code> of the <code>Color</code>. |
|
* If <code>compArray</code> is <code>null</code>, an array with |
|
* length equal to the number of components in the associated |
|
* <code>ColorSpace</code> is created for |
|
* the return value. Otherwise, <code>compArray</code> must have at |
|
* least this length and it is filled in with the components and |
|
* returned. |
|
* @param compArray an array that this method fills with the color |
|
* components of this <code>Color</code> in its |
|
* <code>ColorSpace</code> and returns |
|
* @return the color components in a <code>float</code> array. |
|
*/ |
|
public float[] getColorComponents(float[] compArray) { |
|
if (fvalue == null) |
|
return getRGBColorComponents(compArray); |
|
float[] f; |
|
int n = fvalue.length; |
|
if (compArray == null) { |
|
f = new float[n]; |
|
} else { |
|
f = compArray; |
|
} |
|
for (int i = 0; i < n; i++) { |
|
f[i] = fvalue[i]; |
|
} |
|
return f; |
|
} |
|
/** |
|
* Returns a <code>float</code> array containing the color and alpha |
|
* components of the <code>Color</code>, in the |
|
* <code>ColorSpace</code> specified by the <code>cspace</code> |
|
* parameter. If <code>compArray</code> is <code>null</code>, an |
|
* array with length equal to the number of components in |
|
* <code>cspace</code> plus one is created for the return value. |
|
* Otherwise, <code>compArray</code> must have at least this |
|
* length, and it is filled in with the components and returned. |
|
* @param cspace a specified <code>ColorSpace</code> |
|
* @param compArray an array that this method fills with the |
|
* color and alpha components of this <code>Color</code> in |
|
* the specified <code>ColorSpace</code> and returns |
|
* @return the color and alpha components in a <code>float</code> |
|
* array. |
|
*/ |
|
public float[] getComponents(ColorSpace cspace, float[] compArray) { |
|
if (cs == null) { |
|
cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); |
|
} |
|
float f[]; |
|
if (fvalue == null) { |
|
f = new float[3]; |
|
f[0] = ((float)getRed())/255f; |
|
f[1] = ((float)getGreen())/255f; |
|
f[2] = ((float)getBlue())/255f; |
|
} else { |
|
f = fvalue; |
|
} |
|
float tmp[] = cs.toCIEXYZ(f); |
|
float tmpout[] = cspace.fromCIEXYZ(tmp); |
|
if (compArray == null) { |
|
compArray = new float[tmpout.length + 1]; |
|
} |
|
for (int i = 0 ; i < tmpout.length ; i++) { |
|
compArray[i] = tmpout[i]; |
|
} |
|
if (fvalue == null) { |
|
compArray[tmpout.length] = ((float)getAlpha())/255f; |
|
} else { |
|
compArray[tmpout.length] = falpha; |
|
} |
|
return compArray; |
|
} |
|
/** |
|
* Returns a <code>float</code> array containing only the color |
|
* components of the <code>Color</code> in the |
|
* <code>ColorSpace</code> specified by the <code>cspace</code> |
|
* parameter. If <code>compArray</code> is <code>null</code>, an array |
|
* with length equal to the number of components in |
|
* <code>cspace</code> is created for the return value. Otherwise, |
|
* <code>compArray</code> must have at least this length, and it is |
|
* filled in with the components and returned. |
|
* @param cspace a specified <code>ColorSpace</code> |
|
* @param compArray an array that this method fills with the color |
|
* components of this <code>Color</code> in the specified |
|
* <code>ColorSpace</code> |
|
* @return the color components in a <code>float</code> array. |
|
*/ |
|
public float[] getColorComponents(ColorSpace cspace, float[] compArray) { |
|
if (cs == null) { |
|
cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); |
|
} |
|
float f[]; |
|
if (fvalue == null) { |
|
f = new float[3]; |
|
f[0] = ((float)getRed())/255f; |
|
f[1] = ((float)getGreen())/255f; |
|
f[2] = ((float)getBlue())/255f; |
|
} else { |
|
f = fvalue; |
|
} |
|
float tmp[] = cs.toCIEXYZ(f); |
|
float tmpout[] = cspace.fromCIEXYZ(tmp); |
|
if (compArray == null) { |
|
return tmpout; |
|
} |
|
for (int i = 0 ; i < tmpout.length ; i++) { |
|
compArray[i] = tmpout[i]; |
|
} |
|
return compArray; |
|
} |
|
/** |
|
* Returns the <code>ColorSpace</code> of this <code>Color</code>. |
|
* @return this <code>Color</code> object's <code>ColorSpace</code>. |
|
*/ |
|
public ColorSpace getColorSpace() { |
|
if (cs == null) { |
|
cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); |
|
} |
|
return cs; |
|
} |
|
/** |
|
* Creates and returns a {@link PaintContext} used to |
|
* generate a solid color field pattern. |
|
* See the {@link Paint#createContext specification} of the |
|
* method in the {@link Paint} interface for information |
|
* on null parameter handling. |
|
* |
|
* @param cm the preferred {@link ColorModel} which represents the most convenient |
|
* format for the caller to receive the pixel data, or {@code null} |
|
* if there is no preference. |
|
* @param r the device space bounding box |
|
* of the graphics primitive being rendered. |
|
* @param r2d the user space bounding box |
|
* of the graphics primitive being rendered. |
|
* @param xform the {@link AffineTransform} from user |
|
* space into device space. |
|
* @param hints the set of hints that the context object can use to |
|
* choose between rendering alternatives. |
|
* @return the {@code PaintContext} for |
|
* generating color patterns. |
|
* @see Paint |
|
* @see PaintContext |
|
* @see ColorModel |
|
* @see Rectangle |
|
* @see Rectangle2D |
|
* @see AffineTransform |
|
* @see RenderingHints |
|
*/ |
|
public synchronized PaintContext createContext(ColorModel cm, Rectangle r, |
|
Rectangle2D r2d, |
|
AffineTransform xform, |
|
RenderingHints hints) { |
|
return new ColorPaintContext(getRGB(), cm); |
|
} |
|
/** |
|
* Returns the transparency mode for this <code>Color</code>. This is |
|
* required to implement the <code>Paint</code> interface. |
|
* @return this <code>Color</code> object's transparency mode. |
|
* @see Paint |
|
* @see Transparency |
|
* @see #createContext |
|
*/ |
|
public int getTransparency() { |
|
int alpha = getAlpha(); |
|
if (alpha == 0xff) { |
|
return Transparency.OPAQUE; |
|
} |
|
else if (alpha == 0) { |
|
return Transparency.BITMASK; |
|
} |
|
else { |
|
return Transparency.TRANSLUCENT; |
|
} |
|
} |
|
} |