0001 /*
0002 * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package java.awt;
0027
0028 import java.beans.ConstructorProperties;
0029 import java.awt.image.ColorModel;
0030 import java.awt.geom.AffineTransform;
0031 import java.awt.geom.Rectangle2D;
0032 import java.awt.color.ColorSpace;
0033
0034 /**
0035 * The <code>Color</code> class is used to encapsulate colors in the default
0036 * sRGB color space or colors in arbitrary color spaces identified by a
0037 * {@link ColorSpace}. Every color has an implicit alpha value of 1.0 or
0038 * an explicit one provided in the constructor. The alpha value
0039 * defines the transparency of a color and can be represented by
0040 * a float value in the range 0.0 - 1.0 or 0 - 255.
0041 * An alpha value of 1.0 or 255 means that the color is completely
0042 * opaque and an alpha value of 0 or 0.0 means that the color is
0043 * completely transparent.
0044 * When constructing a <code>Color</code> with an explicit alpha or
0045 * getting the color/alpha components of a <code>Color</code>, the color
0046 * components are never premultiplied by the alpha component.
0047 * <p>
0048 * The default color space for the Java 2D(tm) API is sRGB, a proposed
0049 * standard RGB color space. For further information on sRGB,
0050 * see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
0051 * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
0052 * </A>.
0053 * <p>
0054 * @version 10 Feb 1997
0055 * @author Sami Shaio
0056 * @author Arthur van Hoff
0057 * @see ColorSpace
0058 * @see AlphaComposite
0059 */
0060 public class Color implements Paint, java.io.Serializable {
0061
0062 /**
0063 * The color white. In the default sRGB space.
0064 */
0065 public final static Color white = new Color(255, 255, 255);
0066
0067 /**
0068 * The color white. In the default sRGB space.
0069 * @since 1.4
0070 */
0071 public final static Color WHITE = white;
0072
0073 /**
0074 * The color light gray. In the default sRGB space.
0075 */
0076 public final static Color lightGray = new Color(192, 192, 192);
0077
0078 /**
0079 * The color light gray. In the default sRGB space.
0080 * @since 1.4
0081 */
0082 public final static Color LIGHT_GRAY = lightGray;
0083
0084 /**
0085 * The color gray. In the default sRGB space.
0086 */
0087 public final static Color gray = new Color(128, 128, 128);
0088
0089 /**
0090 * The color gray. In the default sRGB space.
0091 * @since 1.4
0092 */
0093 public final static Color GRAY = gray;
0094
0095 /**
0096 * The color dark gray. In the default sRGB space.
0097 */
0098 public final static Color darkGray = new Color(64, 64, 64);
0099
0100 /**
0101 * The color dark gray. In the default sRGB space.
0102 * @since 1.4
0103 */
0104 public final static Color DARK_GRAY = darkGray;
0105
0106 /**
0107 * The color black. In the default sRGB space.
0108 */
0109 public final static Color black = new Color(0, 0, 0);
0110
0111 /**
0112 * The color black. In the default sRGB space.
0113 * @since 1.4
0114 */
0115 public final static Color BLACK = black;
0116
0117 /**
0118 * The color red. In the default sRGB space.
0119 */
0120 public final static Color red = new Color(255, 0, 0);
0121
0122 /**
0123 * The color red. In the default sRGB space.
0124 * @since 1.4
0125 */
0126 public final static Color RED = red;
0127
0128 /**
0129 * The color pink. In the default sRGB space.
0130 */
0131 public final static Color pink = new Color(255, 175, 175);
0132
0133 /**
0134 * The color pink. In the default sRGB space.
0135 * @since 1.4
0136 */
0137 public final static Color PINK = pink;
0138
0139 /**
0140 * The color orange. In the default sRGB space.
0141 */
0142 public final static Color orange = new Color(255, 200, 0);
0143
0144 /**
0145 * The color orange. In the default sRGB space.
0146 * @since 1.4
0147 */
0148 public final static Color ORANGE = orange;
0149
0150 /**
0151 * The color yellow. In the default sRGB space.
0152 */
0153 public final static Color yellow = new Color(255, 255, 0);
0154
0155 /**
0156 * The color yellow. In the default sRGB space.
0157 * @since 1.4
0158 */
0159 public final static Color YELLOW = yellow;
0160
0161 /**
0162 * The color green. In the default sRGB space.
0163 */
0164 public final static Color green = new Color(0, 255, 0);
0165
0166 /**
0167 * The color green. In the default sRGB space.
0168 * @since 1.4
0169 */
0170 public final static Color GREEN = green;
0171
0172 /**
0173 * The color magenta. In the default sRGB space.
0174 */
0175 public final static Color magenta = new Color(255, 0, 255);
0176
0177 /**
0178 * The color magenta. In the default sRGB space.
0179 * @since 1.4
0180 */
0181 public final static Color MAGENTA = magenta;
0182
0183 /**
0184 * The color cyan. In the default sRGB space.
0185 */
0186 public final static Color cyan = new Color(0, 255, 255);
0187
0188 /**
0189 * The color cyan. In the default sRGB space.
0190 * @since 1.4
0191 */
0192 public final static Color CYAN = cyan;
0193
0194 /**
0195 * The color blue. In the default sRGB space.
0196 */
0197 public final static Color blue = new Color(0, 0, 255);
0198
0199 /**
0200 * The color blue. In the default sRGB space.
0201 * @since 1.4
0202 */
0203 public final static Color BLUE = blue;
0204
0205 /**
0206 * The color value.
0207 * @serial
0208 * @see #getRGB
0209 */
0210 int value;
0211
0212 /**
0213 * The color value in the default sRGB <code>ColorSpace</code> as
0214 * <code>float</code> components (no alpha).
0215 * If <code>null</code> after object construction, this must be an
0216 * sRGB color constructed with 8-bit precision, so compute from the
0217 * <code>int</code> color value.
0218 * @serial
0219 * @see #getRGBColorComponents
0220 * @see #getRGBComponents
0221 */
0222 private float frgbvalue[] = null;
0223
0224 /**
0225 * The color value in the native <code>ColorSpace</code> as
0226 * <code>float</code> components (no alpha).
0227 * If <code>null</code> after object construction, this must be an
0228 * sRGB color constructed with 8-bit precision, so compute from the
0229 * <code>int</code> color value.
0230 * @serial
0231 * @see #getRGBColorComponents
0232 * @see #getRGBComponents
0233 */
0234 private float fvalue[] = null;
0235
0236 /**
0237 * The alpha value as a <code>float</code> component.
0238 * If <code>frgbvalue</code> is <code>null</code>, this is not valid
0239 * data, so compute from the <code>int</code> color value.
0240 * @serial
0241 * @see #getRGBComponents
0242 * @see #getComponents
0243 */
0244 private float falpha = 0.0f;
0245
0246 /**
0247 * The <code>ColorSpace</code>. If <code>null</code>, then it's
0248 * default is sRGB.
0249 * @serial
0250 * @see #getColor
0251 * @see #getColorSpace
0252 * @see #getColorComponents
0253 */
0254 private ColorSpace cs = null;
0255
0256 /*
0257 * JDK 1.1 serialVersionUID
0258 */
0259 private static final long serialVersionUID = 118526816881161077L;
0260
0261 /**
0262 * Initialize JNI field and method IDs
0263 */
0264 private static native void initIDs();
0265
0266 static {
0267 /** 4112352 - Calling getDefaultToolkit()
0268 ** here can cause this class to be accessed before it is fully
0269 ** initialized. DON'T DO IT!!!
0270 **
0271 ** Toolkit.getDefaultToolkit();
0272 **/
0273
0274 /* ensure that the necessary native libraries are loaded */
0275 Toolkit.loadLibraries();
0276 if (!GraphicsEnvironment.isHeadless()) {
0277 initIDs();
0278 }
0279 }
0280
0281 /**
0282 * Checks the color integer components supplied for validity.
0283 * Throws an {@link IllegalArgumentException} if the value is out of
0284 * range.
0285 * @param r the Red component
0286 * @param g the Green component
0287 * @param b the Blue component
0288 **/
0289 private static void testColorValueRange(int r, int g, int b, int a) {
0290 boolean rangeError = false;
0291 String badComponentString = "";
0292
0293 if (a < 0 || a > 255) {
0294 rangeError = true;
0295 badComponentString = badComponentString + " Alpha";
0296 }
0297 if (r < 0 || r > 255) {
0298 rangeError = true;
0299 badComponentString = badComponentString + " Red";
0300 }
0301 if (g < 0 || g > 255) {
0302 rangeError = true;
0303 badComponentString = badComponentString + " Green";
0304 }
0305 if (b < 0 || b > 255) {
0306 rangeError = true;
0307 badComponentString = badComponentString + " Blue";
0308 }
0309 if (rangeError == true) {
0310 throw new IllegalArgumentException(
0311 "Color parameter outside of expected range:"
0312 + badComponentString);
0313 }
0314 }
0315
0316 /**
0317 * Checks the color <code>float</code> components supplied for
0318 * validity.
0319 * Throws an <code>IllegalArgumentException</code> if the value is out
0320 * of range.
0321 * @param r the Red component
0322 * @param g the Green component
0323 * @param b the Blue component
0324 **/
0325 private static void testColorValueRange(float r, float g, float b,
0326 float a) {
0327 boolean rangeError = false;
0328 String badComponentString = "";
0329 if (a < 0.0 || a > 1.0) {
0330 rangeError = true;
0331 badComponentString = badComponentString + " Alpha";
0332 }
0333 if (r < 0.0 || r > 1.0) {
0334 rangeError = true;
0335 badComponentString = badComponentString + " Red";
0336 }
0337 if (g < 0.0 || g > 1.0) {
0338 rangeError = true;
0339 badComponentString = badComponentString + " Green";
0340 }
0341 if (b < 0.0 || b > 1.0) {
0342 rangeError = true;
0343 badComponentString = badComponentString + " Blue";
0344 }
0345 if (rangeError == true) {
0346 throw new IllegalArgumentException(
0347 "Color parameter outside of expected range:"
0348 + badComponentString);
0349 }
0350 }
0351
0352 /**
0353 * Creates an opaque sRGB color with the specified red, green,
0354 * and blue values in the range (0 - 255).
0355 * The actual color used in rendering depends
0356 * on finding the best match given the color space
0357 * available for a given output device.
0358 * Alpha is defaulted to 255.
0359 *
0360 * @throws IllegalArgumentException if <code>r</code>, <code>g</code>
0361 * or <code>b</code> are outside of the range
0362 * 0 to 255, inclusive
0363 * @param r the red component
0364 * @param g the green component
0365 * @param b the blue component
0366 * @see #getRed
0367 * @see #getGreen
0368 * @see #getBlue
0369 * @see #getRGB
0370 */
0371 public Color(int r, int g, int b) {
0372 this (r, g, b, 255);
0373 }
0374
0375 /**
0376 * Creates an sRGB color with the specified red, green, blue, and alpha
0377 * values in the range (0 - 255).
0378 *
0379 * @throws IllegalArgumentException if <code>r</code>, <code>g</code>,
0380 * <code>b</code> or <code>a</code> are outside of the range
0381 * 0 to 255, inclusive
0382 * @param r the red component
0383 * @param g the green component
0384 * @param b the blue component
0385 * @param a the alpha component
0386 * @see #getRed
0387 * @see #getGreen
0388 * @see #getBlue
0389 * @see #getAlpha
0390 * @see #getRGB
0391 */
0392 @ConstructorProperties({"red","green","blue","alpha"})
0393 public Color(int r, int g, int b, int a) {
0394 value = ((a & 0xFF) << 24) | ((r & 0xFF) << 16)
0395 | ((g & 0xFF) << 8) | ((b & 0xFF) << 0);
0396 testColorValueRange(r, g, b, a);
0397 }
0398
0399 /**
0400 * Creates an opaque sRGB color with the specified combined RGB value
0401 * consisting of the red component in bits 16-23, the green component
0402 * in bits 8-15, and the blue component in bits 0-7. The actual color
0403 * used in rendering depends on finding the best match given the
0404 * color space available for a particular output device. Alpha is
0405 * defaulted to 255.
0406 *
0407 * @param rgb the combined RGB components
0408 * @see java.awt.image.ColorModel#getRGBdefault
0409 * @see #getRed
0410 * @see #getGreen
0411 * @see #getBlue
0412 * @see #getRGB
0413 */
0414 public Color(int rgb) {
0415 value = 0xff000000 | rgb;
0416 }
0417
0418 /**
0419 * Creates an sRGB color with the specified combined RGBA value consisting
0420 * of the alpha component in bits 24-31, the red component in bits 16-23,
0421 * the green component in bits 8-15, and the blue component in bits 0-7.
0422 * If the <code>hasalpha</code> argument is <code>false</code>, alpha
0423 * is defaulted to 255.
0424 *
0425 * @param rgba the combined RGBA components
0426 * @param hasalpha <code>true</code> if the alpha bits are valid;
0427 * <code>false</code> otherwise
0428 * @see java.awt.image.ColorModel#getRGBdefault
0429 * @see #getRed
0430 * @see #getGreen
0431 * @see #getBlue
0432 * @see #getAlpha
0433 * @see #getRGB
0434 */
0435 public Color(int rgba, boolean hasalpha) {
0436 if (hasalpha) {
0437 value = rgba;
0438 } else {
0439 value = 0xff000000 | rgba;
0440 }
0441 }
0442
0443 /**
0444 * Creates an opaque sRGB color with the specified red, green, and blue
0445 * values in the range (0.0 - 1.0). Alpha is defaulted to 1.0. The
0446 * actual color used in rendering depends on finding the best
0447 * match given the color space available for a particular output
0448 * device.
0449 *
0450 * @throws IllegalArgumentException if <code>r</code>, <code>g</code>
0451 * or <code>b</code> are outside of the range
0452 * 0.0 to 1.0, inclusive
0453 * @param r the red component
0454 * @param g the green component
0455 * @param b the blue component
0456 * @see #getRed
0457 * @see #getGreen
0458 * @see #getBlue
0459 * @see #getRGB
0460 */
0461 public Color(float r, float g, float b) {
0462 this ((int) (r * 255 + 0.5), (int) (g * 255 + 0.5),
0463 (int) (b * 255 + 0.5));
0464 testColorValueRange(r, g, b, 1.0f);
0465 frgbvalue = new float[3];
0466 frgbvalue[0] = r;
0467 frgbvalue[1] = g;
0468 frgbvalue[2] = b;
0469 falpha = 1.0f;
0470 fvalue = frgbvalue;
0471 }
0472
0473 /**
0474 * Creates an sRGB color with the specified red, green, blue, and
0475 * alpha values in the range (0.0 - 1.0). The actual color
0476 * used in rendering depends on finding the best match given the
0477 * color space available for a particular output device.
0478 * @throws IllegalArgumentException if <code>r</code>, <code>g</code>
0479 * <code>b</code> or <code>a</code> are outside of the range
0480 * 0.0 to 1.0, inclusive
0481 * @param r the red component
0482 * @param g the green component
0483 * @param b the blue component
0484 * @param a the alpha component
0485 * @see #getRed
0486 * @see #getGreen
0487 * @see #getBlue
0488 * @see #getAlpha
0489 * @see #getRGB
0490 */
0491 public Color(float r, float g, float b, float a) {
0492 this ((int) (r * 255 + 0.5), (int) (g * 255 + 0.5),
0493 (int) (b * 255 + 0.5), (int) (a * 255 + 0.5));
0494 frgbvalue = new float[3];
0495 frgbvalue[0] = r;
0496 frgbvalue[1] = g;
0497 frgbvalue[2] = b;
0498 falpha = a;
0499 fvalue = frgbvalue;
0500 }
0501
0502 /**
0503 * Creates a color in the specified <code>ColorSpace</code>
0504 * with the color components specified in the <code>float</code>
0505 * array and the specified alpha. The number of components is
0506 * determined by the type of the <code>ColorSpace</code>. For
0507 * example, RGB requires 3 components, but CMYK requires 4
0508 * components.
0509 * @param cspace the <code>ColorSpace</code> to be used to
0510 * interpret the components
0511 * @param components an arbitrary number of color components
0512 * that is compatible with the <code>ColorSpace</code>
0513 * @param alpha alpha value
0514 * @throws IllegalArgumentException if any of the values in the
0515 * <code>components</code> array or <code>alpha</code> is
0516 * outside of the range 0.0 to 1.0
0517 * @see #getComponents
0518 * @see #getColorComponents
0519 */
0520 public Color(ColorSpace cspace, float components[], float alpha) {
0521 boolean rangeError = false;
0522 String badComponentString = "";
0523 int n = cspace.getNumComponents();
0524 fvalue = new float[n];
0525 for (int i = 0; i < n; i++) {
0526 if (components[i] < 0.0 || components[i] > 1.0) {
0527 rangeError = true;
0528 badComponentString = badComponentString + "Component "
0529 + i + " ";
0530 } else {
0531 fvalue[i] = components[i];
0532 }
0533 }
0534 if (alpha < 0.0 || alpha > 1.0) {
0535 rangeError = true;
0536 badComponentString = badComponentString + "Alpha";
0537 } else {
0538 falpha = alpha;
0539 }
0540 if (rangeError) {
0541 throw new IllegalArgumentException(
0542 "Color parameter outside of expected range: "
0543 + badComponentString);
0544 }
0545 frgbvalue = cspace.toRGB(fvalue);
0546 cs = cspace;
0547 value = ((((int) (falpha * 255)) & 0xFF) << 24)
0548 | ((((int) (frgbvalue[0] * 255)) & 0xFF) << 16)
0549 | ((((int) (frgbvalue[1] * 255)) & 0xFF) << 8)
0550 | ((((int) (frgbvalue[2] * 255)) & 0xFF) << 0);
0551 }
0552
0553 /**
0554 * Returns the red component in the range 0-255 in the default sRGB
0555 * space.
0556 * @return the red component.
0557 * @see #getRGB
0558 */
0559 public int getRed() {
0560 return (getRGB() >> 16) & 0xFF;
0561 }
0562
0563 /**
0564 * Returns the green component in the range 0-255 in the default sRGB
0565 * space.
0566 * @return the green component.
0567 * @see #getRGB
0568 */
0569 public int getGreen() {
0570 return (getRGB() >> 8) & 0xFF;
0571 }
0572
0573 /**
0574 * Returns the blue component in the range 0-255 in the default sRGB
0575 * space.
0576 * @return the blue component.
0577 * @see #getRGB
0578 */
0579 public int getBlue() {
0580 return (getRGB() >> 0) & 0xFF;
0581 }
0582
0583 /**
0584 * Returns the alpha component in the range 0-255.
0585 * @return the alpha component.
0586 * @see #getRGB
0587 */
0588 public int getAlpha() {
0589 return (getRGB() >> 24) & 0xff;
0590 }
0591
0592 /**
0593 * Returns the RGB value representing the color in the default sRGB
0594 * {@link ColorModel}.
0595 * (Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are
0596 * blue).
0597 * @return the RGB value of the color in the default sRGB
0598 * <code>ColorModel</code>.
0599 * @see java.awt.image.ColorModel#getRGBdefault
0600 * @see #getRed
0601 * @see #getGreen
0602 * @see #getBlue
0603 * @since JDK1.0
0604 */
0605 public int getRGB() {
0606 return value;
0607 }
0608
0609 private static final double FACTOR = 0.7;
0610
0611 /**
0612 * Creates a new <code>Color</code> that is a brighter version of this
0613 * <code>Color</code>.
0614 * <p>
0615 * This method applies an arbitrary scale factor to each of the three RGB
0616 * components of this <code>Color</code> to create a brighter version
0617 * of this <code>Color</code>. Although <code>brighter</code> and
0618 * <code>darker</code> are inverse operations, the results of a
0619 * series of invocations of these two methods might be inconsistent
0620 * because of rounding errors.
0621 * @return a new <code>Color</code> object that is
0622 * a brighter version of this <code>Color</code>.
0623 * @see java.awt.Color#darker
0624 * @since JDK1.0
0625 */
0626 public Color brighter() {
0627 int r = getRed();
0628 int g = getGreen();
0629 int b = getBlue();
0630
0631 /* From 2D group:
0632 * 1. black.brighter() should return grey
0633 * 2. applying brighter to blue will always return blue, brighter
0634 * 3. non pure color (non zero rgb) will eventually return white
0635 */
0636 int i = (int) (1.0 / (1.0 - FACTOR));
0637 if (r == 0 && g == 0 && b == 0) {
0638 return new Color(i, i, i);
0639 }
0640 if (r > 0 && r < i)
0641 r = i;
0642 if (g > 0 && g < i)
0643 g = i;
0644 if (b > 0 && b < i)
0645 b = i;
0646
0647 return new Color(Math.min((int) (r / FACTOR), 255), Math.min(
0648 (int) (g / FACTOR), 255), Math.min((int) (b / FACTOR),
0649 255));
0650 }
0651
0652 /**
0653 * Creates a new <code>Color</code> that is a darker version of this
0654 * <code>Color</code>.
0655 * <p>
0656 * This method applies an arbitrary scale factor to each of the three RGB
0657 * components of this <code>Color</code> to create a darker version of
0658 * this <code>Color</code>. Although <code>brighter</code> and
0659 * <code>darker</code> are inverse operations, the results of a series
0660 * of invocations of these two methods might be inconsistent because
0661 * of rounding errors.
0662 * @return a new <code>Color</code> object that is
0663 * a darker version of this <code>Color</code>.
0664 * @see java.awt.Color#brighter
0665 * @since JDK1.0
0666 */
0667 public Color darker() {
0668 return new Color(Math.max((int) (getRed() * FACTOR), 0), Math
0669 .max((int) (getGreen() * FACTOR), 0), Math.max(
0670 (int) (getBlue() * FACTOR), 0));
0671 }
0672
0673 /**
0674 * Computes the hash code for this <code>Color</code>.
0675 * @return a hash code value for this object.
0676 * @since JDK1.0
0677 */
0678 public int hashCode() {
0679 return value;
0680 }
0681
0682 /**
0683 * Determines whether another object is equal to this
0684 * <code>Color</code>.
0685 * <p>
0686 * The result is <code>true</code> if and only if the argument is not
0687 * <code>null</code> and is a <code>Color</code> object that has the same
0688 * red, green, blue, and alpha values as this object.
0689 * @param obj the object to test for equality with this
0690 * <code>Color</code>
0691 * @return <code>true</code> if the objects are the same;
0692 * <code>false</code> otherwise.
0693 * @since JDK1.0
0694 */
0695 public boolean equals(Object obj) {
0696 return obj instanceof Color
0697 && ((Color) obj).value == this .value;
0698 }
0699
0700 /**
0701 * Returns a string representation of this <code>Color</code>. This
0702 * method is intended to be used only for debugging purposes. The
0703 * content and format of the returned string might vary between
0704 * implementations. The returned string might be empty but cannot
0705 * be <code>null</code>.
0706 *
0707 * @return a string representation of this <code>Color</code>.
0708 */
0709 public String toString() {
0710 return getClass().getName() + "[r=" + getRed() + ",g="
0711 + getGreen() + ",b=" + getBlue() + "]";
0712 }
0713
0714 /**
0715 * Converts a <code>String</code> to an integer and returns the
0716 * specified opaque <code>Color</code>. This method handles string
0717 * formats that are used to represent octal and hexadecimal numbers.
0718 * @param nm a <code>String</code> that represents
0719 * an opaque color as a 24-bit integer
0720 * @return the new <code>Color</code> object.
0721 * @see java.lang.Integer#decode
0722 * @exception NumberFormatException if the specified string cannot
0723 * be interpreted as a decimal,
0724 * octal, or hexadecimal integer.
0725 * @since JDK1.1
0726 */
0727 public static Color decode(String nm) throws NumberFormatException {
0728 Integer intval = Integer.decode(nm);
0729 int i = intval.intValue();
0730 return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF);
0731 }
0732
0733 /**
0734 * Finds a color in the system properties.
0735 * <p>
0736 * The argument is treated as the name of a system property to
0737 * be obtained. The string value of this property is then interpreted
0738 * as an integer which is then converted to a <code>Color</code>
0739 * object.
0740 * <p>
0741 * If the specified property is not found or could not be parsed as
0742 * an integer then <code>null</code> is returned.
0743 * @param nm the name of the color property
0744 * @return the <code>Color</code> converted from the system
0745 * property.
0746 * @see java.lang.System#getProperty(java.lang.String)
0747 * @see java.lang.Integer#getInteger(java.lang.String)
0748 * @see java.awt.Color#Color(int)
0749 * @since JDK1.0
0750 */
0751 public static Color getColor(String nm) {
0752 return getColor(nm, null);
0753 }
0754
0755 /**
0756 * Finds a color in the system properties.
0757 * <p>
0758 * The first argument is treated as the name of a system property to
0759 * be obtained. The string value of this property is then interpreted
0760 * as an integer which is then converted to a <code>Color</code>
0761 * object.
0762 * <p>
0763 * If the specified property is not found or cannot be parsed as
0764 * an integer then the <code>Color</code> specified by the second
0765 * argument is returned instead.
0766 * @param nm the name of the color property
0767 * @param v the default <code>Color</code>
0768 * @return the <code>Color</code> converted from the system
0769 * property, or the specified <code>Color</code>.
0770 * @see java.lang.System#getProperty(java.lang.String)
0771 * @see java.lang.Integer#getInteger(java.lang.String)
0772 * @see java.awt.Color#Color(int)
0773 * @since JDK1.0
0774 */
0775 public static Color getColor(String nm, Color v) {
0776 Integer intval = Integer.getInteger(nm);
0777 if (intval == null) {
0778 return v;
0779 }
0780 int i = intval.intValue();
0781 return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF);
0782 }
0783
0784 /**
0785 * Finds a color in the system properties.
0786 * <p>
0787 * The first argument is treated as the name of a system property to
0788 * be obtained. The string value of this property is then interpreted
0789 * as an integer which is then converted to a <code>Color</code>
0790 * object.
0791 * <p>
0792 * If the specified property is not found or could not be parsed as
0793 * an integer then the integer value <code>v</code> is used instead,
0794 * and is converted to a <code>Color</code> object.
0795 * @param nm the name of the color property
0796 * @param v the default color value, as an integer
0797 * @return the <code>Color</code> converted from the system
0798 * property or the <code>Color</code> converted from
0799 * the specified integer.
0800 * @see java.lang.System#getProperty(java.lang.String)
0801 * @see java.lang.Integer#getInteger(java.lang.String)
0802 * @see java.awt.Color#Color(int)
0803 * @since JDK1.0
0804 */
0805 public static Color getColor(String nm, int v) {
0806 Integer intval = Integer.getInteger(nm);
0807 int i = (intval != null) ? intval.intValue() : v;
0808 return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF,
0809 (i >> 0) & 0xFF);
0810 }
0811
0812 /**
0813 * Converts the components of a color, as specified by the HSB
0814 * model, to an equivalent set of values for the default RGB model.
0815 * <p>
0816 * The <code>saturation</code> and <code>brightness</code> components
0817 * should be floating-point values between zero and one
0818 * (numbers in the range 0.0-1.0). The <code>hue</code> component
0819 * can be any floating-point number. The floor of this number is
0820 * subtracted from it to create a fraction between 0 and 1. This
0821 * fractional number is then multiplied by 360 to produce the hue
0822 * angle in the HSB color model.
0823 * <p>
0824 * The integer that is returned by <code>HSBtoRGB</code> encodes the
0825 * value of a color in bits 0-23 of an integer value that is the same
0826 * format used by the method {@link #getRGB() <code>getRGB</code>}.
0827 * This integer can be supplied as an argument to the
0828 * <code>Color</code> constructor that takes a single integer argument.
0829 * @param hue the hue component of the color
0830 * @param saturation the saturation of the color
0831 * @param brightness the brightness of the color
0832 * @return the RGB value of the color with the indicated hue,
0833 * saturation, and brightness.
0834 * @see java.awt.Color#getRGB()
0835 * @see java.awt.Color#Color(int)
0836 * @see java.awt.image.ColorModel#getRGBdefault()
0837 * @since JDK1.0
0838 */
0839 public static int HSBtoRGB(float hue, float saturation,
0840 float brightness) {
0841 int r = 0, g = 0, b = 0;
0842 if (saturation == 0) {
0843 r = g = b = (int) (brightness * 255.0f + 0.5f);
0844 } else {
0845 float h = (hue - (float) Math.floor(hue)) * 6.0f;
0846 float f = h - (float) java.lang.Math.floor(h);
0847 float p = brightness * (1.0f - saturation);
0848 float q = brightness * (1.0f - saturation * f);
0849 float t = brightness * (1.0f - (saturation * (1.0f - f)));
0850 switch ((int) h) {
0851 case 0:
0852 r = (int) (brightness * 255.0f + 0.5f);
0853 g = (int) (t * 255.0f + 0.5f);
0854 b = (int) (p * 255.0f + 0.5f);
0855 break;
0856 case 1:
0857 r = (int) (q * 255.0f + 0.5f);
0858 g = (int) (brightness * 255.0f + 0.5f);
0859 b = (int) (p * 255.0f + 0.5f);
0860 break;
0861 case 2:
0862 r = (int) (p * 255.0f + 0.5f);
0863 g = (int) (brightness * 255.0f + 0.5f);
0864 b = (int) (t * 255.0f + 0.5f);
0865 break;
0866 case 3:
0867 r = (int) (p * 255.0f + 0.5f);
0868 g = (int) (q * 255.0f + 0.5f);
0869 b = (int) (brightness * 255.0f + 0.5f);
0870 break;
0871 case 4:
0872 r = (int) (t * 255.0f + 0.5f);
0873 g = (int) (p * 255.0f + 0.5f);
0874 b = (int) (brightness * 255.0f + 0.5f);
0875 break;
0876 case 5:
0877 r = (int) (brightness * 255.0f + 0.5f);
0878 g = (int) (p * 255.0f + 0.5f);
0879 b = (int) (q * 255.0f + 0.5f);
0880 break;
0881 }
0882 }
0883 return 0xff000000 | (r << 16) | (g << 8) | (b << 0);
0884 }
0885
0886 /**
0887 * Converts the components of a color, as specified by the default RGB
0888 * model, to an equivalent set of values for hue, saturation, and
0889 * brightness that are the three components of the HSB model.
0890 * <p>
0891 * If the <code>hsbvals</code> argument is <code>null</code>, then a
0892 * new array is allocated to return the result. Otherwise, the method
0893 * returns the array <code>hsbvals</code>, with the values put into
0894 * that array.
0895 * @param r the red component of the color
0896 * @param g the green component of the color
0897 * @param b the blue component of the color
0898 * @param hsbvals the array used to return the
0899 * three HSB values, or <code>null</code>
0900 * @return an array of three elements containing the hue, saturation,
0901 * and brightness (in that order), of the color with
0902 * the indicated red, green, and blue components.
0903 * @see java.awt.Color#getRGB()
0904 * @see java.awt.Color#Color(int)
0905 * @see java.awt.image.ColorModel#getRGBdefault()
0906 * @since JDK1.0
0907 */
0908 public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
0909 float hue, saturation, brightness;
0910 if (hsbvals == null) {
0911 hsbvals = new float[3];
0912 }
0913 int cmax = (r > g) ? r : g;
0914 if (b > cmax)
0915 cmax = b;
0916 int cmin = (r < g) ? r : g;
0917 if (b < cmin)
0918 cmin = b;
0919
0920 brightness = ((float) cmax) / 255.0f;
0921 if (cmax != 0)
0922 saturation = ((float) (cmax - cmin)) / ((float) cmax);
0923 else
0924 saturation = 0;
0925 if (saturation == 0)
0926 hue = 0;
0927 else {
0928 float redc = ((float) (cmax - r)) / ((float) (cmax - cmin));
0929 float greenc = ((float) (cmax - g))
0930 / ((float) (cmax - cmin));
0931 float bluec = ((float) (cmax - b))
0932 / ((float) (cmax - cmin));
0933 if (r == cmax)
0934 hue = bluec - greenc;
0935 else if (g == cmax)
0936 hue = 2.0f + redc - bluec;
0937 else
0938 hue = 4.0f + greenc - redc;
0939 hue = hue / 6.0f;
0940 if (hue < 0)
0941 hue = hue + 1.0f;
0942 }
0943 hsbvals[0] = hue;
0944 hsbvals[1] = saturation;
0945 hsbvals[2] = brightness;
0946 return hsbvals;
0947 }
0948
0949 /**
0950 * Creates a <code>Color</code> object based on the specified values
0951 * for the HSB color model.
0952 * <p>
0953 * The <code>s</code> and <code>b</code> components should be
0954 * floating-point values between zero and one
0955 * (numbers in the range 0.0-1.0). The <code>h</code> component
0956 * can be any floating-point number. The floor of this number is
0957 * subtracted from it to create a fraction between 0 and 1. This
0958 * fractional number is then multiplied by 360 to produce the hue
0959 * angle in the HSB color model.
0960 * @param h the hue component
0961 * @param s the saturation of the color
0962 * @param b the brightness of the color
0963 * @return a <code>Color</code> object with the specified hue,
0964 * saturation, and brightness.
0965 * @since JDK1.0
0966 */
0967 public static Color getHSBColor(float h, float s, float b) {
0968 return new Color(HSBtoRGB(h, s, b));
0969 }
0970
0971 /**
0972 * Returns a <code>float</code> array containing the color and alpha
0973 * components of the <code>Color</code>, as represented in the default
0974 * sRGB color space.
0975 * If <code>compArray</code> is <code>null</code>, an array of length
0976 * 4 is created for the return value. Otherwise,
0977 * <code>compArray</code> must have length 4 or greater,
0978 * and it is filled in with the components and returned.
0979 * @param compArray an array that this method fills with
0980 * color and alpha components and returns
0981 * @return the RGBA components in a <code>float</code> array.
0982 */
0983 public float[] getRGBComponents(float[] compArray) {
0984 float[] f;
0985 if (compArray == null) {
0986 f = new float[4];
0987 } else {
0988 f = compArray;
0989 }
0990 if (frgbvalue == null) {
0991 f[0] = ((float) getRed()) / 255f;
0992 f[1] = ((float) getGreen()) / 255f;
0993 f[2] = ((float) getBlue()) / 255f;
0994 f[3] = ((float) getAlpha()) / 255f;
0995 } else {
0996 f[0] = frgbvalue[0];
0997 f[1] = frgbvalue[1];
0998 f[2] = frgbvalue[2];
0999 f[3] = falpha;
1000 }
1001 return f;
1002 }
1003
1004 /**
1005 * Returns a <code>float</code> array containing only the color
1006 * components of the <code>Color</code>, in the default sRGB color
1007 * space. If <code>compArray</code> is <code>null</code>, an array of
1008 * length 3 is created for the return value. Otherwise,
1009 * <code>compArray</code> must have length 3 or greater, and it is
1010 * filled in with the components and returned.
1011 * @param compArray an array that this method fills with color
1012 * components and returns
1013 * @return the RGB components in a <code>float</code> array.
1014 */
1015 public float[] getRGBColorComponents(float[] compArray) {
1016 float[] f;
1017 if (compArray == null) {
1018 f = new float[3];
1019 } else {
1020 f = compArray;
1021 }
1022 if (frgbvalue == null) {
1023 f[0] = ((float) getRed()) / 255f;
1024 f[1] = ((float) getGreen()) / 255f;
1025 f[2] = ((float) getBlue()) / 255f;
1026 } else {
1027 f[0] = frgbvalue[0];
1028 f[1] = frgbvalue[1];
1029 f[2] = frgbvalue[2];
1030 }
1031 return f;
1032 }
1033
1034 /**
1035 * Returns a <code>float</code> array containing the color and alpha
1036 * components of the <code>Color</code>, in the
1037 * <code>ColorSpace</code> of the <code>Color</code>.
1038 * If <code>compArray</code> is <code>null</code>, an array with
1039 * length equal to the number of components in the associated
1040 * <code>ColorSpace</code> plus one is created for
1041 * the return value. Otherwise, <code>compArray</code> must have at
1042 * least this length and it is filled in with the components and
1043 * returned.
1044 * @param compArray an array that this method fills with the color and
1045 * alpha components of this <code>Color</code> in its
1046 * <code>ColorSpace</code> and returns
1047 * @return the color and alpha components in a <code>float</code>
1048 * array.
1049 */
1050 public float[] getComponents(float[] compArray) {
1051 if (fvalue == null)
1052 return getRGBComponents(compArray);
1053 float[] f;
1054 int n = fvalue.length;
1055 if (compArray == null) {
1056 f = new float[n + 1];
1057 } else {
1058 f = compArray;
1059 }
1060 for (int i = 0; i < n; i++) {
1061 f[i] = fvalue[i];
1062 }
1063 f[n] = falpha;
1064 return f;
1065 }
1066
1067 /**
1068 * Returns a <code>float</code> array containing only the color
1069 * components of the <code>Color</code>, in the
1070 * <code>ColorSpace</code> of the <code>Color</code>.
1071 * If <code>compArray</code> is <code>null</code>, an array with
1072 * length equal to the number of components in the associated
1073 * <code>ColorSpace</code> is created for
1074 * the return value. Otherwise, <code>compArray</code> must have at
1075 * least this length and it is filled in with the components and
1076 * returned.
1077 * @param compArray an array that this method fills with the color
1078 * components of this <code>Color</code> in its
1079 * <code>ColorSpace</code> and returns
1080 * @return the color components in a <code>float</code> array.
1081 */
1082 public float[] getColorComponents(float[] compArray) {
1083 if (fvalue == null)
1084 return getRGBColorComponents(compArray);
1085 float[] f;
1086 int n = fvalue.length;
1087 if (compArray == null) {
1088 f = new float[n];
1089 } else {
1090 f = compArray;
1091 }
1092 for (int i = 0; i < n; i++) {
1093 f[i] = fvalue[i];
1094 }
1095 return f;
1096 }
1097
1098 /**
1099 * Returns a <code>float</code> array containing the color and alpha
1100 * components of the <code>Color</code>, in the
1101 * <code>ColorSpace</code> specified by the <code>cspace</code>
1102 * parameter. If <code>compArray</code> is <code>null</code>, an
1103 * array with length equal to the number of components in
1104 * <code>cspace</code> plus one is created for the return value.
1105 * Otherwise, <code>compArray</code> must have at least this
1106 * length, and it is filled in with the components and returned.
1107 * @param cspace a specified <code>ColorSpace</code>
1108 * @param compArray an array that this method fills with the
1109 * color and alpha components of this <code>Color</code> in
1110 * the specified <code>ColorSpace</code> and returns
1111 * @return the color and alpha components in a <code>float</code>
1112 * array.
1113 */
1114 public float[] getComponents(ColorSpace cspace, float[] compArray) {
1115 if (cs == null) {
1116 cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
1117 }
1118 float f[];
1119 if (fvalue == null) {
1120 f = new float[3];
1121 f[0] = ((float) getRed()) / 255f;
1122 f[1] = ((float) getGreen()) / 255f;
1123 f[2] = ((float) getBlue()) / 255f;
1124 } else {
1125 f = fvalue;
1126 }
1127 float tmp[] = cs.toCIEXYZ(f);
1128 float tmpout[] = cspace.fromCIEXYZ(tmp);
1129 if (compArray == null) {
1130 compArray = new float[tmpout.length + 1];
1131 }
1132 for (int i = 0; i < tmpout.length; i++) {
1133 compArray[i] = tmpout[i];
1134 }
1135 if (fvalue == null) {
1136 compArray[tmpout.length] = ((float) getAlpha()) / 255f;
1137 } else {
1138 compArray[tmpout.length] = falpha;
1139 }
1140 return compArray;
1141 }
1142
1143 /**
1144 * Returns a <code>float</code> array containing only the color
1145 * components of the <code>Color</code> in the
1146 * <code>ColorSpace</code> specified by the <code>cspace</code>
1147 * parameter. If <code>compArray</code> is <code>null</code>, an array
1148 * with length equal to the number of components in
1149 * <code>cspace</code> is created for the return value. Otherwise,
1150 * <code>compArray</code> must have at least this length, and it is
1151 * filled in with the components and returned.
1152 * @param cspace a specified <code>ColorSpace</code>
1153 * @param compArray an array that this method fills with the color
1154 * components of this <code>Color</code> in the specified
1155 * <code>ColorSpace</code>
1156 * @return the color components in a <code>float</code> array.
1157 */
1158 public float[] getColorComponents(ColorSpace cspace,
1159 float[] compArray) {
1160 if (cs == null) {
1161 cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
1162 }
1163 float f[];
1164 if (fvalue == null) {
1165 f = new float[3];
1166 f[0] = ((float) getRed()) / 255f;
1167 f[1] = ((float) getGreen()) / 255f;
1168 f[2] = ((float) getBlue()) / 255f;
1169 } else {
1170 f = fvalue;
1171 }
1172 float tmp[] = cs.toCIEXYZ(f);
1173 float tmpout[] = cspace.fromCIEXYZ(tmp);
1174 if (compArray == null) {
1175 return tmpout;
1176 }
1177 for (int i = 0; i < tmpout.length; i++) {
1178 compArray[i] = tmpout[i];
1179 }
1180 return compArray;
1181 }
1182
1183 /**
1184 * Returns the <code>ColorSpace</code> of this <code>Color</code>.
1185 * @return this <code>Color</code> object's <code>ColorSpace</code>.
1186 */
1187 public ColorSpace getColorSpace() {
1188 if (cs == null) {
1189 cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
1190 }
1191 return cs;
1192 }
1193
1194 /**
1195 * Creates and returns a {@link PaintContext} used to generate a solid
1196 * color pattern. This enables a <code>Color</code> object to be used
1197 * as an argument to any method requiring an object implementing the
1198 * {@link Paint} interface.
1199 * The same <code>PaintContext</code> is returned, regardless of
1200 * whether or not <code>r</code>, <code>r2d</code>,
1201 * <code>xform</code>, or <code>hints</code> are <code>null</code>.
1202 * @param cm the specified <code>ColorModel</code>
1203 * @param r the specified {@link Rectangle}
1204 * @param r2d the specified {@link Rectangle2D}
1205 * @param xform the specified {@link AffineTransform}
1206 * @param hints the specified {@link RenderingHints}
1207 * @return a <code>PaintContext</code> that is used to generate a
1208 * solid color pattern.
1209 * @see Paint
1210 * @see PaintContext
1211 * @see Graphics2D#setPaint
1212 */
1213 public synchronized PaintContext createContext(ColorModel cm,
1214 Rectangle r, Rectangle2D r2d, AffineTransform xform,
1215 RenderingHints hints) {
1216 return new ColorPaintContext(getRGB(), cm);
1217 }
1218
1219 /**
1220 * Returns the transparency mode for this <code>Color</code>. This is
1221 * required to implement the <code>Paint</code> interface.
1222 * @return this <code>Color</code> object's transparency mode.
1223 * @see Paint
1224 * @see Transparency
1225 * @see #createContext
1226 */
1227 public int getTransparency() {
1228 int alpha = getAlpha();
1229 if (alpha == 0xff) {
1230 return Transparency.OPAQUE;
1231 } else if (alpha == 0) {
1232 return Transparency.BITMASK;
1233 } else {
1234 return Transparency.TRANSLUCENT;
1235 }
1236 }
1237
1238 }
|