/******************************************************************************* * Copyright 2011 See AUTHORS file. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.badlogic.gdx.graphics; import com.badlogic.gdx.utils.NumberUtils; /** A color class, holding the r, g, b and alpha component as floats in the range [0,1]. All methods perform clamping on the * internal values after execution. * * @author mzechner */ public class Color { public static final Color CLEAR = new Color(0, 0, 0, 0); public static final Color BLACK = new Color(0, 0, 0, 1); public static final Color WHITE = new Color(0xffffffff); public static final Color LIGHT_GRAY = new Color(0xbfbfbfff); public static final Color GRAY = new Color(0x7f7f7fff); public static final Color DARK_GRAY = new Color(0x3f3f3fff); public static final Color BLUE = new Color(0, 0, 1, 1); public static final Color NAVY = new Color(0, 0, 0.5f, 1); public static final Color ROYAL = new Color(0x4169e1ff); public static final Color SLATE = new Color(0x708090ff); public static final Color SKY = new Color(0x87ceebff); public static final Color CYAN = new Color(0, 1, 1, 1); public static final Color TEAL = new Color(0, 0.5f, 0.5f, 1); public static final Color GREEN = new Color(0x00ff00ff); public static final Color CHARTREUSE = new Color(0x7fff00ff); public static final Color LIME = new Color(0x32cd32ff); public static final Color FOREST = new Color(0x228b22ff); public static final Color OLIVE = new Color(0x6b8e23ff); public static final Color YELLOW = new Color(0xffff00ff); public static final Color GOLD = new Color(0xffd700ff); public static final Color GOLDENROD = new Color(0xdaa520ff); public static final Color ORANGE = new Color(0xffa500ff); public static final Color BROWN = new Color(0x8b4513ff); public static final Color TAN = new Color(0xd2b48cff); public static final Color FIREBRICK = new Color(0xb22222ff); public static final Color RED = new Color(0xff0000ff); public static final Color SCARLET = new Color(0xff341cff); public static final Color CORAL = new Color(0xff7f50ff); public static final Color SALMON = new Color(0xfa8072ff); public static final Color PINK = new Color(0xff69b4ff); public static final Color MAGENTA = new Color(1, 0, 1, 1); public static final Color PURPLE = new Color(0xa020f0ff); public static final Color VIOLET = new Color(0xee82eeff); public static final Color MAROON = new Color(0xb03060ff); /** the red, green, blue and alpha components **/ public float r, g, b, a; /** Constructs a new Color with all components set to 0. */ public Color () { } /** @see #rgba8888ToColor(Color, int) */ public Color (int rgba8888) { rgba8888ToColor(this, rgba8888); } /** Constructor, sets the components of the color * * @param r the red component * @param g the green component * @param b the blue component * @param a the alpha component */ public Color (float r, float g, float b, float a) { this.r = r; this.g = g; this.b = b; this.a = a; clamp(); } /** Constructs a new color using the given color * * @param color the color */ public Color (Color color) { set(color); } /** Sets this color to the given color. * * @param color the Color */ public Color set (Color color) { this.r = color.r; this.g = color.g; this.b = color.b; this.a = color.a; return this; } /** Multiplies the this color and the given color * * @param color the color * @return this color. */ public Color mul (Color color) { this.r *= color.r; this.g *= color.g; this.b *= color.b; this.a *= color.a; return clamp(); } /** Multiplies all components of this Color with the given value. * * @param value the value * @return this color */ public Color mul (float value) { this.r *= value; this.g *= value; this.b *= value; this.a *= value; return clamp(); } /** Adds the given color to this color. * * @param color the color * @return this color */ public Color add (Color color) { this.r += color.r; this.g += color.g; this.b += color.b; this.a += color.a; return clamp(); } /** Subtracts the given color from this color * * @param color the color * @return this color */ public Color sub (Color color) { this.r -= color.r; this.g -= color.g; this.b -= color.b; this.a -= color.a; return clamp(); } /** Clamps this Color's components to a valid range [0 - 1] * @return this Color for chaining */ public Color clamp () { if (r < 0) r = 0; else if (r > 1) r = 1; if (g < 0) g = 0; else if (g > 1) g = 1; if (b < 0) b = 0; else if (b > 1) b = 1; if (a < 0) a = 0; else if (a > 1) a = 1; return this; } /** Sets this Color's component values. * * @param r Red component * @param g Green component * @param b Blue component * @param a Alpha component * * @return this Color for chaining */ public Color set (float r, float g, float b, float a) { this.r = r; this.g = g; this.b = b; this.a = a; return clamp(); } /** Sets this color's component values through an integer representation. * * @return this Color for chaining * @see #rgba8888ToColor(Color, int) */ public Color set (int rgba) { rgba8888ToColor(this, rgba); return this; } /** Adds the given color component values to this Color's values. * * @param r Red component * @param g Green component * @param b Blue component * @param a Alpha component * * @return this Color for chaining */ public Color add (float r, float g, float b, float a) { this.r += r; this.g += g; this.b += b; this.a += a; return clamp(); } /** Subtracts the given values from this Color's component values. * * @param r Red component * @param g Green component * @param b Blue component * @param a Alpha component * * @return this Color for chaining */ public Color sub (float r, float g, float b, float a) { this.r -= r; this.g -= g; this.b -= b; this.a -= a; return clamp(); } /** Multiplies this Color's color components by the given ones. * * @param r Red component * @param g Green component * @param b Blue component * @param a Alpha component * * @return this Color for chaining */ public Color mul (float r, float g, float b, float a) { this.r *= r; this.g *= g; this.b *= b; this.a *= a; return clamp(); } /** Linearly interpolates between this color and the target color by t which is in the range [0,1]. The result is stored in * this color. * @param target The target color * @param t The interpolation coefficient * @return This color for chaining. */ public Color lerp (final Color target, final float t) { this.r += t * (target.r - this.r); this.g += t * (target.g - this.g); this.b += t * (target.b - this.b); this.a += t * (target.a - this.a); return clamp(); } /** Linearly interpolates between this color and the target color by t which is in the range [0,1]. The result is stored in * this color. * @param r The red component of the target color * @param g The green component of the target color * @param b The blue component of the target color * @param a The alpha component of the target color * @param t The interpolation coefficient * @return This color for chaining. */ public Color lerp (final float r, final float g, final float b, final float a, final float t) { this.r += t * (r - this.r); this.g += t * (g - this.g); this.b += t * (b - this.b); this.a += t * (a - this.a); return clamp(); } /** Multiplies the RGB values by the alpha. */ public Color premultiplyAlpha () { r *= a; g *= a; b *= a; return this; } @Override public boolean equals (Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Color color = (Color)o; return toIntBits() == color.toIntBits(); } @Override public int hashCode () { int result = (r != +0.0f ? NumberUtils.floatToIntBits(r) : 0); result = 31 * result + (g != +0.0f ? NumberUtils.floatToIntBits(g) : 0); result = 31 * result + (b != +0.0f ? NumberUtils.floatToIntBits(b) : 0); result = 31 * result + (a != +0.0f ? NumberUtils.floatToIntBits(a) : 0); return result; } /** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float. * @return the packed color as a 32-bit float * @see NumberUtils#intToFloatColor(int) */ public float toFloatBits () { int color = ((int)(255 * a) << 24) | ((int)(255 * b) << 16) | ((int)(255 * g) << 8) | ((int)(255 * r)); return NumberUtils.intToFloatColor(color); } /** Packs the color components into a 32-bit integer with the format ABGR. * @return the packed color as a 32-bit int. */ public int toIntBits () { int color = ((int)(255 * a) << 24) | ((int)(255 * b) << 16) | ((int)(255 * g) << 8) | ((int)(255 * r)); return color; } /** Returns the color encoded as hex string with the format RRGGBBAA. */ public String toString () { String value = Integer .toHexString(((int)(255 * r) << 24) | ((int)(255 * g) << 16) | ((int)(255 * b) << 8) | ((int)(255 * a))); while (value.length() < 8) value = "0" + value; return value; } /** Returns a new color from a hex string with the format RRGGBBAA. * @see #toString() */ public static Color valueOf (String hex) { hex = hex.charAt(0) == '#' ? hex.substring(1) : hex; int r = Integer.valueOf(hex.substring(0, 2), 16); int g = Integer.valueOf(hex.substring(2, 4), 16); int b = Integer.valueOf(hex.substring(4, 6), 16); int a = hex.length() != 8 ? 255 : Integer.valueOf(hex.substring(6, 8), 16); return new Color(r / 255f, g / 255f, b / 255f, a / 255f); } /** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float. Note that no range * checking is performed for higher performance. * @param r the red component, 0 - 255 * @param g the green component, 0 - 255 * @param b the blue component, 0 - 255 * @param a the alpha component, 0 - 255 * @return the packed color as a float * @see NumberUtils#intToFloatColor(int) */ public static float toFloatBits (int r, int g, int b, int a) { int color = (a << 24) | (b << 16) | (g << 8) | r; float floatColor = NumberUtils.intToFloatColor(color); return floatColor; } /** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float. * @return the packed color as a 32-bit float * @see NumberUtils#intToFloatColor(int) */ public static float toFloatBits (float r, float g, float b, float a) { int color = ((int)(255 * a) << 24) | ((int)(255 * b) << 16) | ((int)(255 * g) << 8) | ((int)(255 * r)); return NumberUtils.intToFloatColor(color); } /** Packs the color components into a 32-bit integer with the format ABGR. Note that no range checking is performed for higher * performance. * @param r the red component, 0 - 255 * @param g the green component, 0 - 255 * @param b the blue component, 0 - 255 * @param a the alpha component, 0 - 255 * @return the packed color as a 32-bit int */ public static int toIntBits (int r, int g, int b, int a) { return (a << 24) | (b << 16) | (g << 8) | r; } public static int alpha (float alpha) { return (int)(alpha * 255.0f); } public static int luminanceAlpha (float luminance, float alpha) { return ((int)(luminance * 255.0f) << 8) | (int)(alpha * 255); } public static int rgb565 (float r, float g, float b) { return ((int)(r * 31) << 11) | ((int)(g * 63) << 5) | (int)(b * 31); } public static int rgba4444 (float r, float g, float b, float a) { return ((int)(r * 15) << 12) | ((int)(g * 15) << 8) | ((int)(b * 15) << 4) | (int)(a * 15); } public static int rgb888 (float r, float g, float b) { return ((int)(r * 255) << 16) | ((int)(g * 255) << 8) | (int)(b * 255); } public static int rgba8888 (float r, float g, float b, float a) { return ((int)(r * 255) << 24) | ((int)(g * 255) << 16) | ((int)(b * 255) << 8) | (int)(a * 255); } public static int argb8888 (float a, float r, float g, float b) { return ((int)(a * 255) << 24) | ((int)(r * 255) << 16) | ((int)(g * 255) << 8) | (int)(b * 255); } public static int rgb565 (Color color) { return ((int)(color.r * 31) << 11) | ((int)(color.g * 63) << 5) | (int)(color.b * 31); } public static int rgba4444 (Color color) { return ((int)(color.r * 15) << 12) | ((int)(color.g * 15) << 8) | ((int)(color.b * 15) << 4) | (int)(color.a * 15); } public static int rgb888 (Color color) { return ((int)(color.r * 255) << 16) | ((int)(color.g * 255) << 8) | (int)(color.b * 255); } public static int rgba8888 (Color color) { return ((int)(color.r * 255) << 24) | ((int)(color.g * 255) << 16) | ((int)(color.b * 255) << 8) | (int)(color.a * 255); } public static int argb8888 (Color color) { return ((int)(color.a * 255) << 24) | ((int)(color.r * 255) << 16) | ((int)(color.g * 255) << 8) | (int)(color.b * 255); } /** Sets the Color components using the specified integer value in the format RGB565. This is inverse to the rgb565(r, g, b) * method. * * @param color The Color to be modified. * @param value An integer color value in RGB565 format. */ public static void rgb565ToColor (Color color, int value) { color.r = ((value & 0x0000F800) >>> 11) / 31f; color.g = ((value & 0x000007E0) >>> 5) / 63f; color.b = ((value & 0x0000001F) >>> 0) / 31f; } /** Sets the Color components using the specified integer value in the format RGBA4444. This is inverse to the rgba4444(r, g, * b, a) method. * * @param color The Color to be modified. * @param value An integer color value in RGBA4444 format. */ public static void rgba4444ToColor (Color color, int value) { color.r = ((value & 0x0000f000) >>> 12) / 15f; color.g = ((value & 0x00000f00) >>> 8) / 15f; color.b = ((value & 0x000000f0) >>> 4) / 15f; color.a = ((value & 0x0000000f)) / 15f; } /** Sets the Color components using the specified integer value in the format RGB888. This is inverse to the rgb888(r, g, b) * method. * * @param color The Color to be modified. * @param value An integer color value in RGB888 format. */ public static void rgb888ToColor (Color color, int value) { color.r = ((value & 0x00ff0000) >>> 16) / 255f; color.g = ((value & 0x0000ff00) >>> 8) / 255f; color.b = ((value & 0x000000ff)) / 255f; } /** Sets the Color components using the specified integer value in the format RGBA8888. This is inverse to the rgba8888(r, g, * b, a) method. * * @param color The Color to be modified. * @param value An integer color value in RGBA8888 format. */ public static void rgba8888ToColor (Color color, int value) { color.r = ((value & 0xff000000) >>> 24) / 255f; color.g = ((value & 0x00ff0000) >>> 16) / 255f; color.b = ((value & 0x0000ff00) >>> 8) / 255f; color.a = ((value & 0x000000ff)) / 255f; } /** Sets the Color components using the specified integer value in the format ARGB8888. This is the inverse to the argb8888(a, * r, g, b) method * * @param color The Color to be modified. * @param value An integer color value in ARGB8888 format. */ public static void argb8888ToColor (Color color, int value) { color.a = ((value & 0xff000000) >>> 24) / 255f; color.r = ((value & 0x00ff0000) >>> 16) / 255f; color.g = ((value & 0x0000ff00) >>> 8) / 255f; color.b = ((value & 0x000000ff)) / 255f; } /** Sets the Color components using the specified float value in the format ABGB8888. * @param color The Color to be modified. */ public static void abgr8888ToColor (Color color, float value) { int c = NumberUtils.floatToIntColor(value); color.a = ((c & 0xff000000) >>> 24) / 255f; color.b = ((c & 0x00ff0000) >>> 16) / 255f; color.g = ((c & 0x0000ff00) >>> 8) / 255f; color.r = ((c & 0x000000ff)) / 255f; } /** @return a copy of this color */ public Color cpy () { return new Color(this); } }