/******************************************************************************* * Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://robocode.sourceforge.net/license/epl-v10.html * * Contributors: * Flemming N. Larsen * - Initial implementation *******************************************************************************/ package net.sf.robocode.ui.gfx; import static robocode.util.Utils.isNear; import java.awt.*; /** * Class used for utilizing colors. * * @author Flemming N. Larsen (original) */ class ColorUtil { /** * Return a Color based on a color in RGB565 format. * * @param rgb565 the color in RGB565 format. * @return a Color based on the specifed color in RGB565 format. */ public static Color toColor(short rgb565) { if (rgb565 == 0) { return null; } if (rgb565 == 0x20) { return Color.BLACK; } return new Color(255 * ((rgb565 & 0xF800) >> 11) / 31, 255 * ((rgb565 & 0x07e0) >> 5) / 63, 255 * (rgb565 & 0x001f) / 31); } /** * Returns a color in the RGB565 format based on a Color instance. * * @param c the color to convert into a RGB565 color. * @return a color in the RGB565 format based on the specified Color. */ public static short toRGB565(Color c) { if (c == null) { return 0; } short rgb = (short) (((c.getRed() & 0xf8) << 8) | ((c.getGreen() & 0xfc) << 3) | (c.getBlue() >> 3)); // 0 is reserved for null -> set green (has highest resolution) to 1 if (rgb == 0) { return 0x20; } // If the color actually was 0x20 then set it to 0x40 (to the nearest green) if (rgb == 0x20) { return 0x40; } return rgb; } /** * Converts a RGB color into a HSL color. * * @param r the red color component. * @param g the green color component. * @param b the blue color component. * @return a {@code float[] { H, S, L }} representing the HSL color. */ public static float[] fromRGBtoHSL(int r, int g, int b) { float R = (float) r / 255; float G = (float) g / 255; float B = (float) b / 255; float min = Math.min(Math.min(R, G), B); // Min. value of RGB float max = Math.max(Math.max(R, G), B); // Max. value of RGB float delta = max - min; // Delta RGB value float L = (max + min) / 2; float H, S; if (delta == 0) { // This is a gray, no chroma... H = 0; S = 0; } else { // Chromatic data... if (L < 0.5f) { S = delta / (max + min); } else { S = delta / (2 - max - min); } float deltaR = (((max - R) / 6) + (delta / 2)) / delta; float deltaG = (((max - G) / 6) + (delta / 2)) / delta; float deltaB = (((max - B) / 6) + (delta / 2)) / delta; if (isNear(R, max)) { H = deltaB - deltaG; } else if (isNear(G, max)) { H = (1f / 3) + deltaR - deltaB; } else { H = (2f / 3) + deltaG - deltaR; } if (H < 0) { H++; } if (H > 1) { H--; } } return new float[] { H, S, L}; } /** * Converts a HSL color into a RGB color integer value. * * @param h the color hue. * @param s the color saturation. * @param l the color lumination. * @return an RGB integer value. */ public static int fromHSLtoRGB(float h, float s, float l) { float m2 = (l <= 0.5f) ? (l * (s + 1)) : (l + s - l * s); float m1 = 2 * l - m2; int r = (int) (255 * fromHUEtoRGB(m1, m2, h + (1f / 3))); int g = (int) (255 * fromHUEtoRGB(m1, m2, h)); int b = (int) (255 * fromHUEtoRGB(m1, m2, h - (1f / 3))); return (((r << 8) | g) << 8) | b; } private static float fromHUEtoRGB(float m1, float m2, float h) { if (h < 0) { h++; } if (h > 1) { h--; } if ((h * 6) < 1) { return m1 + (m2 - m1) * h * 6; } if ((h * 2) < 1) { return m2; } if ((h * 3) < 2) { return m1 + (m2 - m1) * ((2f / 3) - h) * 6; } return m1; } }