OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [awt/] [Color.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* Color.java -- represents a color in Java
2
   Copyright (C) 1999, 2002, 2005  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package java.awt;
40
 
41
import java.awt.color.ColorSpace;
42
import java.awt.geom.AffineTransform;
43
import java.awt.geom.Rectangle2D;
44
import java.awt.image.ColorModel;
45
import java.io.Serializable;
46
 
47
/**
48
 * This class represents a color value in the AWT system. It uses the sRGB
49
 * (standard Red-Green-Blue) system, along with an alpha value ranging from
50
 * transparent (0.0f or 0) and opaque (1.0f or 255). The color is not
51
 * pre-multiplied by the alpha value an any of the accessor methods. Further
52
 * information about sRGB can be found at
53
 * <a href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
54
 * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html</a>.
55
 *
56
 * @author Aaron M. Renn (arenn@urbanophile.com)
57
 * @see ColorSpace
58
 * @see AlphaComposite
59
 * @since 1.0
60
 * @status updated to 1.4
61
 */
62
public class Color implements Paint, Serializable
63
{
64
  /**
65
   * Compatible with JDK 1.0+.
66
   */
67
  private static final long serialVersionUID = 118526816881161077L;
68
 
69
  /** Constant for the color white: R=255, G=255, B=255. */
70
  public static final Color white = new Color(0xffffff, false);
71
 
72
  /**
73
   * Constant for the color white: R=255, G=255, B=255.
74
   *
75
   * @since 1.4
76
   */
77
  public static final Color WHITE = white;
78
 
79
  /** Constant for the color light gray: R=192, G=192, B=192. */
80
  public static final Color lightGray = new Color(0xc0c0c0, false);
81
 
82
  /**
83
   * Constant for the color light gray: R=192, G=192, B=192.
84
   *
85
   * @since 1.4
86
   */
87
  public static final Color LIGHT_GRAY = lightGray;
88
 
89
  /** Constant for the color gray: R=128, G=128, B=128. */
90
  public static final Color gray = new Color(0x808080, false);
91
 
92
  /**
93
   * Constant for the color gray: R=128, G=128, B=128.
94
   *
95
   * @since 1.4
96
   */
97
  public static final Color GRAY = gray;
98
 
99
  /** Constant for the color dark gray: R=64, G=64, B=64. */
100
  public static final Color darkGray = new Color(0x404040, false);
101
 
102
  /**
103
   * Constant for the color dark gray: R=64, G=64, B=64.
104
   *
105
   * @since 1.4
106
   */
107
  public static final Color DARK_GRAY = darkGray;
108
 
109
  /** Constant for the color black: R=0, G=0, B=0. */
110
  public static final Color black = new Color(0x000000, false);
111
 
112
  /**
113
   * Constant for the color black: R=0, G=0, B=0.
114
   *
115
   * @since 1.4
116
   */
117
  public static final Color BLACK = black;
118
 
119
  /** Constant for the color red: R=255, G=0, B=0. */
120
  public static final Color red = new Color(0xff0000, false);
121
 
122
  /**
123
   * Constant for the color red: R=255, G=0, B=0.
124
   *
125
   * @since 1.4
126
   */
127
  public static final Color RED = red;
128
 
129
  /** Constant for the color pink: R=255, G=175, B=175. */
130
  public static final Color pink = new Color(0xffafaf, false);
131
 
132
  /**
133
   * Constant for the color pink: R=255, G=175, B=175.
134
   *
135
   * @since 1.4
136
   */
137
  public static final Color PINK = pink;
138
 
139
  /** Constant for the color orange: R=255, G=200, B=0. */
140
  public static final Color orange = new Color(0xffc800, false);
141
 
142
  /**
143
   * Constant for the color orange: R=255, G=200, B=0.
144
   *
145
   * @since 1.4
146
   */
147
  public static final Color ORANGE = orange;
148
 
149
  /** Constant for the color yellow: R=255, G=255, B=0. */
150
  public static final Color yellow = new Color(0xffff00, false);
151
 
152
  /**
153
   * Constant for the color yellow: R=255, G=255, B=0.
154
   *
155
   * @since 1.4
156
   */
157
  public static final Color YELLOW = yellow;
158
 
159
  /** Constant for the color green: R=0, G=255, B=0. */
160
  public static final Color green = new Color(0x00ff00, false);
161
 
162
  /**
163
   * Constant for the color green: R=0, G=255, B=0.
164
   *
165
   * @since 1.4
166
   */
167
  public static final Color GREEN = green;
168
 
169
  /** Constant for the color magenta: R=255, G=0, B=255. */
170
  public static final Color magenta = new Color(0xff00ff, false);
171
 
172
  /**
173
   * Constant for the color magenta: R=255, G=0, B=255.
174
   *
175
   * @since 1.4
176
   */
177
  public static final Color MAGENTA = magenta;
178
 
179
  /** Constant for the color cyan: R=0, G=255, B=255. */
180
  public static final Color cyan = new Color(0x00ffff, false);
181
 
182
  /**
183
   * Constant for the color cyan: R=0, G=255, B=255.
184
   *
185
   * @since 1.4
186
   */
187
  public static final Color CYAN = cyan;
188
 
189
  /** Constant for the color blue: R=0, G=0, B=255. */
190
  public static final Color blue = new Color(0x0000ff, false);
191
 
192
  /**
193
   * Constant for the color blue: R=0, G=0, B=255.
194
   *
195
   * @since 1.4
196
   */
197
  public static final Color BLUE = blue;
198
 
199
  /** Internal mask for red. */
200
  private static final int RED_MASK = 255 << 16;
201
 
202
  /** Internal mask for green. */
203
  private static final int GREEN_MASK = 255 << 8;
204
 
205
  /** Internal mask for blue. */
206
  private static final int BLUE_MASK = 255;
207
 
208
  /** Internal mask for alpha. Package visible for use in subclass. */
209
  static final int ALPHA_MASK = 255 << 24;
210
 
211
  /** Amount to scale a color by when brightening or darkening. */
212
  private static final float BRIGHT_SCALE = 0.7f;
213
 
214
  /**
215
   * The color value, in sRGB. Note that the actual color may be more
216
   * precise if frgbvalue or fvalue is non-null. This class stores alpha, red,
217
   * green, and blue, each 0-255, packed in an int. However, the subclass
218
   * SystemColor stores an index into an array. Therefore, for serial
219
   * compatibility (and because of poor design on Sun's part), this value
220
   * cannot be used directly; instead you must use <code>getRGB()</code>.
221
   *
222
   * @see #getRGB()
223
   * @serial the value of the color, whether an RGB literal or array index
224
   */
225
  final int value;
226
 
227
  /**
228
   * The color value, in sRGB. This may be null if the color was constructed
229
   * with ints; and it does not include alpha. This stores red, green, and
230
   * blue, in the range 0.0f - 1.0f.
231
   *
232
   * @see #getRGBColorComponents(float[])
233
   * @see #getRGBComponents(float[])
234
   * @serial the rgb components of the value
235
   * @since 1.2
236
   */
237
  private float[] frgbvalue;
238
 
239
  /**
240
   * The color value, in the native ColorSpace components. This may be null
241
   * if the color was constructed with ints or in the sRGB color space; and
242
   * it does not include alpha.
243
   *
244
   * @see #getRGBColorComponents(float[])
245
   * @see #getRGBComponents(float[])
246
   * @serial the original color space components of the color
247
   * @since 1.2
248
   */
249
  private float[] fvalue;
250
 
251
  /**
252
   * The alpha value. This is in the range 0.0f - 1.0f, but is invalid if
253
   * deserialized as 0.0 when frgbvalue is null.
254
   *
255
   * @see #getRGBComponents(float[])
256
   * @see #getComponents(float[])
257
   * @serial the alpha component of this color
258
   * @since 1.2
259
   */
260
  private final float falpha;
261
 
262
  /**
263
   * The ColorSpace. Null means the default sRGB space.
264
   *
265
   * @see #getColor(String)
266
   * @see #getColorSpace()
267
   * @see #getColorComponents(float[])
268
   * @serial the color space for this color
269
   * @since 1.2
270
   */
271
  private final ColorSpace cs;
272
 
273
  /**
274
   * The paint context for this solid color. Package visible for use in
275
   * subclass.
276
   */
277
  transient ColorPaintContext context;
278
 
279
  /**
280
   * Initializes a new instance of <code>Color</code> using the specified
281
   * red, green, and blue values, which must be given as integers in the
282
   * range of 0-255. Alpha will default to 255 (opaque). When drawing to
283
   * screen, the actual color may be adjusted to the best match of hardware
284
   * capabilities.
285
   *
286
   * @param red the red component of the RGB value
287
   * @param green the green component of the RGB value
288
   * @param blue the blue component of the RGB value
289
   * @throws IllegalArgumentException if the values are out of range 0-255
290
   * @see #getRed()
291
   * @see #getGreen()
292
   * @see #getBlue()
293
   * @see #getRGB()
294
   * @see #Color(int, int, int, int)
295
   */
296
  public Color(int red, int green, int blue)
297
  {
298
    this(red, green, blue, 255);
299
  }
300
 
301
  /**
302
   * Initializes a new instance of <code>Color</code> using the specified
303
   * red, green, blue, and alpha values, which must be given as integers in
304
   * the range of 0-255. When drawing to screen, the actual color may be
305
   * adjusted to the best match of hardware capabilities.
306
   *
307
   * @param red the red component of the RGB value
308
   * @param green the green component of the RGB value
309
   * @param blue the blue component of the RGB value
310
   * @param alpha the alpha value of the color
311
   * @throws IllegalArgumentException if the values are out of range 0-255
312
   * @see #getRed()
313
   * @see #getGreen()
314
   * @see #getBlue()
315
   * @see #getAlpha()
316
   * @see #getRGB()
317
   */
318
  public Color(int red, int green, int blue, int alpha)
319
  {
320
    if ((red & 255) != red || (green & 255) != green || (blue & 255) != blue
321
        || (alpha & 255) != alpha)
322
      throw new IllegalArgumentException("Bad RGB values"
323
                                        +" red=0x"+Integer.toHexString(red)
324
                                        +" green=0x"+Integer.toHexString(green)
325
                                        +" blue=0x"+Integer.toHexString(blue)
326
                                        +" alpha=0x"+Integer.toHexString(alpha)  );
327
 
328
    value = (alpha << 24) | (red << 16) | (green << 8) | blue;
329
    falpha = 1;
330
    cs = null;
331
  }
332
 
333
  /**
334
   * Initializes a new instance of <code>Color</code> using the specified
335
   * RGB value. The blue value is in bits 0-7, green in bits 8-15, and
336
   * red in bits 16-23. The other bits are ignored. The alpha value is set
337
   * to 255 (opaque). When drawing to screen, the actual color may be
338
   * adjusted to the best match of hardware capabilities.
339
   *
340
   * @param value the RGB value
341
   * @see ColorModel#getRGBdefault()
342
   * @see #getRed()
343
   * @see #getGreen()
344
   * @see #getBlue()
345
   * @see #getRGB()
346
   * @see #Color(int, boolean)
347
   */
348
  public Color(int value)
349
  {
350
    this(value, false);
351
  }
352
 
353
  /**
354
   * Initializes a new instance of <code>Color</code> using the specified
355
   * RGB value. The blue value is in bits 0-7, green in bits 8-15, and
356
   * red in bits 16-23. The alpha value is in bits 24-31, unless hasalpha
357
   * is false, in which case alpha is set to 255. When drawing to screen, the
358
   * actual color may be adjusted to the best match of hardware capabilities.
359
   *
360
   * @param value the RGB value
361
   * @param hasalpha true if value includes the alpha
362
   * @see ColorModel#getRGBdefault()
363
   * @see #getRed()
364
   * @see #getGreen()
365
   * @see #getBlue()
366
   * @see #getAlpha()
367
   * @see #getRGB()
368
   */
369
  public Color(int value, boolean hasalpha)
370
  {
371
    // Note: SystemColor calls this constructor, setting falpha to 0; but
372
    // code in getRGBComponents correctly reports falpha as 1.0 to the user
373
    // for all instances of SystemColor since frgbvalue is left null here.
374
    if (hasalpha)
375
      falpha = ((value & ALPHA_MASK) >> 24) / 255f;
376
    else
377
      {
378
        value |= ALPHA_MASK;
379
        falpha = 1;
380
      }
381
    this.value = value;
382
    cs = null;
383
  }
384
 
385
  /**
386
   * Initializes a new instance of <code>Color</code> using the specified
387
   * RGB values. These must be in the range of 0.0-1.0. Alpha is assigned
388
   * the value of 1.0 (opaque). When drawing to screen, the actual color may
389
   * be adjusted to the best match of hardware capabilities.
390
   *
391
   * @param red the red component of the RGB value
392
   * @param green the green component of the RGB value
393
   * @param blue the blue component of the RGB value
394
   * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f
395
   * @see #getRed()
396
   * @see #getGreen()
397
   * @see #getBlue()
398
   * @see #getRGB()
399
   * @see #Color(float, float, float, float)
400
   */
401
  public Color(float red, float green, float blue)
402
  {
403
    this(red, green, blue, 1.0f);
404
  }
405
 
406
  /**
407
   * Initializes a new instance of <code>Color</code> using the specified
408
   * RGB and alpha values. These must be in the range of 0.0-1.0. When drawing
409
   * to screen, the actual color may be adjusted to the best match of
410
   * hardware capabilities.
411
   *
412
   * @param red the red component of the RGB value
413
   * @param green the green component of the RGB value
414
   * @param blue the blue component of the RGB value
415
   * @param alpha the alpha value of the color
416
   * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f
417
   * @see #getRed()
418
   * @see #getGreen()
419
   * @see #getBlue()
420
   * @see #getAlpha()
421
   * @see #getRGB()
422
   */
423
  public Color(float red, float green, float blue, float alpha)
424
  {
425
    value = convert(red, green, blue, alpha);
426
    frgbvalue = new float[] {red, green, blue};
427
    falpha = alpha;
428
    cs = null;
429
  }
430
 
431
  /**
432
   * Creates a color in the given ColorSpace with the specified alpha. The
433
   * array must be non-null and have enough elements for the color space
434
   * (for example, RGB requires 3 elements, CMYK requires 4). When drawing
435
   * to screen, the actual color may be adjusted to the best match of
436
   * hardware capabilities.
437
   *
438
   * @param space the color space of components
439
   * @param components the color components, except alpha
440
   * @param alpha the alpha value of the color
441
   * @throws NullPointerException if cpsace or components is null
442
   * @throws ArrayIndexOutOfBoundsException if components is too small
443
   * @throws IllegalArgumentException if alpha or any component is out of range
444
   * @see #getComponents(float[])
445
   * @see #getColorComponents(float[])
446
   */
447
  public Color(ColorSpace space, float[] components, float alpha)
448
  {
449
    frgbvalue = space.toRGB(components);
450
    fvalue = components;
451
    falpha = alpha;
452
    cs = space;
453
    value = convert(frgbvalue[0], frgbvalue[1], frgbvalue[2], alpha);
454
  }
455
 
456
  /**
457
   * Returns the red value for this color, as an integer in the range 0-255
458
   * in the sRGB color space.
459
   *
460
   * @return the red value for this color
461
   * @see #getRGB()
462
   */
463
  public int getRed()
464
  {
465
    // Do not inline getRGB() to value, because of SystemColor.
466
    return (getRGB() & RED_MASK) >> 16;
467
  }
468
 
469
  /**
470
   * Returns the green value for this color, as an integer in the range 0-255
471
   * in the sRGB color space.
472
   *
473
   * @return the green value for this color
474
   * @see #getRGB()
475
   */
476
  public int getGreen()
477
  {
478
    // Do not inline getRGB() to value, because of SystemColor.
479
    return (getRGB() & GREEN_MASK) >> 8;
480
  }
481
 
482
  /**
483
   * Returns the blue value for this color, as an integer in the range 0-255
484
   * in the sRGB color space.
485
   *
486
   * @return the blue value for this color
487
   * @see #getRGB()
488
   */
489
  public int getBlue()
490
  {
491
    // Do not inline getRGB() to value, because of SystemColor.
492
    return getRGB() & BLUE_MASK;
493
  }
494
 
495
  /**
496
   * Returns the alpha value for this color, as an integer in the range 0-255.
497
   *
498
   * @return the alpha value for this color
499
   * @see #getRGB()
500
   */
501
  public int getAlpha()
502
  {
503
    // Do not inline getRGB() to value, because of SystemColor.
504
    return (getRGB() & ALPHA_MASK) >>> 24;
505
  }
506
 
507
  /**
508
   * Returns the RGB value for this color, in the sRGB color space. The blue
509
   * value will be in bits 0-7, green in 8-15, red in 16-23, and alpha value in
510
   * 24-31.
511
   *
512
   * @return the RGB value for this color
513
   * @see ColorModel#getRGBdefault()
514
   * @see #getRed()
515
   * @see #getGreen()
516
   * @see #getBlue()
517
   * @see #getAlpha()
518
   */
519
  public int getRGB()
520
  {
521
    return value;
522
  }
523
 
524
  /**
525
   * Returns a brighter version of this color. This is done by increasing the
526
   * RGB values by an arbitrary scale factor. The new color is opaque (an
527
   * alpha of 255). Note that this method and the <code>darker()</code>
528
   * method are not necessarily inverses.
529
   *
530
   * @return a brighter version of this color
531
   * @see #darker()
532
   */
533
  public Color brighter()
534
  {
535
    // Do not inline getRGB() to this.value, because of SystemColor.
536
    int value = getRGB();
537
    int red = (value & RED_MASK) >> 16;
538
    int green = (value & GREEN_MASK) >> 8;
539
    int blue = value & BLUE_MASK;
540
    // We have to special case 0-2 because they won't scale by division.
541
    red = red < 3 ? 3 : (int) Math.min(255, red / BRIGHT_SCALE);
542
    green = green < 3 ? 3 : (int) Math.min(255, green / BRIGHT_SCALE);
543
    blue = blue < 3 ? 3 : (int) Math.min(255, blue / BRIGHT_SCALE);
544
    return new Color(red, green, blue, 255);
545
  }
546
 
547
  /**
548
   * Returns a darker version of this color. This is done by decreasing the
549
   * RGB values by an arbitrary scale factor. The new color is opaque (an
550
   * alpha of 255). Note that this method and the <code>brighter()</code>
551
   * method are not necessarily inverses.
552
   *
553
   * @return a darker version of this color
554
   * @see #brighter()
555
   */
556
  public Color darker()
557
  {
558
    // Do not inline getRGB() to this.value, because of SystemColor.
559
    int value = getRGB();
560
    return new Color((int) (((value & RED_MASK) >> 16) * BRIGHT_SCALE),
561
                     (int) (((value & GREEN_MASK) >> 8) * BRIGHT_SCALE),
562
                     (int) ((value & BLUE_MASK) * BRIGHT_SCALE), 255);
563
  }
564
 
565
  /**
566
   * Returns a hash value for this color. This is simply the color in 8-bit
567
   * precision, in the format 0xAARRGGBB (alpha, red, green, blue).
568
   *
569
   * @return a hash value for this color
570
   */
571
  public int hashCode()
572
  {
573
    return value;
574
  }
575
 
576
  /**
577
   * Tests this object for equality against the specified object.  This will
578
   * be true if and only if the specified object is an instance of
579
   * <code>Color</code> and has the same 8-bit integer red, green, and blue
580
   * values as this object. Note that two colors may be slightly different
581
   * as float values, but round to the same integer values. Also note that
582
   * this does not accurately compare SystemColors, since that class does
583
   * not store its internal data in RGB format like regular colors.
584
   *
585
   * @param obj the object to compare to
586
   * @return true if the specified object is semantically equal to this one
587
   */
588
  public boolean equals(Object obj)
589
  {
590
    return obj instanceof Color && ((Color) obj).value == value;
591
  }
592
 
593
  /**
594
   * Returns a string representation of this object. Subclasses may return
595
   * any desired format, except for null, but this implementation returns
596
   * <code>getClass().getName() + "[r=" + getRed() + ",g=" + getGreen()
597
   * + ",b=" + getBlue() + ']'</code>.
598
   *
599
   * @return a string representation of this object
600
   */
601
  public String toString()
602
  {
603
    return getClass().getName() + "[r=" + ((value & RED_MASK) >> 16)
604
      + ",g=" + ((value & GREEN_MASK) >> 8) + ",b=" + (value & BLUE_MASK)
605
      + ']';
606
  }
607
 
608
  /**
609
   * Converts the specified string to a number, using Integer.decode, and
610
   * creates a new instance of <code>Color</code> from the value. The alpha
611
   * value will be 255 (opaque).
612
   *
613
   * @param str the numeric color string
614
   * @return a new instance of <code>Color</code> for the string
615
   * @throws NumberFormatException if the string cannot be parsed
616
   * @throws NullPointerException if the string is null
617
   * @see Integer#decode(String)
618
   * @see #Color(int)
619
   * @since 1.1
620
   */
621
  public static Color decode(String str)
622
  {
623
    return new Color(Integer.decode(str).intValue(), false);
624
  }
625
 
626
  /**
627
   * Returns a new instance of <code>Color</code> from the value of the
628
   * system property named by the specified string.  If the property does not
629
   * exist, or cannot be parsed, then <code>null</code> will be returned.
630
   *
631
   * @param prop the system property to retrieve
632
   * @throws SecurityException if getting the property is denied
633
   * @see #getColor(String, Color)
634
   * @see Integer#getInteger(String)
635
   */
636
  public static Color getColor(String prop)
637
  {
638
    return getColor(prop, null);
639
  }
640
 
641
  /**
642
   * Returns a new instance of <code>Color</code> from the value of the
643
   * system property named by the specified string.  If the property does
644
   * not exist, or cannot be parsed, then the default color value will be
645
   * returned.
646
   *
647
   * @param prop the system property to retrieve
648
   * @param defcolor the default color
649
   * @throws SecurityException if getting the property is denied
650
   * @see Integer#getInteger(String)
651
   */
652
  public static Color getColor(String prop, Color defcolor)
653
  {
654
    Integer val = Integer.getInteger(prop, null);
655
    return val == null ? defcolor
656
      : new Color(val.intValue(), false);
657
  }
658
 
659
  /**
660
   * Returns a new instance of <code>Color</code> from the value of the
661
   * system property named by the specified string.  If the property does
662
   * not exist, or cannot be parsed, then the default RGB value will be
663
   * used to create a return value.
664
   *
665
   * @param prop the system property to retrieve
666
   * @param defrgb the default RGB value
667
   * @throws SecurityException if getting the property is denied
668
   * @see #getColor(String, Color)
669
   * @see Integer#getInteger(String, int)
670
   */
671
  public static Color getColor(String prop, int defrgb)
672
  {
673
    Color c = getColor(prop, null);
674
    return c == null ? new Color(defrgb, false) : c;
675
  }
676
 
677
  /**
678
   * Converts from the HSB (hue, saturation, brightness) color model to the
679
   * RGB (red, green, blue) color model. The hue may be any floating point;
680
   * it's fractional portion is used to select the angle in the HSB model.
681
   * The saturation and brightness must be between 0 and 1. The result is
682
   * suitable for creating an RGB color with the one-argument constructor.
683
   *
684
   * @param hue the hue of the HSB value
685
   * @param saturation the saturation of the HSB value
686
   * @param brightness the brightness of the HSB value
687
   * @return the RGB value
688
   * @see #getRGB()
689
   * @see #Color(int)
690
   * @see ColorModel#getRGBdefault()
691
   */
692
  public static int HSBtoRGB(float hue, float saturation, float brightness)
693
  {
694
    if (saturation == 0)
695
      return convert(brightness, brightness, brightness, 0);
696
    if (saturation < 0 || saturation > 1 || brightness < 0 || brightness > 1)
697
      throw new IllegalArgumentException();
698
    hue = hue - (float) Math.floor(hue);
699
    int i = (int) (6 * hue);
700
    float f = 6 * hue - i;
701
    float p = brightness * (1 - saturation);
702
    float q = brightness * (1 - saturation * f);
703
    float t = brightness * (1 - saturation * (1 - f));
704
    switch (i)
705
      {
706
      case 0:
707
        return convert(brightness, t, p, 0);
708
      case 1:
709
        return convert(q, brightness, p, 0);
710
      case 2:
711
        return convert(p, brightness, t, 0);
712
      case 3:
713
        return convert(p, q, brightness, 0);
714
      case 4:
715
        return convert(t, p, brightness, 0);
716
      case 5:
717
        return convert(brightness, p, q, 0);
718
      default:
719
        throw new InternalError("impossible");
720
      }
721
  }
722
 
723
  /**
724
   * Converts from the RGB (red, green, blue) color model to the HSB (hue,
725
   * saturation, brightness) color model. If the array is null, a new one
726
   * is created, otherwise it is recycled. The results will be in the range
727
   * 0.0-1.0 if the inputs are in the range 0-255.
728
   *
729
   * @param red the red part of the RGB value
730
   * @param green the green part of the RGB value
731
   * @param blue the blue part of the RGB value
732
   * @param array an array for the result (at least 3 elements), or null
733
   * @return the array containing HSB value
734
   * @throws ArrayIndexOutOfBoundsException of array is too small
735
   * @see #getRGB()
736
   * @see #Color(int)
737
   * @see ColorModel#getRGBdefault()
738
   */
739
  public static float[] RGBtoHSB(int red, int green, int blue, float array[])
740
  {
741
    if (array == null)
742
      array = new float[3];
743
    // Calculate brightness.
744
    int min;
745
    int max;
746
    if (red < green)
747
      {
748
        min = red;
749
        max = green;
750
      }
751
    else
752
      {
753
        min = green;
754
        max = red;
755
      }
756
    if (blue > max)
757
      max = blue;
758
    else if (blue < min)
759
      min = blue;
760
    array[2] = max / 255f;
761
    // Calculate saturation.
762
    if (max == 0)
763
      array[1] = 0;
764
    else
765
      array[1] = ((float) (max - min)) / ((float) max);
766
    // Calculate hue.
767
    if (array[1] == 0)
768
      array[0] = 0;
769
    else
770
      {
771
        float delta = (max - min) * 6;
772
        if (red == max)
773
          array[0] = (green - blue) / delta;
774
        else if (green == max)
775
          array[0] = 1f / 3 + (blue - red) / delta;
776
        else
777
          array[0] = 2f / 3 + (red - green) / delta;
778
        if (array[0] < 0)
779
          array[0]++;
780
      }
781
    return array;
782
  }
783
 
784
  /**
785
   * Returns a new instance of <code>Color</code> based on the specified
786
   * HSB values. The hue may be any floating point; it's fractional portion
787
   * is used to select the angle in the HSB model. The saturation and
788
   * brightness must be between 0 and 1.
789
   *
790
   * @param hue the hue of the HSB value
791
   * @param saturation the saturation of the HSB value
792
   * @param brightness the brightness of the HSB value
793
   * @return the new <code>Color</code> object
794
   */
795
  public static Color getHSBColor(float hue, float saturation,
796
                                  float brightness)
797
  {
798
    return new Color(HSBtoRGB(hue, saturation, brightness), false);
799
  }
800
 
801
  /**
802
   * Returns a float array with the red, green, and blue components, and the
803
   * alpha value, in the default sRGB space, with values in the range 0.0-1.0.
804
   * If the array is null, a new one is created, otherwise it is recycled.
805
   *
806
   * @param array the array to put results into (at least 4 elements), or null
807
   * @return the RGB components and alpha value
808
   * @throws ArrayIndexOutOfBoundsException if array is too small
809
   */
810
  public float[] getRGBComponents(float[] array)
811
  {
812
    if (array == null)
813
      array = new float[4];
814
    getRGBColorComponents(array);
815
    // Stupid serialization issues require this check.
816
    array[3] = (falpha == 0 && frgbvalue == null
817
                ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
818
    return array;
819
  }
820
 
821
  /**
822
   * Returns a float array with the red, green, and blue components, in the
823
   * default sRGB space, with values in the range 0.0-1.0. If the array is
824
   * null, a new one is created, otherwise it is recycled.
825
   *
826
   * @param array the array to put results into (at least 3 elements), or null
827
   * @return the RGB components
828
   * @throws ArrayIndexOutOfBoundsException if array is too small
829
   */
830
  public float[] getRGBColorComponents(float[] array)
831
  {
832
    if (array == null)
833
      array = new float[3];
834
    else if (array == frgbvalue)
835
      return array; // Optimization for getColorComponents(float[]).
836
    if (frgbvalue == null)
837
      {
838
        // Do not inline getRGB() to this.value, because of SystemColor.
839
        int value = getRGB();
840
        frgbvalue = new float[] { ((value & RED_MASK) >> 16) / 255f,
841
                                  ((value & GREEN_MASK) >> 8) / 255f,
842
                                  (value & BLUE_MASK) / 255f };
843
      }
844
    array[0] = frgbvalue[0];
845
    array[1] = frgbvalue[1];
846
    array[2] = frgbvalue[2];
847
    return array;
848
  }
849
 
850
  /**
851
   * Returns a float array containing the color and alpha components of this
852
   * color in the ColorSpace it was created with (the constructors which do
853
   * not take a ColorSpace parameter use a default sRGB ColorSpace). If the
854
   * array is null, a new one is created, otherwise it is recycled, and must
855
   * have at least one more position than components used in the color space.
856
   *
857
   * @param array the array to put results into, or null
858
   * @return the original color space components and alpha value
859
   * @throws ArrayIndexOutOfBoundsException if array is too small
860
   */
861
  public float[] getComponents(float[] array)
862
  {
863
    int numComponents = cs == null ? 3 : cs.getNumComponents();
864
    if (array == null)
865
      array = new float[1 + numComponents];
866
    getColorComponents(array);
867
    // Stupid serialization issues require this check.
868
    array[numComponents] = (falpha == 0 && frgbvalue == null
869
                            ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
870
    return array;
871
  }
872
 
873
  /**
874
   * Returns a float array containing the color components of this color in
875
   * the ColorSpace it was created with (the constructors which do not take
876
   * a ColorSpace parameter use a default sRGB ColorSpace). If the array is
877
   * null, a new one is created, otherwise it is recycled, and must have at
878
   * least as many positions as used in the color space.
879
   *
880
   * @param array the array to put results into, or null
881
   * @return the original color space components
882
   * @throws ArrayIndexOutOfBoundsException if array is too small
883
   */
884
  public float[] getColorComponents(float[] array)
885
  {
886
    int numComponents = cs == null ? 3 : cs.getNumComponents();
887
    if (array == null)
888
      array = new float[numComponents];
889
    if (fvalue == null) // If fvalue is null, cs should be null too.
890
      fvalue = getRGBColorComponents(frgbvalue);
891
    System.arraycopy(fvalue, 0, array, 0, numComponents);
892
    return array;
893
  }
894
 
895
  /**
896
   * Returns a float array containing the color and alpha components of this
897
   * color in the given ColorSpace. If the array is null, a new one is
898
   * created, otherwise it is recycled, and must have at least one more
899
   * position than components used in the color space.
900
   *
901
   * @param space the color space to translate to
902
   * @param array the array to put results into, or null
903
   * @return the color space components and alpha value
904
   * @throws ArrayIndexOutOfBoundsException if array is too small
905
   * @throws NullPointerException if space is null
906
   */
907
  public float[] getComponents(ColorSpace space, float[] array)
908
  {
909
    int numComponents = space.getNumComponents();
910
    if (array == null)
911
      array = new float[1 + numComponents];
912
    getColorComponents(space, array);
913
    // Stupid serialization issues require this check.
914
    array[numComponents] = (falpha == 0 && frgbvalue == null
915
                            ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
916
    return array;
917
  }
918
 
919
  /**
920
   * Returns a float array containing the color components of this color in
921
   * the given ColorSpace. If the array is null, a new one is created,
922
   * otherwise it is recycled, and must have at least as many positions as
923
   * used in the color space.
924
   *
925
   * @param space the color space to translate to
926
   * @return the color space components
927
   * @throws ArrayIndexOutOfBoundsException if array is too small
928
   * @throws NullPointerException if space is null
929
   */
930
  public float[] getColorComponents(ColorSpace space, float[] array)
931
  {
932
    float[] components = space.fromRGB(getRGBColorComponents(frgbvalue));
933
    if (array == null)
934
      return components;
935
    System.arraycopy(components, 0, array, 0, components.length);
936
    return array;
937
  }
938
 
939
  /**
940
   * Returns the color space of this color. Except for the constructor which
941
   * takes a ColorSpace argument, this will be an implementation of
942
   * ColorSpace.CS_sRGB.
943
   *
944
   * @return the color space
945
   */
946
  public ColorSpace getColorSpace()
947
  {
948
    return cs == null ? ColorSpace.getInstance(ColorSpace.CS_sRGB) : cs;
949
  }
950
 
951
  /**
952
   * Returns a paint context, used for filling areas of a raster scan with
953
   * this color. Since the color is constant across the entire rectangle, and
954
   * since it is always in sRGB space, this implementation returns the same
955
   * object, regardless of the parameters. Subclasses, however, may have a
956
   * mutable result.
957
   *
958
   * @param cm the requested color model
959
   * @param deviceBounds the bounding box in device coordinates, ignored
960
   * @param userBounds the bounding box in user coordinates, ignored
961
   * @param xform the bounds transformation, ignored
962
   * @param hints any rendering hints, ignored
963
   * @return a context for painting this solid color
964
   */
965
  public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
966
                                    Rectangle2D userBounds,
967
                                    AffineTransform xform,
968
                                    RenderingHints hints)
969
  {
970
    if (context == null || !context.getColorModel().equals(cm))
971
      context = new ColorPaintContext(cm,value);
972
    return context;
973
  }
974
 
975
  /**
976
   * Returns the transparency level of this color.
977
   *
978
   * @return one of {@link #OPAQUE}, {@link #BITMASK}, or {@link #TRANSLUCENT}
979
   */
980
  public int getTransparency()
981
  {
982
    // Do not inline getRGB() to this.value, because of SystemColor.
983
    int alpha = getRGB() & ALPHA_MASK;
984
    return alpha == (255 << 24) ? OPAQUE : alpha == 0 ? BITMASK : TRANSLUCENT;
985
  }
986
 
987
  /**
988
   * Converts float values to integer value.
989
   *
990
   * @param red the red value
991
   * @param green the green value
992
   * @param blue the blue value
993
   * @param alpha the alpha value
994
   * @return the integer value made of 8-bit sections
995
   * @throws IllegalArgumentException if parameters are out of range 0.0-1.0
996
   */
997
  private static int convert(float red, float green, float blue, float alpha)
998
  {
999
    if (red < 0 || red > 1 || green < 0 || green > 1 || blue < 0 || blue > 1
1000
        || alpha < 0 || alpha > 1)
1001
      throw new IllegalArgumentException("Bad RGB values");
1002
    int redval = Math.round(255 * red);
1003
    int greenval = Math.round(255 * green);
1004
    int blueval = Math.round(255 * blue);
1005
    int alphaval = Math.round(255 * alpha);
1006
    return (alphaval << 24) | (redval << 16) | (greenval << 8) | blueval;
1007
  }
1008
} // class Color

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.