991 lines
27 KiB
Java
991 lines
27 KiB
Java
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
* (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/**
|
|
* @author Oleg V. Khaschansky
|
|
* @version $Revision$
|
|
*/
|
|
|
|
package java.awt;
|
|
|
|
import java.awt.color.ColorSpace;
|
|
import java.awt.geom.AffineTransform;
|
|
import java.awt.geom.Rectangle2D;
|
|
import java.awt.image.ColorModel;
|
|
import java.awt.image.DataBufferInt;
|
|
import java.awt.image.Raster;
|
|
import java.awt.image.WritableRaster;
|
|
import java.io.Serializable;
|
|
import java.util.Arrays;
|
|
|
|
import org.apache.harmony.awt.internal.nls.Messages;
|
|
|
|
/**
|
|
* The Color class defines colors in the default sRGB color space or in the
|
|
* specified ColorSpace. Every Color contains alpha value. 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.
|
|
*
|
|
* @since Android 1.0
|
|
*/
|
|
public class Color implements Paint, Serializable {
|
|
|
|
/**
|
|
* The Constant serialVersionUID.
|
|
*/
|
|
private static final long serialVersionUID = 118526816881161077L;
|
|
|
|
/*
|
|
* The values of the following colors are based on 1.5 release behavior
|
|
* which can be revealed using the following or similar code: Color c =
|
|
* Color.white; System.out.println(c);
|
|
*/
|
|
|
|
/**
|
|
* The color white.
|
|
*/
|
|
public static final Color white = new Color(255, 255, 255);
|
|
|
|
/**
|
|
* The color white.
|
|
*/
|
|
public static final Color WHITE = white;
|
|
|
|
/**
|
|
* The color light gray.
|
|
*/
|
|
public static final Color lightGray = new Color(192, 192, 192);
|
|
|
|
/**
|
|
* The color light gray.
|
|
*/
|
|
public static final Color LIGHT_GRAY = lightGray;
|
|
|
|
/**
|
|
* The color gray.
|
|
*/
|
|
public static final Color gray = new Color(128, 128, 128);
|
|
|
|
/**
|
|
* The color gray.
|
|
*/
|
|
public static final Color GRAY = gray;
|
|
|
|
/**
|
|
* The color dark gray.
|
|
*/
|
|
public static final Color darkGray = new Color(64, 64, 64);
|
|
|
|
/**
|
|
* The color dark gray.
|
|
*/
|
|
public static final Color DARK_GRAY = darkGray;
|
|
|
|
/**
|
|
* The color black.
|
|
*/
|
|
public static final Color black = new Color(0, 0, 0);
|
|
|
|
/**
|
|
* The color black.
|
|
*/
|
|
public static final Color BLACK = black;
|
|
|
|
/**
|
|
* The color red.
|
|
*/
|
|
public static final Color red = new Color(255, 0, 0);
|
|
|
|
/**
|
|
* The color red.
|
|
*/
|
|
public static final Color RED = red;
|
|
|
|
/**
|
|
* The color pink.
|
|
*/
|
|
public static final Color pink = new Color(255, 175, 175);
|
|
|
|
/**
|
|
* The color pink.
|
|
*/
|
|
public static final Color PINK = pink;
|
|
|
|
/**
|
|
* The color orange.
|
|
*/
|
|
public static final Color orange = new Color(255, 200, 0);
|
|
|
|
/**
|
|
* The color orange.
|
|
*/
|
|
public static final Color ORANGE = orange;
|
|
|
|
/**
|
|
* The color yellow.
|
|
*/
|
|
public static final Color yellow = new Color(255, 255, 0);
|
|
|
|
/**
|
|
* The color yellow.
|
|
*/
|
|
public static final Color YELLOW = yellow;
|
|
|
|
/**
|
|
* The color green.
|
|
*/
|
|
public static final Color green = new Color(0, 255, 0);
|
|
|
|
/**
|
|
* The color green.
|
|
*/
|
|
public static final Color GREEN = green;
|
|
|
|
/**
|
|
* The color magenta.
|
|
*/
|
|
public static final Color magenta = new Color(255, 0, 255);
|
|
|
|
/**
|
|
* The color magenta.
|
|
*/
|
|
public static final Color MAGENTA = magenta;
|
|
|
|
/**
|
|
* The color cyan.
|
|
*/
|
|
public static final Color cyan = new Color(0, 255, 255);
|
|
|
|
/**
|
|
* The color cyan.
|
|
*/
|
|
public static final Color CYAN = cyan;
|
|
|
|
/**
|
|
* The color blue.
|
|
*/
|
|
public static final Color blue = new Color(0, 0, 255);
|
|
|
|
/**
|
|
* The color blue.
|
|
*/
|
|
public static final Color BLUE = blue;
|
|
|
|
/**
|
|
* integer RGB value.
|
|
*/
|
|
int value;
|
|
|
|
/**
|
|
* Float sRGB value.
|
|
*/
|
|
private float[] frgbvalue;
|
|
|
|
/**
|
|
* Color in an arbitrary color space with <code>float</code> components. If
|
|
* null, other value should be used.
|
|
*/
|
|
private float fvalue[];
|
|
|
|
/**
|
|
* Float alpha value. If frgbvalue is null, this is not valid data.
|
|
*/
|
|
private float falpha;
|
|
|
|
/**
|
|
* The color's color space if applicable.
|
|
*/
|
|
private ColorSpace cs;
|
|
|
|
/*
|
|
* The value of the SCALE_FACTOR is based on 1.5 release behavior which can
|
|
* be revealed using the following code: Color c = new Color(100, 100, 100);
|
|
* Color bc = c.brighter(); System.out.println("Brighter factor: " +
|
|
* ((float)c.getRed())/((float)bc.getRed())); Color dc = c.darker();
|
|
* System.out.println("Darker factor: " +
|
|
* ((float)dc.getRed())/((float)c.getRed())); The result is the same for
|
|
* brighter and darker methods, so we need only one scale factor for both.
|
|
*/
|
|
/**
|
|
* The Constant SCALE_FACTOR.
|
|
*/
|
|
private static final double SCALE_FACTOR = 0.7;
|
|
|
|
/**
|
|
* The Constant MIN_SCALABLE.
|
|
*/
|
|
private static final int MIN_SCALABLE = 3; // should increase when
|
|
|
|
// multiplied by SCALE_FACTOR
|
|
|
|
/**
|
|
* The current paint context.
|
|
*/
|
|
transient private PaintContext currentPaintContext;
|
|
|
|
/**
|
|
* Creates a color in the specified ColorSpace, the specified color
|
|
* components and the specified alpha.
|
|
*
|
|
* @param cspace
|
|
* the ColorSpace to be used to define the components.
|
|
* @param components
|
|
* the components.
|
|
* @param alpha
|
|
* the alpha.
|
|
*/
|
|
public Color(ColorSpace cspace, float[] components, float alpha) {
|
|
int nComps = cspace.getNumComponents();
|
|
float comp;
|
|
fvalue = new float[nComps];
|
|
|
|
for (int i = 0; i < nComps; i++) {
|
|
comp = components[i];
|
|
if (comp < 0.0f || comp > 1.0f) {
|
|
// awt.107=Color parameter outside of expected range: component
|
|
// {0}.
|
|
throw new IllegalArgumentException(Messages.getString("awt.107", i)); //$NON-NLS-1$
|
|
}
|
|
fvalue[i] = components[i];
|
|
}
|
|
|
|
if (alpha < 0.0f || alpha > 1.0f) {
|
|
// awt.108=Alpha value outside of expected range.
|
|
throw new IllegalArgumentException(Messages.getString("awt.108")); //$NON-NLS-1$
|
|
}
|
|
falpha = alpha;
|
|
|
|
cs = cspace;
|
|
|
|
frgbvalue = cs.toRGB(fvalue);
|
|
|
|
value = ((int)(frgbvalue[2] * 255 + 0.5)) | (((int)(frgbvalue[1] * 255 + 0.5)) << 8)
|
|
| (((int)(frgbvalue[0] * 255 + 0.5)) << 16) | (((int)(falpha * 255 + 0.5)) << 24);
|
|
}
|
|
|
|
/**
|
|
* Instantiates a new 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 hasalpha argument is false, the alpha has default value
|
|
* - 255.
|
|
*
|
|
* @param rgba
|
|
* the RGBA components.
|
|
* @param hasAlpha
|
|
* the alpha parameter is true if alpha bits are valid, false
|
|
* otherwise.
|
|
*/
|
|
public Color(int rgba, boolean hasAlpha) {
|
|
if (!hasAlpha) {
|
|
value = rgba | 0xFF000000;
|
|
} else {
|
|
value = rgba;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Instantiates a new color with the specified red, green, blue and alpha
|
|
* components.
|
|
*
|
|
* @param r
|
|
* the red component.
|
|
* @param g
|
|
* the green component.
|
|
* @param b
|
|
* the blue component.
|
|
* @param a
|
|
* the alpha component.
|
|
*/
|
|
public Color(int r, int g, int b, int a) {
|
|
if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b || (a & 0xFF) != a) {
|
|
// awt.109=Color parameter outside of expected range.
|
|
throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
|
|
}
|
|
value = b | (g << 8) | (r << 16) | (a << 24);
|
|
}
|
|
|
|
/**
|
|
* Instantiates a new opaque sRGB color with the specified red, green, and
|
|
* blue values. The Alpha component is set to the default - 1.0.
|
|
*
|
|
* @param r
|
|
* the red component.
|
|
* @param g
|
|
* the green component.
|
|
* @param b
|
|
* the blue component.
|
|
*/
|
|
public Color(int r, int g, int b) {
|
|
if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b) {
|
|
// awt.109=Color parameter outside of expected range.
|
|
throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
|
|
}
|
|
// 0xFF for alpha channel
|
|
value = b | (g << 8) | (r << 16) | 0xFF000000;
|
|
}
|
|
|
|
/**
|
|
* Instantiates a new sRGB color with the specified 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. Alpha has default value - 255.
|
|
*
|
|
* @param rgb
|
|
* the RGB components.
|
|
*/
|
|
public Color(int rgb) {
|
|
value = rgb | 0xFF000000;
|
|
}
|
|
|
|
/**
|
|
* Instantiates a new color with the specified red, green, blue and alpha
|
|
* components.
|
|
*
|
|
* @param r
|
|
* the red component.
|
|
* @param g
|
|
* the green component.
|
|
* @param b
|
|
* the blue component.
|
|
* @param a
|
|
* the alpha component.
|
|
*/
|
|
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));
|
|
falpha = a;
|
|
fvalue = new float[3];
|
|
fvalue[0] = r;
|
|
fvalue[1] = g;
|
|
fvalue[2] = b;
|
|
frgbvalue = fvalue;
|
|
}
|
|
|
|
/**
|
|
* Instantiates a new color with the specified red, green, and blue
|
|
* components and default alpha value - 1.0.
|
|
*
|
|
* @param r
|
|
* the red component.
|
|
* @param g
|
|
* the green component.
|
|
* @param b
|
|
* the blue component.
|
|
*/
|
|
public Color(float r, float g, float b) {
|
|
this(r, g, b, 1.0f);
|
|
}
|
|
|
|
public PaintContext createContext(ColorModel cm, Rectangle r, Rectangle2D r2d,
|
|
AffineTransform xform, RenderingHints rhs) {
|
|
if (currentPaintContext != null) {
|
|
return currentPaintContext;
|
|
}
|
|
currentPaintContext = new Color.ColorPaintContext(value);
|
|
return currentPaintContext;
|
|
}
|
|
|
|
/**
|
|
* Returns a string representation of the Color object.
|
|
*
|
|
* @return the string representation of the Color object.
|
|
*/
|
|
@Override
|
|
public String toString() {
|
|
/*
|
|
* The format of the string is based on 1.5 release behavior which can
|
|
* be revealed using the following code: Color c = new Color(1, 2, 3);
|
|
* System.out.println(c);
|
|
*/
|
|
|
|
return getClass().getName() + "[r=" + getRed() + //$NON-NLS-1$
|
|
",g=" + getGreen() + //$NON-NLS-1$
|
|
",b=" + getBlue() + //$NON-NLS-1$
|
|
"]"; //$NON-NLS-1$
|
|
}
|
|
|
|
/**
|
|
* Compares the specified Object to the Color.
|
|
*
|
|
* @param obj
|
|
* the Object to be compared.
|
|
* @return true, if the specified Object is a Color whose value is equal to
|
|
* this Color, false otherwise.
|
|
*/
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
if (obj instanceof Color) {
|
|
return ((Color)obj).value == this.value;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns a float array containing the color and alpha components of the
|
|
* Color in the specified ColorSpace.
|
|
*
|
|
* @param colorSpace
|
|
* the specified ColorSpace.
|
|
* @param components
|
|
* the results of this method will be written to this float
|
|
* array. If null, a float array will be created.
|
|
* @return the color and alpha components in a float array.
|
|
*/
|
|
public float[] getComponents(ColorSpace colorSpace, float[] components) {
|
|
int nComps = colorSpace.getNumComponents();
|
|
if (components == null) {
|
|
components = new float[nComps + 1];
|
|
}
|
|
|
|
getColorComponents(colorSpace, components);
|
|
|
|
if (frgbvalue != null) {
|
|
components[nComps] = falpha;
|
|
} else {
|
|
components[nComps] = getAlpha() / 255f;
|
|
}
|
|
|
|
return components;
|
|
}
|
|
|
|
/**
|
|
* Returns a float array containing the color components of the Color in the
|
|
* specified ColorSpace.
|
|
*
|
|
* @param colorSpace
|
|
* the specified ColorSpace.
|
|
* @param components
|
|
* the results of this method will be written to this float
|
|
* array. If null, a float array will be created.
|
|
* @return the color components in a float array.
|
|
*/
|
|
public float[] getColorComponents(ColorSpace colorSpace, float[] components) {
|
|
float[] cieXYZComponents = getColorSpace().toCIEXYZ(getColorComponents(null));
|
|
float[] csComponents = colorSpace.fromCIEXYZ(cieXYZComponents);
|
|
|
|
if (components == null) {
|
|
return csComponents;
|
|
}
|
|
|
|
for (int i = 0; i < csComponents.length; i++) {
|
|
components[i] = csComponents[i];
|
|
}
|
|
|
|
return components;
|
|
}
|
|
|
|
/**
|
|
* Gets the ColorSpace of this Color.
|
|
*
|
|
* @return the ColorSpace object.
|
|
*/
|
|
public ColorSpace getColorSpace() {
|
|
if (cs == null) {
|
|
cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
|
}
|
|
|
|
return cs;
|
|
}
|
|
|
|
/**
|
|
* Creates a new Color which is a darker than this Color according to a
|
|
* fixed scale factor.
|
|
*
|
|
* @return the darker Color.
|
|
*/
|
|
public Color darker() {
|
|
return new Color((int)(getRed() * SCALE_FACTOR), (int)(getGreen() * SCALE_FACTOR),
|
|
(int)(getBlue() * SCALE_FACTOR));
|
|
}
|
|
|
|
/**
|
|
* Creates a new Color which is a brighter than this Color.
|
|
*
|
|
* @return the brighter Color.
|
|
*/
|
|
public Color brighter() {
|
|
|
|
int r = getRed();
|
|
int b = getBlue();
|
|
int g = getGreen();
|
|
|
|
if (r == 0 && b == 0 && g == 0) {
|
|
return new Color(MIN_SCALABLE, MIN_SCALABLE, MIN_SCALABLE);
|
|
}
|
|
|
|
if (r < MIN_SCALABLE && r != 0) {
|
|
r = MIN_SCALABLE;
|
|
} else {
|
|
r = (int)(r / SCALE_FACTOR);
|
|
r = (r > 255) ? 255 : r;
|
|
}
|
|
|
|
if (b < MIN_SCALABLE && b != 0) {
|
|
b = MIN_SCALABLE;
|
|
} else {
|
|
b = (int)(b / SCALE_FACTOR);
|
|
b = (b > 255) ? 255 : b;
|
|
}
|
|
|
|
if (g < MIN_SCALABLE && g != 0) {
|
|
g = MIN_SCALABLE;
|
|
} else {
|
|
g = (int)(g / SCALE_FACTOR);
|
|
g = (g > 255) ? 255 : g;
|
|
}
|
|
|
|
return new Color(r, g, b);
|
|
}
|
|
|
|
/**
|
|
* Returns a float array containing the color and alpha components of the
|
|
* Color in the default sRGB color space.
|
|
*
|
|
* @param components
|
|
* the results of this method will be written to this float
|
|
* array. A new float array will be created if this argument is
|
|
* null.
|
|
* @return the RGB color and alpha components in a float array.
|
|
*/
|
|
public float[] getRGBComponents(float[] components) {
|
|
if (components == null) {
|
|
components = new float[4];
|
|
}
|
|
|
|
if (frgbvalue != null) {
|
|
components[3] = falpha;
|
|
} else {
|
|
components[3] = getAlpha() / 255f;
|
|
}
|
|
|
|
getRGBColorComponents(components);
|
|
|
|
return components;
|
|
}
|
|
|
|
/**
|
|
* Returns a float array containing the color components of the Color in the
|
|
* default sRGB color space.
|
|
*
|
|
* @param components
|
|
* the results of this method will be written to this float
|
|
* array. A new float array will be created if this argument is
|
|
* null.
|
|
* @return the RGB color components in a float array.
|
|
*/
|
|
public float[] getRGBColorComponents(float[] components) {
|
|
if (components == null) {
|
|
components = new float[3];
|
|
}
|
|
|
|
if (frgbvalue != null) {
|
|
components[2] = frgbvalue[2];
|
|
components[1] = frgbvalue[1];
|
|
components[0] = frgbvalue[0];
|
|
} else {
|
|
components[2] = getBlue() / 255f;
|
|
components[1] = getGreen() / 255f;
|
|
components[0] = getRed() / 255f;
|
|
}
|
|
|
|
return components;
|
|
}
|
|
|
|
/**
|
|
* Returns a float array which contains the color and alpha components of
|
|
* the Color in the ColorSpace of the Color.
|
|
*
|
|
* @param components
|
|
* the results of this method will be written to this float
|
|
* array. A new float array will be created if this argument is
|
|
* null.
|
|
* @return the color and alpha components in a float array.
|
|
*/
|
|
public float[] getComponents(float[] components) {
|
|
if (fvalue == null) {
|
|
return getRGBComponents(components);
|
|
}
|
|
|
|
int nColorComps = fvalue.length;
|
|
|
|
if (components == null) {
|
|
components = new float[nColorComps + 1];
|
|
}
|
|
|
|
getColorComponents(components);
|
|
|
|
components[nColorComps] = falpha;
|
|
|
|
return components;
|
|
}
|
|
|
|
/**
|
|
* Returns a float array which contains the color components of the Color in
|
|
* the ColorSpace of the Color.
|
|
*
|
|
* @param components
|
|
* the results of this method will be written to this float
|
|
* array. A new float array will be created if this argument is
|
|
* null.
|
|
* @return the color components in a float array.
|
|
*/
|
|
public float[] getColorComponents(float[] components) {
|
|
if (fvalue == null) {
|
|
return getRGBColorComponents(components);
|
|
}
|
|
|
|
if (components == null) {
|
|
components = new float[fvalue.length];
|
|
}
|
|
|
|
for (int i = 0; i < fvalue.length; i++) {
|
|
components[i] = fvalue[i];
|
|
}
|
|
|
|
return components;
|
|
}
|
|
|
|
/**
|
|
* Returns a hash code of this Color object.
|
|
*
|
|
* @return a hash code of this Color object.
|
|
*/
|
|
@Override
|
|
public int hashCode() {
|
|
return value;
|
|
}
|
|
|
|
public int getTransparency() {
|
|
switch (getAlpha()) {
|
|
case 0xff:
|
|
return Transparency.OPAQUE;
|
|
case 0:
|
|
return Transparency.BITMASK;
|
|
default:
|
|
return Transparency.TRANSLUCENT;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the red component of the Color in the range 0-255.
|
|
*
|
|
* @return the red component of the Color.
|
|
*/
|
|
public int getRed() {
|
|
return (value >> 16) & 0xFF;
|
|
}
|
|
|
|
/**
|
|
* Gets the RGB value that represents the color in the default sRGB
|
|
* ColorModel.
|
|
*
|
|
* @return the RGB color value in the default sRGB ColorModel.
|
|
*/
|
|
public int getRGB() {
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Gets the green component of the Color in the range 0-255.
|
|
*
|
|
* @return the green component of the Color.
|
|
*/
|
|
public int getGreen() {
|
|
return (value >> 8) & 0xFF;
|
|
}
|
|
|
|
/**
|
|
* Gets the blue component of the Color in the range 0-255.
|
|
*
|
|
* @return the blue component of the Color.
|
|
*/
|
|
public int getBlue() {
|
|
return value & 0xFF;
|
|
}
|
|
|
|
/**
|
|
* Gets the alpha component of the Color in the range 0-255.
|
|
*
|
|
* @return the alpha component of the Color.
|
|
*/
|
|
public int getAlpha() {
|
|
return (value >> 24) & 0xFF;
|
|
}
|
|
|
|
/**
|
|
* Gets the Color from the specified string, or returns the Color specified
|
|
* by the second parameter.
|
|
*
|
|
* @param nm
|
|
* the specified string.
|
|
* @param def
|
|
* the default Color.
|
|
* @return the color from the specified string, or the Color specified by
|
|
* the second parameter.
|
|
*/
|
|
public static Color getColor(String nm, Color def) {
|
|
Integer integer = Integer.getInteger(nm);
|
|
|
|
if (integer == null) {
|
|
return def;
|
|
}
|
|
|
|
return new Color(integer.intValue());
|
|
}
|
|
|
|
/**
|
|
* Gets the Color from the specified string, or returns the Color converted
|
|
* from the second parameter.
|
|
*
|
|
* @param nm
|
|
* the specified string.
|
|
* @param def
|
|
* the default Color.
|
|
* @return the color from the specified string, or the Color converted from
|
|
* the second parameter.
|
|
*/
|
|
public static Color getColor(String nm, int def) {
|
|
Integer integer = Integer.getInteger(nm);
|
|
|
|
if (integer == null) {
|
|
return new Color(def);
|
|
}
|
|
|
|
return new Color(integer.intValue());
|
|
}
|
|
|
|
/**
|
|
* Gets the Color from the specified String.
|
|
*
|
|
* @param nm
|
|
* the specified string.
|
|
* @return the Color object, or null.
|
|
*/
|
|
public static Color getColor(String nm) {
|
|
Integer integer = Integer.getInteger(nm);
|
|
|
|
if (integer == null) {
|
|
return null;
|
|
}
|
|
|
|
return new Color(integer.intValue());
|
|
}
|
|
|
|
/**
|
|
* Decodes a String to an integer and returns the specified opaque Color.
|
|
*
|
|
* @param nm
|
|
* the String which represents an opaque color as a 24-bit
|
|
* integer.
|
|
* @return the Color object from the given String.
|
|
* @throws NumberFormatException
|
|
* if the specified string can not be converted to an integer.
|
|
*/
|
|
public static Color decode(String nm) throws NumberFormatException {
|
|
Integer integer = Integer.decode(nm);
|
|
return new Color(integer.intValue());
|
|
}
|
|
|
|
/**
|
|
* Gets a Color object using the specified values of the HSB color model.
|
|
*
|
|
* @param h
|
|
* the hue component of the Color.
|
|
* @param s
|
|
* the saturation of the Color.
|
|
* @param b
|
|
* the brightness of the Color.
|
|
* @return a color object with the specified hue, saturation and brightness
|
|
* values.
|
|
*/
|
|
public static Color getHSBColor(float h, float s, float b) {
|
|
return new Color(HSBtoRGB(h, s, b));
|
|
}
|
|
|
|
/**
|
|
* Converts the Color specified by the RGB model to an equivalent color in
|
|
* the HSB model.
|
|
*
|
|
* @param r
|
|
* the red component.
|
|
* @param g
|
|
* the green component.
|
|
* @param b
|
|
* the blue component.
|
|
* @param hsbvals
|
|
* the array of result hue, saturation, brightness values or
|
|
* null.
|
|
* @return the float array of hue, saturation, brightness values.
|
|
*/
|
|
public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
|
|
if (hsbvals == null) {
|
|
hsbvals = new float[3];
|
|
}
|
|
|
|
int V = Math.max(b, Math.max(r, g));
|
|
int temp = Math.min(b, Math.min(r, g));
|
|
|
|
float H, S, B;
|
|
|
|
B = V / 255.f;
|
|
|
|
if (V == temp) {
|
|
H = S = 0;
|
|
} else {
|
|
S = (V - temp) / ((float)V);
|
|
|
|
float Cr = (V - r) / (float)(V - temp);
|
|
float Cg = (V - g) / (float)(V - temp);
|
|
float Cb = (V - b) / (float)(V - temp);
|
|
|
|
if (r == V) {
|
|
H = Cb - Cg;
|
|
} else if (g == V) {
|
|
H = 2 + Cr - Cb;
|
|
} else {
|
|
H = 4 + Cg - Cr;
|
|
}
|
|
|
|
H /= 6.f;
|
|
if (H < 0) {
|
|
H++;
|
|
}
|
|
}
|
|
|
|
hsbvals[0] = H;
|
|
hsbvals[1] = S;
|
|
hsbvals[2] = B;
|
|
|
|
return hsbvals;
|
|
}
|
|
|
|
/**
|
|
* Converts the Color specified by the HSB model to an equivalent color in
|
|
* the default RGB model.
|
|
*
|
|
* @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 specified hue, saturation and
|
|
* brightness.
|
|
*/
|
|
public static int HSBtoRGB(float hue, float saturation, float brightness) {
|
|
float fr, fg, fb;
|
|
|
|
if (saturation == 0) {
|
|
fr = fg = fb = brightness;
|
|
} else {
|
|
float H = (hue - (float)Math.floor(hue)) * 6;
|
|
int I = (int)Math.floor(H);
|
|
float F = H - I;
|
|
float M = brightness * (1 - saturation);
|
|
float N = brightness * (1 - saturation * F);
|
|
float K = brightness * (1 - saturation * (1 - F));
|
|
|
|
switch (I) {
|
|
case 0:
|
|
fr = brightness;
|
|
fg = K;
|
|
fb = M;
|
|
break;
|
|
case 1:
|
|
fr = N;
|
|
fg = brightness;
|
|
fb = M;
|
|
break;
|
|
case 2:
|
|
fr = M;
|
|
fg = brightness;
|
|
fb = K;
|
|
break;
|
|
case 3:
|
|
fr = M;
|
|
fg = N;
|
|
fb = brightness;
|
|
break;
|
|
case 4:
|
|
fr = K;
|
|
fg = M;
|
|
fb = brightness;
|
|
break;
|
|
case 5:
|
|
fr = brightness;
|
|
fg = M;
|
|
fb = N;
|
|
break;
|
|
default:
|
|
fr = fb = fg = 0; // impossible, to supress compiler error
|
|
}
|
|
}
|
|
|
|
int r = (int)(fr * 255. + 0.5);
|
|
int g = (int)(fg * 255. + 0.5);
|
|
int b = (int)(fb * 255. + 0.5);
|
|
|
|
return (r << 16) | (g << 8) | b | 0xFF000000;
|
|
}
|
|
|
|
/**
|
|
* The Class ColorPaintContext.
|
|
*/
|
|
class ColorPaintContext implements PaintContext {
|
|
|
|
/**
|
|
* The RGB value.
|
|
*/
|
|
int rgbValue;
|
|
|
|
/**
|
|
* The saved raster.
|
|
*/
|
|
WritableRaster savedRaster = null;
|
|
|
|
/**
|
|
* Instantiates a new color paint context.
|
|
*
|
|
* @param rgb
|
|
* the RGB value.
|
|
*/
|
|
protected ColorPaintContext(int rgb) {
|
|
rgbValue = rgb;
|
|
}
|
|
|
|
public void dispose() {
|
|
savedRaster = null;
|
|
}
|
|
|
|
public ColorModel getColorModel() {
|
|
return ColorModel.getRGBdefault();
|
|
}
|
|
|
|
public Raster getRaster(int x, int y, int w, int h) {
|
|
if (savedRaster == null || w != savedRaster.getWidth() || h != savedRaster.getHeight()) {
|
|
savedRaster = getColorModel().createCompatibleWritableRaster(w, h);
|
|
|
|
// Suppose we have here simple INT/RGB color/sample model
|
|
DataBufferInt intBuffer = (DataBufferInt)savedRaster.getDataBuffer();
|
|
int rgbValues[] = intBuffer.getData();
|
|
int rgbFillValue = rgbValue;
|
|
Arrays.fill(rgbValues, rgbFillValue);
|
|
}
|
|
|
|
return savedRaster;
|
|
}
|
|
}
|
|
}
|