/* * Copyright 2000-2016 Vaadin Ltd. * * 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.vaadin.v7.shared.ui.colorpicker; import java.io.Serializable; /** * Default implementation for color. * * @since 7.0.0 */ @Deprecated public class Color implements Serializable { public static final Color WHITE = new Color(255, 255, 255); public static final Color BLACK = new Color(0, 0, 0); public static final Color RED = new Color(255, 0, 0); public static final Color GREEN = new Color(0, 255, 0); public static final Color BLUE = new Color(0, 0, 255); public static final Color YELLOW = new Color(255, 255, 0); public static final Color MAGENTA = new Color(255, 0, 255); public static final Color CYAN = new Color(0, 255, 255); private int red; private int green; private int blue; private int alpha; private String OUTOFRANGE = "Value must be within the range [0-255]. Was: "; /** * Creates a color that has the specified red, green, blue, and alpha values * within the range [0 - 255]. * * @throws IllegalArgumentException * if <code>red</code>, <code>green</code>, <code>blue</code> or * <code>alpha</code> fall outside of the inclusive range from 0 * to 255 * @param red * the red value * @param green * the green value * @param blue * the blue value * @param alpha * the alpha value */ public Color(int red, int green, int blue, int alpha) { checkRange(red, green, blue, alpha); this.red = red; this.green = green; this.blue = blue; this.alpha = alpha; } /** * Creates a color that has the specified red, green, and blue values within * the range [0 - 255]. Alpha gets the default value of 255. * * @throws IllegalArgumentException * if <code>red</code>, <code>green</code> or <code>blue</code> * fall outside of the inclusive range from 0 to 255 * @param red * the red value * @param green * the green value * @param blue * the blue value */ public Color(int red, int green, int blue) { this(red, green, blue, 255); } /** * Creates a color based on an RGB value. * * @throws IllegalArgumentException * if converted values of <code>red</code>, <code>green</code>, * <code>blue</code> or <code>alpha</code> fall outside of the * inclusive range from 0 to 255 * * @param rgb * the RGB value */ public Color(int rgb) { int value = 0xff000000 | rgb; int red = (value >> 16) & 0xFF; int green = (value >> 8) & 0xFF; int blue = (value >> 0) & 0xFF; int alpha = (value >> 24) & 0xff; checkRange(red, green, blue, alpha); this.red = red; this.green = green; this.blue = blue; this.alpha = alpha; } /** * Checks that all values are within the acceptable range of [0, 255]. * * @throws IllegalArgumentException * if any of the values fall outside of the range * * @param red * @param green * @param blue * @param alpha */ private void checkRange(int red, int green, int blue, int alpha) { if (!withinRange(red) || !withinRange(green) || !withinRange(blue) || !withinRange(alpha)) { String errorMessage = "All values must fall within range [0-255]. (red: " + red + ", green: " + green + ", blue: " + blue + ", alpha: " + alpha + ")"; throw new IllegalArgumentException(errorMessage); } } /** * Checks whether the value is within the acceptable range of [0, 255]. * * @param value * @return true if the value falls within the range, false otherwise */ private boolean withinRange(int value) { if (value < 0 || value > 255) { return false; } return true; } /** * Returns the red value of the color. * */ public int getRed() { return red; } /** * Sets the red value of the color. Value must be within the range [0, 255]. * * @param red * new red value */ public void setRed(int red) { if (withinRange(red)) { this.red = red; } else { throw new IllegalArgumentException(OUTOFRANGE + red); } } /** * Returns the green value of the color. * */ public int getGreen() { return green; } /** * Sets the green value of the color. Value must be within the range [0, * 255]. * * @param green * new green value */ public void setGreen(int green) { if (withinRange(green)) { this.green = green; } else { throw new IllegalArgumentException(OUTOFRANGE + green); } } /** * Returns the blue value of the color. * */ public int getBlue() { return blue; } /** * Sets the blue value of the color. Value must be within the range [0, * 255]. * * @param blue * new blue value */ public void setBlue(int blue) { if (withinRange(blue)) { this.blue = blue; } else { throw new IllegalArgumentException(OUTOFRANGE + blue); } } /** * Returns the alpha value of the color. * */ public int getAlpha() { return alpha; } /** * Sets the alpha value of the color. Value must be within the range [0, * 255]. * * @param alpha * new alpha value */ public void setAlpha(int alpha) { if (withinRange(alpha)) { this.alpha = alpha; } else { throw new IllegalArgumentException(OUTOFRANGE + alpha); } } /** * Returns CSS representation of the Color, e.g. #000000. */ public String getCSS() { String redString = Integer.toHexString(red); redString = redString.length() < 2 ? "0" + redString : redString; String greenString = Integer.toHexString(green); greenString = greenString.length() < 2 ? "0" + greenString : greenString; String blueString = Integer.toHexString(blue); blueString = blueString.length() < 2 ? "0" + blueString : blueString; return "#" + redString + greenString + blueString; } /** * Returns RGB value of the color. */ public int getRGB() { return ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | ((blue & 0xFF) << 0); } /** * Returns converted HSV components of the color. * */ public float[] getHSV() { float[] hsv = new float[3]; int maxColor = (red > green) ? red : green; if (blue > maxColor) { maxColor = blue; } int minColor = (red < green) ? red : green; if (blue < minColor) { minColor = blue; } float value = maxColor / 255.0f; float saturation = 0; if (maxColor != 0) { saturation = ((float) (maxColor - minColor)) / ((float) maxColor); } float hue = 0; if (saturation != 0) { float redF = ((float) (maxColor - red)) / ((float) (maxColor - minColor)); float greenF = ((float) (maxColor - green)) / ((float) (maxColor - minColor)); float blueF = ((float) (maxColor - blue)) / ((float) (maxColor - minColor)); if (red == maxColor) { hue = blueF - greenF; } else if (green == maxColor) { hue = 2.0f + redF - blueF; } else { hue = 4.0f + greenF - redF; } hue = hue / 6.0f; if (hue < 0) { hue = hue + 1.0f; } } hsv[0] = hue; hsv[1] = saturation; hsv[2] = value; return hsv; } @Override public int hashCode() { return getRGB(); } @Override public boolean equals(Object obj) { return obj instanceof Color && ((Color) obj).getRGB() == getRGB(); } /** * <p> * Converts HSV's hue, saturation and value into an RGB value. * <p> * The <code>saturation</code> and <code>value</code> components should be * floating-point values within the range [0.0-1.0]. * <p> * * @param hue * the hue of the color * @param saturation * the saturation of the color * @param value * the value of the color * @return the RGB value of corresponding color */ public static int HSVtoRGB(float hue, float saturation, float value) { int red = 0; int green = 0; int blue = 0; if (saturation == 0) { red = green = blue = (int) (value * 255.0f + 0.5f); } else { float h = (hue - (float) Math.floor(hue)) * 6.0f; float f = h - (float) java.lang.Math.floor(h); float p = value * (1.0f - saturation); float q = value * (1.0f - saturation * f); float t = value * (1.0f - (saturation * (1.0f - f))); switch ((int) h) { case 0: red = (int) (value * 255.0f + 0.5f); green = (int) (t * 255.0f + 0.5f); blue = (int) (p * 255.0f + 0.5f); break; case 1: red = (int) (q * 255.0f + 0.5f); green = (int) (value * 255.0f + 0.5f); blue = (int) (p * 255.0f + 0.5f); break; case 2: red = (int) (p * 255.0f + 0.5f); green = (int) (value * 255.0f + 0.5f); blue = (int) (t * 255.0f + 0.5f); break; case 3: red = (int) (p * 255.0f + 0.5f); green = (int) (q * 255.0f + 0.5f); blue = (int) (value * 255.0f + 0.5f); break; case 4: red = (int) (t * 255.0f + 0.5f); green = (int) (p * 255.0f + 0.5f); blue = (int) (value * 255.0f + 0.5f); break; case 5: red = (int) (value * 255.0f + 0.5f); green = (int) (p * 255.0f + 0.5f); blue = (int) (q * 255.0f + 0.5f); break; } } return 0xff000000 | (red << 16) | (green << 8) | (blue << 0); } /** * <p> * Converts HSL's hue, saturation and lightness into an RGB value. * * @param hue * the hue of the color. The unit of the value is degrees and * should be between 0-360. * @param saturation * the saturation of the color. The unit of the value is * percentages and should be between 0-100; * @param lightness * the lightness of the color. The unit of the value is * percentages and should be between 0-100; * * @return the RGB value of corresponding color */ public static int HSLtoRGB(int hue, int saturation, int lightness) { int red = 0; int green = 0; int blue = 0; float hueRatio = hue / 360f; float saturationRatio = saturation / 100f; float lightnessRatio = lightness / 100f; if (saturationRatio == 0) { red = green = blue = (int) (lightnessRatio * 255.0f + 0.5f); } else { float p = lightnessRatio < 0.5f ? lightnessRatio * (1f + saturationRatio) : lightnessRatio + saturationRatio - lightnessRatio * saturationRatio; float q = 2 * lightnessRatio - p; red = hslComponentToRgbComponent(p, q, hueRatio + (1f / 3f)); green = hslComponentToRgbComponent(p, q, hueRatio); blue = hslComponentToRgbComponent(p, q, hueRatio - (1f / 3f)); } return 0xff000000 | (red << 16) | (green << 8) | (blue << 0); } private static int hslComponentToRgbComponent(float p, float q, float ratio) { if (ratio < 0) { ratio += 1; } else if (ratio > 1) { ratio -= 1; } if (6 * ratio < 1f) { return (int) ((q + (p - q) * 6f * ratio) * 255f + 0.5f); } else if (2f * ratio < 1f) { return (int) (p * 255f + 0.5f); } else if (3f * ratio < 2f) { return (int) ((q + (p - q) * ((2f / 3f) - ratio) * 6f) * 255f + 0.5f); } return (int) (q * 255f + 0.5f); } }