View Javadoc
1   /*
2    * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package java.awt;
27  
28  import java.beans.ConstructorProperties;
29  import java.awt.image.ColorModel;
30  import java.awt.geom.AffineTransform;
31  import java.awt.geom.Rectangle2D;
32  import java.awt.color.ColorSpace;
33  
34  /**
35   * The <code>Color</code> class is used to encapsulate colors in the default
36   * sRGB color space or colors in arbitrary color spaces identified by a
37   * {@link ColorSpace}.  Every color has an implicit alpha value of 1.0 or
38   * an explicit one provided in the constructor.  The alpha value
39   * defines the transparency of a color and can be represented by
40   * a float value in the range 0.0&nbsp;-&nbsp;1.0 or 0&nbsp;-&nbsp;255.
41   * An alpha value of 1.0 or 255 means that the color is completely
42   * opaque and an alpha value of 0 or 0.0 means that the color is
43   * completely transparent.
44   * When constructing a <code>Color</code> with an explicit alpha or
45   * getting the color/alpha components of a <code>Color</code>, the color
46   * components are never premultiplied by the alpha component.
47   * <p>
48   * The default color space for the Java 2D(tm) API is sRGB, a proposed
49   * standard RGB color space.  For further information on sRGB,
50   * see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
51   * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
52   * </A>.
53   * <p>
54   * @version     10 Feb 1997
55   * @author      Sami Shaio
56   * @author      Arthur van Hoff
57   * @see         ColorSpace
58   * @see         AlphaComposite
59   */
60  public class Color implements Paint, java.io.Serializable {
61  
62      /**
63       * The color white.  In the default sRGB space.
64       */
65      public final static Color white     = new Color(255, 255, 255);
66  
67      /**
68       * The color white.  In the default sRGB space.
69       * @since 1.4
70       */
71      public final static Color WHITE = white;
72  
73      /**
74       * The color light gray.  In the default sRGB space.
75       */
76      public final static Color lightGray = new Color(192, 192, 192);
77  
78      /**
79       * The color light gray.  In the default sRGB space.
80       * @since 1.4
81       */
82      public final static Color LIGHT_GRAY = lightGray;
83  
84      /**
85       * The color gray.  In the default sRGB space.
86       */
87      public final static Color gray      = new Color(128, 128, 128);
88  
89      /**
90       * The color gray.  In the default sRGB space.
91       * @since 1.4
92       */
93      public final static Color GRAY = gray;
94  
95      /**
96       * The color dark gray.  In the default sRGB space.
97       */
98      public final static Color darkGray  = new Color(64, 64, 64);
99  
100     /**
101      * The color dark gray.  In the default sRGB space.
102      * @since 1.4
103      */
104     public final static Color DARK_GRAY = darkGray;
105 
106     /**
107      * The color black.  In the default sRGB space.
108      */
109     public final static Color black     = new Color(0, 0, 0);
110 
111     /**
112      * The color black.  In the default sRGB space.
113      * @since 1.4
114      */
115     public final static Color BLACK = black;
116 
117     /**
118      * The color red.  In the default sRGB space.
119      */
120     public final static Color red       = new Color(255, 0, 0);
121 
122     /**
123      * The color red.  In the default sRGB space.
124      * @since 1.4
125      */
126     public final static Color RED = red;
127 
128     /**
129      * The color pink.  In the default sRGB space.
130      */
131     public final static Color pink      = new Color(255, 175, 175);
132 
133     /**
134      * The color pink.  In the default sRGB space.
135      * @since 1.4
136      */
137     public final static Color PINK = pink;
138 
139     /**
140      * The color orange.  In the default sRGB space.
141      */
142     public final static Color orange    = new Color(255, 200, 0);
143 
144     /**
145      * The color orange.  In the default sRGB space.
146      * @since 1.4
147      */
148     public final static Color ORANGE = orange;
149 
150     /**
151      * The color yellow.  In the default sRGB space.
152      */
153     public final static Color yellow    = new Color(255, 255, 0);
154 
155     /**
156      * The color yellow.  In the default sRGB space.
157      * @since 1.4
158      */
159     public final static Color YELLOW = yellow;
160 
161     /**
162      * The color green.  In the default sRGB space.
163      */
164     public final static Color green     = new Color(0, 255, 0);
165 
166     /**
167      * The color green.  In the default sRGB space.
168      * @since 1.4
169      */
170     public final static Color GREEN = green;
171 
172     /**
173      * The color magenta.  In the default sRGB space.
174      */
175     public final static Color magenta   = new Color(255, 0, 255);
176 
177     /**
178      * The color magenta.  In the default sRGB space.
179      * @since 1.4
180      */
181     public final static Color MAGENTA = magenta;
182 
183     /**
184      * The color cyan.  In the default sRGB space.
185      */
186     public final static Color cyan      = new Color(0, 255, 255);
187 
188     /**
189      * The color cyan.  In the default sRGB space.
190      * @since 1.4
191      */
192     public final static Color CYAN = cyan;
193 
194     /**
195      * The color blue.  In the default sRGB space.
196      */
197     public final static Color blue      = new Color(0, 0, 255);
198 
199     /**
200      * The color blue.  In the default sRGB space.
201      * @since 1.4
202      */
203     public final static Color BLUE = blue;
204 
205     /**
206      * The color value.
207      * @serial
208      * @see #getRGB
209      */
210     int value;
211 
212     /**
213      * The color value in the default sRGB <code>ColorSpace</code> as
214      * <code>float</code> components (no alpha).
215      * If <code>null</code> after object construction, this must be an
216      * sRGB color constructed with 8-bit precision, so compute from the
217      * <code>int</code> color value.
218      * @serial
219      * @see #getRGBColorComponents
220      * @see #getRGBComponents
221      */
222     private float frgbvalue[] = null;
223 
224     /**
225      * The color value in the native <code>ColorSpace</code> as
226      * <code>float</code> components (no alpha).
227      * If <code>null</code> after object construction, this must be an
228      * sRGB color constructed with 8-bit precision, so compute from the
229      * <code>int</code> color value.
230      * @serial
231      * @see #getRGBColorComponents
232      * @see #getRGBComponents
233      */
234     private float fvalue[] = null;
235 
236     /**
237      * The alpha value as a <code>float</code> component.
238      * If <code>frgbvalue</code> is <code>null</code>, this is not valid
239      * data, so compute from the <code>int</code> color value.
240      * @serial
241      * @see #getRGBComponents
242      * @see #getComponents
243      */
244     private float falpha = 0.0f;
245 
246     /**
247      * The <code>ColorSpace</code>.  If <code>null</code>, then it's
248      * default is sRGB.
249      * @serial
250      * @see #getColor
251      * @see #getColorSpace
252      * @see #getColorComponents
253      */
254     private ColorSpace cs = null;
255 
256     /*
257      * JDK 1.1 serialVersionUID
258      */
259      private static final long serialVersionUID = 118526816881161077L;
260 
261     /**
262      * Initialize JNI field and method IDs
263      */
264     private static native void initIDs();
265 
266     static {
267         /** 4112352 - Calling getDefaultToolkit()
268          ** here can cause this class to be accessed before it is fully
269          ** initialized. DON'T DO IT!!!
270          **
271          ** Toolkit.getDefaultToolkit();
272          **/
273 
274         /* ensure that the necessary native libraries are loaded */
275         Toolkit.loadLibraries();
276         if (!GraphicsEnvironment.isHeadless()) {
277             initIDs();
278         }
279     }
280 
281     /**
282      * Checks the color integer components supplied for validity.
283      * Throws an {@link IllegalArgumentException} if the value is out of
284      * range.
285      * @param r the Red component
286      * @param g the Green component
287      * @param b the Blue component
288      **/
289     private static void testColorValueRange(int r, int g, int b, int a) {
290         boolean rangeError = false;
291         String badComponentString = "";
292 
293         if ( a < 0 || a > 255) {
294             rangeError = true;
295             badComponentString = badComponentString + " Alpha";
296         }
297         if ( r < 0 || r > 255) {
298             rangeError = true;
299             badComponentString = badComponentString + " Red";
300         }
301         if ( g < 0 || g > 255) {
302             rangeError = true;
303             badComponentString = badComponentString + " Green";
304         }
305         if ( b < 0 || b > 255) {
306             rangeError = true;
307             badComponentString = badComponentString + " Blue";
308         }
309         if ( rangeError == true ) {
310         throw new IllegalArgumentException("Color parameter outside of expected range:"
311                                            + badComponentString);
312         }
313     }
314 
315     /**
316      * Checks the color <code>float</code> components supplied for
317      * validity.
318      * Throws an <code>IllegalArgumentException</code> if the value is out
319      * of range.
320      * @param r the Red component
321      * @param g the Green component
322      * @param b the Blue component
323      **/
324     private static void testColorValueRange(float r, float g, float b, float a) {
325         boolean rangeError = false;
326         String badComponentString = "";
327         if ( a < 0.0 || a > 1.0) {
328             rangeError = true;
329             badComponentString = badComponentString + " Alpha";
330         }
331         if ( r < 0.0 || r > 1.0) {
332             rangeError = true;
333             badComponentString = badComponentString + " Red";
334         }
335         if ( g < 0.0 || g > 1.0) {
336             rangeError = true;
337             badComponentString = badComponentString + " Green";
338         }
339         if ( b < 0.0 || b > 1.0) {
340             rangeError = true;
341             badComponentString = badComponentString + " Blue";
342         }
343         if ( rangeError == true ) {
344         throw new IllegalArgumentException("Color parameter outside of expected range:"
345                                            + badComponentString);
346         }
347     }
348 
349     /**
350      * Creates an opaque sRGB color with the specified red, green,
351      * and blue values in the range (0 - 255).
352      * The actual color used in rendering depends
353      * on finding the best match given the color space
354      * available for a given output device.
355      * Alpha is defaulted to 255.
356      *
357      * @throws IllegalArgumentException if <code>r</code>, <code>g</code>
358      *        or <code>b</code> are outside of the range
359      *        0 to 255, inclusive
360      * @param r the red component
361      * @param g the green component
362      * @param b the blue component
363      * @see #getRed
364      * @see #getGreen
365      * @see #getBlue
366      * @see #getRGB
367      */
368     public Color(int r, int g, int b) {
369         this(r, g, b, 255);
370     }
371 
372     /**
373      * Creates an sRGB color with the specified red, green, blue, and alpha
374      * values in the range (0 - 255).
375      *
376      * @throws IllegalArgumentException if <code>r</code>, <code>g</code>,
377      *        <code>b</code> or <code>a</code> are outside of the range
378      *        0 to 255, inclusive
379      * @param r the red component
380      * @param g the green component
381      * @param b the blue component
382      * @param a the alpha component
383      * @see #getRed
384      * @see #getGreen
385      * @see #getBlue
386      * @see #getAlpha
387      * @see #getRGB
388      */
389     @ConstructorProperties({"red", "green", "blue", "alpha"})
390     public Color(int r, int g, int b, int a) {
391         value = ((a & 0xFF) << 24) |
392                 ((r & 0xFF) << 16) |
393                 ((g & 0xFF) << 8)  |
394                 ((b & 0xFF) << 0);
395         testColorValueRange(r,g,b,a);
396     }
397 
398     /**
399      * Creates an opaque sRGB color with the specified combined RGB value
400      * consisting of the red component in bits 16-23, the green component
401      * in bits 8-15, and the blue component in bits 0-7.  The actual color
402      * used in rendering depends on finding the best match given the
403      * color space available for a particular output device.  Alpha is
404      * defaulted to 255.
405      *
406      * @param rgb the combined RGB components
407      * @see java.awt.image.ColorModel#getRGBdefault
408      * @see #getRed
409      * @see #getGreen
410      * @see #getBlue
411      * @see #getRGB
412      */
413     public Color(int rgb) {
414         value = 0xff000000 | rgb;
415     }
416 
417     /**
418      * Creates an sRGB color with the specified combined RGBA value consisting
419      * of the alpha component in bits 24-31, the red component in bits 16-23,
420      * the green component in bits 8-15, and the blue component in bits 0-7.
421      * If the <code>hasalpha</code> argument is <code>false</code>, alpha
422      * is defaulted to 255.
423      *
424      * @param rgba the combined RGBA components
425      * @param hasalpha <code>true</code> if the alpha bits are valid;
426      *        <code>false</code> otherwise
427      * @see java.awt.image.ColorModel#getRGBdefault
428      * @see #getRed
429      * @see #getGreen
430      * @see #getBlue
431      * @see #getAlpha
432      * @see #getRGB
433      */
434     public Color(int rgba, boolean hasalpha) {
435         if (hasalpha) {
436             value = rgba;
437         } else {
438             value = 0xff000000 | rgba;
439         }
440     }
441 
442     /**
443      * Creates an opaque sRGB color with the specified red, green, and blue
444      * values in the range (0.0 - 1.0).  Alpha is defaulted to 1.0.  The
445      * actual color used in rendering depends on finding the best
446      * match given the color space available for a particular output
447      * device.
448      *
449      * @throws IllegalArgumentException if <code>r</code>, <code>g</code>
450      *        or <code>b</code> are outside of the range
451      *        0.0 to 1.0, inclusive
452      * @param r the red component
453      * @param g the green component
454      * @param b the blue component
455      * @see #getRed
456      * @see #getGreen
457      * @see #getBlue
458      * @see #getRGB
459      */
460     public Color(float r, float g, float b) {
461         this( (int) (r*255+0.5), (int) (g*255+0.5), (int) (b*255+0.5));
462         testColorValueRange(r,g,b,1.0f);
463         frgbvalue = new float[3];
464         frgbvalue[0] = r;
465         frgbvalue[1] = g;
466         frgbvalue[2] = b;
467         falpha = 1.0f;
468         fvalue = frgbvalue;
469     }
470 
471     /**
472      * Creates an sRGB color with the specified red, green, blue, and
473      * alpha values in the range (0.0 - 1.0).  The actual color
474      * used in rendering depends on finding the best match given the
475      * color space available for a particular output device.
476      * @throws IllegalArgumentException if <code>r</code>, <code>g</code>
477      *        <code>b</code> or <code>a</code> are outside of the range
478      *        0.0 to 1.0, inclusive
479      * @param r the red component
480      * @param g the green component
481      * @param b the blue component
482      * @param a the alpha component
483      * @see #getRed
484      * @see #getGreen
485      * @see #getBlue
486      * @see #getAlpha
487      * @see #getRGB
488      */
489     public Color(float r, float g, float b, float a) {
490         this((int)(r*255+0.5), (int)(g*255+0.5), (int)(b*255+0.5), (int)(a*255+0.5));
491         frgbvalue = new float[3];
492         frgbvalue[0] = r;
493         frgbvalue[1] = g;
494         frgbvalue[2] = b;
495         falpha = a;
496         fvalue = frgbvalue;
497     }
498 
499     /**
500      * Creates a color in the specified <code>ColorSpace</code>
501      * with the color components specified in the <code>float</code>
502      * array and the specified alpha.  The number of components is
503      * determined by the type of the <code>ColorSpace</code>.  For
504      * example, RGB requires 3 components, but CMYK requires 4
505      * components.
506      * @param cspace the <code>ColorSpace</code> to be used to
507      *                  interpret the components
508      * @param components an arbitrary number of color components
509      *                      that is compatible with the <code>ColorSpace</code>
510      * @param alpha alpha value
511      * @throws IllegalArgumentException if any of the values in the
512      *         <code>components</code> array or <code>alpha</code> is
513      *         outside of the range 0.0 to 1.0
514      * @see #getComponents
515      * @see #getColorComponents
516      */
517     public Color(ColorSpace cspace, float components[], float alpha) {
518         boolean rangeError = false;
519         String badComponentString = "";
520         int n = cspace.getNumComponents();
521         fvalue = new float[n];
522         for (int i = 0; i < n; i++) {
523             if (components[i] < 0.0 || components[i] > 1.0) {
524                 rangeError = true;
525                 badComponentString = badComponentString + "Component " + i
526                                      + " ";
527             } else {
528                 fvalue[i] = components[i];
529             }
530         }
531         if (alpha < 0.0 || alpha > 1.0) {
532             rangeError = true;
533             badComponentString = badComponentString + "Alpha";
534         } else {
535             falpha = alpha;
536         }
537         if (rangeError) {
538             throw new IllegalArgumentException(
539                 "Color parameter outside of expected range: " +
540                 badComponentString);
541         }
542         frgbvalue = cspace.toRGB(fvalue);
543         cs = cspace;
544         value = ((((int)(falpha*255)) & 0xFF) << 24) |
545                 ((((int)(frgbvalue[0]*255)) & 0xFF) << 16) |
546                 ((((int)(frgbvalue[1]*255)) & 0xFF) << 8)  |
547                 ((((int)(frgbvalue[2]*255)) & 0xFF) << 0);
548     }
549 
550     /**
551      * Returns the red component in the range 0-255 in the default sRGB
552      * space.
553      * @return the red component.
554      * @see #getRGB
555      */
556     public int getRed() {
557         return (getRGB() >> 16) & 0xFF;
558     }
559 
560     /**
561      * Returns the green component in the range 0-255 in the default sRGB
562      * space.
563      * @return the green component.
564      * @see #getRGB
565      */
566     public int getGreen() {
567         return (getRGB() >> 8) & 0xFF;
568     }
569 
570     /**
571      * Returns the blue component in the range 0-255 in the default sRGB
572      * space.
573      * @return the blue component.
574      * @see #getRGB
575      */
576     public int getBlue() {
577         return (getRGB() >> 0) & 0xFF;
578     }
579 
580     /**
581      * Returns the alpha component in the range 0-255.
582      * @return the alpha component.
583      * @see #getRGB
584      */
585     public int getAlpha() {
586         return (getRGB() >> 24) & 0xff;
587     }
588 
589     /**
590      * Returns the RGB value representing the color in the default sRGB
591      * {@link ColorModel}.
592      * (Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are
593      * blue).
594      * @return the RGB value of the color in the default sRGB
595      *         <code>ColorModel</code>.
596      * @see java.awt.image.ColorModel#getRGBdefault
597      * @see #getRed
598      * @see #getGreen
599      * @see #getBlue
600      * @since JDK1.0
601      */
602     public int getRGB() {
603         return value;
604     }
605 
606     private static final double FACTOR = 0.7;
607 
608     /**
609      * Creates a new <code>Color</code> that is a brighter version of this
610      * <code>Color</code>.
611      * <p>
612      * This method applies an arbitrary scale factor to each of the three RGB
613      * components of this <code>Color</code> to create a brighter version
614      * of this <code>Color</code>.
615      * The {@code alpha} value is preserved.
616      * Although <code>brighter</code> and
617      * <code>darker</code> are inverse operations, the results of a
618      * series of invocations of these two methods might be inconsistent
619      * because of rounding errors.
620      * @return     a new <code>Color</code> object that is
621      *                 a brighter version of this <code>Color</code>
622      *                 with the same {@code alpha} value.
623      * @see        java.awt.Color#darker
624      * @since      JDK1.0
625      */
626     public Color brighter() {
627         int r = getRed();
628         int g = getGreen();
629         int b = getBlue();
630         int alpha = getAlpha();
631 
632         /* From 2D group:
633          * 1. black.brighter() should return grey
634          * 2. applying brighter to blue will always return blue, brighter
635          * 3. non pure color (non zero rgb) will eventually return white
636          */
637         int i = (int)(1.0/(1.0-FACTOR));
638         if ( r == 0 && g == 0 && b == 0) {
639             return new Color(i, i, i, alpha);
640         }
641         if ( r > 0 && r < i ) r = i;
642         if ( g > 0 && g < i ) g = i;
643         if ( b > 0 && b < i ) b = i;
644 
645         return new Color(Math.min((int)(r/FACTOR), 255),
646                          Math.min((int)(g/FACTOR), 255),
647                          Math.min((int)(b/FACTOR), 255),
648                          alpha);
649     }
650 
651     /**
652      * Creates a new <code>Color</code> that is a darker version of this
653      * <code>Color</code>.
654      * <p>
655      * This method applies an arbitrary scale factor to each of the three RGB
656      * components of this <code>Color</code> to create a darker version of
657      * this <code>Color</code>.
658      * The {@code alpha} value is preserved.
659      * Although <code>brighter</code> and
660      * <code>darker</code> are inverse operations, the results of a series
661      * of invocations of these two methods might be inconsistent because
662      * of rounding errors.
663      * @return  a new <code>Color</code> object that is
664      *                    a darker version of this <code>Color</code>
665      *                    with the same {@code alpha} value.
666      * @see        java.awt.Color#brighter
667      * @since      JDK1.0
668      */
669     public Color darker() {
670         return new Color(Math.max((int)(getRed()  *FACTOR), 0),
671                          Math.max((int)(getGreen()*FACTOR), 0),
672                          Math.max((int)(getBlue() *FACTOR), 0),
673                          getAlpha());
674     }
675 
676     /**
677      * Computes the hash code for this <code>Color</code>.
678      * @return     a hash code value for this object.
679      * @since      JDK1.0
680      */
681     public int hashCode() {
682         return value;
683     }
684 
685     /**
686      * Determines whether another object is equal to this
687      * <code>Color</code>.
688      * <p>
689      * The result is <code>true</code> if and only if the argument is not
690      * <code>null</code> and is a <code>Color</code> object that has the same
691      * red, green, blue, and alpha values as this object.
692      * @param       obj   the object to test for equality with this
693      *                          <code>Color</code>
694      * @return      <code>true</code> if the objects are the same;
695      *                             <code>false</code> otherwise.
696      * @since   JDK1.0
697      */
698     public boolean equals(Object obj) {
699         return obj instanceof Color && ((Color)obj).getRGB() == this.getRGB();
700     }
701 
702     /**
703      * Returns a string representation of this <code>Color</code>. This
704      * method is intended to be used only for debugging purposes.  The
705      * content and format of the returned string might vary between
706      * implementations. The returned string might be empty but cannot
707      * be <code>null</code>.
708      *
709      * @return  a string representation of this <code>Color</code>.
710      */
711     public String toString() {
712         return getClass().getName() + "[r=" + getRed() + ",g=" + getGreen() + ",b=" + getBlue() + "]";
713     }
714 
715     /**
716      * Converts a <code>String</code> to an integer and returns the
717      * specified opaque <code>Color</code>. This method handles string
718      * formats that are used to represent octal and hexadecimal numbers.
719      * @param      nm a <code>String</code> that represents
720      *                            an opaque color as a 24-bit integer
721      * @return     the new <code>Color</code> object.
722      * @see        java.lang.Integer#decode
723      * @exception  NumberFormatException  if the specified string cannot
724      *                      be interpreted as a decimal,
725      *                      octal, or hexadecimal integer.
726      * @since      JDK1.1
727      */
728     public static Color decode(String nm) throws NumberFormatException {
729         Integer intval = Integer.decode(nm);
730         int i = intval.intValue();
731         return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF);
732     }
733 
734     /**
735      * Finds a color in the system properties.
736      * <p>
737      * The argument is treated as the name of a system property to
738      * be obtained. The string value of this property is then interpreted
739      * as an integer which is then converted to a <code>Color</code>
740      * object.
741      * <p>
742      * If the specified property is not found or could not be parsed as
743      * an integer then <code>null</code> is returned.
744      * @param    nm the name of the color property
745      * @return   the <code>Color</code> converted from the system
746      *          property.
747      * @see      java.lang.System#getProperty(java.lang.String)
748      * @see      java.lang.Integer#getInteger(java.lang.String)
749      * @see      java.awt.Color#Color(int)
750      * @since    JDK1.0
751      */
752     public static Color getColor(String nm) {
753         return getColor(nm, null);
754     }
755 
756     /**
757      * Finds a color in the system properties.
758      * <p>
759      * The first argument is treated as the name of a system property to
760      * be obtained. The string value of this property is then interpreted
761      * as an integer which is then converted to a <code>Color</code>
762      * object.
763      * <p>
764      * If the specified property is not found or cannot be parsed as
765      * an integer then the <code>Color</code> specified by the second
766      * argument is returned instead.
767      * @param    nm the name of the color property
768      * @param    v    the default <code>Color</code>
769      * @return   the <code>Color</code> converted from the system
770      *          property, or the specified <code>Color</code>.
771      * @see      java.lang.System#getProperty(java.lang.String)
772      * @see      java.lang.Integer#getInteger(java.lang.String)
773      * @see      java.awt.Color#Color(int)
774      * @since    JDK1.0
775      */
776     public static Color getColor(String nm, Color v) {
777         Integer intval = Integer.getInteger(nm);
778         if (intval == null) {
779             return v;
780         }
781         int i = intval.intValue();
782         return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF);
783     }
784 
785     /**
786      * Finds a color in the system properties.
787      * <p>
788      * The first argument is treated as the name of a system property to
789      * be obtained. The string value of this property is then interpreted
790      * as an integer which is then converted to a <code>Color</code>
791      * object.
792      * <p>
793      * If the specified property is not found or could not be parsed as
794      * an integer then the integer value <code>v</code> is used instead,
795      * and is converted to a <code>Color</code> object.
796      * @param    nm  the name of the color property
797      * @param    v   the default color value, as an integer
798      * @return   the <code>Color</code> converted from the system
799      *          property or the <code>Color</code> converted from
800      *          the specified integer.
801      * @see      java.lang.System#getProperty(java.lang.String)
802      * @see      java.lang.Integer#getInteger(java.lang.String)
803      * @see      java.awt.Color#Color(int)
804      * @since    JDK1.0
805      */
806     public static Color getColor(String nm, int v) {
807         Integer intval = Integer.getInteger(nm);
808         int i = (intval != null) ? intval.intValue() : v;
809         return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, (i >> 0) & 0xFF);
810     }
811 
812     /**
813      * Converts the components of a color, as specified by the HSB
814      * model, to an equivalent set of values for the default RGB model.
815      * <p>
816      * The <code>saturation</code> and <code>brightness</code> components
817      * should be floating-point values between zero and one
818      * (numbers in the range 0.0-1.0).  The <code>hue</code> component
819      * can be any floating-point number.  The floor of this number is
820      * subtracted from it to create a fraction between 0 and 1.  This
821      * fractional number is then multiplied by 360 to produce the hue
822      * angle in the HSB color model.
823      * <p>
824      * The integer that is returned by <code>HSBtoRGB</code> encodes the
825      * value of a color in bits 0-23 of an integer value that is the same
826      * format used by the method {@link #getRGB() getRGB}.
827      * This integer can be supplied as an argument to the
828      * <code>Color</code> constructor that takes a single integer argument.
829      * @param     hue   the hue component of the color
830      * @param     saturation   the saturation of the color
831      * @param     brightness   the brightness of the color
832      * @return    the RGB value of the color with the indicated hue,
833      *                            saturation, and brightness.
834      * @see       java.awt.Color#getRGB()
835      * @see       java.awt.Color#Color(int)
836      * @see       java.awt.image.ColorModel#getRGBdefault()
837      * @since     JDK1.0
838      */
839     public static int HSBtoRGB(float hue, float saturation, float brightness) {
840         int r = 0, g = 0, b = 0;
841         if (saturation == 0) {
842             r = g = b = (int) (brightness * 255.0f + 0.5f);
843         } else {
844             float h = (hue - (float)Math.floor(hue)) * 6.0f;
845             float f = h - (float)java.lang.Math.floor(h);
846             float p = brightness * (1.0f - saturation);
847             float q = brightness * (1.0f - saturation * f);
848             float t = brightness * (1.0f - (saturation * (1.0f - f)));
849             switch ((int) h) {
850             case 0:
851                 r = (int) (brightness * 255.0f + 0.5f);
852                 g = (int) (t * 255.0f + 0.5f);
853                 b = (int) (p * 255.0f + 0.5f);
854                 break;
855             case 1:
856                 r = (int) (q * 255.0f + 0.5f);
857                 g = (int) (brightness * 255.0f + 0.5f);
858                 b = (int) (p * 255.0f + 0.5f);
859                 break;
860             case 2:
861                 r = (int) (p * 255.0f + 0.5f);
862                 g = (int) (brightness * 255.0f + 0.5f);
863                 b = (int) (t * 255.0f + 0.5f);
864                 break;
865             case 3:
866                 r = (int) (p * 255.0f + 0.5f);
867                 g = (int) (q * 255.0f + 0.5f);
868                 b = (int) (brightness * 255.0f + 0.5f);
869                 break;
870             case 4:
871                 r = (int) (t * 255.0f + 0.5f);
872                 g = (int) (p * 255.0f + 0.5f);
873                 b = (int) (brightness * 255.0f + 0.5f);
874                 break;
875             case 5:
876                 r = (int) (brightness * 255.0f + 0.5f);
877                 g = (int) (p * 255.0f + 0.5f);
878                 b = (int) (q * 255.0f + 0.5f);
879                 break;
880             }
881         }
882         return 0xff000000 | (r << 16) | (g << 8) | (b << 0);
883     }
884 
885     /**
886      * Converts the components of a color, as specified by the default RGB
887      * model, to an equivalent set of values for hue, saturation, and
888      * brightness that are the three components of the HSB model.
889      * <p>
890      * If the <code>hsbvals</code> argument is <code>null</code>, then a
891      * new array is allocated to return the result. Otherwise, the method
892      * returns the array <code>hsbvals</code>, with the values put into
893      * that array.
894      * @param     r   the red component of the color
895      * @param     g   the green component of the color
896      * @param     b   the blue component of the color
897      * @param     hsbvals  the array used to return the
898      *                     three HSB values, or <code>null</code>
899      * @return    an array of three elements containing the hue, saturation,
900      *                     and brightness (in that order), of the color with
901      *                     the indicated red, green, and blue components.
902      * @see       java.awt.Color#getRGB()
903      * @see       java.awt.Color#Color(int)
904      * @see       java.awt.image.ColorModel#getRGBdefault()
905      * @since     JDK1.0
906      */
907     public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
908         float hue, saturation, brightness;
909         if (hsbvals == null) {
910             hsbvals = new float[3];
911         }
912         int cmax = (r > g) ? r : g;
913         if (b > cmax) cmax = b;
914         int cmin = (r < g) ? r : g;
915         if (b < cmin) cmin = b;
916 
917         brightness = ((float) cmax) / 255.0f;
918         if (cmax != 0)
919             saturation = ((float) (cmax - cmin)) / ((float) cmax);
920         else
921             saturation = 0;
922         if (saturation == 0)
923             hue = 0;
924         else {
925             float redc = ((float) (cmax - r)) / ((float) (cmax - cmin));
926             float greenc = ((float) (cmax - g)) / ((float) (cmax - cmin));
927             float bluec = ((float) (cmax - b)) / ((float) (cmax - cmin));
928             if (r == cmax)
929                 hue = bluec - greenc;
930             else if (g == cmax)
931                 hue = 2.0f + redc - bluec;
932             else
933                 hue = 4.0f + greenc - redc;
934             hue = hue / 6.0f;
935             if (hue < 0)
936                 hue = hue + 1.0f;
937         }
938         hsbvals[0] = hue;
939         hsbvals[1] = saturation;
940         hsbvals[2] = brightness;
941         return hsbvals;
942     }
943 
944     /**
945      * Creates a <code>Color</code> object based on the specified values
946      * for the HSB color model.
947      * <p>
948      * The <code>s</code> and <code>b</code> components should be
949      * floating-point values between zero and one
950      * (numbers in the range 0.0-1.0).  The <code>h</code> component
951      * can be any floating-point number.  The floor of this number is
952      * subtracted from it to create a fraction between 0 and 1.  This
953      * fractional number is then multiplied by 360 to produce the hue
954      * angle in the HSB color model.
955      * @param  h   the hue component
956      * @param  s   the saturation of the color
957      * @param  b   the brightness of the color
958      * @return  a <code>Color</code> object with the specified hue,
959      *                                 saturation, and brightness.
960      * @since   JDK1.0
961      */
962     public static Color getHSBColor(float h, float s, float b) {
963         return new Color(HSBtoRGB(h, s, b));
964     }
965 
966     /**
967      * Returns a <code>float</code> array containing the color and alpha
968      * components of the <code>Color</code>, as represented in the default
969      * sRGB color space.
970      * If <code>compArray</code> is <code>null</code>, an array of length
971      * 4 is created for the return value.  Otherwise,
972      * <code>compArray</code> must have length 4 or greater,
973      * and it is filled in with the components and returned.
974      * @param compArray an array that this method fills with
975      *                  color and alpha components and returns
976      * @return the RGBA components in a <code>float</code> array.
977      */
978     public float[] getRGBComponents(float[] compArray) {
979         float[] f;
980         if (compArray == null) {
981             f = new float[4];
982         } else {
983             f = compArray;
984         }
985         if (frgbvalue == null) {
986             f[0] = ((float)getRed())/255f;
987             f[1] = ((float)getGreen())/255f;
988             f[2] = ((float)getBlue())/255f;
989             f[3] = ((float)getAlpha())/255f;
990         } else {
991             f[0] = frgbvalue[0];
992             f[1] = frgbvalue[1];
993             f[2] = frgbvalue[2];
994             f[3] = falpha;
995         }
996         return f;
997     }
998 
999     /**
1000      * Returns a <code>float</code> array containing only the color
1001      * components of the <code>Color</code>, in the default sRGB color
1002      * space.  If <code>compArray</code> is <code>null</code>, an array of
1003      * length 3 is created for the return value.  Otherwise,
1004      * <code>compArray</code> must have length 3 or greater, and it is
1005      * filled in with the components and returned.
1006      * @param compArray an array that this method fills with color
1007      *          components and returns
1008      * @return the RGB components in a <code>float</code> array.
1009      */
1010     public float[] getRGBColorComponents(float[] compArray) {
1011         float[] f;
1012         if (compArray == null) {
1013             f = new float[3];
1014         } else {
1015             f = compArray;
1016         }
1017         if (frgbvalue == null) {
1018             f[0] = ((float)getRed())/255f;
1019             f[1] = ((float)getGreen())/255f;
1020             f[2] = ((float)getBlue())/255f;
1021         } else {
1022             f[0] = frgbvalue[0];
1023             f[1] = frgbvalue[1];
1024             f[2] = frgbvalue[2];
1025         }
1026         return f;
1027     }
1028 
1029     /**
1030      * Returns a <code>float</code> array containing the color and alpha
1031      * components of the <code>Color</code>, in the
1032      * <code>ColorSpace</code> of the <code>Color</code>.
1033      * If <code>compArray</code> is <code>null</code>, an array with
1034      * length equal to the number of components in the associated
1035      * <code>ColorSpace</code> plus one is created for
1036      * the return value.  Otherwise, <code>compArray</code> must have at
1037      * least this length and it is filled in with the components and
1038      * returned.
1039      * @param compArray an array that this method fills with the color and
1040      *          alpha components of this <code>Color</code> in its
1041      *          <code>ColorSpace</code> and returns
1042      * @return the color and alpha components in a <code>float</code>
1043      *          array.
1044      */
1045     public float[] getComponents(float[] compArray) {
1046         if (fvalue == null)
1047             return getRGBComponents(compArray);
1048         float[] f;
1049         int n = fvalue.length;
1050         if (compArray == null) {
1051             f = new float[n + 1];
1052         } else {
1053             f = compArray;
1054         }
1055         for (int i = 0; i < n; i++) {
1056             f[i] = fvalue[i];
1057         }
1058         f[n] = falpha;
1059         return f;
1060     }
1061 
1062     /**
1063      * Returns a <code>float</code> array containing only the color
1064      * components of the <code>Color</code>, in the
1065      * <code>ColorSpace</code> of the <code>Color</code>.
1066      * If <code>compArray</code> is <code>null</code>, an array with
1067      * length equal to the number of components in the associated
1068      * <code>ColorSpace</code> is created for
1069      * the return value.  Otherwise, <code>compArray</code> must have at
1070      * least this length and it is filled in with the components and
1071      * returned.
1072      * @param compArray an array that this method fills with the color
1073      *          components of this <code>Color</code> in its
1074      *          <code>ColorSpace</code> and returns
1075      * @return the color components in a <code>float</code> array.
1076      */
1077     public float[] getColorComponents(float[] compArray) {
1078         if (fvalue == null)
1079             return getRGBColorComponents(compArray);
1080         float[] f;
1081         int n = fvalue.length;
1082         if (compArray == null) {
1083             f = new float[n];
1084         } else {
1085             f = compArray;
1086         }
1087         for (int i = 0; i < n; i++) {
1088             f[i] = fvalue[i];
1089         }
1090         return f;
1091     }
1092 
1093     /**
1094      * Returns a <code>float</code> array containing the color and alpha
1095      * components of the <code>Color</code>, in the
1096      * <code>ColorSpace</code> specified by the <code>cspace</code>
1097      * parameter.  If <code>compArray</code> is <code>null</code>, an
1098      * array with length equal to the number of components in
1099      * <code>cspace</code> plus one is created for the return value.
1100      * Otherwise, <code>compArray</code> must have at least this
1101      * length, and it is filled in with the components and returned.
1102      * @param cspace a specified <code>ColorSpace</code>
1103      * @param compArray an array that this method fills with the
1104      *          color and alpha components of this <code>Color</code> in
1105      *          the specified <code>ColorSpace</code> and returns
1106      * @return the color and alpha components in a <code>float</code>
1107      *          array.
1108      */
1109     public float[] getComponents(ColorSpace cspace, float[] compArray) {
1110         if (cs == null) {
1111             cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
1112         }
1113         float f[];
1114         if (fvalue == null) {
1115             f = new float[3];
1116             f[0] = ((float)getRed())/255f;
1117             f[1] = ((float)getGreen())/255f;
1118             f[2] = ((float)getBlue())/255f;
1119         } else {
1120             f = fvalue;
1121         }
1122         float tmp[] = cs.toCIEXYZ(f);
1123         float tmpout[] = cspace.fromCIEXYZ(tmp);
1124         if (compArray == null) {
1125             compArray = new float[tmpout.length + 1];
1126         }
1127         for (int i = 0 ; i < tmpout.length ; i++) {
1128             compArray[i] = tmpout[i];
1129         }
1130         if (fvalue == null) {
1131             compArray[tmpout.length] = ((float)getAlpha())/255f;
1132         } else {
1133             compArray[tmpout.length] = falpha;
1134         }
1135         return compArray;
1136     }
1137 
1138     /**
1139      * Returns a <code>float</code> array containing only the color
1140      * components of the <code>Color</code> in the
1141      * <code>ColorSpace</code> specified by the <code>cspace</code>
1142      * parameter. If <code>compArray</code> is <code>null</code>, an array
1143      * with length equal to the number of components in
1144      * <code>cspace</code> is created for the return value.  Otherwise,
1145      * <code>compArray</code> must have at least this length, and it is
1146      * filled in with the components and returned.
1147      * @param cspace a specified <code>ColorSpace</code>
1148      * @param compArray an array that this method fills with the color
1149      *          components of this <code>Color</code> in the specified
1150      *          <code>ColorSpace</code>
1151      * @return the color components in a <code>float</code> array.
1152      */
1153     public float[] getColorComponents(ColorSpace cspace, float[] compArray) {
1154         if (cs == null) {
1155             cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
1156         }
1157         float f[];
1158         if (fvalue == null) {
1159             f = new float[3];
1160             f[0] = ((float)getRed())/255f;
1161             f[1] = ((float)getGreen())/255f;
1162             f[2] = ((float)getBlue())/255f;
1163         } else {
1164             f = fvalue;
1165         }
1166         float tmp[] = cs.toCIEXYZ(f);
1167         float tmpout[] = cspace.fromCIEXYZ(tmp);
1168         if (compArray == null) {
1169             return tmpout;
1170         }
1171         for (int i = 0 ; i < tmpout.length ; i++) {
1172             compArray[i] = tmpout[i];
1173         }
1174         return compArray;
1175     }
1176 
1177     /**
1178      * Returns the <code>ColorSpace</code> of this <code>Color</code>.
1179      * @return this <code>Color</code> object's <code>ColorSpace</code>.
1180      */
1181     public ColorSpace getColorSpace() {
1182         if (cs == null) {
1183             cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
1184         }
1185         return cs;
1186     }
1187 
1188     /**
1189      * Creates and returns a {@link PaintContext} used to
1190      * generate a solid color field pattern.
1191      * See the {@link Paint#createContext specification} of the
1192      * method in the {@link Paint} interface for information
1193      * on null parameter handling.
1194      *
1195      * @param cm the preferred {@link ColorModel} which represents the most convenient
1196      *           format for the caller to receive the pixel data, or {@code null}
1197      *           if there is no preference.
1198      * @param r the device space bounding box
1199      *                     of the graphics primitive being rendered.
1200      * @param r2d the user space bounding box
1201      *                   of the graphics primitive being rendered.
1202      * @param xform the {@link AffineTransform} from user
1203      *              space into device space.
1204      * @param hints the set of hints that the context object can use to
1205      *              choose between rendering alternatives.
1206      * @return the {@code PaintContext} for
1207      *         generating color patterns.
1208      * @see Paint
1209      * @see PaintContext
1210      * @see ColorModel
1211      * @see Rectangle
1212      * @see Rectangle2D
1213      * @see AffineTransform
1214      * @see RenderingHints
1215      */
1216     public synchronized PaintContext createContext(ColorModel cm, Rectangle r,
1217                                                    Rectangle2D r2d,
1218                                                    AffineTransform xform,
1219                                                    RenderingHints hints) {
1220         return new ColorPaintContext(getRGB(), cm);
1221     }
1222 
1223     /**
1224      * Returns the transparency mode for this <code>Color</code>.  This is
1225      * required to implement the <code>Paint</code> interface.
1226      * @return this <code>Color</code> object's transparency mode.
1227      * @see Paint
1228      * @see Transparency
1229      * @see #createContext
1230      */
1231     public int getTransparency() {
1232         int alpha = getAlpha();
1233         if (alpha == 0xff) {
1234             return Transparency.OPAQUE;
1235         }
1236         else if (alpha == 0) {
1237             return Transparency.BITMASK;
1238         }
1239         else {
1240             return Transparency.TRANSLUCENT;
1241         }
1242     }
1243 
1244 }