1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.graphics; 18 19 import com.badlogic.gdx.utils.NumberUtils; 20 21 /** A color class, holding the r, g, b and alpha component as floats in the range [0,1]. All methods perform clamping on the 22 * internal values after execution. 23 * 24 * @author mzechner */ 25 public class Color { 26 public static final Color CLEAR = new Color(0, 0, 0, 0); 27 public static final Color BLACK = new Color(0, 0, 0, 1); 28 29 public static final Color WHITE = new Color(0xffffffff); 30 public static final Color LIGHT_GRAY = new Color(0xbfbfbfff); 31 public static final Color GRAY = new Color(0x7f7f7fff); 32 public static final Color DARK_GRAY = new Color(0x3f3f3fff); 33 34 public static final Color BLUE = new Color(0, 0, 1, 1); 35 public static final Color NAVY = new Color(0, 0, 0.5f, 1); 36 public static final Color ROYAL = new Color(0x4169e1ff); 37 public static final Color SLATE = new Color(0x708090ff); 38 public static final Color SKY = new Color(0x87ceebff); 39 public static final Color CYAN = new Color(0, 1, 1, 1); 40 public static final Color TEAL = new Color(0, 0.5f, 0.5f, 1); 41 42 public static final Color GREEN = new Color(0x00ff00ff); 43 public static final Color CHARTREUSE = new Color(0x7fff00ff); 44 public static final Color LIME = new Color(0x32cd32ff); 45 public static final Color FOREST = new Color(0x228b22ff); 46 public static final Color OLIVE = new Color(0x6b8e23ff); 47 48 public static final Color YELLOW = new Color(0xffff00ff); 49 public static final Color GOLD = new Color(0xffd700ff); 50 public static final Color GOLDENROD = new Color(0xdaa520ff); 51 public static final Color ORANGE = new Color(0xffa500ff); 52 53 public static final Color BROWN = new Color(0x8b4513ff); 54 public static final Color TAN = new Color(0xd2b48cff); 55 public static final Color FIREBRICK = new Color(0xb22222ff); 56 57 public static final Color RED = new Color(0xff0000ff); 58 public static final Color SCARLET = new Color(0xff341cff); 59 public static final Color CORAL = new Color(0xff7f50ff); 60 public static final Color SALMON = new Color(0xfa8072ff); 61 public static final Color PINK = new Color(0xff69b4ff); 62 public static final Color MAGENTA = new Color(1, 0, 1, 1); 63 64 public static final Color PURPLE = new Color(0xa020f0ff); 65 public static final Color VIOLET = new Color(0xee82eeff); 66 public static final Color MAROON = new Color(0xb03060ff); 67 68 /** the red, green, blue and alpha components **/ 69 public float r, g, b, a; 70 71 /** Constructs a new Color with all components set to 0. */ Color()72 public Color () { 73 } 74 75 /** @see #rgba8888ToColor(Color, int) */ Color(int rgba8888)76 public Color (int rgba8888) { 77 rgba8888ToColor(this, rgba8888); 78 } 79 80 /** Constructor, sets the components of the color 81 * 82 * @param r the red component 83 * @param g the green component 84 * @param b the blue component 85 * @param a the alpha component */ Color(float r, float g, float b, float a)86 public Color (float r, float g, float b, float a) { 87 this.r = r; 88 this.g = g; 89 this.b = b; 90 this.a = a; 91 clamp(); 92 } 93 94 /** Constructs a new color using the given color 95 * 96 * @param color the color */ Color(Color color)97 public Color (Color color) { 98 set(color); 99 } 100 101 /** Sets this color to the given color. 102 * 103 * @param color the Color */ set(Color color)104 public Color set (Color color) { 105 this.r = color.r; 106 this.g = color.g; 107 this.b = color.b; 108 this.a = color.a; 109 return this; 110 } 111 112 /** Multiplies the this color and the given color 113 * 114 * @param color the color 115 * @return this color. */ mul(Color color)116 public Color mul (Color color) { 117 this.r *= color.r; 118 this.g *= color.g; 119 this.b *= color.b; 120 this.a *= color.a; 121 return clamp(); 122 } 123 124 /** Multiplies all components of this Color with the given value. 125 * 126 * @param value the value 127 * @return this color */ mul(float value)128 public Color mul (float value) { 129 this.r *= value; 130 this.g *= value; 131 this.b *= value; 132 this.a *= value; 133 return clamp(); 134 } 135 136 /** Adds the given color to this color. 137 * 138 * @param color the color 139 * @return this color */ add(Color color)140 public Color add (Color color) { 141 this.r += color.r; 142 this.g += color.g; 143 this.b += color.b; 144 this.a += color.a; 145 return clamp(); 146 } 147 148 /** Subtracts the given color from this color 149 * 150 * @param color the color 151 * @return this color */ sub(Color color)152 public Color sub (Color color) { 153 this.r -= color.r; 154 this.g -= color.g; 155 this.b -= color.b; 156 this.a -= color.a; 157 return clamp(); 158 } 159 160 /** Clamps this Color's components to a valid range [0 - 1] 161 * @return this Color for chaining */ clamp()162 public Color clamp () { 163 if (r < 0) 164 r = 0; 165 else if (r > 1) r = 1; 166 167 if (g < 0) 168 g = 0; 169 else if (g > 1) g = 1; 170 171 if (b < 0) 172 b = 0; 173 else if (b > 1) b = 1; 174 175 if (a < 0) 176 a = 0; 177 else if (a > 1) a = 1; 178 return this; 179 } 180 181 /** Sets this Color's component values. 182 * 183 * @param r Red component 184 * @param g Green component 185 * @param b Blue component 186 * @param a Alpha component 187 * 188 * @return this Color for chaining */ set(float r, float g, float b, float a)189 public Color set (float r, float g, float b, float a) { 190 this.r = r; 191 this.g = g; 192 this.b = b; 193 this.a = a; 194 return clamp(); 195 } 196 197 /** Sets this color's component values through an integer representation. 198 * 199 * @return this Color for chaining 200 * @see #rgba8888ToColor(Color, int) */ set(int rgba)201 public Color set (int rgba) { 202 rgba8888ToColor(this, rgba); 203 return this; 204 } 205 206 /** Adds the given color component values to this Color's values. 207 * 208 * @param r Red component 209 * @param g Green component 210 * @param b Blue component 211 * @param a Alpha component 212 * 213 * @return this Color for chaining */ add(float r, float g, float b, float a)214 public Color add (float r, float g, float b, float a) { 215 this.r += r; 216 this.g += g; 217 this.b += b; 218 this.a += a; 219 return clamp(); 220 } 221 222 /** Subtracts the given values from this Color's component values. 223 * 224 * @param r Red component 225 * @param g Green component 226 * @param b Blue component 227 * @param a Alpha component 228 * 229 * @return this Color for chaining */ sub(float r, float g, float b, float a)230 public Color sub (float r, float g, float b, float a) { 231 this.r -= r; 232 this.g -= g; 233 this.b -= b; 234 this.a -= a; 235 return clamp(); 236 } 237 238 /** Multiplies this Color's color components by the given ones. 239 * 240 * @param r Red component 241 * @param g Green component 242 * @param b Blue component 243 * @param a Alpha component 244 * 245 * @return this Color for chaining */ mul(float r, float g, float b, float a)246 public Color mul (float r, float g, float b, float a) { 247 this.r *= r; 248 this.g *= g; 249 this.b *= b; 250 this.a *= a; 251 return clamp(); 252 } 253 254 /** Linearly interpolates between this color and the target color by t which is in the range [0,1]. The result is stored in 255 * this color. 256 * @param target The target color 257 * @param t The interpolation coefficient 258 * @return This color for chaining. */ lerp(final Color target, final float t)259 public Color lerp (final Color target, final float t) { 260 this.r += t * (target.r - this.r); 261 this.g += t * (target.g - this.g); 262 this.b += t * (target.b - this.b); 263 this.a += t * (target.a - this.a); 264 return clamp(); 265 } 266 267 /** Linearly interpolates between this color and the target color by t which is in the range [0,1]. The result is stored in 268 * this color. 269 * @param r The red component of the target color 270 * @param g The green component of the target color 271 * @param b The blue component of the target color 272 * @param a The alpha component of the target color 273 * @param t The interpolation coefficient 274 * @return This color for chaining. */ lerp(final float r, final float g, final float b, final float a, final float t)275 public Color lerp (final float r, final float g, final float b, final float a, final float t) { 276 this.r += t * (r - this.r); 277 this.g += t * (g - this.g); 278 this.b += t * (b - this.b); 279 this.a += t * (a - this.a); 280 return clamp(); 281 } 282 283 /** Multiplies the RGB values by the alpha. */ premultiplyAlpha()284 public Color premultiplyAlpha () { 285 r *= a; 286 g *= a; 287 b *= a; 288 return this; 289 } 290 291 @Override equals(Object o)292 public boolean equals (Object o) { 293 if (this == o) return true; 294 if (o == null || getClass() != o.getClass()) return false; 295 Color color = (Color)o; 296 return toIntBits() == color.toIntBits(); 297 } 298 299 @Override hashCode()300 public int hashCode () { 301 int result = (r != +0.0f ? NumberUtils.floatToIntBits(r) : 0); 302 result = 31 * result + (g != +0.0f ? NumberUtils.floatToIntBits(g) : 0); 303 result = 31 * result + (b != +0.0f ? NumberUtils.floatToIntBits(b) : 0); 304 result = 31 * result + (a != +0.0f ? NumberUtils.floatToIntBits(a) : 0); 305 return result; 306 } 307 308 /** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float. 309 * @return the packed color as a 32-bit float 310 * @see NumberUtils#intToFloatColor(int) */ toFloatBits()311 public float toFloatBits () { 312 int color = ((int)(255 * a) << 24) | ((int)(255 * b) << 16) | ((int)(255 * g) << 8) | ((int)(255 * r)); 313 return NumberUtils.intToFloatColor(color); 314 } 315 316 /** Packs the color components into a 32-bit integer with the format ABGR. 317 * @return the packed color as a 32-bit int. */ toIntBits()318 public int toIntBits () { 319 int color = ((int)(255 * a) << 24) | ((int)(255 * b) << 16) | ((int)(255 * g) << 8) | ((int)(255 * r)); 320 return color; 321 } 322 323 /** Returns the color encoded as hex string with the format RRGGBBAA. */ toString()324 public String toString () { 325 String value = Integer 326 .toHexString(((int)(255 * r) << 24) | ((int)(255 * g) << 16) | ((int)(255 * b) << 8) | ((int)(255 * a))); 327 while (value.length() < 8) 328 value = "0" + value; 329 return value; 330 } 331 332 /** Returns a new color from a hex string with the format RRGGBBAA. 333 * @see #toString() */ valueOf(String hex)334 public static Color valueOf (String hex) { 335 hex = hex.charAt(0) == '#' ? hex.substring(1) : hex; 336 int r = Integer.valueOf(hex.substring(0, 2), 16); 337 int g = Integer.valueOf(hex.substring(2, 4), 16); 338 int b = Integer.valueOf(hex.substring(4, 6), 16); 339 int a = hex.length() != 8 ? 255 : Integer.valueOf(hex.substring(6, 8), 16); 340 return new Color(r / 255f, g / 255f, b / 255f, a / 255f); 341 } 342 343 /** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float. Note that no range 344 * checking is performed for higher performance. 345 * @param r the red component, 0 - 255 346 * @param g the green component, 0 - 255 347 * @param b the blue component, 0 - 255 348 * @param a the alpha component, 0 - 255 349 * @return the packed color as a float 350 * @see NumberUtils#intToFloatColor(int) */ toFloatBits(int r, int g, int b, int a)351 public static float toFloatBits (int r, int g, int b, int a) { 352 int color = (a << 24) | (b << 16) | (g << 8) | r; 353 float floatColor = NumberUtils.intToFloatColor(color); 354 return floatColor; 355 } 356 357 /** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float. 358 * @return the packed color as a 32-bit float 359 * @see NumberUtils#intToFloatColor(int) */ toFloatBits(float r, float g, float b, float a)360 public static float toFloatBits (float r, float g, float b, float a) { 361 int color = ((int)(255 * a) << 24) | ((int)(255 * b) << 16) | ((int)(255 * g) << 8) | ((int)(255 * r)); 362 return NumberUtils.intToFloatColor(color); 363 } 364 365 /** Packs the color components into a 32-bit integer with the format ABGR. Note that no range checking is performed for higher 366 * performance. 367 * @param r the red component, 0 - 255 368 * @param g the green component, 0 - 255 369 * @param b the blue component, 0 - 255 370 * @param a the alpha component, 0 - 255 371 * @return the packed color as a 32-bit int */ toIntBits(int r, int g, int b, int a)372 public static int toIntBits (int r, int g, int b, int a) { 373 return (a << 24) | (b << 16) | (g << 8) | r; 374 } 375 alpha(float alpha)376 public static int alpha (float alpha) { 377 return (int)(alpha * 255.0f); 378 } 379 luminanceAlpha(float luminance, float alpha)380 public static int luminanceAlpha (float luminance, float alpha) { 381 return ((int)(luminance * 255.0f) << 8) | (int)(alpha * 255); 382 } 383 rgb565(float r, float g, float b)384 public static int rgb565 (float r, float g, float b) { 385 return ((int)(r * 31) << 11) | ((int)(g * 63) << 5) | (int)(b * 31); 386 } 387 rgba4444(float r, float g, float b, float a)388 public static int rgba4444 (float r, float g, float b, float a) { 389 return ((int)(r * 15) << 12) | ((int)(g * 15) << 8) | ((int)(b * 15) << 4) | (int)(a * 15); 390 } 391 rgb888(float r, float g, float b)392 public static int rgb888 (float r, float g, float b) { 393 return ((int)(r * 255) << 16) | ((int)(g * 255) << 8) | (int)(b * 255); 394 } 395 rgba8888(float r, float g, float b, float a)396 public static int rgba8888 (float r, float g, float b, float a) { 397 return ((int)(r * 255) << 24) | ((int)(g * 255) << 16) | ((int)(b * 255) << 8) | (int)(a * 255); 398 } 399 argb8888(float a, float r, float g, float b)400 public static int argb8888 (float a, float r, float g, float b) { 401 return ((int)(a * 255) << 24) | ((int)(r * 255) << 16) | ((int)(g * 255) << 8) | (int)(b * 255); 402 } 403 rgb565(Color color)404 public static int rgb565 (Color color) { 405 return ((int)(color.r * 31) << 11) | ((int)(color.g * 63) << 5) | (int)(color.b * 31); 406 } 407 rgba4444(Color color)408 public static int rgba4444 (Color color) { 409 return ((int)(color.r * 15) << 12) | ((int)(color.g * 15) << 8) | ((int)(color.b * 15) << 4) | (int)(color.a * 15); 410 } 411 rgb888(Color color)412 public static int rgb888 (Color color) { 413 return ((int)(color.r * 255) << 16) | ((int)(color.g * 255) << 8) | (int)(color.b * 255); 414 } 415 rgba8888(Color color)416 public static int rgba8888 (Color color) { 417 return ((int)(color.r * 255) << 24) | ((int)(color.g * 255) << 16) | ((int)(color.b * 255) << 8) | (int)(color.a * 255); 418 } 419 argb8888(Color color)420 public static int argb8888 (Color color) { 421 return ((int)(color.a * 255) << 24) | ((int)(color.r * 255) << 16) | ((int)(color.g * 255) << 8) | (int)(color.b * 255); 422 } 423 424 /** Sets the Color components using the specified integer value in the format RGB565. This is inverse to the rgb565(r, g, b) 425 * method. 426 * 427 * @param color The Color to be modified. 428 * @param value An integer color value in RGB565 format. */ rgb565ToColor(Color color, int value)429 public static void rgb565ToColor (Color color, int value) { 430 color.r = ((value & 0x0000F800) >>> 11) / 31f; 431 color.g = ((value & 0x000007E0) >>> 5) / 63f; 432 color.b = ((value & 0x0000001F) >>> 0) / 31f; 433 } 434 435 /** Sets the Color components using the specified integer value in the format RGBA4444. This is inverse to the rgba4444(r, g, 436 * b, a) method. 437 * 438 * @param color The Color to be modified. 439 * @param value An integer color value in RGBA4444 format. */ rgba4444ToColor(Color color, int value)440 public static void rgba4444ToColor (Color color, int value) { 441 color.r = ((value & 0x0000f000) >>> 12) / 15f; 442 color.g = ((value & 0x00000f00) >>> 8) / 15f; 443 color.b = ((value & 0x000000f0) >>> 4) / 15f; 444 color.a = ((value & 0x0000000f)) / 15f; 445 } 446 447 /** Sets the Color components using the specified integer value in the format RGB888. This is inverse to the rgb888(r, g, b) 448 * method. 449 * 450 * @param color The Color to be modified. 451 * @param value An integer color value in RGB888 format. */ rgb888ToColor(Color color, int value)452 public static void rgb888ToColor (Color color, int value) { 453 color.r = ((value & 0x00ff0000) >>> 16) / 255f; 454 color.g = ((value & 0x0000ff00) >>> 8) / 255f; 455 color.b = ((value & 0x000000ff)) / 255f; 456 } 457 458 /** Sets the Color components using the specified integer value in the format RGBA8888. This is inverse to the rgba8888(r, g, 459 * b, a) method. 460 * 461 * @param color The Color to be modified. 462 * @param value An integer color value in RGBA8888 format. */ rgba8888ToColor(Color color, int value)463 public static void rgba8888ToColor (Color color, int value) { 464 color.r = ((value & 0xff000000) >>> 24) / 255f; 465 color.g = ((value & 0x00ff0000) >>> 16) / 255f; 466 color.b = ((value & 0x0000ff00) >>> 8) / 255f; 467 color.a = ((value & 0x000000ff)) / 255f; 468 } 469 470 /** Sets the Color components using the specified integer value in the format ARGB8888. This is the inverse to the argb8888(a, 471 * r, g, b) method 472 * 473 * @param color The Color to be modified. 474 * @param value An integer color value in ARGB8888 format. */ argb8888ToColor(Color color, int value)475 public static void argb8888ToColor (Color color, int value) { 476 color.a = ((value & 0xff000000) >>> 24) / 255f; 477 color.r = ((value & 0x00ff0000) >>> 16) / 255f; 478 color.g = ((value & 0x0000ff00) >>> 8) / 255f; 479 color.b = ((value & 0x000000ff)) / 255f; 480 } 481 482 /** @return a copy of this color */ cpy()483 public Color cpy () { 484 return new Color(this); 485 } 486 } 487