/* * Copyright 2014-16 Skynav, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY SKYNAV, INC. AND ITS CONTRIBUTORS “AS IS” AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL SKYNAV, INC. OR ITS CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.skynav.ttpe.style; import java.awt.Paint; import java.text.MessageFormat; import java.util.Locale; import java.util.Map; public class Color { public static final Color AQUA = new Color(0,1,1); public static final Color BLACK = new Color(0,0,0); public static final Color BLUE = new Color(0,0,1); public static final Color CYAN = new Color(0,1,1); public static final Color FUCHSIA = new Color(1,0,1); public static final Color GRAY = new Color(0.5,0.5,0.5); public static final Color GREEN = new Color(0,0.5,0); public static final Color LIME = new Color(0,1,0); public static final Color MAGENTA = new Color(1,0,1); public static final Color MAROON = new Color(0.5,0,0); public static final Color NAVY = new Color(0,0,0.5); public static final Color OLIVE = new Color(0.5,0.5,0); public static final Color PURPLE = new Color(0.5,0,0.5); public static final Color RED = new Color(1,0,0); public static final Color SILVER = new Color(0.75,0.75,0.75); public static final Color TEAL = new Color(0,0.5,0.5); public static final Color TRANSPARENT = new Color(0,0,0,0); public static final Color WHITE = new Color(1,1,1); public static final Color YELLOW = new Color(1,1,0); public static final String rgbFormat = "#%02X%02X%02X"; public static final String rgbaFormat = "#%02X%02X%02X%02X"; public static final MessageFormat tupleFormatter = new MessageFormat("[{0,number,0.0},{1,number,0.0},{2,number,0.0},{3,number,0.0}]", Locale.US); private double red; private double green; private double blue; private double alpha; // 0 = transparent, 1 = opaque public Color(double red, double green, double blue) { this(red, green, blue, 1); } public Color(Color color) { this(color.red, color.green, color.blue, color.alpha); } public Color(double red, double green, double blue, double alpha) { assert red >= 0; assert red <= 1; this.red = red; assert green >= 0; assert green <= 1; this.green = green; assert blue >= 0; assert blue <= 1; this.blue = blue; assert alpha >= 0; assert alpha <= 1; this.alpha = alpha; } public double getRed() { return red; } public double getGreen() { return green; } public double getBlue() { return blue; } public double getAlpha() { return alpha; } public double getHue() { double a = (2 * red + green + blue) * 0.5000; double b = (green - blue) * 0.8660; return Math.toDegrees(Math.atan2(a, b)); } public double getLuminance() { return 0.2126 * red + 0.7152 * green + 0.0722 * blue; } public double getSaturation() { return (max() - min())/max(); } public boolean isTransparent() { return alpha == 0; } private double max() { double m1 = Math.max(red, green); double m2 = Math.max(green, blue); return Math.max(m1, m2); } private double min() { double m1 = Math.min(red, green); double m2 = Math.min(green, blue); return Math.min(m1, m2); } public Color contrast() { if (getSaturation() < 0.4) return (getLuminance() > 0.5) ? BLACK : WHITE; else { double h = getHue(); if ((h >= 30) && (h < 90)) return BLUE; else if ((h >= 90) && (h < 150)) return MAGENTA; else if ((h >= 150) && (h < 210)) return RED; else if ((h >= 210) && (h < 270)) return YELLOW; else if ((h >= 270) && (h < 330)) return LIME; else return CYAN; } } public Paint getPaint() { return new java.awt.Color((float) red, (float) green, (float) blue, (float) alpha); } public String toRGBString() { return String.format(rgbFormat, (int) (red * 255), (int) (green * 255), (int) (blue * 255)); } public String toRGBAString(boolean abbreviate) { if (abbreviate && (alpha == 0)) return String.format(rgbFormat, (int) (red * 255), (int) (green * 255), (int) (blue * 255)); else return String.format(rgbaFormat, (int) (red * 255), (int) (green * 255), (int) (blue * 255), (int) (alpha * 255)); } @Override public int hashCode() { int hc = 23; hc = hc * 31 + Double.valueOf(red).hashCode(); hc = hc * 31 + Double.valueOf(green).hashCode(); hc = hc * 31 + Double.valueOf(blue).hashCode(); hc = hc * 31 + Double.valueOf(alpha).hashCode(); return hc; } @Override public boolean equals(Object o) { if (o instanceof Color) { Color other = (Color) o; if (other.red != red) return false; else if (other.green != green) return false; else if (other.blue != blue) return false; else if (other.alpha != alpha) return false; else return true; } else return false; } @Override public String toString() { return tupleFormatter.format(new Object[]{red, green, blue, alpha}); } private static Map<String,Color> namedColors; private static final Object[][] namedColorSpecifications = new Object[][] { { "aqua", AQUA }, { "black", BLACK }, { "blue", BLUE }, { "cyan", CYAN }, { "fuchsia", FUCHSIA }, { "gray", GRAY }, { "green", GREEN }, { "lime", LIME }, { "magenta", MAGENTA }, { "maroon", MAROON }, { "navy", NAVY }, { "olive", OLIVE }, { "purple", PURPLE }, { "red", RED }, { "silver", SILVER }, { "teal", TEAL }, { "transparent", TRANSPARENT }, { "white", WHITE }, { "yellow", YELLOW }, }; static { namedColors = new java.util.HashMap<String,Color>(); for (Object[] spec : namedColorSpecifications) { namedColors.put((String) spec[0], (Color) spec[1]); } } public static Color fromName(String name) { Color c = namedColors.get(name.toLowerCase()); if (c != null) return c; else throw new IllegalArgumentException(); } }