package speiger.src.coreengine.math.misc; import java.awt.Color; import java.nio.ByteBuffer; import java.nio.FloatBuffer; import speiger.src.collections.floats.lists.FloatList; public class ColorObject { static final float DEVIDER = 1F / 255F; public static final int R = 0xFF << 16; public static final int G = 0xFF << 8; public static final int B = 0xFF; public static final int A = 0xFF << 24; public static final long SIGN = 0x00000000FFFFFFFFL; static final int ALL = 0xFFFFFFFF; public static final ColorObject WHITE = new ColorObject(255, 255, 255); public static final ColorObject LIGHT_GRAY = new ColorObject(192, 192, 192); public static final ColorObject GRAY = new ColorObject(128, 128, 128); public static final ColorObject DARK_GRAY = new ColorObject(64, 64, 64); public static final ColorObject BLACK = new ColorObject(0, 0, 0); public static final ColorObject RED = new ColorObject(255, 0, 0); public static final ColorObject PINK = new ColorObject(255, 175, 175); public static final ColorObject PURPLE = new ColorObject(106, 13, 173); public static final ColorObject ORANGE = new ColorObject(255, 200, 0); public static final ColorObject YELLOW = new ColorObject(255, 255, 0); public static final ColorObject GREEN = new ColorObject(0, 255, 0); public static final ColorObject DARK_GREEN = new ColorObject(7, 161, 0); public static final ColorObject MAGENTA = new ColorObject(255, 0, 255); public static final ColorObject CYAN = new ColorObject(0, 255, 255); public static final ColorObject BLUE = new ColorObject(0, 0, 255); public static final ColorObject LIGHT_BLUE = new ColorObject(0, 150, 255); //Specialized Components that get reused public static final ColorObject INVISIBLE = new ColorObject(0, 0, 0, 0); public static final ColorObject TEXT_DEFAULT_BACKGROUND = new ColorObject(80, 80, 80, 144); public static final ColorObject WINDOW_DEFAULT_BACKGROUND = new ColorObject(64, 64, 64, 128); public static final ColorObject POPUP_DEFAULT_BACKGROUND = new ColorObject(85, 85, 85); public static final ColorObject DESTRUCTION = new ColorObject(255, 0, 0, 128); int rgba; public ColorObject(int rgba) { this.rgba = rgba; } public ColorObject(int r, int g, int b) { rgba = A | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF); } public ColorObject(int r, int g, int b, int a) { rgba = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF); } public static ColorObject rgb(int rgb) { return new ColorObject(rgb | (255 << 24)); } public ColorObject copy() { return new ColorObject(rgba); } public ColorObject setRGB(int rgba) { this.rgba = rgba; return this; } public ColorObject setRed(int r) { rgba = rgba & ~R | ((r & 0xFF) << 16); return this; } public ColorObject setGreen(int g) { rgba = rgba & ~G | ((g & 0xFF) << 8); return this; } public ColorObject setBlue(int b) { rgba = rgba & ~B | (b & 0xFF); return this; } public ColorObject setAlpha(int a) { rgba = rgba & ~A | ((a & 0xFF) << 24); return this; } public ColorObject setRed(float r) { return setRed((int)(r * 255F + 0.5F)); } public ColorObject setGreen(float g) { return setGreen((int)(g * 255F + 0.5F)); } public ColorObject setBlue(float b) { return setBlue((int)(b * 255F + 0.5F)); } public ColorObject setAlpha(float a) { return setAlpha((int)(a * 255F + 0.5F)); } public ColorObject setRGB(float hue, float brightness, float saturation, int alpha) { return setRGB(Color.HSBtoRGB(hue, saturation, brightness) | alpha << 24); } public int getRGB() { return rgba; } public int getRed() { return (rgba >> 16) & 0xFF; } public int getGreen() { return (rgba >> 8) & 0xFF; } public int getBlue() { return rgba & 0xFF; } public int getAlpha() { return (rgba >> 24) & 0xFF; } public float getRedFloat() { return ((rgba >> 16) & 0xFF) * DEVIDER; } public float getGreenFloat() { return ((rgba >> 8) & 0xFF) * DEVIDER; } public float getBlueFloat() { return (rgba & 0xFF) * DEVIDER; } public float getAlphaFloat() { return ((rgba >> 24) & 0xFF) * DEVIDER; } public String getHexCode(boolean alpha) { return "0x"+(alpha ? Long.toHexString(1 << 32 | rgba & SIGN) : Integer.toHexString((1 << 24) | (rgba & ~A))).substring(1); } public String getHTMLCode(boolean alpha) { return "#"+(alpha ? Long.toHexString(1 << 32 | rgba & SIGN) : Integer.toHexString((1 << 24) | (rgba & ~A))).substring(1); } public boolean needsDarkColor() { return getBrightness() >= 130; } public int getBrightness() { return getBrightness(rgba); } public Color toColor() { return new Color(rgba); } public float[] toHue() { return Color.RGBtoHSB(getRed(), getGreen(), getBlue(), new float[3]); } public ColorObject brighter() { return brighter(0.7F); } public ColorObject brighter(float factor) { rgba = brighter(rgba, factor); return this; } public ColorObject darker() { return darker(0.7F); } public ColorObject darker(float factor) { rgba = darker(rgba, factor); return this; } public ColorObject mix(ColorObject to, float factor) { rgba = mix(rgba, to.rgba, factor); return this; } public ColorObject mix(ColorObject from, ColorObject to, float factor) { rgba = mix(from.rgba, to.rgba, factor); return this; } public ColorObject write(FloatBuffer buffer, boolean alpha) { buffer.put(getRedFloat()).put(getGreenFloat()).put(getBlueFloat()); if(alpha) { buffer.put(getAlphaFloat()); } return this; } public ColorObject read(FloatBuffer buffer, boolean alpha) { setRed(buffer.get()).setGreen(buffer.get()).setBlue(buffer.get()); if(alpha) { setAlpha(buffer.get()); } return this; } public ColorObject write(ByteBuffer buffer, boolean alpha) { pack(rgba, alpha, buffer); return this; } public ColorObject read(ByteBuffer buffer, boolean alpha) { setRed(buffer.get()).setGreen(buffer.get()).setBlue(buffer.get()); if(alpha) { setAlpha(buffer.get()); } return this; } public ColorObject write(FloatList buffer, boolean alpha) { buffer.add(getRedFloat()); buffer.add(getGreenFloat()); buffer.add(getBlueFloat()); if(alpha) { buffer.add(getAlphaFloat()); } return this; } public ColorObject writeFloat(ByteBuffer buffer, boolean alpha) { buffer.putFloat(getRedFloat()).putFloat(getGreenFloat()).putFloat(getBlueFloat()); if(alpha) { buffer.putFloat(getAlphaFloat()); } return this; } @Override public int hashCode() { return rgba; } @Override public boolean equals(Object obj) { if(obj instanceof ColorObject) { return ((ColorObject)obj).rgba == rgba; } return false; } @Override public String toString() { return "Color[r=" + getRed() + ", g=" + getGreen() + ", b=" + getBlue() + ", a=" + getAlpha() + "]"; } public String getFloatColor() { return "Color[r=" + getRedFloat() + ", g=" + getGreenFloat() + ", b=" + getBlueFloat() + ", a=" + getAlphaFloat() + "]"; } public static void pack(int color, boolean alpha, ByteBuffer buffer) { buffer.put((byte)((color >> 16) & 0xFF)).put((byte)((color >> 8) & 0xFF)).put((byte)(color & 0xFF)); if(alpha) { buffer.put((byte)((color >> 24) & 0xFF)); } } public static void packFloat(int color, boolean alpha, FloatBuffer buffer) { buffer.put(((color >> 16) & 0xFF) * DEVIDER).put(((color >> 8) & 0xFF) * DEVIDER).put((color & 0xFF) * DEVIDER); if(alpha) { buffer.put(((color >> 24) & 0xFF) * DEVIDER); } } public static int getBrightness(int rgba) { return getBrightness((rgba >> 16) & 0xFF, (rgba >> 8) & 0xFF, rgba & 0xFF); } public static int getBrightness(int r, int g, int b) { return (int)Math.sqrt((r * r * 0.241F) + (g * g * 0.691F) + (b * b * 0.068F)); } public static int mix(int from, int to, float factor) { float weight0 = (1F - factor); float weight1 = factor; int r = (int)((((from >> 16) & 0xFF) * weight0) + (((to >> 16) & 0xFF) * weight1)); int g = (int)((((from >> 8) & 0xFF) * weight0) + (((to >> 8) & 0xFF) * weight1)); int b = (int)(((from & 0xFF) * weight0) + ((to & 0xFF) * weight1)); int a = (int)((((from >> 24) & 0xFF) * weight0) + (((to >> 24) & 0xFF) * weight1)); return ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | b & 0xFF; } public static int darker(int color, float factor) { int r = Math.max(0, (int)(((color >> 16) & 0xFF) * factor)); int g = Math.max(0, (int)(((color >> 8) & 0xFF) * factor)); int b = Math.max(0, (int)((color & 0xFF) * factor)); return (color & A) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF); } public static int brighter(int color, float factor) { int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = color & 0xFF; int i = (int)(1.0 / (1.0 - factor)); if(r == 0 && g == 0 && b == 0) { return (color & A) | ((i & 0xFF) << 16) | ((i & 0xFF) << 8) | (i & 0xFF); } if(r > 0 && r < i) r = i; if(g > 0 && g < i) g = i; if(b > 0 && b < i) b = i; return (color & A) | Math.min(255, (int)(r / factor)) << 16 | Math.min(255, (int)(g / factor)) << 8 | Math.min(255, (int)(b / factor)); } }