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  *
  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 }