/*
* Copyright 2013 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.backend.canvas;
import org.oscim.utils.FastMath;
public final class Color {
private static final int OPAQUE = 0xff000000;
public static int fadePremul(int color, double alpha) {
alpha = FastMath.clamp(alpha, 0, 1);
alpha *= (color >>> 24) & 0xff;
int c = (((int) alpha) & 0xff) << 24;
alpha /= 255;
c |= ((int) (alpha * ((color >>> 16) & 0xff))) << 16;
c |= ((int) (alpha * ((color >>> 8) & 0xff))) << 8;
c |= ((int) (alpha * (color & 0xff)));
return c;
}
public static int fade(int color, double alpha) {
alpha = FastMath.clamp(alpha, 0, 1);
alpha *= (color >>> 24) & 0xff;
int c = (((int) alpha) & 0xff) << 24;
return c | (color & 0x00ffffff);
}
public static int rainbow(float pos) {
float i = 255 * pos;
int r = (int) Math.round(Math.sin(0.024 * i + 0) * 127 + 128);
int g = (int) Math.round(Math.sin(0.024 * i + 2) * 127 + 128);
int b = (int) Math.round(Math.sin(0.024 * i + 4) * 127 + 128);
return 0xff000000 | (r << 16) | (g << 8) | b;
}
/**
* Pack r, g, b bytes into one int.
*/
public static int get(int r, int g, int b) {
return 0xff << 24 | r << 16 | g << 8 | b;
}
public static int get(double r, double g, double b) {
return 0xff << 24
| (int) Math.round(r * 255) << 16
| (int) Math.round(g * 255) << 8
| (int) Math.round(b * 255);
}
/**
* Pack premultiplied a, r, g, b bytes into one int.
*/
public static int get(int a, int r, int g, int b) {
return a << 24 | r << 16 | g << 8 | b;
}
/**
* Pack r, g, b bytes into one int with premultiplied alpha a.
*/
public static int get(float a, int r, int g, int b) {
return fade(0xff << 24 | r << 16 | g << 8 | b, a);
}
public static float rToFloat(int color) {
return ((color >>> 16) & 0xff) / 255f;
}
public static float gToFloat(int color) {
return ((color >>> 8) & 0xff) / 255f;
}
public static float bToFloat(int color) {
return ((color) & 0xff) / 255f;
}
public static float aToFloat(int color) {
return ((color >>> 24) & 0xff) / 255f;
}
public static int a(int color) {
return ((color >>> 24) & 0xff);
}
public static int r(int color) {
return ((color >>> 16) & 0xff);
}
public static int g(int color) {
return ((color >>> 8) & 0xff);
}
public static int b(int color) {
return ((color) & 0xff);
}
public static int parseColorComponents(String str) {
int numComponents = 4;
int cur = 5;
if (str.startsWith("rgb(")) {
numComponents = 3;
cur = 4;
} else if (!str.startsWith("rgba("))
parseColorException(str);
int end = str.length();
int component = 0;
int a = 0, r = 0, g = 0, b = 0;
if (str.charAt(end - 1) != ')')
parseColorException(str);
for (; cur < end; cur++) {
char c = str.charAt(cur);
if (c == ',') {
component++;
if (component >= numComponents)
parseColorException(str);
continue;
} else if (c >= '0' && c <= '9') {
if (component == 0) {
r *= 10;
r += c - '0';
} else if (component == 1) {
g *= 10;
g += c - '0';
} else if (component == 2) {
b *= 10;
b += c - '0';
} else {
a *= 10;
a += c - '0';
}
} else
parseColorException(str);
}
if (r > 255 || g > 255 || b > 255 || a > 255)
parseColorException(str);
if (numComponents == 3)
return get(r, g, b);
else
return get(a, r, g, b);
}
private static void parseColorException(String str) {
throw new IllegalArgumentException("Unknown color: \'" + str + '\'');
}
/* Copyright (C) 2006 The Android Open Source Project
*
* 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. */
public static final int BLACK = 0xFF000000;
public static final int DKGRAY = 0xFF444444;
public static final int GRAY = 0xFF888888;
public static final int LTGRAY = 0xFFCCCCCC;
public static final int WHITE = 0xFFFFFFFF;
public static final int RED = 0xFFFF0000;
public static final int GREEN = 0xFF00FF00;
public static final int BLUE = 0xFF0000FF;
public static final int YELLOW = 0xFFFFFF00;
public static final int CYAN = 0xFF00FFFF;
public static final int MAGENTA = 0xFFFF00FF;
public static final int TRANSPARENT = 0;
/**
* Parse the color string, and return the corresponding color-int.
* If the string cannot be parsed, throws an IllegalArgumentException
* exception. Supported formats are:
* #RRGGBB
* #AARRGGBB
* 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta',
* 'yellow', 'lightgray', 'darkgray'
*
* @param colorString the color string
* @return the int
*/
public static int parseColor(String colorString) {
if (colorString.charAt(0) == '#') {
// Use a long to avoid rollovers on #ffXXXXXX
long color = Long.parseLong(colorString.substring(1), 16);
if (colorString.length() == 7) {
// Set the alpha value
color |= 0x00000000ff000000;
} else if (colorString.length() != 9) {
parseColorException(colorString);
}
return (int) color;
}
if (colorString.charAt(0) == 'r') {
return parseColorComponents(colorString);
}
throw new IllegalArgumentException("Unknown color");
}
public static int parseColor(String colorString, int fallBackColor) {
if (colorString.charAt(0) == '#') {
// Use a long to avoid rollovers on #ffXXXXXX
long color = Long.parseLong(colorString.substring(1), 16);
if (colorString.length() == 7) {
// Set the alpha value
color |= 0x00000000ff000000;
} else if (colorString.length() != 9) {
return fallBackColor;
}
return (int) color;
}
return fallBackColor;
}
public static boolean isOpaque(int color) {
return (color & OPAQUE) == OPAQUE;
}
private Color() {
}
}