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)
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
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
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. */
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
;
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)
60 * @status updated to 1.4
62 public class Color
implements Paint
, Serializable
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);
73 * Constant for the color white: R=255, G=255, B=255.
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);
83 * Constant for the color light gray: R=192, G=192, B=192.
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);
93 * Constant for the color gray: R=128, G=128, B=128.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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>.
223 * @serial the value of the color, whether an RGB literal or array index
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
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
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
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
271 private final ColorSpace cs
;
274 * The paint context for this solid color. Package visible for use in
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
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
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
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
;
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()
346 * @see #Color(int, boolean)
348 public Color(int value
)
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()
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.
375 falpha
= ((value
& ALPHA_MASK
) >> 24) / 255f
;
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
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
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
};
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
);
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
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
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
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
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
512 * @return the RGB value for this color
513 * @see ColorModel#getRGBdefault()
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
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
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()
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
)
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)
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
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
690 * @see ColorModel#getRGBdefault()
692 public static int HSBtoRGB(float hue
, float saturation
, float brightness
)
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
));
707 return convert(brightness
, t
, p
, 0);
709 return convert(q
, brightness
, p
, 0);
711 return convert(p
, brightness
, t
, 0);
713 return convert(p
, q
, brightness
, 0);
715 return convert(t
, p
, brightness
, 0);
717 return convert(brightness
, p
, q
, 0);
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
737 * @see ColorModel#getRGBdefault()
739 public static float[] RGBtoHSB(int red
, int green
, int blue
, float array
[])
742 array
= new float[3];
743 // Calculate brightness.
760 array
[2] = max
/ 255f
;
761 // Calculate saturation.
765 array
[1] = (max
- min
) / max
;
771 float delta
= (max
- min
) * 6;
773 array
[0] = (green
- blue
) / delta
;
774 else if (green
== max
)
775 array
[0] = 1f
/ 3 + (blue
- red
) / delta
;
777 array
[0] = 2f
/ 3 + (red
- green
) / delta
;
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
,
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
)
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
);
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
)
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];
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();
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
);
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();
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
);
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();
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
);
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
));
935 System
.arraycopy(components
, 0, array
, 0, components
.length
);
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
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
);
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
;