2 * Copyright (c) 2008-2012, Matthias Mann
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of Matthias Mann nor the names of its contributors may
15 * be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 package de.matthiasmann.twl;
32 import java.lang.reflect.Field;
33 import java.lang.reflect.Modifier;
34 import java.util.Locale;
37 * A immutable color class. Colors are represented as bytes.
39 * @author Matthias Mann
41 public final class Color {
43 public static final Color BLACK = new Color(0xFF000000);
44 public static final Color SILVER = new Color(0xFFC0C0C0);
45 public static final Color GRAY = new Color(0xFF808080);
46 public static final Color WHITE = new Color(0xFFFFFFFF);
47 public static final Color MAROON = new Color(0xFF800000);
48 public static final Color RED = new Color(0xFFFF0000);
49 public static final Color PURPLE = new Color(0xFF800080);
50 public static final Color FUCHSIA = new Color(0xFFFF00FF);
51 public static final Color GREEN = new Color(0xFF008000);
52 public static final Color LIME = new Color(0xFF00FF00);
53 public static final Color OLIVE = new Color(0xFF808000);
54 public static final Color ORANGE = new Color(0xFFFFA500);
55 public static final Color YELLOW = new Color(0xFFFFFF00);
56 public static final Color NAVY = new Color(0xFF000080);
57 public static final Color BLUE = new Color(0xFF0000FF);
58 public static final Color TEAL = new Color(0xFF008080);
59 public static final Color AQUA = new Color(0xFF00FFFF);
60 public static final Color SKYBLUE = new Color(0xFF87CEEB);
62 public static final Color LIGHTBLUE = new Color(0xFFADD8E6);
63 public static final Color LIGHTCORAL = new Color(0xFFF08080);
64 public static final Color LIGHTCYAN = new Color(0xFFE0FFFF);
65 public static final Color LIGHTGRAY = new Color(0xFFD3D3D3);
66 public static final Color LIGHTGREEN = new Color(0xFF90EE90);
67 public static final Color LIGHTPINK = new Color(0xFFFFB6C1);
68 public static final Color LIGHTSALMON = new Color(0xFFFFA07A);
69 public static final Color LIGHTSKYBLUE = new Color(0xFF87CEFA);
70 public static final Color LIGHTYELLOW = new Color(0xFFFFFFE0);
72 public static final Color TRANSPARENT = new Color(0);
79 public Color(byte r, byte g, byte b, byte a) {
87 * Creates a new color object from an integer in ARGB order.
92 * bits 24-31 are alpha
94 * @param argb the color value as integer
96 public Color(int argb) {
97 this.a = (byte)(argb >> 24);
98 this.r = (byte)(argb >> 16);
99 this.g = (byte)(argb >> 8);
100 this.b = (byte)(argb );
104 * Converts this color into an integer in ARGB format
106 * @return the color value as integer
109 public int toARGB() {
110 return ((a & 255) << 24) |
132 public int getRed() {
136 public int getGreen() {
140 public int getBlue() {
144 public int getAlpha() {
148 public float getRedFloat() {
149 return (r & 255) * (1.0f / 255f);
152 public float getGreenFloat() {
153 return (g & 255) * (1.0f / 255f);
156 public float getBlueFloat() {
157 return (b & 255) * (1.0f / 255f);
160 public float getAlphaFloat() {
161 return (a & 255) * (1.0f / 255f);
164 public void getFloats(float[] dst, int off) {
165 dst[off+0] = getRedFloat();
166 dst[off+1] = getGreenFloat();
167 dst[off+2] = getBlueFloat();
168 dst[off+3] = getAlphaFloat();
172 * Retrieves a color by it's name. This uses the case insensitive lookup
173 * for the color constants defined in this class.
175 * @param name the color name to lookup
176 * @return a Color or null if the name was not found
178 public static Color getColorByName(String name) {
179 name = name.toUpperCase(Locale.ENGLISH);
181 Field f = Color.class.getField(name);
182 if(Modifier.isStatic(f.getModifiers()) && f.getType() == Color.class) {
183 return (Color)f.get(null);
185 } catch (Throwable ex) {
192 * Parses a numeric or symbolic color. Symbolic names are resolved by getColorByName
194 * The following hex formats are supported:
200 * @param value the color to parse
201 * @return a Color object or null
202 * @throws NumberFormatException if the hex color code can't be parsed
203 * @see #getColorByName(java.lang.String)
205 public static Color parserColor(String value) throws NumberFormatException {
206 if(value.length() > 0 && value.charAt(0) == '#') {
207 String hexcode = value.substring(1);
208 switch (value.length()) {
210 int rgb4 = Integer.parseInt(hexcode, 16);
211 int r = ((rgb4 >> 8) & 0xF) * 0x11;
212 int g = ((rgb4 >> 4) & 0xF) * 0x11;
213 int b = ((rgb4 ) & 0xF) * 0x11;
214 return new Color(0xFF000000 | (r << 16) | (g << 8) | b);
217 int rgb4 = Integer.parseInt(hexcode, 16);
218 int a = ((rgb4 >> 12) & 0xF) * 0x11;
219 int r = ((rgb4 >> 8) & 0xF) * 0x11;
220 int g = ((rgb4 >> 4) & 0xF) * 0x11;
221 int b = ((rgb4 ) & 0xF) * 0x11;
222 return new Color((a << 24) | (r << 16) | (g << 8) | b);
225 return new Color(0xFF000000 | Integer.parseInt(hexcode, 16));
227 return new Color((int)Long.parseLong(hexcode, 16));
229 throw new NumberFormatException("Can't parse '" + value + "' as hex color");
232 return Color.getColorByName(value);
236 * Converts this color into it's hex string.
238 * If alpha is 255 then a string in "#RRGGBB" format is created,
239 * otherwise the "#AARRGGBB" format is created
241 * @return hex representation of this color
244 public String toString() {
246 return String.format("#%08X", toARGB());
248 return String.format("#%06X", toARGB() & 0xFFFFFF);
253 public boolean equals(Object obj) {
254 if(!(obj instanceof Color)) {
257 final Color other = (Color)obj;
258 return this.toARGB() == other.toARGB();
262 public int hashCode() {
266 public Color multiply(Color other) {
274 private byte mul(byte a, byte b) {
275 return (byte)(((a & 255) * (b & 255)) / 255);