2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / awt / Color.java
blobe6eb03e8f0a58f35740f37ee244c728613c85a3c
1 /* Color.java -- represents a color in Java
2 Copyright (C) 1999, 2002 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.awt;
41 import java.awt.color.ColorSpace;
42 import java.awt.geom.AffineTransform;
43 import java.awt.geom.Rectangle2D;
44 import java.awt.image.ColorModel;
45 import java.io.Serializable;
47 /**
48 * This class represents a color value in the AWT system. It uses the sRGB
49 * (standard Red-Green-Blue) system, along with an alpha value ranging from
50 * transparent (0.0f or 0) and opaque (1.0f or 255). The color is not
51 * pre-multiplied by the alpha value an any of the accessor methods. Further
52 * information about sRGB can be found at
53 * <a href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
54 * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html</a>.
56 * @author Aaron M. Renn <arenn@urbanophile.com>
57 * @see ColorSpace
58 * @see AlphaComposite
59 * @since 1.0
60 * @status updated to 1.4
62 public class Color implements Paint, Serializable
64 /**
65 * Compatible with JDK 1.0+.
67 private static final long serialVersionUID = 118526816881161077L;
69 /** Constant for the color white: R=255, G=255, B=255. */
70 public static final Color white = new Color(0xffffff, false);
72 /**
73 * Constant for the color white: R=255, G=255, B=255.
75 * @since 1.4
77 public static final Color WHITE = white;
79 /** Constant for the color light gray: R=192, G=192, B=192. */
80 public static final Color lightGray = new Color(0xc0c0c0, false);
82 /**
83 * Constant for the color light gray: R=192, G=192, B=192.
85 * @since 1.4
87 public static final Color LIGHT_GRAY = lightGray;
89 /** Constant for the color gray: R=128, G=128, B=128. */
90 public static final Color gray = new Color(0x808080, false);
92 /**
93 * Constant for the color gray: R=128, G=128, B=128.
95 * @since 1.4
97 public static final Color GRAY = gray;
99 /** Constant for the color dark gray: R=64, G=64, B=64. */
100 public static final Color darkGray = new Color(0x404040, false);
103 * Constant for the color dark gray: R=64, G=64, B=64.
105 * @since 1.4
107 public static final Color DARK_GRAY = darkGray;
109 /** Constant for the color black: R=0, G=0, B=0. */
110 public static final Color black = new Color(0x000000, false);
113 * Constant for the color black: R=0, G=0, B=0.
115 * @since 1.4
117 public static final Color BLACK = black;
119 /** Constant for the color red: R=255, G=0, B=0. */
120 public static final Color red = new Color(0xff0000, false);
123 * Constant for the color red: R=255, G=0, B=0.
125 * @since 1.4
127 public static final Color RED = red;
129 /** Constant for the color pink: R=255, G=175, B=175. */
130 public static final Color pink = new Color(0xffafaf, false);
133 * Constant for the color pink: R=255, G=175, B=175.
135 * @since 1.4
137 public static final Color PINK = pink;
139 /** Constant for the color orange: R=255, G=200, B=0. */
140 public static final Color orange = new Color(0xffc800, false);
143 * Constant for the color orange: R=255, G=200, B=0.
145 * @since 1.4
147 public static final Color ORANGE = orange;
149 /** Constant for the color yellow: R=255, G=255, B=0. */
150 public static final Color yellow = new Color(0xffff00, false);
153 * Constant for the color yellow: R=255, G=255, B=0.
155 * @since 1.4
157 public static final Color YELLOW = yellow;
159 /** Constant for the color green: R=0, G=255, B=0. */
160 public static final Color green = new Color(0x00ff00, false);
163 * Constant for the color green: R=0, G=255, B=0.
165 * @since 1.4
167 public static final Color GREEN = green;
169 /** Constant for the color magenta: R=255, G=0, B=255. */
170 public static final Color magenta = new Color(0xff00ff, false);
173 * Constant for the color magenta: R=255, G=0, B=255.
175 * @since 1.4
177 public static final Color MAGENTA = magenta;
179 /** Constant for the color cyan: R=0, G=255, B=255. */
180 public static final Color cyan = new Color(0x00ffff, false);
183 * Constant for the color cyan: R=0, G=255, B=255.
185 * @since 1.4
187 public static final Color CYAN = cyan;
189 /** Constant for the color blue: R=0, G=0, B=255. */
190 public static final Color blue = new Color(0x0000ff, false);
193 * Constant for the color blue: R=0, G=0, B=255.
195 * @since 1.4
197 public static final Color BLUE = blue;
199 /** Internal mask for red. */
200 private static final int RED_MASK = 255 << 16;
202 /** Internal mask for green. */
203 private static final int GREEN_MASK = 255 << 8;
205 /** Internal mask for blue. */
206 private static final int BLUE_MASK = 255;
208 /** Internal mask for alpha. Package visible for use in subclass. */
209 static final int ALPHA_MASK = 255 << 24;
211 /** Amount to scale a color by when brightening or darkening. */
212 private static final float BRIGHT_SCALE = 0.7f;
215 * The color value, in sRGB. Note that the actual color may be more
216 * precise if frgbvalue or fvalue is non-null. This class stores alpha, red,
217 * green, and blue, each 0-255, packed in an int. However, the subclass
218 * SystemColor stores an index into an array. Therefore, for serial
219 * compatibility (and because of poor design on Sun's part), this value
220 * cannot be used directly; instead you must use <code>getRGB()</code>.
222 * @see #getRGB()
223 * @serial the value of the color, whether an RGB literal or array index
225 final int value;
228 * The color value, in sRGB. This may be null if the color was constructed
229 * with ints; and it does not include alpha. This stores red, green, and
230 * blue, in the range 0.0f - 1.0f.
232 * @see #getRGBColorComponents(float[])
233 * @see #getRGBComponents(float[])
234 * @serial the rgb components of the value
235 * @since 1.2
237 private float[] frgbvalue;
240 * The color value, in the native ColorSpace components. This may be null
241 * if the color was constructed with ints or in the sRGB color space; and
242 * it does not include alpha.
244 * @see #getRGBColorComponents(float[])
245 * @see #getRGBComponents(float[])
246 * @serial the original color space components of the color
247 * @since 1.2
249 private float[] fvalue;
252 * The alpha value. This is in the range 0.0f - 1.0f, but is invalid if
253 * deserialized as 0.0 when frgbvalue is null.
255 * @see #getRGBComponents(float[])
256 * @see #getComponents(float[])
257 * @serial the alpha component of this color
258 * @since 1.2
260 private final float falpha;
263 * The ColorSpace. Null means the default sRGB space.
265 * @see #getColor(String)
266 * @see #getColorSpace()
267 * @see #getColorComponents(float[])
268 * @serial the color space for this color
269 * @since 1.2
271 private final ColorSpace cs;
274 * The paint context for this solid color. Package visible for use in
275 * subclass.
277 transient ColorPaintContext context;
280 * Initializes a new instance of <code>Color</code> using the specified
281 * red, green, and blue values, which must be given as integers in the
282 * range of 0-255. Alpha will default to 255 (opaque). When drawing to
283 * screen, the actual color may be adjusted to the best match of hardware
284 * capabilities.
286 * @param red the red component of the RGB value
287 * @param green the green component of the RGB value
288 * @param blue the blue component of the RGB value
289 * @throws IllegalArgumentException if the values are out of range 0-255
290 * @see #getRed()
291 * @see #getGreen()
292 * @see #getBlue()
293 * @see #getRGB()
294 * @see #Color(int, int, int, int)
296 public Color(int red, int green, int blue)
298 this(red, green, blue, 255);
302 * Initializes a new instance of <code>Color</code> using the specified
303 * red, green, blue, and alpha values, which must be given as integers in
304 * the range of 0-255. When drawing to screen, the actual color may be
305 * adjusted to the best match of hardware capabilities.
307 * @param red the red component of the RGB value
308 * @param green the green component of the RGB value
309 * @param blue the blue component of the RGB value
310 * @param alpha the alpha value of the color
311 * @throws IllegalArgumentException if the values are out of range 0-255
312 * @see #getRed()
313 * @see #getGreen()
314 * @see #getBlue()
315 * @see #getAlpha()
316 * @see #getRGB()
318 public Color(int red, int green, int blue, int alpha)
320 if ((red & 255) != red || (green & 255) != green || (blue & 255) != blue
321 || (alpha & 255) != alpha)
322 throw new IllegalArgumentException("Bad RGB values");
323 value = (alpha << 24) | (red << 16) | (green << 8) | blue;
324 falpha = 1;
325 cs = null;
329 * Initializes a new instance of <code>Color</code> using the specified
330 * RGB value. The blue value is in bits 0-7, green in bits 8-15, and
331 * red in bits 16-23. The other bits are ignored. The alpha value is set
332 * to 255 (opaque). When drawing to screen, the actual color may be
333 * adjusted to the best match of hardware capabilities.
335 * @param value the RGB value
336 * @see ColorModel#getRGBdefault()
337 * @see #getRed()
338 * @see #getGreen()
339 * @see #getBlue()
340 * @see #getRGB()
341 * @see #Color(int, boolean)
343 public Color(int value)
345 this(value, false);
349 * Initializes a new instance of <code>Color</code> using the specified
350 * RGB value. The blue value is in bits 0-7, green in bits 8-15, and
351 * red in bits 16-23. The alpha value is in bits 24-31, unless hasalpha
352 * is false, in which case alpha is set to 255. When drawing to screen, the
353 * actual color may be adjusted to the best match of hardware capabilities.
355 * @param value the RGB value
356 * @param hasalpha true if value includes the alpha
357 * @see ColorModel#getRGBdefault()
358 * @see #getRed()
359 * @see #getGreen()
360 * @see #getBlue()
361 * @see #getAlpha()
362 * @see #getRGB()
364 public Color(int value, boolean hasalpha)
366 // Note: SystemColor calls this constructor, setting falpha to 0; but
367 // code in getRGBComponents correctly reports falpha as 1.0 to the user
368 // for all instances of SystemColor since frgbvalue is left null here.
369 if (hasalpha)
370 falpha = ((value & ALPHA_MASK) >> 24) / 255f;
371 else
373 value |= ALPHA_MASK;
374 falpha = 1;
376 this.value = value;
377 cs = null;
381 * Initializes a new instance of <code>Color</code> using the specified
382 * RGB values. These must be in the range of 0.0-1.0. Alpha is assigned
383 * the value of 1.0 (opaque). When drawing to screen, the actual color may
384 * be adjusted to the best match of hardware capabilities.
386 * @param red the red component of the RGB value
387 * @param green the green component of the RGB value
388 * @param blue the blue component of the RGB value
389 * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f
390 * @see #getRed()
391 * @see #getGreen()
392 * @see #getBlue()
393 * @see #getRGB()
394 * @see #Color(float, float, float, float)
396 public Color(float red, float green, float blue)
398 this(red, green, blue, 1.0f);
402 * Initializes a new instance of <code>Color</code> using the specified
403 * RGB and alpha values. These must be in the range of 0.0-1.0. When drawing
404 * to screen, the actual color may be adjusted to the best match of
405 * hardware capabilities.
407 * @param red the red component of the RGB value
408 * @param green the green component of the RGB value
409 * @param blue the blue component of the RGB value
410 * @param alpha the alpha value of the color
411 * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f
412 * @see #getRed()
413 * @see #getGreen()
414 * @see #getBlue()
415 * @see #getAlpha()
416 * @see #getRGB()
418 public Color(float red, float green, float blue, float alpha)
420 value = convert(red, green, blue, alpha);
421 frgbvalue = new float[] {red, green, blue};
422 falpha = alpha;
423 cs = null;
427 * Creates a color in the given ColorSpace with the specified alpha. The
428 * array must be non-null and have enough elements for the color space
429 * (for example, RGB requires 3 elements, CMYK requires 4). When drawing
430 * to screen, the actual color may be adjusted to the best match of
431 * hardware capabilities.
433 * @param space the color space of components
434 * @param components the color components, except alpha
435 * @param alpha the alpha value of the color
436 * @throws NullPointerException if cpsace or components is null
437 * @throws ArrayIndexOutOfBoundsException if components is too small
438 * @throws IllegalArgumentException if alpha or any component is out of range
439 * @see #getComponents(float[])
440 * @see #getColorComponents(float[])
442 public Color(ColorSpace space, float[] components, float alpha)
444 frgbvalue = space.toRGB(components);
445 fvalue = components;
446 falpha = alpha;
447 cs = space;
448 value = convert(frgbvalue[0], frgbvalue[1], frgbvalue[2], alpha);
452 * Returns the red value for this color, as an integer in the range 0-255
453 * in the sRGB color space.
455 * @return the red value for this color
456 * @see #getRGB()
458 public int getRed()
460 // Do not inline getRGB() to value, because of SystemColor.
461 return (getRGB() & RED_MASK) >> 16;
465 * Returns the green value for this color, as an integer in the range 0-255
466 * in the sRGB color space.
468 * @return the green value for this color
469 * @see #getRGB()
471 public int getGreen()
473 // Do not inline getRGB() to value, because of SystemColor.
474 return (getRGB() & GREEN_MASK) >> 8;
478 * Returns the blue value for this color, as an integer in the range 0-255
479 * in the sRGB color space.
481 * @return the blue value for this color
482 * @see #getRGB()
484 public int getBlue()
486 // Do not inline getRGB() to value, because of SystemColor.
487 return getRGB() & BLUE_MASK;
491 * Returns the alpha value for this color, as an integer in the range 0-255.
493 * @return the alpha value for this color
494 * @see #getRGB()
496 public int getAlpha()
498 // Do not inline getRGB() to value, because of SystemColor.
499 return (getRGB() & ALPHA_MASK) >>> 24;
503 * Returns the RGB value for this color, in the sRGB color space. The blue
504 * value will be in bits 0-7, green in 8-15, red in 6-23, and alpha value in
505 * 24-31.
507 * @return the RGB value for this color
508 * @see ColorModel#getRGBdefault()
509 * @see #getRed()
510 * @see #getGreen()
511 * @see #getBlue()
512 * @see #getAlpha()
514 public int getRGB()
516 return value;
520 * Returns a brighter version of this color. This is done by increasing the
521 * RGB values by an arbitrary scale factor. The new color is opaque (an
522 * alpha of 255). Note that this method and the <code>darker()</code>
523 * method are not necessarily inverses.
525 * @return a brighter version of this color
526 * @see #darker()
528 public Color brighter()
530 // Do not inline getRGB() to this.value, because of SystemColor.
531 int value = getRGB();
532 int red = (value & RED_MASK) >> 16;
533 int green = (value & GREEN_MASK) >> 8;
534 int blue = value & BLUE_MASK;
535 // We have to special case 0-2 because they won't scale by division.
536 red = red < 3 ? 3 : (int) Math.min(255, red / BRIGHT_SCALE);
537 green = green < 3 ? 3 : (int) Math.min(255, green / BRIGHT_SCALE);
538 blue = blue < 3 ? 3 : (int) Math.min(255, blue / BRIGHT_SCALE);
539 return new Color(red, green, blue, 255);
543 * Returns a darker version of this color. This is done by decreasing the
544 * RGB values by an arbitrary scale factor. The new color is opaque (an
545 * alpha of 255). Note that this method and the <code>brighter()</code>
546 * method are not necessarily inverses.
548 * @return a darker version of this color
549 * @see #brighter()
551 public Color darker()
553 // Do not inline getRGB() to this.value, because of SystemColor.
554 int value = getRGB();
555 return new Color((int) (((value & RED_MASK) >> 16) * BRIGHT_SCALE),
556 (int) (((value & GREEN_MASK) >> 8) * BRIGHT_SCALE),
557 (int) ((value & BLUE_MASK) * BRIGHT_SCALE), 255);
561 * Returns a hash value for this color. This is simply the color in 8-bit
562 * precision, in the format 0xAARRGGBB (alpha, red, green, blue).
564 * @return a hash value for this color
566 public int hashCode()
568 return value;
572 * Tests this object for equality against the specified object. This will
573 * be true if and only if the specified object is an instance of
574 * <code>Color</code> and has the same 8-bit integer red, green, and blue
575 * values as this object. Note that two colors may be slightly different
576 * as float values, but round to the same integer values. Also note that
577 * this does not accurately compare SystemColors, since that class does
578 * not store its internal data in RGB format like regular colors.
580 * @param obj the object to compare to
581 * @return true if the specified object is semantically equal to this one
583 public boolean equals(Object obj)
585 return obj instanceof Color && ((Color) obj).value == value;
589 * Returns a string representation of this object. Subclasses may return
590 * any desired format, except for null, but this implementation returns
591 * <code>getClass().getName() + "[r=" + getRed() + ",g=" + getGreen()
592 * + ",b=" + getBlue() + ']'</code>.
594 * @return a string representation of this object
596 public String toString()
598 return getClass().getName() + "[r=" + ((value & RED_MASK) >> 16)
599 + ",g=" + ((value & GREEN_MASK) >> 8) + ",b=" + (value & BLUE_MASK)
600 + ']';
604 * Converts the specified string to a number, using Integer.decode, and
605 * creates a new instance of <code>Color</code> from the value. The alpha
606 * value will be 255 (opaque).
608 * @param str the numeric color string
609 * @return a new instance of <code>Color</code> for the string
610 * @throws NumberFormatException if the string cannot be parsed
611 * @throws NullPointerException if the string is null
612 * @see Integer#decode(String)
613 * @see #Color(int)
614 * @since 1.1
616 public static Color decode(String str)
618 return new Color(Integer.decode(str).intValue(), false);
622 * Returns a new instance of <code>Color</code> from the value of the
623 * system property named by the specified string. If the property does not
624 * exist, or cannot be parsed, then <code>null</code> will be returned.
626 * @param prop the system property to retrieve
627 * @throws SecurityException if getting the property is denied
628 * @see #getColor(String, Color)
629 * @see Integer#getInteger(String)
631 public static Color getColor(String prop)
633 return getColor(prop, null);
637 * Returns a new instance of <code>Color</code> from the value of the
638 * system property named by the specified string. If the property does
639 * not exist, or cannot be parsed, then the default color value will be
640 * returned.
642 * @param prop the system property to retrieve
643 * @param defcolor the default color
644 * @throws SecurityException if getting the property is denied
645 * @see Integer#getInteger(String)
647 public static Color getColor(String prop, Color defcolor)
649 Integer val = Integer.getInteger(prop, null);
650 return val == null ? defcolor
651 : new Color(val.intValue(), false);
655 * Returns a new instance of <code>Color</code> from the value of the
656 * system property named by the specified string. If the property does
657 * not exist, or cannot be parsed, then the default RGB value will be
658 * used to create a return value.
660 * @param prop the system property to retrieve
661 * @param defrgb the default RGB value
662 * @throws SecurityException if getting the property is denied
663 * @see #getColor(String, Color)
664 * @see Integer#getInteger(String, int)
666 public static Color getColor(String prop, int defrgb)
668 Color c = getColor(prop, null);
669 return c == null ? new Color(defrgb, false) : c;
673 * Converts from the HSB (hue, saturation, brightness) color model to the
674 * RGB (red, green, blue) color model. The hue may be any floating point;
675 * it's fractional portion is used to select the angle in the HSB model.
676 * The saturation and brightness must be between 0 and 1. The result is
677 * suitable for creating an RGB color with the one-argument constructor.
679 * @param hue the hue of the HSB value
680 * @param saturation the saturation of the HSB value
681 * @param brightness the brightness of the HSB value
682 * @return the RGB value
683 * @see #getRGB()
684 * @see #Color(int)
685 * @see ColorModel#getRGBdefault()
687 public static int HSBtoRGB(float hue, float saturation, float brightness)
689 if (saturation == 0)
690 return convert(brightness, brightness, brightness, 0);
691 if (saturation < 0 || saturation > 1 || brightness < 0 || brightness > 1)
692 throw new IllegalArgumentException();
693 hue = hue - (float) Math.floor(hue);
694 int i = (int) (6 * hue);
695 float f = 6 * hue - i;
696 float p = brightness * (1 - saturation);
697 float q = brightness * (1 - saturation * f);
698 float t = brightness * (1 - saturation * (1 - f));
699 switch (i)
701 case 0:
702 return convert(brightness, t, p, 0);
703 case 1:
704 return convert(q, brightness, p, 0);
705 case 2:
706 return convert(p, brightness, t, 0);
707 case 3:
708 return convert(p, q, brightness, 0);
709 case 4:
710 return convert(t, p, brightness, 0);
711 case 5:
712 return convert(brightness, p, q, 0);
713 default:
714 throw new InternalError("impossible");
719 * Converts from the RGB (red, green, blue) color model to the HSB (hue,
720 * saturation, brightness) color model. If the array is null, a new one
721 * is created, otherwise it is recycled. The results will be in the range
722 * 0.0-1.0 if the inputs are in the range 0-255.
724 * @param red the red part of the RGB value
725 * @param green the green part of the RGB value
726 * @param blue the blue part of the RGB value
727 * @param array an array for the result (at least 3 elements), or null
728 * @return the array containing HSB value
729 * @throws ArrayIndexOutOfBoundsException of array is too small
730 * @see #getRGB()
731 * @see #Color(int)
732 * @see ColorModel#getRGBdefault()
734 public static float[] RGBtoHSB(int red, int green, int blue, float array[])
736 if (array == null)
737 array = new float[3];
738 // Calculate brightness.
739 int min;
740 int max;
741 if (red < green)
743 min = red;
744 max = green;
746 else
748 min = green;
749 max = red;
751 if (blue > max)
752 max = blue;
753 else if (blue < min)
754 min = blue;
755 array[2] = max / 255f;
756 // Calculate saturation.
757 if (max == 0)
758 array[1] = 0;
759 else
760 array[1] = (max - min) / max;
761 // Calculate hue.
762 if (array[1] == 0)
763 array[0] = 0;
764 else
766 float delta = (max - min) * 6;
767 if (red == max)
768 array[0] = (green - blue) / delta;
769 else if (green == max)
770 array[0] = 1 / 3 + (blue - red) / delta;
771 else
772 array[0] = 2 / 3 + (red - green) / delta;
773 if (array[0] < 0)
774 array[0]++;
776 return array;
780 * Returns a new instance of <code>Color</code> based on the specified
781 * HSB values. The hue may be any floating point; it's fractional portion
782 * is used to select the angle in the HSB model. The saturation and
783 * brightness must be between 0 and 1.
785 * @param hue the hue of the HSB value
786 * @param saturation the saturation of the HSB value
787 * @param brightness the brightness of the HSB value
788 * @return the new <code>Color</code> object
790 public static Color getHSBColor(float hue, float saturation,
791 float brightness)
793 return new Color(HSBtoRGB(hue, saturation, brightness), false);
797 * Returns a float array with the red, green, and blue components, and the
798 * alpha value, in the default sRGB space, with values in the range 0.0-1.0.
799 * If the array is null, a new one is created, otherwise it is recycled.
801 * @param array the array to put results into (at least 4 elements), or null
802 * @return the RGB components and alpha value
803 * @throws ArrayIndexOutOfBoundsException if array is too small
805 public float[] getRGBComponents(float[] array)
807 if (array == null)
808 array = new float[4];
809 getRGBColorComponents(array);
810 // Stupid serialization issues require this check.
811 array[3] = (falpha == 0 && frgbvalue == null
812 ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
813 return array;
817 * Returns a float array with the red, green, and blue components, in the
818 * default sRGB space, with values in the range 0.0-1.0. If the array is
819 * null, a new one is created, otherwise it is recycled.
821 * @param array the array to put results into (at least 3 elements), or null
822 * @return the RGB components
823 * @throws ArrayIndexOutOfBoundsException if array is too small
825 public float[] getRGBColorComponents(float[] array)
827 if (array == null)
828 array = new float[3];
829 else if (array == frgbvalue)
830 return array; // Optimization for getColorComponents(float[]).
831 if (frgbvalue == null)
833 // Do not inline getRGB() to this.value, because of SystemColor.
834 int value = getRGB();
835 frgbvalue = new float[] { ((value & RED_MASK) >> 16) / 255f,
836 ((value & GREEN_MASK) >> 8) / 255f,
837 (value & BLUE_MASK) / 255f };
839 array[0] = frgbvalue[0];
840 array[1] = frgbvalue[1];
841 array[2] = frgbvalue[2];
842 return array;
846 * Returns a float array containing the color and alpha components of this
847 * color in the ColorSpace it was created with (the constructors which do
848 * not take a ColorSpace parameter use a default sRGB ColorSpace). If the
849 * array is null, a new one is created, otherwise it is recycled, and must
850 * have at least one more position than components used in the color space.
852 * @param array the array to put results into, or null
853 * @return the original color space components and alpha value
854 * @throws ArrayIndexOutOfBoundsException if array is too small
856 public float[] getComponents(float[] array)
858 int numComponents = cs == null ? 3 : cs.getNumComponents();
859 if (array == null)
860 array = new float[1 + numComponents];
861 getColorComponents(array);
862 // Stupid serialization issues require this check.
863 array[numComponents] = (falpha == 0 && frgbvalue == null
864 ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
865 return array;
869 * Returns a float array containing the color components of this color in
870 * the ColorSpace it was created with (the constructors which do not take
871 * a ColorSpace parameter use a default sRGB ColorSpace). If the array is
872 * null, a new one is created, otherwise it is recycled, and must have at
873 * least as many positions as used in the color space.
875 * @param array the array to put results into, or null
876 * @return the original color space components
877 * @throws ArrayIndexOutOfBoundsException if array is too small
879 public float[] getColorComponents(float[] array)
881 int numComponents = cs == null ? 3 : cs.getNumComponents();
882 if (array == null)
883 array = new float[numComponents];
884 if (fvalue == null) // If fvalue is null, cs should be null too.
885 fvalue = getRGBColorComponents(frgbvalue);
886 System.arraycopy(fvalue, 0, array, 0, numComponents);
887 return array;
891 * Returns a float array containing the color and alpha components of this
892 * color in the given ColorSpace. If the array is null, a new one is
893 * created, otherwise it is recycled, and must have at least one more
894 * position than components used in the color space.
896 * @param space the color space to translate to
897 * @param array the array to put results into, or null
898 * @return the color space components and alpha value
899 * @throws ArrayIndexOutOfBoundsException if array is too small
900 * @throws NullPointerException if space is null
902 public float[] getComponents(ColorSpace space, float[] array)
904 int numComponents = space.getNumComponents();
905 if (array == null)
906 array = new float[1 + numComponents];
907 getColorComponents(space, array);
908 // Stupid serialization issues require this check.
909 array[numComponents] = (falpha == 0 && frgbvalue == null
910 ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
911 return array;
915 * Returns a float array containing the color components of this color in
916 * the given ColorSpace. If the array is null, a new one is created,
917 * otherwise it is recycled, and must have at least as many positions as
918 * used in the color space.
920 * @param space the color space to translate to
921 * @return the color space components
922 * @throws ArrayIndexOutOfBoundsException if array is too small
923 * @throws NullPointerException if space is null
925 public float[] getColorComponents(ColorSpace space, float[] array)
927 float[] components = space.fromRGB(getRGBColorComponents(frgbvalue));
928 if (array == null)
929 return components;
930 System.arraycopy(components, 0, array, 0, components.length);
931 return array;
935 * Returns the color space of this color. Except for the constructor which
936 * takes a ColorSpace argument, this will be an implementation of
937 * ColorSpace.CS_sRGB.
939 * @return the color space
941 public ColorSpace getColorSpace()
943 return cs == null ? ColorSpace.getInstance(ColorSpace.CS_sRGB) : cs;
947 * Returns a paint context, used for filling areas of a raster scan with
948 * this color. Since the color is constant across the entire rectangle, and
949 * since it is always in sRGB space, this implementation returns the same
950 * object, regardless of the parameters. Subclasses, however, may have a
951 * mutable result.
953 * @param cm the requested color model, ignored
954 * @param deviceBounds the bounding box in device coordinates, ignored
955 * @param userBounds the bounding box in user coordinates, ignored
956 * @param xform the bounds transformation, ignored
957 * @param hints any rendering hints, ignored
958 * @return a context for painting this solid color
960 public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
961 Rectangle2D userBounds,
962 AffineTransform xform,
963 RenderingHints hints)
965 if (context == null)
966 context = new ColorPaintContext(value);
967 return context;
971 * Returns the transparency level of this color.
973 * @return one of {@link #OPAQUE}, {@link #BITMASK}, or {@link #TRANSLUCENT}
975 public int getTransparency()
977 // Do not inline getRGB() to this.value, because of SystemColor.
978 int alpha = getRGB() & ALPHA_MASK;
979 return alpha == (255 << 24) ? OPAQUE : alpha == 0 ? BITMASK : TRANSLUCENT;
983 * Converts float values to integer value.
985 * @param red the red value
986 * @param green the green value
987 * @param blue the blue value
988 * @param alpha the alpha value
989 * @return the integer value made of 8-bit sections
990 * @throws IllegalArgumentException if parameters are out of range 0.0-1.0
992 private static int convert(float red, float green, float blue, float alpha)
994 if (red < 0 || red > 1 || green < 0 || green > 1 || blue < 0 || blue > 1
995 || alpha < 0 || alpha > 1)
996 throw new IllegalArgumentException("Bad RGB values");
997 int redval = Math.round(255 * red);
998 int greenval = Math.round(255 * green);
999 int blueval = Math.round(255 * blue);
1000 int alphaval = Math.round(255 * alpha);
1001 return (alphaval << 24) | (redval << 16) | (greenval << 8) | blueval;
1003 } // class Color