History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/awt/Color.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/awt/Color.java+1244−0
@@ -0,0 +1,1244 @@
1+/*
2+ * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt;
27+
28+import java.beans.ConstructorProperties;
29+import java.awt.image.ColorModel;
30+import java.awt.geom.AffineTransform;
31+import java.awt.geom.Rectangle2D;
32+import java.awt.color.ColorSpace;
33+
34+/**
35+ * The <code>Color</code> class is used to encapsulate colors in the default
36+ * sRGB color space or colors in arbitrary color spaces identified by a
37+ * {@link ColorSpace}. Every color has an implicit alpha value of 1.0 or
38+ * an explicit one provided in the constructor. The alpha value
39+ * defines the transparency of a color and can be represented by
40+ * a float value in the range 0.0&nbsp;-&nbsp;1.0 or 0&nbsp;-&nbsp;255.
41+ * An alpha value of 1.0 or 255 means that the color is completely
42+ * opaque and an alpha value of 0 or 0.0 means that the color is
43+ * completely transparent.
44+ * When constructing a <code>Color</code> with an explicit alpha or
45+ * getting the color/alpha components of a <code>Color</code>, the color
46+ * components are never premultiplied by the alpha component.
47+ * <p>
48+ * The default color space for the Java 2D(tm) API is sRGB, a proposed
49+ * standard RGB color space. For further information on sRGB,
50+ * see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
51+ * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
52+ * </A>.
53+ * <p>
54+ * @version 10 Feb 1997
55+ * @author Sami Shaio
56+ * @author Arthur van Hoff
57+ * @see ColorSpace
58+ * @see AlphaComposite
59+ */
60+public class Color implements Paint, java.io.Serializable {
61+
62+ /**
63+ * The color white. In the default sRGB space.
64+ */
65+ public final static Color white = new Color(255, 255, 255);
66+
67+ /**
68+ * The color white. In the default sRGB space.
69+ * @since 1.4
70+ */
71+ public final static Color WHITE = white;
72+
73+ /**
74+ * The color light gray. In the default sRGB space.
75+ */
76+ public final static Color lightGray = new Color(192, 192, 192);
77+
78+ /**
79+ * The color light gray. In the default sRGB space.
80+ * @since 1.4
81+ */
82+ public final static Color LIGHT_GRAY = lightGray;
83+
84+ /**
85+ * The color gray. In the default sRGB space.
86+ */
87+ public final static Color gray = new Color(128, 128, 128);
88+
89+ /**
90+ * The color gray. In the default sRGB space.
91+ * @since 1.4
92+ */
93+ public final static Color GRAY = gray;
94+
95+ /**
96+ * The color dark gray. In the default sRGB space.
97+ */
98+ public final static Color darkGray = new Color(64, 64, 64);
99+
100+ /**
101+ * The color dark gray. In the default sRGB space.
102+ * @since 1.4
103+ */
104+ public final static Color DARK_GRAY = darkGray;
105+
106+ /**
107+ * The color black. In the default sRGB space.
108+ */
109+ public final static Color black = new Color(0, 0, 0);
110+
111+ /**
112+ * The color black. In the default sRGB space.
113+ * @since 1.4
114+ */
115+ public final static Color BLACK = black;
116+
117+ /**
118+ * The color red. In the default sRGB space.
119+ */
120+ public final static Color red = new Color(255, 0, 0);
121+
122+ /**
123+ * The color red. In the default sRGB space.
124+ * @since 1.4
125+ */
126+ public final static Color RED = red;
127+
128+ /**
129+ * The color pink. In the default sRGB space.
130+ */
131+ public final static Color pink = new Color(255, 175, 175);
132+
133+ /**
134+ * The color pink. In the default sRGB space.
135+ * @since 1.4
136+ */
137+ public final static Color PINK = pink;
138+
139+ /**
140+ * The color orange. In the default sRGB space.
141+ */
142+ public final static Color orange = new Color(255, 200, 0);
143+
144+ /**
145+ * The color orange. In the default sRGB space.
146+ * @since 1.4
147+ */
148+ public final static Color ORANGE = orange;
149+
150+ /**
151+ * The color yellow. In the default sRGB space.
152+ */
153+ public final static Color yellow = new Color(255, 255, 0);
154+
155+ /**
156+ * The color yellow. In the default sRGB space.
157+ * @since 1.4
158+ */
159+ public final static Color YELLOW = yellow;
160+
161+ /**
162+ * The color green. In the default sRGB space.
163+ */
164+ public final static Color green = new Color(0, 255, 0);
165+
166+ /**
167+ * The color green. In the default sRGB space.
168+ * @since 1.4
169+ */
170+ public final static Color GREEN = green;
171+
172+ /**
173+ * The color magenta. In the default sRGB space.
174+ */
175+ public final static Color magenta = new Color(255, 0, 255);
176+
177+ /**
178+ * The color magenta. In the default sRGB space.
179+ * @since 1.4
180+ */
181+ public final static Color MAGENTA = magenta;
182+
183+ /**
184+ * The color cyan. In the default sRGB space.
185+ */
186+ public final static Color cyan = new Color(0, 255, 255);
187+
188+ /**
189+ * The color cyan. In the default sRGB space.
190+ * @since 1.4
191+ */
192+ public final static Color CYAN = cyan;
193+
194+ /**
195+ * The color blue. In the default sRGB space.
196+ */
197+ public final static Color blue = new Color(0, 0, 255);
198+
199+ /**
200+ * The color blue. In the default sRGB space.
201+ * @since 1.4
202+ */
203+ public final static Color BLUE = blue;
204+
205+ /**
206+ * The color value.
207+ * @serial
208+ * @see #getRGB
209+ */
210+ int value;
211+
212+ /**
213+ * The color value in the default sRGB <code>ColorSpace</code> as
214+ * <code>float</code> components (no alpha).
215+ * If <code>null</code> after object construction, this must be an
216+ * sRGB color constructed with 8-bit precision, so compute from the
217+ * <code>int</code> color value.
218+ * @serial
219+ * @see #getRGBColorComponents
220+ * @see #getRGBComponents
221+ */
222+ private float frgbvalue[] = null;
223+
224+ /**
225+ * The color value in the native <code>ColorSpace</code> as
226+ * <code>float</code> components (no alpha).
227+ * If <code>null</code> after object construction, this must be an
228+ * sRGB color constructed with 8-bit precision, so compute from the
229+ * <code>int</code> color value.
230+ * @serial
231+ * @see #getRGBColorComponents
232+ * @see #getRGBComponents
233+ */
234+ private float fvalue[] = null;
235+
236+ /**
237+ * The alpha value as a <code>float</code> component.
238+ * If <code>frgbvalue</code> is <code>null</code>, this is not valid
239+ * data, so compute from the <code>int</code> color value.
240+ * @serial
241+ * @see #getRGBComponents
242+ * @see #getComponents
243+ */
244+ private float falpha = 0.0f;
245+
246+ /**
247+ * The <code>ColorSpace</code>. If <code>null</code>, then it's
248+ * default is sRGB.
249+ * @serial
250+ * @see #getColor
251+ * @see #getColorSpace
252+ * @see #getColorComponents
253+ */
254+ private ColorSpace cs = null;
255+
256+ /*
257+ * JDK 1.1 serialVersionUID
258+ */
259+ private static final long serialVersionUID = 118526816881161077L;
260+
261+ /**
262+ * Initialize JNI field and method IDs
263+ */
264+ private static native void initIDs();
265+
266+ static {
267+ /** 4112352 - Calling getDefaultToolkit()
268+ ** here can cause this class to be accessed before it is fully
269+ ** initialized. DON'T DO IT!!!
270+ **
271+ ** Toolkit.getDefaultToolkit();
272+ **/
273+
274+ /* ensure that the necessary native libraries are loaded */
275+ Toolkit.loadLibraries();
276+ if (!GraphicsEnvironment.isHeadless()) {
277+ initIDs();
278+ }
279+ }
280+
281+ /**
282+ * Checks the color integer components supplied for validity.
283+ * Throws an {@link IllegalArgumentException} if the value is out of
284+ * range.
285+ * @param r the Red component
286+ * @param g the Green component
287+ * @param b the Blue component
288+ **/
289+ private static void testColorValueRange(int r, int g, int b, int a) {
290+ boolean rangeError = false;
291+ String badComponentString = "";
292+
293+ if ( a < 0 || a > 255) {
294+ rangeError = true;
295+ badComponentString = badComponentString + " Alpha";
296+ }
297+ if ( r < 0 || r > 255) {
298+ rangeError = true;
299+ badComponentString = badComponentString + " Red";
300+ }
301+ if ( g < 0 || g > 255) {
302+ rangeError = true;
303+ badComponentString = badComponentString + " Green";
304+ }
305+ if ( b < 0 || b > 255) {
306+ rangeError = true;
307+ badComponentString = badComponentString + " Blue";
308+ }
309+ if ( rangeError == true ) {
310+ throw new IllegalArgumentException("Color parameter outside of expected range:"
311+ + badComponentString);
312+ }
313+ }
314+
315+ /**
316+ * Checks the color <code>float</code> components supplied for
317+ * validity.
318+ * Throws an <code>IllegalArgumentException</code> if the value is out
319+ * of range.
320+ * @param r the Red component
321+ * @param g the Green component
322+ * @param b the Blue component
323+ **/
324+ private static void testColorValueRange(float r, float g, float b, float a) {
325+ boolean rangeError = false;
326+ String badComponentString = "";
327+ if ( a < 0.0 || a > 1.0) {
328+ rangeError = true;
329+ badComponentString = badComponentString + " Alpha";
330+ }
331+ if ( r < 0.0 || r > 1.0) {
332+ rangeError = true;
333+ badComponentString = badComponentString + " Red";
334+ }
335+ if ( g < 0.0 || g > 1.0) {
336+ rangeError = true;
337+ badComponentString = badComponentString + " Green";
338+ }
339+ if ( b < 0.0 || b > 1.0) {
340+ rangeError = true;
341+ badComponentString = badComponentString + " Blue";
342+ }
343+ if ( rangeError == true ) {
344+ throw new IllegalArgumentException("Color parameter outside of expected range:"
345+ + badComponentString);
346+ }
347+ }
348+
349+ /**
350+ * Creates an opaque sRGB color with the specified red, green,
351+ * and blue values in the range (0 - 255).
352+ * The actual color used in rendering depends
353+ * on finding the best match given the color space
354+ * available for a given output device.
355+ * Alpha is defaulted to 255.
356+ *
357+ * @throws IllegalArgumentException if <code>r</code>, <code>g</code>
358+ * or <code>b</code> are outside of the range
359+ * 0 to 255, inclusive
360+ * @param r the red component
361+ * @param g the green component
362+ * @param b the blue component
363+ * @see #getRed
364+ * @see #getGreen
365+ * @see #getBlue
366+ * @see #getRGB
367+ */
368+ public Color(int r, int g, int b) {
369+ this(r, g, b, 255);
370+ }
371+
372+ /**
373+ * Creates an sRGB color with the specified red, green, blue, and alpha
374+ * values in the range (0 - 255).
375+ *
376+ * @throws IllegalArgumentException if <code>r</code>, <code>g</code>,
377+ * <code>b</code> or <code>a</code> are outside of the range
378+ * 0 to 255, inclusive
379+ * @param r the red component
380+ * @param g the green component
381+ * @param b the blue component
382+ * @param a the alpha component
383+ * @see #getRed
384+ * @see #getGreen
385+ * @see #getBlue
386+ * @see #getAlpha
387+ * @see #getRGB
388+ */
389+ @ConstructorProperties({"red", "green", "blue", "alpha"})
390+ public Color(int r, int g, int b, int a) {
391+ value = ((a & 0xFF) << 24) |
392+ ((r & 0xFF) << 16) |
393+ ((g & 0xFF) << 8) |
394+ ((b & 0xFF) << 0);
395+ testColorValueRange(r,g,b,a);
396+ }
397+
398+ /**
399+ * Creates an opaque sRGB color with the specified combined RGB value
400+ * consisting of the red component in bits 16-23, the green component
401+ * in bits 8-15, and the blue component in bits 0-7. The actual color
402+ * used in rendering depends on finding the best match given the
403+ * color space available for a particular output device. Alpha is
404+ * defaulted to 255.
405+ *
406+ * @param rgb the combined RGB components
407+ * @see java.awt.image.ColorModel#getRGBdefault
408+ * @see #getRed
409+ * @see #getGreen
410+ * @see #getBlue
411+ * @see #getRGB
412+ */
413+ public Color(int rgb) {
414+ value = 0xff000000 | rgb;
415+ }
416+
417+ /**
418+ * Creates an sRGB color with the specified combined RGBA value consisting
419+ * of the alpha component in bits 24-31, the red component in bits 16-23,
420+ * the green component in bits 8-15, and the blue component in bits 0-7.
421+ * If the <code>hasalpha</code> argument is <code>false</code>, alpha
422+ * is defaulted to 255.
423+ *
424+ * @param rgba the combined RGBA components
425+ * @param hasalpha <code>true</code> if the alpha bits are valid;
426+ * <code>false</code> otherwise
427+ * @see java.awt.image.ColorModel#getRGBdefault
428+ * @see #getRed
429+ * @see #getGreen
430+ * @see #getBlue
431+ * @see #getAlpha
432+ * @see #getRGB
433+ */
434+ public Color(int rgba, boolean hasalpha) {
435+ if (hasalpha) {
436+ value = rgba;
437+ } else {
438+ value = 0xff000000 | rgba;
439+ }
440+ }
441+
442+ /**
443+ * Creates an opaque sRGB color with the specified red, green, and blue
444+ * values in the range (0.0 - 1.0). Alpha is defaulted to 1.0. The
445+ * actual color used in rendering depends on finding the best
446+ * match given the color space available for a particular output
447+ * device.
448+ *
449+ * @throws IllegalArgumentException if <code>r</code>, <code>g</code>
450+ * or <code>b</code> are outside of the range
451+ * 0.0 to 1.0, inclusive
452+ * @param r the red component
453+ * @param g the green component
454+ * @param b the blue component
455+ * @see #getRed
456+ * @see #getGreen
457+ * @see #getBlue
458+ * @see #getRGB
459+ */
460+ public Color(float r, float g, float b) {
461+ this( (int) (r*255+0.5), (int) (g*255+0.5), (int) (b*255+0.5));
462+ testColorValueRange(r,g,b,1.0f);
463+ frgbvalue = new float[3];
464+ frgbvalue[0] = r;
465+ frgbvalue[1] = g;
466+ frgbvalue[2] = b;
467+ falpha = 1.0f;
468+ fvalue = frgbvalue;
469+ }
470+
471+ /**
472+ * Creates an sRGB color with the specified red, green, blue, and
473+ * alpha values in the range (0.0 - 1.0). The actual color
474+ * used in rendering depends on finding the best match given the
475+ * color space available for a particular output device.
476+ * @throws IllegalArgumentException if <code>r</code>, <code>g</code>
477+ * <code>b</code> or <code>a</code> are outside of the range
478+ * 0.0 to 1.0, inclusive
479+ * @param r the red component
480+ * @param g the green component
481+ * @param b the blue component
482+ * @param a the alpha component
483+ * @see #getRed
484+ * @see #getGreen
485+ * @see #getBlue
486+ * @see #getAlpha
487+ * @see #getRGB
488+ */
489+ public Color(float r, float g, float b, float a) {
490+ this((int)(r*255+0.5), (int)(g*255+0.5), (int)(b*255+0.5), (int)(a*255+0.5));
491+ frgbvalue = new float[3];
492+ frgbvalue[0] = r;
493+ frgbvalue[1] = g;
494+ frgbvalue[2] = b;
495+ falpha = a;
496+ fvalue = frgbvalue;
497+ }
498+
499+ /**
500+ * Creates a color in the specified <code>ColorSpace</code>
501+ * with the color components specified in the <code>float</code>
502+ * array and the specified alpha. The number of components is
503+ * determined by the type of the <code>ColorSpace</code>. For
504+ * example, RGB requires 3 components, but CMYK requires 4
505+ * components.
506+ * @param cspace the <code>ColorSpace</code> to be used to
507+ * interpret the components
508+ * @param components an arbitrary number of color components
509+ * that is compatible with the <code>ColorSpace</code>
510+ * @param alpha alpha value
511+ * @throws IllegalArgumentException if any of the values in the
512+ * <code>components</code> array or <code>alpha</code> is
513+ * outside of the range 0.0 to 1.0
514+ * @see #getComponents
515+ * @see #getColorComponents
516+ */
517+ public Color(ColorSpace cspace, float components[], float alpha) {
518+ boolean rangeError = false;
519+ String badComponentString = "";
520+ int n = cspace.getNumComponents();
521+ fvalue = new float[n];
522+ for (int i = 0; i < n; i++) {
523+ if (components[i] < 0.0 || components[i] > 1.0) {
524+ rangeError = true;
525+ badComponentString = badComponentString + "Component " + i
526+ + " ";
527+ } else {
528+ fvalue[i] = components[i];
529+ }
530+ }
531+ if (alpha < 0.0 || alpha > 1.0) {
532+ rangeError = true;
533+ badComponentString = badComponentString + "Alpha";
534+ } else {
535+ falpha = alpha;
536+ }
537+ if (rangeError) {
538+ throw new IllegalArgumentException(
539+ "Color parameter outside of expected range: " +
540+ badComponentString);
541+ }
542+ frgbvalue = cspace.toRGB(fvalue);
543+ cs = cspace;
544+ value = ((((int)(falpha*255)) & 0xFF) << 24) |
545+ ((((int)(frgbvalue[0]*255)) & 0xFF) << 16) |
546+ ((((int)(frgbvalue[1]*255)) & 0xFF) << 8) |
547+ ((((int)(frgbvalue[2]*255)) & 0xFF) << 0);
548+ }
549+
550+ /**
551+ * Returns the red component in the range 0-255 in the default sRGB
552+ * space.
553+ * @return the red component.
554+ * @see #getRGB
555+ */
556+ public int getRed() {
557+ return (getRGB() >> 16) & 0xFF;
558+ }
559+
560+ /**
561+ * Returns the green component in the range 0-255 in the default sRGB
562+ * space.
563+ * @return the green component.
564+ * @see #getRGB
565+ */
566+ public int getGreen() {
567+ return (getRGB() >> 8) & 0xFF;
568+ }
569+
570+ /**
571+ * Returns the blue component in the range 0-255 in the default sRGB
572+ * space.
573+ * @return the blue component.
574+ * @see #getRGB
575+ */
576+ public int getBlue() {
577+ return (getRGB() >> 0) & 0xFF;
578+ }
579+
580+ /**
581+ * Returns the alpha component in the range 0-255.
582+ * @return the alpha component.
583+ * @see #getRGB
584+ */
585+ public int getAlpha() {
586+ return (getRGB() >> 24) & 0xff;
587+ }
588+
589+ /**
590+ * Returns the RGB value representing the color in the default sRGB
591+ * {@link ColorModel}.
592+ * (Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are
593+ * blue).
594+ * @return the RGB value of the color in the default sRGB
595+ * <code>ColorModel</code>.
596+ * @see java.awt.image.ColorModel#getRGBdefault
597+ * @see #getRed
598+ * @see #getGreen
599+ * @see #getBlue
600+ * @since JDK1.0
601+ */
602+ public int getRGB() {
603+ return value;
604+ }
605+
606+ private static final double FACTOR = 0.7;
607+
608+ /**
609+ * Creates a new <code>Color</code> that is a brighter version of this
610+ * <code>Color</code>.
611+ * <p>
612+ * This method applies an arbitrary scale factor to each of the three RGB
613+ * components of this <code>Color</code> to create a brighter version
614+ * of this <code>Color</code>.
615+ * The {@code alpha} value is preserved.
616+ * Although <code>brighter</code> and
617+ * <code>darker</code> are inverse operations, the results of a
618+ * series of invocations of these two methods might be inconsistent
619+ * because of rounding errors.
620+ * @return a new <code>Color</code> object that is
621+ * a brighter version of this <code>Color</code>
622+ * with the same {@code alpha} value.
623+ * @see java.awt.Color#darker
624+ * @since JDK1.0
625+ */
626+ public Color brighter() {
627+ int r = getRed();
628+ int g = getGreen();
629+ int b = getBlue();
630+ int alpha = getAlpha();
631+
632+ /* From 2D group:
633+ * 1. black.brighter() should return grey
634+ * 2. applying brighter to blue will always return blue, brighter
635+ * 3. non pure color (non zero rgb) will eventually return white
636+ */
637+ int i = (int)(1.0/(1.0-FACTOR));
638+ if ( r == 0 && g == 0 && b == 0) {
639+ return new Color(i, i, i, alpha);
640+ }
641+ if ( r > 0 && r < i ) r = i;
642+ if ( g > 0 && g < i ) g = i;
643+ if ( b > 0 && b < i ) b = i;
644+
645+ return new Color(Math.min((int)(r/FACTOR), 255),
646+ Math.min((int)(g/FACTOR), 255),
647+ Math.min((int)(b/FACTOR), 255),
648+ alpha);
649+ }
650+
651+ /**
652+ * Creates a new <code>Color</code> that is a darker version of this
653+ * <code>Color</code>.
654+ * <p>
655+ * This method applies an arbitrary scale factor to each of the three RGB
656+ * components of this <code>Color</code> to create a darker version of
657+ * this <code>Color</code>.
658+ * The {@code alpha} value is preserved.
659+ * Although <code>brighter</code> and
660+ * <code>darker</code> are inverse operations, the results of a series
661+ * of invocations of these two methods might be inconsistent because
662+ * of rounding errors.
663+ * @return a new <code>Color</code> object that is
664+ * a darker version of this <code>Color</code>
665+ * with the same {@code alpha} value.
666+ * @see java.awt.Color#brighter
667+ * @since JDK1.0
668+ */
669+ public Color darker() {
670+ return new Color(Math.max((int)(getRed() *FACTOR), 0),
671+ Math.max((int)(getGreen()*FACTOR), 0),
672+ Math.max((int)(getBlue() *FACTOR), 0),
673+ getAlpha());
674+ }
675+
676+ /**
677+ * Computes the hash code for this <code>Color</code>.
678+ * @return a hash code value for this object.
679+ * @since JDK1.0
680+ */
681+ public int hashCode() {
682+ return value;
683+ }
684+
685+ /**
686+ * Determines whether another object is equal to this
687+ * <code>Color</code>.
688+ * <p>
689+ * The result is <code>true</code> if and only if the argument is not
690+ * <code>null</code> and is a <code>Color</code> object that has the same
691+ * red, green, blue, and alpha values as this object.
692+ * @param obj the object to test for equality with this
693+ * <code>Color</code>
694+ * @return <code>true</code> if the objects are the same;
695+ * <code>false</code> otherwise.
696+ * @since JDK1.0
697+ */
698+ public boolean equals(Object obj) {
699+ return obj instanceof Color && ((Color)obj).getRGB() == this.getRGB();
700+ }
701+
702+ /**
703+ * Returns a string representation of this <code>Color</code>. This
704+ * method is intended to be used only for debugging purposes. The
705+ * content and format of the returned string might vary between
706+ * implementations. The returned string might be empty but cannot
707+ * be <code>null</code>.
708+ *
709+ * @return a string representation of this <code>Color</code>.
710+ */
711+ public String toString() {
712+ return getClass().getName() + "[r=" + getRed() + ",g=" + getGreen() + ",b=" + getBlue() + "]";
713+ }
714+
715+ /**
716+ * Converts a <code>String</code> to an integer and returns the
717+ * specified opaque <code>Color</code>. This method handles string
718+ * formats that are used to represent octal and hexadecimal numbers.
719+ * @param nm a <code>String</code> that represents
720+ * an opaque color as a 24-bit integer
721+ * @return the new <code>Color</code> object.
722+ * @see java.lang.Integer#decode
723+ * @exception NumberFormatException if the specified string cannot
724+ * be interpreted as a decimal,
725+ * octal, or hexadecimal integer.
726+ * @since JDK1.1
727+ */
728+ public static Color decode(String nm) throws NumberFormatException {
729+ Integer intval = Integer.decode(nm);
730+ int i = intval.intValue();
731+ return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF);
732+ }
733+
734+ /**
735+ * Finds a color in the system properties.
736+ * <p>
737+ * The argument is treated as the name of a system property to
738+ * be obtained. The string value of this property is then interpreted
739+ * as an integer which is then converted to a <code>Color</code>
740+ * object.
741+ * <p>
742+ * If the specified property is not found or could not be parsed as
743+ * an integer then <code>null</code> is returned.
744+ * @param nm the name of the color property
745+ * @return the <code>Color</code> converted from the system
746+ * property.
747+ * @see java.lang.System#getProperty(java.lang.String)
748+ * @see java.lang.Integer#getInteger(java.lang.String)
749+ * @see java.awt.Color#Color(int)
750+ * @since JDK1.0
751+ */
752+ public static Color getColor(String nm) {
753+ return getColor(nm, null);
754+ }
755+
756+ /**
757+ * Finds a color in the system properties.
758+ * <p>
759+ * The first argument is treated as the name of a system property to
760+ * be obtained. The string value of this property is then interpreted
761+ * as an integer which is then converted to a <code>Color</code>
762+ * object.
763+ * <p>
764+ * If the specified property is not found or cannot be parsed as
765+ * an integer then the <code>Color</code> specified by the second
766+ * argument is returned instead.
767+ * @param nm the name of the color property
768+ * @param v the default <code>Color</code>
769+ * @return the <code>Color</code> converted from the system
770+ * property, or the specified <code>Color</code>.
771+ * @see java.lang.System#getProperty(java.lang.String)
772+ * @see java.lang.Integer#getInteger(java.lang.String)
773+ * @see java.awt.Color#Color(int)
774+ * @since JDK1.0
775+ */
776+ public static Color getColor(String nm, Color v) {
777+ Integer intval = Integer.getInteger(nm);
778+ if (intval == null) {
779+ return v;
780+ }
781+ int i = intval.intValue();
782+ return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF);
783+ }
784+
785+ /**
786+ * Finds a color in the system properties.
787+ * <p>
788+ * The first argument is treated as the name of a system property to
789+ * be obtained. The string value of this property is then interpreted
790+ * as an integer which is then converted to a <code>Color</code>
791+ * object.
792+ * <p>
793+ * If the specified property is not found or could not be parsed as
794+ * an integer then the integer value <code>v</code> is used instead,
795+ * and is converted to a <code>Color</code> object.
796+ * @param nm the name of the color property
797+ * @param v the default color value, as an integer
798+ * @return the <code>Color</code> converted from the system
799+ * property or the <code>Color</code> converted from
800+ * the specified integer.
801+ * @see java.lang.System#getProperty(java.lang.String)
802+ * @see java.lang.Integer#getInteger(java.lang.String)
803+ * @see java.awt.Color#Color(int)
804+ * @since JDK1.0
805+ */
806+ public static Color getColor(String nm, int v) {
807+ Integer intval = Integer.getInteger(nm);
808+ int i = (intval != null) ? intval.intValue() : v;
809+ return new Color((i >> 16) & 0xFF, (i >> 8) & 0xFF, (i >> 0) & 0xFF);
810+ }
811+
812+ /**
813+ * Converts the components of a color, as specified by the HSB
814+ * model, to an equivalent set of values for the default RGB model.
815+ * <p>
816+ * The <code>saturation</code> and <code>brightness</code> components
817+ * should be floating-point values between zero and one
818+ * (numbers in the range 0.0-1.0). The <code>hue</code> component
819+ * can be any floating-point number. The floor of this number is
820+ * subtracted from it to create a fraction between 0 and 1. This
821+ * fractional number is then multiplied by 360 to produce the hue
822+ * angle in the HSB color model.
823+ * <p>
824+ * The integer that is returned by <code>HSBtoRGB</code> encodes the
825+ * value of a color in bits 0-23 of an integer value that is the same
826+ * format used by the method {@link #getRGB() <code>getRGB</code>}.
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+}