Merge from mainline.
[official-gcc.git] / libjava / classpath / java / awt / Color.java
blobb0312924170b9d796097afb54ba604afdb170135
1 /* Color.java -- represents a color in Java
2 Copyright (C) 1999, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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 +" red=0x"+Integer.toHexString(red)
324 +" green=0x"+Integer.toHexString(green)
325 +" blue=0x"+Integer.toHexString(blue)
326 +" alpha=0x"+Integer.toHexString(alpha) );
328 value = (alpha << 24) | (red << 16) | (green << 8) | blue;
329 falpha = 1;
330 cs = null;
334 * Initializes a new instance of <code>Color</code> using the specified
335 * RGB value. The blue value is in bits 0-7, green in bits 8-15, and
336 * red in bits 16-23. The other bits are ignored. The alpha value is set
337 * to 255 (opaque). When drawing to screen, the actual color may be
338 * adjusted to the best match of hardware capabilities.
340 * @param value the RGB value
341 * @see ColorModel#getRGBdefault()
342 * @see #getRed()
343 * @see #getGreen()
344 * @see #getBlue()
345 * @see #getRGB()
346 * @see #Color(int, boolean)
348 public Color(int value)
350 this(value, false);
354 * Initializes a new instance of <code>Color</code> using the specified
355 * RGB value. The blue value is in bits 0-7, green in bits 8-15, and
356 * red in bits 16-23. The alpha value is in bits 24-31, unless hasalpha
357 * is false, in which case alpha is set to 255. When drawing to screen, the
358 * actual color may be adjusted to the best match of hardware capabilities.
360 * @param value the RGB value
361 * @param hasalpha true if value includes the alpha
362 * @see ColorModel#getRGBdefault()
363 * @see #getRed()
364 * @see #getGreen()
365 * @see #getBlue()
366 * @see #getAlpha()
367 * @see #getRGB()
369 public Color(int value, boolean hasalpha)
371 // Note: SystemColor calls this constructor, setting falpha to 0; but
372 // code in getRGBComponents correctly reports falpha as 1.0 to the user
373 // for all instances of SystemColor since frgbvalue is left null here.
374 if (hasalpha)
375 falpha = ((value & ALPHA_MASK) >> 24) / 255f;
376 else
378 value |= ALPHA_MASK;
379 falpha = 1;
381 this.value = value;
382 cs = null;
386 * Initializes a new instance of <code>Color</code> using the specified
387 * RGB values. These must be in the range of 0.0-1.0. Alpha is assigned
388 * the value of 1.0 (opaque). When drawing to screen, the actual color may
389 * be adjusted to the best match of hardware capabilities.
391 * @param red the red component of the RGB value
392 * @param green the green component of the RGB value
393 * @param blue the blue component of the RGB value
394 * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f
395 * @see #getRed()
396 * @see #getGreen()
397 * @see #getBlue()
398 * @see #getRGB()
399 * @see #Color(float, float, float, float)
401 public Color(float red, float green, float blue)
403 this(red, green, blue, 1.0f);
407 * Initializes a new instance of <code>Color</code> using the specified
408 * RGB and alpha values. These must be in the range of 0.0-1.0. When drawing
409 * to screen, the actual color may be adjusted to the best match of
410 * hardware capabilities.
412 * @param red the red component of the RGB value
413 * @param green the green component of the RGB value
414 * @param blue the blue component of the RGB value
415 * @param alpha the alpha value of the color
416 * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f
417 * @see #getRed()
418 * @see #getGreen()
419 * @see #getBlue()
420 * @see #getAlpha()
421 * @see #getRGB()
423 public Color(float red, float green, float blue, float alpha)
425 value = convert(red, green, blue, alpha);
426 frgbvalue = new float[] {red, green, blue};
427 falpha = alpha;
428 cs = null;
432 * Creates a color in the given ColorSpace with the specified alpha. The
433 * array must be non-null and have enough elements for the color space
434 * (for example, RGB requires 3 elements, CMYK requires 4). When drawing
435 * to screen, the actual color may be adjusted to the best match of
436 * hardware capabilities.
438 * @param space the color space of components
439 * @param components the color components, except alpha
440 * @param alpha the alpha value of the color
441 * @throws NullPointerException if cpsace or components is null
442 * @throws ArrayIndexOutOfBoundsException if components is too small
443 * @throws IllegalArgumentException if alpha or any component is out of range
444 * @see #getComponents(float[])
445 * @see #getColorComponents(float[])
447 public Color(ColorSpace space, float[] components, float alpha)
449 frgbvalue = space.toRGB(components);
450 fvalue = components;
451 falpha = alpha;
452 cs = space;
453 value = convert(frgbvalue[0], frgbvalue[1], frgbvalue[2], alpha);
457 * Returns the red value for this color, as an integer in the range 0-255
458 * in the sRGB color space.
460 * @return the red value for this color
461 * @see #getRGB()
463 public int getRed()
465 // Do not inline getRGB() to value, because of SystemColor.
466 return (getRGB() & RED_MASK) >> 16;
470 * Returns the green value for this color, as an integer in the range 0-255
471 * in the sRGB color space.
473 * @return the green value for this color
474 * @see #getRGB()
476 public int getGreen()
478 // Do not inline getRGB() to value, because of SystemColor.
479 return (getRGB() & GREEN_MASK) >> 8;
483 * Returns the blue value for this color, as an integer in the range 0-255
484 * in the sRGB color space.
486 * @return the blue value for this color
487 * @see #getRGB()
489 public int getBlue()
491 // Do not inline getRGB() to value, because of SystemColor.
492 return getRGB() & BLUE_MASK;
496 * Returns the alpha value for this color, as an integer in the range 0-255.
498 * @return the alpha value for this color
499 * @see #getRGB()
501 public int getAlpha()
503 // Do not inline getRGB() to value, because of SystemColor.
504 return (getRGB() & ALPHA_MASK) >>> 24;
508 * Returns the RGB value for this color, in the sRGB color space. The blue
509 * value will be in bits 0-7, green in 8-15, red in 16-23, and alpha value in
510 * 24-31.
512 * @return the RGB value for this color
513 * @see ColorModel#getRGBdefault()
514 * @see #getRed()
515 * @see #getGreen()
516 * @see #getBlue()
517 * @see #getAlpha()
519 public int getRGB()
521 return value;
525 * Returns a brighter version of this color. This is done by increasing the
526 * RGB values by an arbitrary scale factor. The new color is opaque (an
527 * alpha of 255). Note that this method and the <code>darker()</code>
528 * method are not necessarily inverses.
530 * @return a brighter version of this color
531 * @see #darker()
533 public Color brighter()
535 // Do not inline getRGB() to this.value, because of SystemColor.
536 int value = getRGB();
537 int red = (value & RED_MASK) >> 16;
538 int green = (value & GREEN_MASK) >> 8;
539 int blue = value & BLUE_MASK;
540 // We have to special case 0-2 because they won't scale by division.
541 red = red < 3 ? 3 : (int) Math.min(255, red / BRIGHT_SCALE);
542 green = green < 3 ? 3 : (int) Math.min(255, green / BRIGHT_SCALE);
543 blue = blue < 3 ? 3 : (int) Math.min(255, blue / BRIGHT_SCALE);
544 return new Color(red, green, blue, 255);
548 * Returns a darker version of this color. This is done by decreasing the
549 * RGB values by an arbitrary scale factor. The new color is opaque (an
550 * alpha of 255). Note that this method and the <code>brighter()</code>
551 * method are not necessarily inverses.
553 * @return a darker version of this color
554 * @see #brighter()
556 public Color darker()
558 // Do not inline getRGB() to this.value, because of SystemColor.
559 int value = getRGB();
560 return new Color((int) (((value & RED_MASK) >> 16) * BRIGHT_SCALE),
561 (int) (((value & GREEN_MASK) >> 8) * BRIGHT_SCALE),
562 (int) ((value & BLUE_MASK) * BRIGHT_SCALE), 255);
566 * Returns a hash value for this color. This is simply the color in 8-bit
567 * precision, in the format 0xAARRGGBB (alpha, red, green, blue).
569 * @return a hash value for this color
571 public int hashCode()
573 return value;
577 * Tests this object for equality against the specified object. This will
578 * be true if and only if the specified object is an instance of
579 * <code>Color</code> and has the same 8-bit integer red, green, and blue
580 * values as this object. Note that two colors may be slightly different
581 * as float values, but round to the same integer values. Also note that
582 * this does not accurately compare SystemColors, since that class does
583 * not store its internal data in RGB format like regular colors.
585 * @param obj the object to compare to
586 * @return true if the specified object is semantically equal to this one
588 public boolean equals(Object obj)
590 return obj instanceof Color && ((Color) obj).value == value;
594 * Returns a string representation of this object. Subclasses may return
595 * any desired format, except for null, but this implementation returns
596 * <code>getClass().getName() + "[r=" + getRed() + ",g=" + getGreen()
597 * + ",b=" + getBlue() + ']'</code>.
599 * @return a string representation of this object
601 public String toString()
603 return getClass().getName() + "[r=" + ((value & RED_MASK) >> 16)
604 + ",g=" + ((value & GREEN_MASK) >> 8) + ",b=" + (value & BLUE_MASK)
605 + ']';
609 * Converts the specified string to a number, using Integer.decode, and
610 * creates a new instance of <code>Color</code> from the value. The alpha
611 * value will be 255 (opaque).
613 * @param str the numeric color string
614 * @return a new instance of <code>Color</code> for the string
615 * @throws NumberFormatException if the string cannot be parsed
616 * @throws NullPointerException if the string is null
617 * @see Integer#decode(String)
618 * @see #Color(int)
619 * @since 1.1
621 public static Color decode(String str)
623 return new Color(Integer.decode(str).intValue(), false);
627 * Returns a new instance of <code>Color</code> from the value of the
628 * system property named by the specified string. If the property does not
629 * exist, or cannot be parsed, then <code>null</code> will be returned.
631 * @param prop the system property to retrieve
632 * @throws SecurityException if getting the property is denied
633 * @see #getColor(String, Color)
634 * @see Integer#getInteger(String)
636 public static Color getColor(String prop)
638 return getColor(prop, null);
642 * Returns a new instance of <code>Color</code> from the value of the
643 * system property named by the specified string. If the property does
644 * not exist, or cannot be parsed, then the default color value will be
645 * returned.
647 * @param prop the system property to retrieve
648 * @param defcolor the default color
649 * @throws SecurityException if getting the property is denied
650 * @see Integer#getInteger(String)
652 public static Color getColor(String prop, Color defcolor)
654 Integer val = Integer.getInteger(prop, null);
655 return val == null ? defcolor
656 : new Color(val.intValue(), false);
660 * Returns a new instance of <code>Color</code> from the value of the
661 * system property named by the specified string. If the property does
662 * not exist, or cannot be parsed, then the default RGB value will be
663 * used to create a return value.
665 * @param prop the system property to retrieve
666 * @param defrgb the default RGB value
667 * @throws SecurityException if getting the property is denied
668 * @see #getColor(String, Color)
669 * @see Integer#getInteger(String, int)
671 public static Color getColor(String prop, int defrgb)
673 Color c = getColor(prop, null);
674 return c == null ? new Color(defrgb, false) : c;
678 * Converts from the HSB (hue, saturation, brightness) color model to the
679 * RGB (red, green, blue) color model. The hue may be any floating point;
680 * it's fractional portion is used to select the angle in the HSB model.
681 * The saturation and brightness must be between 0 and 1. The result is
682 * suitable for creating an RGB color with the one-argument constructor.
684 * @param hue the hue of the HSB value
685 * @param saturation the saturation of the HSB value
686 * @param brightness the brightness of the HSB value
687 * @return the RGB value
688 * @see #getRGB()
689 * @see #Color(int)
690 * @see ColorModel#getRGBdefault()
692 public static int HSBtoRGB(float hue, float saturation, float brightness)
694 if (saturation == 0)
695 return convert(brightness, brightness, brightness, 0);
696 if (saturation < 0 || saturation > 1 || brightness < 0 || brightness > 1)
697 throw new IllegalArgumentException();
698 hue = hue - (float) Math.floor(hue);
699 int i = (int) (6 * hue);
700 float f = 6 * hue - i;
701 float p = brightness * (1 - saturation);
702 float q = brightness * (1 - saturation * f);
703 float t = brightness * (1 - saturation * (1 - f));
704 switch (i)
706 case 0:
707 return convert(brightness, t, p, 0);
708 case 1:
709 return convert(q, brightness, p, 0);
710 case 2:
711 return convert(p, brightness, t, 0);
712 case 3:
713 return convert(p, q, brightness, 0);
714 case 4:
715 return convert(t, p, brightness, 0);
716 case 5:
717 return convert(brightness, p, q, 0);
718 default:
719 throw new InternalError("impossible");
724 * Converts from the RGB (red, green, blue) color model to the HSB (hue,
725 * saturation, brightness) color model. If the array is null, a new one
726 * is created, otherwise it is recycled. The results will be in the range
727 * 0.0-1.0 if the inputs are in the range 0-255.
729 * @param red the red part of the RGB value
730 * @param green the green part of the RGB value
731 * @param blue the blue part of the RGB value
732 * @param array an array for the result (at least 3 elements), or null
733 * @return the array containing HSB value
734 * @throws ArrayIndexOutOfBoundsException of array is too small
735 * @see #getRGB()
736 * @see #Color(int)
737 * @see ColorModel#getRGBdefault()
739 public static float[] RGBtoHSB(int red, int green, int blue, float array[])
741 if (array == null)
742 array = new float[3];
743 // Calculate brightness.
744 int min;
745 int max;
746 if (red < green)
748 min = red;
749 max = green;
751 else
753 min = green;
754 max = red;
756 if (blue > max)
757 max = blue;
758 else if (blue < min)
759 min = blue;
760 array[2] = max / 255f;
761 // Calculate saturation.
762 if (max == 0)
763 array[1] = 0;
764 else
765 array[1] = ((float) (max - min)) / ((float) max);
766 // Calculate hue.
767 if (array[1] == 0)
768 array[0] = 0;
769 else
771 float delta = (max - min) * 6;
772 if (red == max)
773 array[0] = (green - blue) / delta;
774 else if (green == max)
775 array[0] = 1f / 3 + (blue - red) / delta;
776 else
777 array[0] = 2f / 3 + (red - green) / delta;
778 if (array[0] < 0)
779 array[0]++;
781 return array;
785 * Returns a new instance of <code>Color</code> based on the specified
786 * HSB values. The hue may be any floating point; it's fractional portion
787 * is used to select the angle in the HSB model. The saturation and
788 * brightness must be between 0 and 1.
790 * @param hue the hue of the HSB value
791 * @param saturation the saturation of the HSB value
792 * @param brightness the brightness of the HSB value
793 * @return the new <code>Color</code> object
795 public static Color getHSBColor(float hue, float saturation,
796 float brightness)
798 return new Color(HSBtoRGB(hue, saturation, brightness), false);
802 * Returns a float array with the red, green, and blue components, and the
803 * alpha value, in the default sRGB space, with values in the range 0.0-1.0.
804 * If the array is null, a new one is created, otherwise it is recycled.
806 * @param array the array to put results into (at least 4 elements), or null
807 * @return the RGB components and alpha value
808 * @throws ArrayIndexOutOfBoundsException if array is too small
810 public float[] getRGBComponents(float[] array)
812 if (array == null)
813 array = new float[4];
814 getRGBColorComponents(array);
815 // Stupid serialization issues require this check.
816 array[3] = (falpha == 0 && frgbvalue == null
817 ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
818 return array;
822 * Returns a float array with the red, green, and blue components, in the
823 * default sRGB space, with values in the range 0.0-1.0. If the array is
824 * null, a new one is created, otherwise it is recycled.
826 * @param array the array to put results into (at least 3 elements), or null
827 * @return the RGB components
828 * @throws ArrayIndexOutOfBoundsException if array is too small
830 public float[] getRGBColorComponents(float[] array)
832 if (array == null)
833 array = new float[3];
834 else if (array == frgbvalue)
835 return array; // Optimization for getColorComponents(float[]).
836 if (frgbvalue == null)
838 // Do not inline getRGB() to this.value, because of SystemColor.
839 int value = getRGB();
840 frgbvalue = new float[] { ((value & RED_MASK) >> 16) / 255f,
841 ((value & GREEN_MASK) >> 8) / 255f,
842 (value & BLUE_MASK) / 255f };
844 array[0] = frgbvalue[0];
845 array[1] = frgbvalue[1];
846 array[2] = frgbvalue[2];
847 return array;
851 * Returns a float array containing the color and alpha components of this
852 * color in the ColorSpace it was created with (the constructors which do
853 * not take a ColorSpace parameter use a default sRGB ColorSpace). If the
854 * array is null, a new one is created, otherwise it is recycled, and must
855 * have at least one more position than components used in the color space.
857 * @param array the array to put results into, or null
858 * @return the original color space components and alpha value
859 * @throws ArrayIndexOutOfBoundsException if array is too small
861 public float[] getComponents(float[] array)
863 int numComponents = cs == null ? 3 : cs.getNumComponents();
864 if (array == null)
865 array = new float[1 + numComponents];
866 getColorComponents(array);
867 // Stupid serialization issues require this check.
868 array[numComponents] = (falpha == 0 && frgbvalue == null
869 ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
870 return array;
874 * Returns a float array containing the color components of this color in
875 * the ColorSpace it was created with (the constructors which do not take
876 * a ColorSpace parameter use a default sRGB ColorSpace). If the array is
877 * null, a new one is created, otherwise it is recycled, and must have at
878 * least as many positions as used in the color space.
880 * @param array the array to put results into, or null
881 * @return the original color space components
882 * @throws ArrayIndexOutOfBoundsException if array is too small
884 public float[] getColorComponents(float[] array)
886 int numComponents = cs == null ? 3 : cs.getNumComponents();
887 if (array == null)
888 array = new float[numComponents];
889 if (fvalue == null) // If fvalue is null, cs should be null too.
890 fvalue = getRGBColorComponents(frgbvalue);
891 System.arraycopy(fvalue, 0, array, 0, numComponents);
892 return array;
896 * Returns a float array containing the color and alpha components of this
897 * color in the given ColorSpace. If the array is null, a new one is
898 * created, otherwise it is recycled, and must have at least one more
899 * position than components used in the color space.
901 * @param space the color space to translate to
902 * @param array the array to put results into, or null
903 * @return the color space components and alpha value
904 * @throws ArrayIndexOutOfBoundsException if array is too small
905 * @throws NullPointerException if space is null
907 public float[] getComponents(ColorSpace space, float[] array)
909 int numComponents = space.getNumComponents();
910 if (array == null)
911 array = new float[1 + numComponents];
912 getColorComponents(space, array);
913 // Stupid serialization issues require this check.
914 array[numComponents] = (falpha == 0 && frgbvalue == null
915 ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
916 return array;
920 * Returns a float array containing the color components of this color in
921 * the given ColorSpace. If the array is null, a new one is created,
922 * otherwise it is recycled, and must have at least as many positions as
923 * used in the color space.
925 * @param space the color space to translate to
926 * @return the color space components
927 * @throws ArrayIndexOutOfBoundsException if array is too small
928 * @throws NullPointerException if space is null
930 public float[] getColorComponents(ColorSpace space, float[] array)
932 float[] components = space.fromRGB(getRGBColorComponents(frgbvalue));
933 if (array == null)
934 return components;
935 System.arraycopy(components, 0, array, 0, components.length);
936 return array;
940 * Returns the color space of this color. Except for the constructor which
941 * takes a ColorSpace argument, this will be an implementation of
942 * ColorSpace.CS_sRGB.
944 * @return the color space
946 public ColorSpace getColorSpace()
948 return cs == null ? ColorSpace.getInstance(ColorSpace.CS_sRGB) : cs;
952 * Returns a paint context, used for filling areas of a raster scan with
953 * this color. Since the color is constant across the entire rectangle, and
954 * since it is always in sRGB space, this implementation returns the same
955 * object, regardless of the parameters. Subclasses, however, may have a
956 * mutable result.
958 * @param cm the requested color model
959 * @param deviceBounds the bounding box in device coordinates, ignored
960 * @param userBounds the bounding box in user coordinates, ignored
961 * @param xform the bounds transformation, ignored
962 * @param hints any rendering hints, ignored
963 * @return a context for painting this solid color
965 public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
966 Rectangle2D userBounds,
967 AffineTransform xform,
968 RenderingHints hints)
970 if (context == null || !context.getColorModel().equals(cm))
971 context = new ColorPaintContext(cm,value);
972 return context;
976 * Returns the transparency level of this color.
978 * @return one of {@link #OPAQUE}, {@link #BITMASK}, or {@link #TRANSLUCENT}
980 public int getTransparency()
982 // Do not inline getRGB() to this.value, because of SystemColor.
983 int alpha = getRGB() & ALPHA_MASK;
984 return alpha == (255 << 24) ? OPAQUE : alpha == 0 ? BITMASK : TRANSLUCENT;
988 * Converts float values to integer value.
990 * @param red the red value
991 * @param green the green value
992 * @param blue the blue value
993 * @param alpha the alpha value
994 * @return the integer value made of 8-bit sections
995 * @throws IllegalArgumentException if parameters are out of range 0.0-1.0
997 private static int convert(float red, float green, float blue, float alpha)
999 if (red < 0 || red > 1 || green < 0 || green > 1 || blue < 0 || blue > 1
1000 || alpha < 0 || alpha > 1)
1001 throw new IllegalArgumentException("Bad RGB values");
1002 int redval = Math.round(255 * red);
1003 int greenval = Math.round(255 * green);
1004 int blueval = Math.round(255 * blue);
1005 int alphaval = Math.round(255 * alpha);
1006 return (alphaval << 24) | (redval << 16) | (greenval << 8) | blueval;
1008 } // class Color