Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.scene.paint;
027
028import java.util.HashMap;
029import java.util.Map;
030
031import javafx.animation.Interpolatable;
032
033import com.sun.javafx.Utils;
034import com.sun.javafx.beans.annotations.Default;
035import com.sun.javafx.tk.Toolkit;
036
037// NOTE: this definition, while correct, contains a lot of information which
038// is irrelevant to most developers. We should get to the basic definition and
039// usage patterns sooner.
040
041/**
042 * The Color class is used to encapsulate colors in the default sRGB color space.
043 * Every color has an implicit alpha value of 1.0 or an explicit one provided
044 * in the constructor. The alpha value defines the transparency of a color
045 * and can be  represented by a double value in the range 0.0-1.0 or 0-255.
046 * An alpha value of 1.0 or 255 means that the color is completely opaque
047 * and an alpha value of 0 or 0.0 means that the color is completely transparent.
048 * When constructing a {@code Color} with an explicit alpha or getting
049 * the color/alpha components of a Color,
050 * the color components are never premultiplied by the alpha component.
051 * </p>
052 *
053 * <p>{@code Color}s can be created with the constructor or with one of several
054 * utility methods.  The following lines of code all create the same
055 * blue color:</p>
056 *
057 * <pre><code>
058 * Color c = Color.BLUE;   //use the blue constant
059 * Color c = new Color(0,0,1,1.0); // standard constructor, use 0->1.0 values, explicit alpha of 1.0
060 *
061 * Color c = Color.color(0,0,1.0); //use 0->1.0 values. implicit alpha of 1.0
062 * Color c = Color.color(0,0,1.0,1.0); //use 0->1.0 values, explicit alpha of 1.0
063 *
064 * Color c = Color.rgb(0,0,255); //use 0->255 integers, implicit alpha of 1.0
065 * Color c = Color.rgb(0,0,255,1.0); //use 0->255 integers, explicit alpha of 1.0
066 *
067 * Color c = Color.hsb(270,1.0,1.0); //hue = 270, saturation & value = 1.0. inplicit alpha of 1.0
068 * Color c = Color.hsb(270,1.0,1.0,1.0); //hue = 270, saturation & value = 1.0, explicit alpha of 1.0
069 *
070 * Color c = Color.web("0x0000FF",1.0);// blue as a hex web value, explicit alpha
071 * Color c = Color.web("0x0000FF");// blue as a hex web value, implicit alpha
072 * Color c = Color.web("0x00F");// blue as a short hex web value, implicit alpha
073 * Color c = Color.web("#0000FF",1.0);// blue as a hex web value, explicit alpha
074 * Color c = Color.web("#0000FF");// blue as a hex web value, implicit alpha
075 * Color c = Color.web("#00F");// blue as a short hex web value, implicit alpha
076 * Color c = Color.web("0000FF",1.0);// blue as a hex web value, explicit alpha
077 * Color c = Color.web("0000FF");// blue as a hex web value, implicit alpha
078 * Color c = Color.web("00F");// blue as a short hex web value, implicit alpha
079 * Color c = Color.web("rgba(0,0,255,1.0)");// blue as an rgb web value, explicit alpha
080 * Color c = Color.web("rgb(0,0,255)");// blue as an rgb web value, implicit alpha
081 * Color c = Color.web("rgba(0,0,100%,1.0)");// blue as an rgb percent web value, explicit alpha
082 * Color c = Color.web("rgb(0,0,100%)");// blue as an rgb percent web value, implicit alpha
083 * Color c = Color.web("hsla(270,100%,100%,1.0)");// blue as an hsl web value, explicit alpha
084 * Color c = Color.web("hsl(270,100%,100%)");// blue as an hsl web value, implicit alpha
085 * </code></pre>
086 *
087 * <p>
088 * The creation of a {@code Color} will throw {@code IllegalArgumentException} if any
089 * of the values are out of range.
090 * </p>
091 *
092 * <p>
093 * For example:
094 * <pre><code>
095 * Rectangle rec1 = new Rectangle(5, 5, 50, 40);
096 * rec1.setFill(Color.RED);
097 * rec1.setStroke(Color.GREEN);
098 * rec1.setStrokeWidth(3);
099 *
100 * Rectangle rec2 = new Rectangle(65, 5, 50, 40);
101 * rec2.setFill(Color.rgb(91, 127, 255));
102 * rec2.setStroke(Color.hsb(40, 0.7, 0.8));
103 * rec2.setStrokeWidth(3);
104 * </code></pre>
105 * </p>
106 */
107public class Color extends Paint implements Interpolatable<Color> { // final
108
109    /**
110     * Brightness change factor for darker() and brighter() methods.
111     */
112    private static final double DARKER_BRIGHTER_FACTOR = 0.7;
113
114    /**
115     * Saturation change factor for saturate() and desaturate() methods.
116     */
117    private static final double SATURATE_DESATURATE_FACTOR = 0.7;
118
119    /**
120     * Creates an sRGB color with the specified red, green and blue values
121     * in the range {@code 0.0-1.0}, and a given opacity.
122     *
123     * @param red the red component, in the range {@code 0.0-1.0}
124     * @param green the green component, in the range {@code 0.0-1.0}
125     * @param blue the blue component, in the range {@code 0.0-1.0}
126     * @param opacity the opacity component, in the range {@code 0.0-1.0}
127     * @return the {@code Color}
128     * @throws IllegalArgumentException if any value is out of range
129     */
130    public static Color color(double red, double green, double blue, @Default("1") double opacity) {
131        return new Color(red, green, blue, opacity);
132    }
133
134    /**
135     * Creates an opaque sRGB color with the specified red, green and blue values
136     * in the range {@code 0.0-1.0}.
137     *
138     * @param red the red component, in the range {@code 0.0-1.0}
139     * @param green the green component, in the range {@code 0.0-1.0}
140     * @param blue the blue component, in the range {@code 0.0-1.0}
141     * @return the {@code Color}
142     * @throws IllegalArgumentException if any value is out of range
143     */
144    public static Color color(double red, double green, double blue) {
145        return new Color(red, green, blue, 1);
146    }
147
148    /**
149     * Creates an sRGB color with the specified RGB values in the range {@code 0-255},
150     * and a given opacity.
151     *
152     * @param red the red component, in the range {@code 0-255}
153     * @param green the green component, in the range {@code 0-255}
154     * @param blue the blue component, in the range {@code 0-255}
155     * @param opacity the opacity component, in the range {@code 0.0-1.0}
156     * @return the {@code Color}
157     * @throws IllegalArgumentException if any value is out of range
158     */
159    public static Color rgb(int red, int green, int blue, double opacity) {
160        checkRGB(red, green, blue);
161        return new Color(
162            red / 255.0,
163            green / 255.0,
164            blue / 255.0,
165            opacity);
166    }
167
168    /**
169     * Creates an opaque sRGB color with the specified RGB values in the range {@code 0-255}.
170     *
171     * @param red the red component, in the range {@code 0-255}
172     * @param green the green component, in the range {@code 0-255}
173     * @param blue the blue component, in the range {@code 0-255}
174     * @return the {@code Color}
175     * @throws IllegalArgumentException if any value is out of range
176     */
177    public static Color rgb(int red, int green, int blue) {
178        checkRGB(red, green, blue);
179        return new Color(
180            red / 255.0,
181            green / 255.0,
182            blue / 255.0,
183            1.0);
184    }
185
186
187    /**
188     * This is a shortcut for {@code rgb(gray, gray, gray)}.
189     */
190    public static Color grayRgb(int gray) {
191        return rgb(gray, gray, gray);
192    }
193
194    /**
195     * This is a shortcut for {@code rgb(gray, gray, gray, opacity)}.
196     */
197    public static Color grayRgb(int gray, double opacity) {
198        return rgb(gray, gray, gray, opacity);
199    }
200
201    /**
202     * Creates a grey color.
203     * @param gray color on gray scale in the range
204     *             {@code 0.0} (black) - {@code 1.0} (white).
205     * @param opacity the opacity component, in the range {@code 0.0-1.0}
206     * @return the {@code Color}
207     * @throws IllegalArgumentException if any value is out of range
208     */
209    public static Color gray(double gray, double opacity) {
210        return new Color(gray, gray, gray, opacity);
211    }
212
213    /**
214     * Creates an opaque grey color.
215     * @param gray color on gray scale in the range
216     *             {@code 0.0} (black) - {@code 1.0} (white).
217     * @return the {@code Color}
218     * @throws IllegalArgumentException if any value is out of range
219     */
220    public static Color gray(double gray) {
221        return gray(gray, 1.0);
222    }
223
224    private static void checkRGB(int red, int green, int blue) {
225        if (red < 0 || red > 255) {
226            throw new IllegalArgumentException("Color.rgb's red parameter (" + red + ") expects color values 0-255");
227        }
228        if (green < 0 || green > 255) {
229            throw new IllegalArgumentException("Color.rgb's green parameter (" + green + ") expects color values 0-255");
230        }
231        if (blue < 0 || blue > 255) {
232            throw new IllegalArgumentException("Color.rgb's blue parameter (" + blue + ") expects color values 0-255");
233        }
234    }
235
236    /**
237     * Creates a {@code Color} based on the specified values in the HSB color model,
238     * and a given opacity.
239     *
240     * @param hue the hue, in degrees
241     * @param saturation the saturation, {@code 0.0 to 1.0}
242     * @param brightness the brightness, {@code 0.0 to 1.0}
243     * @param opacity the opacity, {@code 0.0 to 1.0}
244     * @return the {@code Color}
245     * @throws IllegalArgumentException if {@code saturation}, {@code brightness} or
246     *         {@code opacity} are out of range
247     */
248    public static Color hsb(double hue, double saturation, double brightness, double opacity) {
249        checkSB(saturation, brightness);
250        double[] rgb = Utils.HSBtoRGB(hue, saturation, brightness);
251        Color result = new Color(rgb[0], rgb[1], rgb[2], opacity);
252        return result;
253    }
254
255    /**
256     * Creates an opaque {@code Color} based on the specified values in the HSB color model.
257     *
258     * @param hue the hue, in degrees
259     * @param saturation the saturation, {@code 0.0 to 1.0}
260     * @param brightness the brightness, {@code 0.0 to 1.0}
261     * @return the {@code Color}
262     * @throws IllegalArgumentException if {@code saturation} or {@code brightness} are
263     *         out of range
264     */
265    public static Color hsb(double hue, double saturation, double brightness) {
266        return hsb(hue, saturation, brightness, 1.0);
267    }
268
269    private static void checkSB(double saturation, double brightness) {
270        if (saturation < 0.0 || saturation > 1.0) {
271            throw new IllegalArgumentException("Color.hsb's saturation parameter (" + saturation + ") expects values 0.0-1.0");
272        }
273        if (brightness < 0.0 || brightness > 1.0) {
274            throw new IllegalArgumentException("Color.hsb's brightness parameter (" + brightness + ") expects values 0.0-1.0");
275        }
276    }
277
278    /**
279     * Creates an RGB color specified with an HTML or CSS attribute string.
280     *
281     * <p>
282     * This method supports the following formats:
283     * <ul>
284     * <li>Any standard HTML color name
285     * <li>An HTML long or short format hex string with an optional hex alpha
286     * channel.
287     * Hexadecimal values may be preceded by either {@code "0x"} or {@code "#"}
288     * and can either be 2 digits in the range {@code 00} to {@code 0xFF} or a
289     * single digit in the range {@code 0} to {@code F}.
290     * <li>An {@code rgb(r,g,b)} or {@code rgba(r,g,b,a)} format string.
291     * Each of the {@code r}, {@code g}, or {@code b} values can be an integer
292     * from 0 to 255 or a floating point percentage value from 0.0 to 100.0
293     * followed by the percent ({@code %}) character.
294     * The alpha component, if present, is a
295     * floating point value from 0.0 to 1.0.  Spaces are allowed before or
296     * after the numbers and between the percentage number and its percent
297     * sign ({@code %}).
298     * <li>An {@code hsl(h,s,l)} or {@code hsla(h,s,l,a)} format string.
299     * The {@code h} value is a floating point number from 0.0 to 360.0
300     * representing the hue angle on a color wheel in degrees with
301     * {@code 0.0} or {@code 360.0} representing red, {@code 120.0}
302     * representing green, and {@code 240.0} representing blue.  The
303     * {@code s} value is the saturation of the desired color represented
304     * as a floating point percentage from gray ({@code 0.0}) to
305     * the fully saturated color ({@code 100.0}) and the {@code l} value
306     * is the desired lightness or brightness of the desired color represented
307     * as a floating point percentage from black ({@code 0.0}) to the full
308     * brightness of the color ({@code 100.0}).
309     * The alpha component, if present, is a floating
310     * point value from 0.0 to 1.0.  Spaces are allowed before or
311     * after the numbers and between the percentage number and its percent
312     * sign ({@code %}).
313     * </ul>
314     *
315     * <p>For formats without an alpha component and for named colors, opacity
316     * is set according to the {@code opacity} argument. For colors specified
317     * with an alpha component, the resulting opacity is a combination of the
318     * parsed alpha component and the {@code opacity} argument, so a
319     * transparent color becomes more transparent by specifying opacity.</p>
320     *
321     * <p>Examples:</p>
322     * <div class="classUseContainer">
323     * <table class="overviewSummary" border="0" cellpadding="3" cellspacing="0">
324     * <tr>
325     * <th class="colFirst">Web Format String</th>
326     * <th class="colLast">Equivalent constructor or factory call</th>
327     * </tr>
328     * <tr class="rowColor">
329     * <td class="colFirst"><code>Color.web("orange", 0.5);</code></td>
330     * <td class="colLast"><code>new Color(1.0, 0xA5/255.0, 0.0, 0.5)</code></td>
331     * </tr>
332     * <tr class="altColor">
333     * <td class="colFirst"><code>Color.web("0xff66cc33", 0.5);</code></td>
334     * <td class="colLast"><code>new Color(1.0, 0.4, 0.8, 0.1)</code></td>
335     * </tr>
336     * <tr class="rowColor">
337     * <td class="colFirst"><code>Color.web("0xff66cc", 0.5);</code></td>
338     * <td class="colLast"><code>new Color(1.0, 0.4, 0.8, 0.5)</code></td>
339     * </tr>
340     * <tr class="altColor">
341     * <td class="colFirst"><code>Color.web("#ff66cc", 0.5);</code></td>
342     * <td class="colLast"><code>new Color(1.0, 0.4, 0.8, 0.5)</code></td>
343     * </tr>
344     * <tr class="rowColor">
345     * <td class="colFirst"><code>Color.web("#f68", 0.5);</code></td>
346     * <td class="colLast"><code>new Color(1.0, 0.4, 0.8, 0.5)</code></td>
347     * </tr>
348     * <tr class="altColor">
349     * <td class="colFirst"><code>Color.web("rgb(255,102,204)", 0.5);</code></td>
350     * <td class="colLast"><code>new Color(1.0, 0.4, 0.8, 0.5)</code></td>
351     * </tr>
352     * <tr class="rowColor">
353     * <td class="colFirst"><code>Color.web("rgb(100%,50%,50%)", 0.5);</code></td>
354     * <td class="colLast"><code>new Color(1.0, 0.5, 0.5, 0.5)</code></td>
355     * </tr>
356     * <tr class="altColor">
357     * <td class="colFirst"><code>Color.web("rgb(255,50%,50%,0.25)", 0.5);</code></td>
358     * <td class="colLast"><code>new Color(1.0, 0.5, 0.5, 0.125)</code></td>
359     * </tr>
360     * <tr class="rowColor">
361     * <td class="colFirst"><code>Color.web("hsl(240,100%,100%)", 0.5);</code></td>
362     * <td class="colLast"><code>Color.hsb(240.0, 1.0, 1.0, 0.5)</code></td>
363     * </tr>
364     * <tr class="altColor">
365     * <td style="border-bottom:1px solid" class="colFirst">
366     *     <code>Color.web("hsla(120,0%,0%,0.25)", 0.5);</code>
367     * </td>
368     * <td style="border-bottom:1px solid" class="colLast">
369     *     <code>Color.hsb(120.0, 0.0, 0.0, 0.125)</code>
370     * </td>
371     * </tr>
372     * </table>
373     * </div>
374     *
375     * @param colorString the name or numeric representation of the color
376     *                    in one of the supported formats
377     * @param opacity the opacity component in range from 0.0 (transparent)
378     *                to 1.0 (opaque)
379     * @throws NullPointerException if {@code colorString} is {@code null}
380     * @throws IllegalArgumentException if {@code colorString} specifies
381     *      an unsupported color name or contains an illegal numeric value
382     */
383    public static Color web(String colorString, double opacity) {
384        if (colorString == null) {
385            throw new NullPointerException(
386                    "The color components or name must be specified");
387        }
388        if (colorString.isEmpty()) {
389            throw new IllegalArgumentException("Invalid color specification");
390        }
391
392        String color = colorString.toLowerCase();
393
394        if (color.startsWith("#")) {
395            color = color.substring(1);
396        } else if (color.startsWith("0x")) {
397            color = color.substring(2);
398        } else if (color.startsWith("rgb")) {
399            if (color.startsWith("(", 3)) {
400                return parseRGBColor(color, 4, false, opacity);
401            } else if (color.startsWith("a(", 3)) {
402                return parseRGBColor(color, 5, true, opacity);
403            }
404        } else if (color.startsWith("hsl")) {
405            if (color.startsWith("(", 3)) {
406                return parseHSLColor(color, 4, false, opacity);
407            } else if (color.startsWith("a(", 3)) {
408                return parseHSLColor(color, 5, true, opacity);
409            }
410        } else {
411            Color col = NamedColors.get(color);
412            if (col != null) {
413                if (opacity == 1.0) {
414                    return col;
415                } else {
416                    return Color.color(col.red, col.green, col.blue, opacity);
417                }
418            }
419        }
420
421        int len = color.length();
422
423        try {
424            int r;
425            int g;
426            int b;
427            int a;
428
429            if (len == 3) {
430                r = Integer.parseInt(color.substring(0, 1), 16);
431                g = Integer.parseInt(color.substring(1, 2), 16);
432                b = Integer.parseInt(color.substring(2, 3), 16);
433                return Color.color(r / 15.0, g / 15.0, b / 15.0, opacity);
434            } else if (len == 4) {
435                r = Integer.parseInt(color.substring(0, 1), 16);
436                g = Integer.parseInt(color.substring(1, 2), 16);
437                b = Integer.parseInt(color.substring(2, 3), 16);
438                a = Integer.parseInt(color.substring(3, 4), 16);
439                return Color.color(r / 15.0, g / 15.0, b / 15.0,
440                        opacity * a / 15.0);
441            } else if (len == 6) {
442                r = Integer.parseInt(color.substring(0, 2), 16);
443                g = Integer.parseInt(color.substring(2, 4), 16);
444                b = Integer.parseInt(color.substring(4, 6), 16);
445                return Color.rgb(r, g, b, opacity);
446            } else if (len == 8) {
447                r = Integer.parseInt(color.substring(0, 2), 16);
448                g = Integer.parseInt(color.substring(2, 4), 16);
449                b = Integer.parseInt(color.substring(4, 6), 16);
450                a = Integer.parseInt(color.substring(6, 8), 16);
451                return Color.rgb(r, g, b, opacity * a / 255.0);
452            }
453        } catch (NumberFormatException nfe) {}
454
455        throw new IllegalArgumentException("Invalid color specification");
456    }
457
458    private static Color parseRGBColor(String color, int roff,
459                                       boolean hasAlpha, double a)
460    {
461        try {
462            int rend = color.indexOf(',', roff);
463            int gend = rend < 0 ? -1 : color.indexOf(',', rend+1);
464            int bend = gend < 0 ? -1 : color.indexOf(hasAlpha ? ',' : ')', gend+1);
465            int aend = hasAlpha ? (bend < 0 ? -1 : color.indexOf(')', bend+1)) : bend;
466            if (aend >= 0) {
467                double r = parseComponent(color, roff, rend, PARSE_COMPONENT);
468                double g = parseComponent(color, rend+1, gend, PARSE_COMPONENT);
469                double b = parseComponent(color, gend+1, bend, PARSE_COMPONENT);
470                if (hasAlpha) {
471                    a *= parseComponent(color, bend+1, aend, PARSE_ALPHA);
472                }
473                return new Color(r, g, b, a);
474            }
475        } catch (NumberFormatException nfe) {}
476
477        throw new IllegalArgumentException("Invalid color specification");
478    }
479
480    private static Color parseHSLColor(String color, int hoff,
481                                       boolean hasAlpha, double a)
482    {
483        try {
484            int hend = color.indexOf(',', hoff);
485            int send = hend < 0 ? -1 : color.indexOf(',', hend+1);
486            int lend = send < 0 ? -1 : color.indexOf(hasAlpha ? ',' : ')', send+1);
487            int aend = hasAlpha ? (lend < 0 ? -1 : color.indexOf(')', lend+1)) : lend;
488            if (aend >= 0) {
489                double h = parseComponent(color, hoff, hend, PARSE_ANGLE);
490                double s = parseComponent(color, hend+1, send, PARSE_PERCENT);
491                double l = parseComponent(color, send+1, lend, PARSE_PERCENT);
492                if (hasAlpha) {
493                    a *= parseComponent(color, lend+1, aend, PARSE_ALPHA);
494                }
495                return Color.hsb(h, s, l, a);
496            }
497        } catch (NumberFormatException nfe) {}
498
499        throw new IllegalArgumentException("Invalid color specification");
500    }
501
502    private static final int PARSE_COMPONENT = 0; // percent, or clamped to [0,255] => [0,1]
503    private static final int PARSE_PERCENT = 1; // clamped to [0,100]% => [0,1]
504    private static final int PARSE_ANGLE = 2; // clamped to [0,360]
505    private static final int PARSE_ALPHA = 3; // clamped to [0.0,1.0]
506    private static double parseComponent(String color, int off, int end, int type) {
507        color = color.substring(off, end).trim();
508        if (color.endsWith("%")) {
509            if (type > PARSE_PERCENT) {
510                throw new IllegalArgumentException("Invalid color specification");
511            }
512            type = PARSE_PERCENT;
513            color = color.substring(0, color.length()-1).trim();
514        } else if (type == PARSE_PERCENT) {
515            throw new IllegalArgumentException("Invalid color specification");
516        }
517        double c = ((type == PARSE_COMPONENT)
518                    ? Integer.parseInt(color)
519                    : Double.parseDouble(color));
520        switch (type) {
521            case PARSE_ALPHA:
522                return (c < 0.0) ? 0.0 : ((c > 1.0) ? 1.0 : c);
523            case PARSE_PERCENT:
524                return (c <= 0.0) ? 0.0 : ((c >= 100.0) ? 1.0 : (c / 100.0));
525            case PARSE_COMPONENT:
526                return (c <= 0.0) ? 0.0 : ((c >= 255.0) ? 1.0 : (c / 255.0));
527            case PARSE_ANGLE:
528                return ((c < 0.0)
529                        ? ((c % 360.0) + 360.0)
530                        : ((c > 360.0)
531                            ? (c % 360.0)
532                            : c));
533        }
534
535        throw new IllegalArgumentException("Invalid color specification");
536    }
537
538    /**
539     * Creates an RGB color specified with an HTML or CSS attribute string.
540     *
541     * <p>
542     * This method supports the following formats:
543     * <ul>
544     * <li>Any standard HTML color name
545     * <li>An HTML long or short format hex string with an optional hex alpha
546     * channel.
547     * Hexadecimal values may be preceded by either {@code "0x"} or {@code "#"}
548     * and can either be 2 digits in the range {@code 00} to {@code 0xFF} or a
549     * single digit in the range {@code 0} to {@code F}.
550     * <li>An {@code rgb(r,g,b)} or {@code rgba(r,g,b,a)} format string.
551     * Each of the {@code r}, {@code g}, or {@code b} values can be an integer
552     * from 0 to 255 or a floating point percentage value from 0.0 to 100.0
553     * followed by the percent ({@code %}) character.
554     * The alpha component, if present, is a
555     * floating point value from 0.0 to 1.0.  Spaces are allowed before or
556     * after the numbers and between the percentage number and its percent
557     * sign ({@code %}).
558     * <li>An {@code hsl(h,s,l)} or {@code hsla(h,s,l,a)} format string.
559     * The {@code h} value is a floating point number from 0.0 to 360.0
560     * representing the hue angle on a color wheel in degrees with
561     * {@code 0.0} or {@code 360.0} representing red, {@code 120.0}
562     * representing green, and {@code 240.0} representing blue.  The
563     * {@code s} value is the saturation of the desired color represented
564     * as a floating point percentage from gray ({@code 0.0}) to
565     * the fully saturated color ({@code 100.0}) and the {@code l} value
566     * is the desired lightness or brightness of the desired color represented
567     * as a floating point percentage from black ({@code 0.0}) to the full
568     * brightness of the color ({@code 100.0}).
569     * The alpha component, if present, is a floating
570     * point value from 0.0 to 1.0.  Spaces are allowed before or
571     * after the numbers and between the percentage number and its percent
572     * sign ({@code %}).
573     * </ul>
574     *
575     * <p>Examples:</p>
576     * <div class="classUseContainer">
577     * <table class="overviewSummary" border="0" cellpadding="3" cellspacing="0">
578     * <tr>
579     * <th class="colFirst">Web Format String</th>
580     * <th class="colLast">Equivalent constant or factory call</th>
581     * </tr>
582     * <tr class="rowColor">
583     * <td class="colFirst"><code>Color.web("orange");</code></td>
584     * <td class="colLast"><code>Color.ORANGE</code></td>
585     * </tr>
586     * <tr class="altColor">
587     * <td class="colFirst"><code>Color.web("0xff668840");</code></td>
588     * <td class="colLast"><code>Color.rgb(255, 102, 136, 0.25)</code></td>
589     * </tr>
590     * <tr class="rowColor">
591     * <td class="colFirst"><code>Color.web("0xff6688");</code></td>
592     * <td class="colLast"><code>Color.rgb(255, 102, 136, 1.0)</code></td>
593     * </tr>
594     * <tr class="altColor">
595     * <td class="colFirst"><code>Color.web("#ff6688");</code></td>
596     * <td class="colLast"><code>Color.rgb(255, 102, 136, 1.0)</code></td>
597     * </tr>
598     * <tr class="rowColor">
599     * <td class="colFirst"><code>Color.web("#f68");</code></td>
600     * <td class="colLast"><code>Color.rgb(255, 102, 136, 1.0)</code></td>
601     * </tr>
602     * <tr class="altColor">
603     * <td class="colFirst"><code>Color.web("rgb(255,102,136)");</code></td>
604     * <td class="colLast"><code>Color.rgb(255, 102, 136, 1.0)</code></td>
605     * </tr>
606     * <tr class="rowColor">
607     * <td class="colFirst"><code>Color.web("rgb(100%,50%,50%)");</code></td>
608     * <td class="colLast"><code>Color.rgb(255, 128, 128, 1.0)</code></td>
609     * </tr>
610     * <tr class="altColor">
611     * <td class="colFirst"><code>Color.web("rgb(255,50%,50%,0.25)");</code></td>
612     * <td class="colLast"><code>Color.rgb(255, 128, 128, 0.25)</code></td>
613     * </tr>
614     * <tr class="rowColor">
615     * <td class="colFirst"><code>Color.web("hsl(240,100%,100%)");</code></td>
616     * <td class="colLast"><code>Color.hsb(240.0, 1.0, 1.0, 1.0)</code></td>
617     * </tr>
618     * <tr class="altColor">
619     * <td style="border-bottom:1px solid" class="colFirst">
620     *     <code>Color.web("hsla(120,0%,0%,0.25)");</code>
621     * </td>
622     * <td style="border-bottom:1px solid" class="colLast">
623     *     <code>Color.hsb(120.0, 0.0, 0.0, 0.25)</code>
624     * </td>
625     * </tr>
626     * </table>
627     * </div>
628     *
629     * @param colorString the name or numeric representation of the color
630     *                    in one of the supported formats
631     * @throws NullPointerException if {@code colorString} is {@code null}
632     * @throws IllegalArgumentException if {@code colorString} specifies
633     *      an unsupported color name or contains an illegal numeric value
634     */
635    public static Color web(String colorString) {
636        return web(colorString, 1.0);
637    }
638
639    /**
640     * Creates a color value from a string representation. The format
641     * of the string representation is the same as in {@link #web(String)}.
642     *
643     * @param value the string to convert
644     * @throws NullPointerException if the {@code value} is {@code null}
645     * @throws IllegalArgumentException if the {@code value} specifies
646     *      an unsupported color name or illegal hexadecimal value
647     * @return a {@code Color} object holding the value represented 
648     * by the string argument
649     * @see #web(String)
650     */
651    public static Color valueOf(String value) {
652        if (value == null) {
653            throw new NullPointerException("color must be specified");
654        }
655
656        return web(value);
657    }
658
659    private static int to32BitInteger(int red, int green, int blue, int alpha) {
660        int i = red;
661        i = i << 8;
662        i = i | green;
663        i = i << 8;
664        i = i | blue;
665        i = i << 8;
666        i = i | alpha;
667        return i;
668    }
669
670    /**
671     * Gets the hue component of this {@code Color}.
672     * @return Hue value in the range in the range {@code 0.0-360.0}.
673     */
674    public double getHue() {
675        return Utils.RGBtoHSB(red, green, blue)[0];
676    }
677
678    /**
679     * Gets the saturation component of this {@code Color}.
680     * @return Saturation value in the range in the range {@code 0.0-1.0}.
681     */
682    public double getSaturation() {
683        return Utils.RGBtoHSB(red, green, blue)[1];
684    }
685
686    /**
687     * Gets the brightness component of this {@code Color}.
688     * @return Brightness value in the range in the range {@code 0.0-1.0}.
689     */
690    public double getBrightness() {
691        return Utils.RGBtoHSB(red, green, blue)[2];
692    }
693
694    /**
695     * Creates a new {@code Color} based on this {@code Color} with hue,
696     * saturation, brightness and opacity values altered. Hue is shifted
697     * about the given value and normalized into its natural range, the
698     * other components' values are multiplied by the given factors and
699     * clipped into their ranges.
700     *
701     * Increasing brightness of black color is allowed by using an arbitrary,
702     * very small source brightness instead of zero.
703     */
704    public Color deriveColor(double hueShift, double saturationFactor,
705                             double brightnessFactor, double opacityFactor) {
706
707        double[] hsb = Utils.RGBtoHSB(red, green, blue);
708
709        /* Allow brightness increase of black color */
710        double b = hsb[2];
711        if (b == 0 && brightnessFactor > 1.0) {
712            b = 0.05;
713        }
714
715        /* the tail "+ 360) % 360" solves shifts into negative numbers */
716        double h = (((hsb[0] + hueShift) % 360) + 360) % 360;
717        double s = Math.max(Math.min(hsb[1] * saturationFactor, 1.0), 0.0);
718        b = Math.max(Math.min(b * brightnessFactor, 1.0), 0.0);
719        double a = Math.max(Math.min(opacity * opacityFactor, 1.0), 0.0);
720        return hsb(h, s, b, a);
721    }
722
723    /**
724     * Creates a new Color that is a brighter version of this Color.
725     */
726    public Color brighter() {
727        return deriveColor(0, 1.0, 1.0 / DARKER_BRIGHTER_FACTOR, 1.0);
728    }
729
730    /**
731     * Creates a new Color that is a darker version of this Color.
732     */
733    public Color darker() {
734        return deriveColor(0, 1.0, DARKER_BRIGHTER_FACTOR, 1.0);
735    }
736
737    /**
738     * Creates a new Color that is a more saturated version of this Color.
739     */
740    public Color saturate() {
741        return deriveColor(0, 1.0 / SATURATE_DESATURATE_FACTOR, 1.0, 1.0);
742    }
743
744    /**
745     * Creates a new Color that is a less saturated version of this Color.
746     */
747    public Color desaturate() {
748        return deriveColor(0, SATURATE_DESATURATE_FACTOR, 1.0, 1.0);
749    }
750
751    /**
752     * Creates a new Color that is grayscale equivalent of this Color.
753     * Opacity is preserved.
754     */
755    public Color grayscale() {
756        double gray = 0.21 * red + 0.71 * green + 0.07 * blue;
757        return Color.color(gray, gray, gray, opacity);
758    }
759
760    /**
761     * Creates a new Color that is inversion of this Color.
762     * Opacity is preserved.
763     */
764    public Color invert() {
765        return Color.color(1.0 - red, 1.0 - green, 1.0 - blue, opacity);
766    }
767
768    /**
769     * A fully transparent color with an ARGB value of #00000000.
770     */
771    public static final Color TRANSPARENT          = new Color(0f, 0f, 0f, 0f);
772
773    /**
774     * The color alice blue with an RGB value of #F0F8FF.
775     */
776    public static final Color ALICEBLUE = new Color(0.9411765f, 0.972549f, 1.0f);
777
778    /**
779     * The color antique white with an RGB value of #FAEBD7.
780     */
781    public static final Color ANTIQUEWHITE = new Color(0.98039216f, 0.92156863f, 0.84313726f);
782
783    /**
784     * The color aqua with an RGB value of #00FFFF.
785     */
786    public static final Color AQUA = new Color(0.0f, 1.0f, 1.0f);
787
788    /**
789     * The color aquamarine with an RGB value of #7FFFD4.
790     */
791    public static final Color AQUAMARINE = new Color(0.49803922f, 1.0f, 0.83137256f);
792
793    /**
794     * The color azure with an RGB value of #F0FFFF.
795     */
796    public static final Color AZURE = new Color(0.9411765f, 1.0f, 1.0f);
797
798    /**
799     * The color beige with an RGB value of #F5F5DC.
800     */
801    public static final Color BEIGE = new Color(0.9607843f, 0.9607843f, 0.8627451f);
802
803    /**
804     * The color bisque with an RGB value of #FFE4C4.
805     */
806    public static final Color BISQUE = new Color(1.0f, 0.89411765f, 0.76862746f);
807
808    /**
809     * The color black with an RGB value of #000000.
810     */
811    public static final Color BLACK = new Color(0.0f, 0.0f, 0.0f);
812
813    /**
814     * The color blanched almond with an RGB value of #FFEBCD.
815     */
816    public static final Color BLANCHEDALMOND = new Color(1.0f, 0.92156863f, 0.8039216f);
817
818    /**
819     * The color blue with an RGB value of #0000FF.
820     */
821    public static final Color BLUE = new Color(0.0f, 0.0f, 1.0f);
822
823    /**
824     * The color blue violet with an RGB value of #8A2BE2.
825     */
826    public static final Color BLUEVIOLET = new Color(0.5411765f, 0.16862746f, 0.8862745f);
827
828    /**
829     * The color brown with an RGB value of #A52A2A.
830     */
831    public static final Color BROWN = new Color(0.64705884f, 0.16470589f, 0.16470589f);
832
833    /**
834     * The color burly wood with an RGB value of #DEB887.
835     */
836    public static final Color BURLYWOOD = new Color(0.87058824f, 0.72156864f, 0.5294118f);
837
838    /**
839     * The color cadet blue with an RGB value of #5F9EA0.
840     */
841    public static final Color CADETBLUE = new Color(0.37254903f, 0.61960787f, 0.627451f);
842
843    /**
844     * The color chartreuse with an RGB value of #7FFF00.
845     */
846    public static final Color CHARTREUSE = new Color(0.49803922f, 1.0f, 0.0f);
847
848    /**
849     * The color chocolate with an RGB value of #D2691E.
850     */
851    public static final Color CHOCOLATE = new Color(0.8235294f, 0.4117647f, 0.11764706f);
852
853    /**
854     * The color coral with an RGB value of #FF7F50.
855     */
856    public static final Color CORAL = new Color(1.0f, 0.49803922f, 0.3137255f);
857
858    /**
859     * The color cornflower blue with an RGB value of #6495ED.
860     */
861    public static final Color CORNFLOWERBLUE = new Color(0.39215687f, 0.58431375f, 0.92941177f);
862
863    /**
864     * The color cornsilk with an RGB value of #FFF8DC.
865     */
866    public static final Color CORNSILK = new Color(1.0f, 0.972549f, 0.8627451f);
867
868    /**
869     * The color crimson with an RGB value of #DC143C.
870     */
871    public static final Color CRIMSON = new Color(0.8627451f, 0.078431375f, 0.23529412f);
872
873    /**
874     * The color cyan with an RGB value of #00FFFF.
875     */
876    public static final Color CYAN = new Color(0.0f, 1.0f, 1.0f);
877
878    /**
879     * The color dark blue with an RGB value of #00008B.
880     */
881    public static final Color DARKBLUE = new Color(0.0f, 0.0f, 0.54509807f);
882
883    /**
884     * The color dark cyan with an RGB value of #008B8B.
885     */
886    public static final Color DARKCYAN = new Color(0.0f, 0.54509807f, 0.54509807f);
887
888    /**
889     * The color dark goldenrod with an RGB value of #B8860B.
890     */
891    public static final Color DARKGOLDENROD = new Color(0.72156864f, 0.5254902f, 0.043137256f);
892
893    /**
894     * The color dark gray with an RGB value of #A9A9A9.
895     */
896    public static final Color DARKGRAY = new Color(0.6627451f, 0.6627451f, 0.6627451f);
897
898    /**
899     * The color dark green with an RGB value of #006400.
900     */
901    public static final Color DARKGREEN = new Color(0.0f, 0.39215687f, 0.0f);
902
903    /**
904     * The color dark grey with an RGB value of #A9A9A9.
905     */
906    public static final Color DARKGREY             = DARKGRAY;
907
908    /**
909     * The color dark khaki with an RGB value of #BDB76B.
910     */
911    public static final Color DARKKHAKI = new Color(0.7411765f, 0.7176471f, 0.41960785f);
912
913    /**
914     * The color dark magenta with an RGB value of #8B008B.
915     */
916    public static final Color DARKMAGENTA = new Color(0.54509807f, 0.0f, 0.54509807f);
917
918    /**
919     * The color dark olive green with an RGB value of #556B2F.
920     */
921    public static final Color DARKOLIVEGREEN = new Color(0.33333334f, 0.41960785f, 0.18431373f);
922
923    /**
924     * The color dark orange with an RGB value of #FF8C00.
925     */
926    public static final Color DARKORANGE = new Color(1.0f, 0.54901963f, 0.0f);
927
928    /**
929     * The color dark orchid with an RGB value of #9932CC.
930     */
931    public static final Color DARKORCHID = new Color(0.6f, 0.19607843f, 0.8f);
932
933    /**
934     * The color dark red with an RGB value of #8B0000.
935     */
936    public static final Color DARKRED = new Color(0.54509807f, 0.0f, 0.0f);
937
938    /**
939     * The color dark salmon with an RGB value of #E9967A.
940     */
941    public static final Color DARKSALMON = new Color(0.9137255f, 0.5882353f, 0.47843137f);
942
943    /**
944     * The color dark sea green with an RGB value of #8FBC8F.
945     */
946    public static final Color DARKSEAGREEN = new Color(0.56078434f, 0.7372549f, 0.56078434f);
947
948    /**
949     * The color dark slate blue with an RGB value of #483D8B.
950     */
951    public static final Color DARKSLATEBLUE = new Color(0.28235295f, 0.23921569f, 0.54509807f);
952
953    /**
954     * The color dark slate gray with an RGB value of #2F4F4F.
955     */
956    public static final Color DARKSLATEGRAY = new Color(0.18431373f, 0.30980393f, 0.30980393f);
957
958    /**
959     * The color dark slate grey with an RGB value of #2F4F4F.
960     */
961    public static final Color DARKSLATEGREY        = DARKSLATEGRAY;
962
963    /**
964     * The color dark turquoise with an RGB value of #00CED1.
965     */
966    public static final Color DARKTURQUOISE = new Color(0.0f, 0.80784315f, 0.81960785f);
967
968    /**
969     * The color dark violet with an RGB value of #9400D3.
970     */
971    public static final Color DARKVIOLET = new Color(0.5803922f, 0.0f, 0.827451f);
972
973    /**
974     * The color deep pink with an RGB value of #FF1493.
975     */
976    public static final Color DEEPPINK = new Color(1.0f, 0.078431375f, 0.5764706f);
977
978    /**
979     * The color deep sky blue with an RGB value of #00BFFF.
980     */
981    public static final Color DEEPSKYBLUE = new Color(0.0f, 0.7490196f, 1.0f);
982
983    /**
984     * The color dim gray with an RGB value of #696969.
985     */
986    public static final Color DIMGRAY = new Color(0.4117647f, 0.4117647f, 0.4117647f);
987
988    /**
989     * The color dim grey with an RGB value of #696969.
990     */
991    public static final Color DIMGREY              = DIMGRAY;
992
993    /**
994     * The color dodger blue with an RGB value of #1E90FF.
995     */
996    public static final Color DODGERBLUE = new Color(0.11764706f, 0.5647059f, 1.0f);
997
998    /**
999     * The color firebrick with an RGB value of #B22222.
1000     */
1001    public static final Color FIREBRICK = new Color(0.69803923f, 0.13333334f, 0.13333334f);
1002
1003    /**
1004     * The color floral white with an RGB value of #FFFAF0.
1005     */
1006    public static final Color FLORALWHITE = new Color(1.0f, 0.98039216f, 0.9411765f);
1007
1008    /**
1009     * The color forest green with an RGB value of #228B22.
1010     */
1011    public static final Color FORESTGREEN = new Color(0.13333334f, 0.54509807f, 0.13333334f);
1012
1013    /**
1014     * The color fuchsia with an RGB value of #FF00FF.
1015     */
1016    public static final Color FUCHSIA = new Color(1.0f, 0.0f, 1.0f);
1017
1018    /**
1019     * The color gainsboro with an RGB value of #DCDCDC.
1020     */
1021    public static final Color GAINSBORO = new Color(0.8627451f, 0.8627451f, 0.8627451f);
1022
1023    /**
1024     * The color ghost white with an RGB value of #F8F8FF.
1025     */
1026    public static final Color GHOSTWHITE = new Color(0.972549f, 0.972549f, 1.0f);
1027
1028    /**
1029     * The color gold with an RGB value of #FFD700.
1030     */
1031    public static final Color GOLD = new Color(1.0f, 0.84313726f, 0.0f);
1032
1033    /**
1034     * The color goldenrod with an RGB value of #DAA520.
1035     */
1036    public static final Color GOLDENROD = new Color(0.85490197f, 0.64705884f, 0.1254902f);
1037
1038    /**
1039     * The color gray with an RGB value of #808080.
1040     */
1041    public static final Color GRAY = new Color(0.5019608f, 0.5019608f, 0.5019608f);
1042
1043    /**
1044     * The color green with an RGB value of #008000.
1045     */
1046    public static final Color GREEN = new Color(0.0f, 0.5019608f, 0.0f);
1047
1048    /**
1049     * The color green yellow with an RGB value of #ADFF2F.
1050     */
1051    public static final Color GREENYELLOW = new Color(0.6784314f, 1.0f, 0.18431373f);
1052
1053    /**
1054     * The color grey with an RGB value of #808080.
1055     */
1056    public static final Color GREY                 = GRAY;
1057
1058    /**
1059     * The color honeydew with an RGB value of #F0FFF0.
1060     */
1061    public static final Color HONEYDEW = new Color(0.9411765f, 1.0f, 0.9411765f);
1062
1063    /**
1064     * The color hot pink with an RGB value of #FF69B4.
1065     */
1066    public static final Color HOTPINK = new Color(1.0f, 0.4117647f, 0.7058824f);
1067
1068    /**
1069     * The color indian red with an RGB value of #CD5C5C.
1070     */
1071    public static final Color INDIANRED = new Color(0.8039216f, 0.36078432f, 0.36078432f);
1072
1073    /**
1074     * The color indigo with an RGB value of #4B0082.
1075     */
1076    public static final Color INDIGO = new Color(0.29411766f, 0.0f, 0.50980395f);
1077
1078    /**
1079     * The color ivory with an RGB value of #FFFFF0.
1080     */
1081    public static final Color IVORY = new Color(1.0f, 1.0f, 0.9411765f);
1082
1083    /**
1084     * The color khaki with an RGB value of #F0E68C.
1085     */
1086    public static final Color KHAKI = new Color(0.9411765f, 0.9019608f, 0.54901963f);
1087
1088    /**
1089     * The color lavender with an RGB value of #E6E6FA.
1090     */
1091    public static final Color LAVENDER = new Color(0.9019608f, 0.9019608f, 0.98039216f);
1092
1093    /**
1094     * The color lavender blush with an RGB value of #FFF0F5.
1095     */
1096    public static final Color LAVENDERBLUSH = new Color(1.0f, 0.9411765f, 0.9607843f);
1097
1098    /**
1099     * The color lawn green with an RGB value of #7CFC00.
1100     */
1101    public static final Color LAWNGREEN = new Color(0.4862745f, 0.9882353f, 0.0f);
1102
1103    /**
1104     * The color lemon chiffon with an RGB value of #FFFACD.
1105     */
1106    public static final Color LEMONCHIFFON = new Color(1.0f, 0.98039216f, 0.8039216f);
1107
1108    /**
1109     * The color light blue with an RGB value of #ADD8E6.
1110     */
1111    public static final Color LIGHTBLUE = new Color(0.6784314f, 0.84705883f, 0.9019608f);
1112
1113    /**
1114     * The color light coral with an RGB value of #F08080.
1115     */
1116    public static final Color LIGHTCORAL = new Color(0.9411765f, 0.5019608f, 0.5019608f);
1117
1118    /**
1119     * The color light cyan with an RGB value of #E0FFFF.
1120     */
1121    public static final Color LIGHTCYAN = new Color(0.8784314f, 1.0f, 1.0f);
1122
1123    /**
1124     * The color light goldenrod yellow with an RGB value of #FAFAD2.
1125     */
1126    public static final Color LIGHTGOLDENRODYELLOW = new Color(0.98039216f, 0.98039216f, 0.8235294f);
1127
1128    /**
1129     * The color light gray with an RGB value of #D3D3D3.
1130     */
1131    public static final Color LIGHTGRAY = new Color(0.827451f, 0.827451f, 0.827451f);
1132
1133    /**
1134     * The color light green with an RGB value of #90EE90.
1135     */
1136    public static final Color LIGHTGREEN = new Color(0.5647059f, 0.93333334f, 0.5647059f);
1137
1138    /**
1139     * The color light grey with an RGB value of #D3D3D3.
1140     */
1141    public static final Color LIGHTGREY            = LIGHTGRAY;
1142
1143    /**
1144     * The color light pink with an RGB value of #FFB6C1.
1145     */
1146    public static final Color LIGHTPINK = new Color(1.0f, 0.7137255f, 0.75686276f);
1147
1148    /**
1149     * The color light salmon with an RGB value of #FFA07A.
1150     */
1151    public static final Color LIGHTSALMON = new Color(1.0f, 0.627451f, 0.47843137f);
1152
1153    /**
1154     * The color light sea green with an RGB value of #20B2AA.
1155     */
1156    public static final Color LIGHTSEAGREEN = new Color(0.1254902f, 0.69803923f, 0.6666667f);
1157
1158    /**
1159     * The color light sky blue with an RGB value of #87CEFA.
1160     */
1161    public static final Color LIGHTSKYBLUE = new Color(0.5294118f, 0.80784315f, 0.98039216f);
1162
1163    /**
1164     * The color light slate gray with an RGB value of #778899.
1165     */
1166    public static final Color LIGHTSLATEGRAY = new Color(0.46666667f, 0.53333336f, 0.6f);
1167
1168    /**
1169     * The color light slate grey with an RGB value of #778899.
1170     */
1171    public static final Color LIGHTSLATEGREY       = LIGHTSLATEGRAY;
1172
1173    /**
1174     * The color light steel blue with an RGB value of #B0C4DE.
1175     */
1176    public static final Color LIGHTSTEELBLUE = new Color(0.6901961f, 0.76862746f, 0.87058824f);
1177
1178    /**
1179     * The color light yellow with an RGB value of #FFFFE0.
1180     */
1181    public static final Color LIGHTYELLOW = new Color(1.0f, 1.0f, 0.8784314f);
1182
1183    /**
1184     * The color lime with an RGB value of #00FF00.
1185     */
1186    public static final Color LIME = new Color(0.0f, 1.0f, 0.0f);
1187
1188    /**
1189     * The color lime green with an RGB value of #32CD32.
1190     */
1191    public static final Color LIMEGREEN = new Color(0.19607843f, 0.8039216f, 0.19607843f);
1192
1193    /**
1194     * The color linen with an RGB value of #FAF0E6.
1195     */
1196    public static final Color LINEN = new Color(0.98039216f, 0.9411765f, 0.9019608f);
1197
1198    /**
1199     * The color magenta with an RGB value of #FF00FF.
1200     */
1201    public static final Color MAGENTA = new Color(1.0f, 0.0f, 1.0f);
1202
1203    /**
1204     * The color maroon with an RGB value of #800000.
1205     */
1206    public static final Color MAROON = new Color(0.5019608f, 0.0f, 0.0f);
1207
1208    /**
1209     * The color medium aquamarine with an RGB value of #66CDAA.
1210     */
1211    public static final Color MEDIUMAQUAMARINE = new Color(0.4f, 0.8039216f, 0.6666667f);
1212
1213    /**
1214     * The color medium blue with an RGB value of #0000CD.
1215     */
1216    public static final Color MEDIUMBLUE = new Color(0.0f, 0.0f, 0.8039216f);
1217
1218    /**
1219     * The color medium orchid with an RGB value of #BA55D3.
1220     */
1221    public static final Color MEDIUMORCHID = new Color(0.7294118f, 0.33333334f, 0.827451f);
1222
1223    /**
1224     * The color medium purple with an RGB value of #9370DB.
1225     */
1226    public static final Color MEDIUMPURPLE = new Color(0.5764706f, 0.4392157f, 0.85882354f);
1227
1228    /**
1229     * The color medium sea green with an RGB value of #3CB371.
1230     */
1231    public static final Color MEDIUMSEAGREEN = new Color(0.23529412f, 0.7019608f, 0.44313726f);
1232
1233    /**
1234     * The color medium slate blue with an RGB value of #7B68EE.
1235     */
1236    public static final Color MEDIUMSLATEBLUE = new Color(0.48235294f, 0.40784314f, 0.93333334f);
1237
1238    /**
1239     * The color medium spring green with an RGB value of #00FA9A.
1240     */
1241    public static final Color MEDIUMSPRINGGREEN = new Color(0.0f, 0.98039216f, 0.6039216f);
1242
1243    /**
1244     * The color medium turquoise with an RGB value of #48D1CC.
1245     */
1246    public static final Color MEDIUMTURQUOISE = new Color(0.28235295f, 0.81960785f, 0.8f);
1247
1248    /**
1249     * The color medium violet red with an RGB value of #C71585.
1250     */
1251    public static final Color MEDIUMVIOLETRED = new Color(0.78039217f, 0.08235294f, 0.52156866f);
1252
1253    /**
1254     * The color midnight blue with an RGB value of #191970.
1255     */
1256    public static final Color MIDNIGHTBLUE = new Color(0.09803922f, 0.09803922f, 0.4392157f);
1257
1258    /**
1259     * The color mint cream with an RGB value of #F5FFFA.
1260     */
1261    public static final Color MINTCREAM = new Color(0.9607843f, 1.0f, 0.98039216f);
1262
1263    /**
1264     * The color misty rose with an RGB value of #FFE4E1.
1265     */
1266    public static final Color MISTYROSE = new Color(1.0f, 0.89411765f, 0.88235295f);
1267
1268    /**
1269     * The color moccasin with an RGB value of #FFE4B5.
1270     */
1271    public static final Color MOCCASIN = new Color(1.0f, 0.89411765f, 0.70980394f);
1272
1273    /**
1274     * The color navajo white with an RGB value of #FFDEAD.
1275     */
1276    public static final Color NAVAJOWHITE = new Color(1.0f, 0.87058824f, 0.6784314f);
1277
1278    /**
1279     * The color navy with an RGB value of #000080.
1280     */
1281    public static final Color NAVY = new Color(0.0f, 0.0f, 0.5019608f);
1282
1283    /**
1284     * The color old lace with an RGB value of #FDF5E6.
1285     */
1286    public static final Color OLDLACE = new Color(0.99215686f, 0.9607843f, 0.9019608f);
1287
1288    /**
1289     * The color olive with an RGB value of #808000.
1290     */
1291    public static final Color OLIVE = new Color(0.5019608f, 0.5019608f, 0.0f);
1292
1293    /**
1294     * The color olive drab with an RGB value of #6B8E23.
1295     */
1296    public static final Color OLIVEDRAB = new Color(0.41960785f, 0.5568628f, 0.13725491f);
1297
1298    /**
1299     * The color orange with an RGB value of #FFA500.
1300     */
1301    public static final Color ORANGE = new Color(1.0f, 0.64705884f, 0.0f);
1302
1303    /**
1304     * The color orange red with an RGB value of #FF4500.
1305     */
1306    public static final Color ORANGERED = new Color(1.0f, 0.27058825f, 0.0f);
1307
1308    /**
1309     * The color orchid with an RGB value of #DA70D6.
1310     */
1311    public static final Color ORCHID = new Color(0.85490197f, 0.4392157f, 0.8392157f);
1312
1313    /**
1314     * The color pale goldenrod with an RGB value of #EEE8AA.
1315     */
1316    public static final Color PALEGOLDENROD = new Color(0.93333334f, 0.9098039f, 0.6666667f);
1317
1318    /**
1319     * The color pale green with an RGB value of #98FB98.
1320     */
1321    public static final Color PALEGREEN = new Color(0.59607846f, 0.9843137f, 0.59607846f);
1322
1323    /**
1324     * The color pale turquoise with an RGB value of #AFEEEE.
1325     */
1326    public static final Color PALETURQUOISE = new Color(0.6862745f, 0.93333334f, 0.93333334f);
1327
1328    /**
1329     * The color pale violet red with an RGB value of #DB7093.
1330     */
1331    public static final Color PALEVIOLETRED = new Color(0.85882354f, 0.4392157f, 0.5764706f);
1332
1333    /**
1334     * The color papaya whip with an RGB value of #FFEFD5.
1335     */
1336    public static final Color PAPAYAWHIP = new Color(1.0f, 0.9372549f, 0.8352941f);
1337
1338    /**
1339     * The color peach puff with an RGB value of #FFDAB9.
1340     */
1341    public static final Color PEACHPUFF = new Color(1.0f, 0.85490197f, 0.7254902f);
1342
1343    /**
1344     * The color peru with an RGB value of #CD853F.
1345     */
1346    public static final Color PERU = new Color(0.8039216f, 0.52156866f, 0.24705882f);
1347
1348    /**
1349     * The color pink with an RGB value of #FFC0CB.
1350     */
1351    public static final Color PINK = new Color(1.0f, 0.7529412f, 0.79607844f);
1352
1353    /**
1354     * The color plum with an RGB value of #DDA0DD.
1355     */
1356    public static final Color PLUM = new Color(0.8666667f, 0.627451f, 0.8666667f);
1357
1358    /**
1359     * The color powder blue with an RGB value of #B0E0E6.
1360     */
1361    public static final Color POWDERBLUE = new Color(0.6901961f, 0.8784314f, 0.9019608f);
1362
1363    /**
1364     * The color purple with an RGB value of #800080.
1365     */
1366    public static final Color PURPLE = new Color(0.5019608f, 0.0f, 0.5019608f);
1367
1368    /**
1369     * The color red with an RGB value of #FF0000.
1370     */
1371    public static final Color RED = new Color(1.0f, 0.0f, 0.0f);
1372
1373    /**
1374     * The color rosy brown with an RGB value of #BC8F8F.
1375     */
1376    public static final Color ROSYBROWN = new Color(0.7372549f, 0.56078434f, 0.56078434f);
1377
1378    /**
1379     * The color royal blue with an RGB value of #4169E1.
1380     */
1381    public static final Color ROYALBLUE = new Color(0.25490198f, 0.4117647f, 0.88235295f);
1382
1383    /**
1384     * The color saddle brown with an RGB value of #8B4513.
1385     */
1386    public static final Color SADDLEBROWN = new Color(0.54509807f, 0.27058825f, 0.07450981f);
1387
1388    /**
1389     * The color salmon with an RGB value of #FA8072.
1390     */
1391    public static final Color SALMON = new Color(0.98039216f, 0.5019608f, 0.44705883f);
1392
1393    /**
1394     * The color sandy brown with an RGB value of #F4A460.
1395     */
1396    public static final Color SANDYBROWN = new Color(0.95686275f, 0.6431373f, 0.3764706f);
1397
1398    /**
1399     * The color sea green with an RGB value of #2E8B57.
1400     */
1401    public static final Color SEAGREEN = new Color(0.18039216f, 0.54509807f, 0.34117648f);
1402
1403    /**
1404     * The color sea shell with an RGB value of #FFF5EE.
1405     */
1406    public static final Color SEASHELL = new Color(1.0f, 0.9607843f, 0.93333334f);
1407
1408    /**
1409     * The color sienna with an RGB value of #A0522D.
1410     */
1411    public static final Color SIENNA = new Color(0.627451f, 0.32156864f, 0.1764706f);
1412
1413    /**
1414     * The color silver with an RGB value of #C0C0C0.
1415     */
1416    public static final Color SILVER = new Color(0.7529412f, 0.7529412f, 0.7529412f);
1417
1418    /**
1419     * The color sky blue with an RGB value of #87CEEB.
1420     */
1421    public static final Color SKYBLUE = new Color(0.5294118f, 0.80784315f, 0.92156863f);
1422
1423    /**
1424     * The color slate blue with an RGB value of #6A5ACD.
1425     */
1426    public static final Color SLATEBLUE = new Color(0.41568628f, 0.3529412f, 0.8039216f);
1427
1428    /**
1429     * The color slate gray with an RGB value of #708090.
1430     */
1431    public static final Color SLATEGRAY = new Color(0.4392157f, 0.5019608f, 0.5647059f);
1432
1433    /**
1434     * The color slate grey with an RGB value of #708090.
1435     */
1436    public static final Color SLATEGREY            = SLATEGRAY;
1437
1438    /**
1439     * The color snow with an RGB value of #FFFAFA.
1440     */
1441    public static final Color SNOW = new Color(1.0f, 0.98039216f, 0.98039216f);
1442
1443    /**
1444     * The color spring green with an RGB value of #00FF7F.
1445     */
1446    public static final Color SPRINGGREEN = new Color(0.0f, 1.0f, 0.49803922f);
1447
1448    /**
1449     * The color steel blue with an RGB value of #4682B4.
1450     */
1451    public static final Color STEELBLUE = new Color(0.27450982f, 0.50980395f, 0.7058824f);
1452
1453    /**
1454     * The color tan with an RGB value of #D2B48C.
1455     */
1456    public static final Color TAN = new Color(0.8235294f, 0.7058824f, 0.54901963f);
1457
1458    /**
1459     * The color teal with an RGB value of #008080.
1460     */
1461    public static final Color TEAL = new Color(0.0f, 0.5019608f, 0.5019608f);
1462
1463    /**
1464     * The color thistle with an RGB value of #D8BFD8.
1465     */
1466    public static final Color THISTLE = new Color(0.84705883f, 0.7490196f, 0.84705883f);
1467
1468    /**
1469     * The color tomato with an RGB value of #FF6347.
1470     */
1471    public static final Color TOMATO = new Color(1.0f, 0.3882353f, 0.2784314f);
1472
1473    /**
1474     * The color turquoise with an RGB value of #40E0D0.
1475     */
1476    public static final Color TURQUOISE = new Color(0.2509804f, 0.8784314f, 0.8156863f);
1477
1478    /**
1479     * The color violet with an RGB value of #EE82EE.
1480     */
1481    public static final Color VIOLET = new Color(0.93333334f, 0.50980395f, 0.93333334f);
1482
1483    /**
1484     * The color wheat with an RGB value of #F5DEB3.
1485     */
1486    public static final Color WHEAT = new Color(0.9607843f, 0.87058824f, 0.7019608f);
1487
1488    /**
1489     * The color white with an RGB value of #FFFFFF.
1490     */
1491    public static final Color WHITE = new Color(1.0f, 1.0f, 1.0f);
1492
1493    /**
1494     * The color white smoke with an RGB value of #F5F5F5.
1495     */
1496    public static final Color WHITESMOKE = new Color(0.9607843f, 0.9607843f, 0.9607843f);
1497
1498    /**
1499     * The color yellow with an RGB value of #FFFF00.
1500     */
1501    public static final Color YELLOW = new Color(1.0f, 1.0f, 0.0f);
1502
1503    /**
1504     * The color yellow green with an RGB value of #9ACD32.
1505     */
1506    public static final Color YELLOWGREEN = new Color(0.6039216f, 0.8039216f, 0.19607843f);
1507
1508    /*
1509     * Named colors moved to nested class to initialize them only when they
1510     * are needed.
1511     */
1512    private static final class NamedColors {
1513        private static final Map<String, Color> namedColors =
1514                createNamedColors();
1515
1516        private NamedColors() {
1517        }
1518
1519        private static Color get(String name) {
1520            return namedColors.get(name);
1521        }
1522
1523        private static Map<String, Color> createNamedColors() {
1524            Map<String, Color> colors = new HashMap<String,Color>(256);
1525
1526            colors.put("aliceblue",            ALICEBLUE);
1527            colors.put("antiquewhite",         ANTIQUEWHITE);
1528            colors.put("aqua",                 AQUA);
1529            colors.put("aquamarine",           AQUAMARINE);
1530            colors.put("azure",                AZURE);
1531            colors.put("beige",                BEIGE);
1532            colors.put("bisque",               BISQUE);
1533            colors.put("black",                BLACK);
1534            colors.put("blanchedalmond",       BLANCHEDALMOND);
1535            colors.put("blue",                 BLUE);
1536            colors.put("blueviolet",           BLUEVIOLET);
1537            colors.put("brown",                BROWN);
1538            colors.put("burlywood",            BURLYWOOD);
1539            colors.put("cadetblue",            CADETBLUE);
1540            colors.put("chartreuse",           CHARTREUSE);
1541            colors.put("chocolate",            CHOCOLATE);
1542            colors.put("coral",                CORAL);
1543            colors.put("cornflowerblue",       CORNFLOWERBLUE);
1544            colors.put("cornsilk",             CORNSILK);
1545            colors.put("crimson",              CRIMSON);
1546            colors.put("cyan",                 CYAN);
1547            colors.put("darkblue",             DARKBLUE);
1548            colors.put("darkcyan",             DARKCYAN);
1549            colors.put("darkgoldenrod",        DARKGOLDENROD);
1550            colors.put("darkgray",             DARKGRAY);
1551            colors.put("darkgreen",            DARKGREEN);
1552            colors.put("darkgrey",             DARKGREY);
1553            colors.put("darkkhaki",            DARKKHAKI);
1554            colors.put("darkmagenta",          DARKMAGENTA);
1555            colors.put("darkolivegreen",       DARKOLIVEGREEN);
1556            colors.put("darkorange",           DARKORANGE);
1557            colors.put("darkorchid",           DARKORCHID);
1558            colors.put("darkred",              DARKRED);
1559            colors.put("darksalmon",           DARKSALMON);
1560            colors.put("darkseagreen",         DARKSEAGREEN);
1561            colors.put("darkslateblue",        DARKSLATEBLUE);
1562            colors.put("darkslategray",        DARKSLATEGRAY);
1563            colors.put("darkslategrey",        DARKSLATEGREY);
1564            colors.put("darkturquoise",        DARKTURQUOISE);
1565            colors.put("darkviolet",           DARKVIOLET);
1566            colors.put("deeppink",             DEEPPINK);
1567            colors.put("deepskyblue",          DEEPSKYBLUE);
1568            colors.put("dimgray",              DIMGRAY);
1569            colors.put("dimgrey",              DIMGREY);
1570            colors.put("dodgerblue",           DODGERBLUE);
1571            colors.put("firebrick",            FIREBRICK);
1572            colors.put("floralwhite",          FLORALWHITE);
1573            colors.put("forestgreen",          FORESTGREEN);
1574            colors.put("fuchsia",              FUCHSIA);
1575            colors.put("gainsboro",            GAINSBORO);
1576            colors.put("ghostwhite",           GHOSTWHITE);
1577            colors.put("gold",                 GOLD);
1578            colors.put("goldenrod",            GOLDENROD);
1579            colors.put("gray",                 GRAY);
1580            colors.put("green",                GREEN);
1581            colors.put("greenyellow",          GREENYELLOW);
1582            colors.put("grey",                 GREY);
1583            colors.put("honeydew",             HONEYDEW);
1584            colors.put("hotpink",              HOTPINK);
1585            colors.put("indianred",            INDIANRED);
1586            colors.put("indigo",               INDIGO);
1587            colors.put("ivory",                IVORY);
1588            colors.put("khaki",                KHAKI);
1589            colors.put("lavender",             LAVENDER);
1590            colors.put("lavenderblush",        LAVENDERBLUSH);
1591            colors.put("lawngreen",            LAWNGREEN);
1592            colors.put("lemonchiffon",         LEMONCHIFFON);
1593            colors.put("lightblue",            LIGHTBLUE);
1594            colors.put("lightcoral",           LIGHTCORAL);
1595            colors.put("lightcyan",            LIGHTCYAN);
1596            colors.put("lightgoldenrodyellow", LIGHTGOLDENRODYELLOW);
1597            colors.put("lightgray",            LIGHTGRAY);
1598            colors.put("lightgreen",           LIGHTGREEN);
1599            colors.put("lightgrey",            LIGHTGREY);
1600            colors.put("lightpink",            LIGHTPINK);
1601            colors.put("lightsalmon",          LIGHTSALMON);
1602            colors.put("lightseagreen",        LIGHTSEAGREEN);
1603            colors.put("lightskyblue",         LIGHTSKYBLUE);
1604            colors.put("lightslategray",       LIGHTSLATEGRAY);
1605            colors.put("lightslategrey",       LIGHTSLATEGREY);
1606            colors.put("lightsteelblue",       LIGHTSTEELBLUE);
1607            colors.put("lightyellow",          LIGHTYELLOW);
1608            colors.put("lime",                 LIME);
1609            colors.put("limegreen",            LIMEGREEN);
1610            colors.put("linen",                LINEN);
1611            colors.put("magenta",              MAGENTA);
1612            colors.put("maroon",               MAROON);
1613            colors.put("mediumaquamarine",     MEDIUMAQUAMARINE);
1614            colors.put("mediumblue",           MEDIUMBLUE);
1615            colors.put("mediumorchid",         MEDIUMORCHID);
1616            colors.put("mediumpurple",         MEDIUMPURPLE);
1617            colors.put("mediumseagreen",       MEDIUMSEAGREEN);
1618            colors.put("mediumslateblue",      MEDIUMSLATEBLUE);
1619            colors.put("mediumspringgreen",    MEDIUMSPRINGGREEN);
1620            colors.put("mediumturquoise",      MEDIUMTURQUOISE);
1621            colors.put("mediumvioletred",      MEDIUMVIOLETRED);
1622            colors.put("midnightblue",         MIDNIGHTBLUE);
1623            colors.put("mintcream",            MINTCREAM);
1624            colors.put("mistyrose",            MISTYROSE);
1625            colors.put("moccasin",             MOCCASIN);
1626            colors.put("navajowhite",          NAVAJOWHITE);
1627            colors.put("navy",                 NAVY);
1628            colors.put("oldlace",              OLDLACE);
1629            colors.put("olive",                OLIVE);
1630            colors.put("olivedrab",            OLIVEDRAB);
1631            colors.put("orange",               ORANGE);
1632            colors.put("orangered",            ORANGERED);
1633            colors.put("orchid",               ORCHID);
1634            colors.put("palegoldenrod",        PALEGOLDENROD);
1635            colors.put("palegreen",            PALEGREEN);
1636            colors.put("paleturquoise",        PALETURQUOISE);
1637            colors.put("palevioletred",        PALEVIOLETRED);
1638            colors.put("papayawhip",           PAPAYAWHIP);
1639            colors.put("peachpuff",            PEACHPUFF);
1640            colors.put("peru",                 PERU);
1641            colors.put("pink",                 PINK);
1642            colors.put("plum",                 PLUM);
1643            colors.put("powderblue",           POWDERBLUE);
1644            colors.put("purple",               PURPLE);
1645            colors.put("red",                  RED);
1646            colors.put("rosybrown",            ROSYBROWN);
1647            colors.put("royalblue",            ROYALBLUE);
1648            colors.put("saddlebrown",          SADDLEBROWN);
1649            colors.put("salmon",               SALMON);
1650            colors.put("sandybrown",           SANDYBROWN);
1651            colors.put("seagreen",             SEAGREEN);
1652            colors.put("seashell",             SEASHELL);
1653            colors.put("sienna",               SIENNA);
1654            colors.put("silver",               SILVER);
1655            colors.put("skyblue",              SKYBLUE);
1656            colors.put("slateblue",            SLATEBLUE);
1657            colors.put("slategray",            SLATEGRAY);
1658            colors.put("slategrey",            SLATEGREY);
1659            colors.put("snow",                 SNOW);
1660            colors.put("springgreen",          SPRINGGREEN);
1661            colors.put("steelblue",            STEELBLUE);
1662            colors.put("tan",                  TAN);
1663            colors.put("teal",                 TEAL);
1664            colors.put("thistle",              THISTLE);
1665            colors.put("tomato",               TOMATO);
1666            colors.put("transparent",          TRANSPARENT);
1667            colors.put("turquoise",            TURQUOISE);
1668            colors.put("violet",               VIOLET);
1669            colors.put("wheat",                WHEAT);
1670            colors.put("white",                WHITE);
1671            colors.put("whitesmoke",           WHITESMOKE);
1672            colors.put("yellow",               YELLOW);
1673            colors.put("yellowgreen",          YELLOWGREEN);
1674
1675            return colors;
1676        }
1677    }
1678
1679    /**
1680     * The red component of the {@code Color}, in the range {@code 0.0-1.0}.
1681     *
1682     * @defaultValue 0.0
1683     */
1684    public final double getRed() { return red; }
1685    private float red;
1686
1687    /**
1688     * The green component of the {@code Color}, in the range {@code 0.0-1.0}.
1689     *
1690     * @defaultValue 0.0
1691     */
1692    public final double getGreen() { return green; }
1693    private float green;
1694
1695    /**
1696     * The blue component of the {@code Color}, in the range {@code 0.0-1.0}.
1697     *
1698     * @defaultValue 0.0
1699     */
1700    public final double getBlue() { return blue; }
1701    private float blue;
1702
1703    /**
1704     * The opacity of the {@code Color}, in the range {@code 0.0-1.0}.
1705     *
1706     * @defaultValue 1.0
1707     */
1708    public final double getOpacity() { return opacity; }
1709    private float opacity = 1;
1710
1711    /**
1712     * @inheritDoc
1713     */
1714    @Override public final boolean isOpaque() {
1715        return opacity >= 1f;
1716    }
1717
1718    private Object platformPaint;
1719
1720    /**
1721     * Creates a new instance of color
1722     * @param red red component ranging from {@code 0} to {@code 1}
1723     * @param green green component ranging from {@code 0} to {@code 1}
1724     * @param blue blue component ranging from {@code 0} to {@code 1}
1725     * @param opacity opacity ranging from {@code 0} to {@code 1}
1726     */
1727    public Color(double red, double green, double blue, @Default("1") double opacity) {
1728        if (red < 0 || red > 1) {
1729            throw new IllegalArgumentException("Color's red value (" + red + ") must be in the range 0.0-1.0");
1730        }
1731        if (green < 0 || green > 1) {
1732            throw new IllegalArgumentException("Color's green value (" + green + ") must be in the range 0.0-1.0");
1733        }
1734        if (blue < 0 || blue > 1) {
1735            throw new IllegalArgumentException("Color's blue value (" + blue + ") must be in the range 0.0-1.0");
1736        }
1737        if (opacity < 0 || opacity > 1) {
1738            throw new IllegalArgumentException("Color's opacity value (" + opacity + ") must be in the range 0.0-1.0");
1739        }
1740
1741        this.red = (float) red;
1742        this.green = (float) green;
1743        this.blue = (float) blue;
1744        this.opacity = (float) opacity;
1745    }
1746
1747    /**
1748     * Creates a new instance of color. This constructor performs no integrity
1749     * checks, and thus should ONLY be used by internal code in Color which
1750     * knows that the hard-coded values are correct.
1751     *
1752     * @param red red component ranging from {@code 0} to {@code 1}
1753     * @param green green component ranging from {@code 0} to {@code 1}
1754     * @param blue blue component ranging from {@code 0} to {@code 1}
1755     * @param opacity opacity ranging from {@code 0} to {@code 1}
1756     */
1757    private Color(float red, float green, float blue) {
1758        this.red = red;
1759        this.green = green;
1760        this.blue = blue;
1761    }
1762
1763    @Override
1764    Object acc_getPlatformPaint() {
1765        if (platformPaint == null) {
1766            platformPaint = Toolkit.getToolkit().getPaint(this);
1767        }
1768        return platformPaint;
1769    }
1770    
1771    /**
1772     * @inheritDoc
1773     */
1774    @Override public Color interpolate(Color endValue, double t) {
1775        if (t <= 0.0) return this;
1776        if (t >= 1.0) return endValue;
1777        float ft = (float) t;
1778        return new Color(
1779            red     + (endValue.red     - red)     * ft,
1780            green   + (endValue.green   - green)   * ft,
1781            blue    + (endValue.blue    - blue)    * ft,
1782            opacity + (endValue.opacity - opacity) * ft
1783        );
1784    }
1785
1786    /**
1787     * Indicates whether some other object is "equal to" this one.
1788     * @param obj the reference object with which to compare.
1789     * @return {@code true} if this object is equal to the {@code obj} argument; {@code false} otherwise.
1790     */
1791    @Override public boolean equals(Object obj) {
1792        if (obj == this) return true;
1793        if (obj instanceof Color) {
1794            Color other = (Color) obj;
1795            return red == other.red
1796                && green == other.green
1797                && blue == other.blue
1798                && opacity == other.opacity;
1799        } else return false;
1800    }
1801
1802    /**
1803     * Returns a hash code for this {@code Color} object.
1804     * @return a hash code for this {@code Color} object.
1805     */
1806    @Override public int hashCode() {
1807        // construct the 32bit integer representation of this color
1808        int r = (int)Math.round(red * 255.0);
1809        int g = (int)Math.round(green * 255.0);
1810        int b = (int)Math.round(blue * 255.0);
1811        int a = (int)Math.round(opacity * 255.0);
1812        return to32BitInteger(r, g, b, a);
1813    }
1814
1815    /**
1816     * Returns a string representation of this {@code Color}.
1817     * This method is intended to be used only for informational purposes.
1818     * The content and format of the returned string might vary between implementations.
1819     * The returned string might be empty but cannot be {@code null}.
1820     *
1821     * @return the string representation
1822     */
1823    @Override public String toString() {
1824        int r = (int)Math.round(red * 255.0);
1825        int g = (int)Math.round(green * 255.0);
1826        int b = (int)Math.round(blue * 255.0);
1827        int o = (int)Math.round(opacity * 255.0);
1828        return String.format("0x%02x%02x%02x%02x" , r, g, b, o);
1829    }
1830}