/*********************************************************************************
* TotalCross Software Development Kit *
* Copyright (C) 1998, 1999 Wabasoft <www.wabasoft.com> *
* Copyright (C) 2000-2012 SuperWaba Ltda. *
* All Rights Reserved *
* *
* This library and virtual machine 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. *
* *
* This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 *
* A copy of this license is located in file license.txt at the root of this *
* SDK or can be downloaded here: *
* http://www.gnu.org/licenses/lgpl-3.0.txt *
* *
*********************************************************************************/
package totalcross.ui.gfx;
import totalcross.sys.*;
import totalcross.util.*;
/**
* The Color class is just an utility class used to do operations in a color, which
* is actually represented by an <code>int</code> in the format 0x00RRGGBB.
* <p>
* A color is defined as a mixture of red, green and blue color values.
* Each value is in the range of 0 to 255 where 0 is darkest and 255 is brightest.
* For example, Color(255, 0, 0) is the color red.
* <p>
* Here are some more examples:
* <ul>
* <li>Color(0, 0, 0) is black
* <li>Color(255, 255, 255) is white
* <li>Color(255, 0, 0 ) is red
* <li>Color(0, 255, 0) is green
* <li>Color(0, 0, 255) is blue
* </ul>
*/
public final class Color
{
public static final int WHITE = 0xFFFFFF;
public static final int BRIGHT = 0xBFBFBF;
public static final int DARK = 0x7F7F7F;
public static final int BLACK = 0x000000;
public static final int RED = 0xFF0000;
public static final int PINK = 0xFFAFAF;
public static final int ORANGE = 0xFFC800;
public static final int YELLOW = 0xFFFF00;
public static final int GREEN = 0x00FF00;
public static final int MAGENTA = 0xFF00FF;
public static final int CYAN = 0x00FFFF;
public static final int BLUE = 0x0000FF;
/** Increase or decrease all RGB values by 96. To be used in the darker(step) and brighter(step) methods. */
public static final int FULL_STEP = 96;
/** Increase or decrease all RGB values by 32. To be used in the darker(step) and brighter(step) methods. */
public static final int LESS_STEP = 32;
/** Increase or decrease all RGB values by 48. To be used in the darker(step) and brighter(step) methods. */
public static final int HALF_STEP = 48;
private static int lastDarkerSrc=-1,lastDarkerDst,lastBrighterSrc=-1,lastBrighterDst;
/**
* Returns a color integer value with the given red, green and blue components.
* @param red the red value in the range of 0 to 255
* @param green the green value in the range of 0 to 255
* @param blue the blue value in the range of 0 to 255
* @since SuperWaba 5.8
*/
public static int getRGB(int red, int green, int blue) // guich@580_28
{
return (red << 16) | (green << 8) | blue;
}
/**
* Returns a color integer value with the given red, green and blue components,
* ensuring that the values are within the 0-255 range.
* @param red the red value in any range
* @param green the green value in any range
* @param blue the blue value in any range
* @since SuperWaba 5.8
*/
public static int getRGBEnsureRange(int red, int green, int blue) // guich@580_28
{
if (red < 0) red = 0;
else
if (red > 255) red = 255;
if (green < 0) green = 0;
else
if (green > 255) green = 255;
if (blue < 0) blue = 0;
else
if (blue > 255) blue = 255;
return (red << 16) | (green << 8) | blue;
}
/**
* Returns a color integer value parsing the given rgb. Note that this method is rather slow.
* @param rrggbb a string in the format RRGGBB (colors in hex).
* @since SuperWaba 5.8
*/
public static int getRGB(String rrggbb) // guich@580_28
{
try {return rrggbb == null ? -1 : (int)Convert.toLong(rrggbb,16);} catch (InvalidNumberException ine) {return -1;}
}
/** This class can't be instantiated. */
private Color()
{
}
/** Returns the alpha channel (brightness) of the color value in a value from 0 to 255 */
public static int getAlpha(int rgb)
{
return ((((rgb >> 16) & 0xFF) << 5) + (((rgb >> 8) & 0xFF) << 6) + ((rgb & 0xFF) << 2)) / 100;
}
/** Returns the blue value of the color. */
public static int getBlue(int rgb)
{
return rgb & 0xFF;
}
/** Returns the green value of the color. */
public static int getGreen(int rgb)
{
return (rgb >> 8) & 0xFF;
}
/** Returns the red value of the color. */
public static int getRed(int rgb)
{
return (rgb >> 16) & 0xFF;
}
/** Returns a color that is brighter than the current one. */
public static int brighter(int rgb)
{
if (rgb == lastBrighterSrc)
return lastBrighterDst;
lastBrighterSrc = rgb;
return lastBrighterDst = getRGBEnsureRange(((rgb >> 16) & 0xFF)+FULL_STEP,((rgb >> 8) & 0xFF)+FULL_STEP,(rgb & 0xFF)+FULL_STEP);
}
/** Return a color that is darker than the current one. */
public static int darker(int rgb)
{
if (rgb == lastDarkerSrc)
return lastDarkerDst;
lastDarkerSrc = rgb;
return lastDarkerDst = getRGBEnsureRange(((rgb >> 16) & 0xFF)-FULL_STEP,((rgb >> 8) & 0xFF)-FULL_STEP,(rgb & 0xFF)-FULL_STEP);
}
/** Returns the best cursor color depending on this color */
public static int getCursorColor(int rgb)
{
return getAlpha(rgb) > 128
? getRGBEnsureRange(((rgb >> 16) & 0xFF)-FULL_STEP,((rgb >> 8) & 0xFF)-FULL_STEP,(rgb & 0xFF)-FULL_STEP)
: getRGBEnsureRange(((rgb >> 16) & 0xFF)+FULL_STEP,((rgb >> 8) & 0xFF)+FULL_STEP,(rgb & 0xFF)+FULL_STEP); // guich@220_45 - guich@340_51: in color devices, use normal step
}
/** Returns a color that is brighter than the current one. */
public static int brighter(int rgb, int step)
{
return getRGBEnsureRange(((rgb >> 16) & 0xFF)+step,((rgb >> 8) & 0xFF)+step,(rgb & 0xFF)+step);
}
/** Returns a color that is darker than the current one. */
public static int darker(int rgb, int step)
{
return getRGBEnsureRange(((rgb >> 16) & 0xFF)-step,((rgb >> 8) & 0xFF)-step,(rgb & 0xFF)-step);
}
/** Returns the string representation of this color: the rgb in hexadecimal */
public static String toString(int rgb)
{
return Convert.unsigned2hex(rgb,6); // never change this!
}
/** Interpolates the given colors.
* @since TotalCross 1.0 beta 4
*/
public static int interpolate(int color1, int color2)
{
int r1 = (color1 >> 16) & 0xFF;
int g1 = (color1 >> 8) & 0xFF;
int b1 = (color1 ) & 0xFF;
int r2 = (color2 >> 16) & 0xFF;
int g2 = (color2 >> 8) & 0xFF;
int b2 = (color2 ) & 0xFF;
int r = (r1+r2)/2;
int g = (g1+g2)/2;
int b = (b1+b2)/2;
return (r << 16) | (g << 8) | b;
}
/** Interpolates the given colors by the given factor, ranging from 0 to 100.
* @since TotalCross 1.23
*/
public static int interpolate(int color1, int color2, int factor)
{
int m = 100-factor;
int r1 = (color1 >> 16) & 0xFF;
int g1 = (color1 >> 8) & 0xFF;
int b1 = (color1 ) & 0xFF;
int r2 = (color2 >> 16) & 0xFF;
int g2 = (color2 >> 8) & 0xFF;
int b2 = (color2 ) & 0xFF;
int r = (r1*factor+r2*m)/100;
int g = (g1*factor+g2*m)/100;
int b = (b1*factor+b2*m)/100;
return (r << 16) | (g << 8) | b;
}
/** Interpolates the given colors by the given factor, ranging from 0 to 255.
* @since TotalCross 1.23
*/
public static int interpolateA(int color1, int color2, int factor)
{
int m = 255-factor;
int r1 = (color1 >> 16) & 0xFF;
int g1 = (color1 >> 8) & 0xFF;
int b1 = (color1 ) & 0xFF;
int r2 = (color2 >> 16) & 0xFF;
int g2 = (color2 >> 8) & 0xFF;
int b2 = (color2 ) & 0xFF;
int r = (r1*factor+r2*m)/255;
int g = (g1*factor+g2*m)/255;
int b = (b1*factor+b2*m)/255;
return (r << 16) | (g << 8) | b;
}
/** Returns a color that better contrasts with the given original color.
* @since TotalCross 1.23
*/
public static int getBetterContrast(int original, int color1, int color2)
{
int a0 = getAlpha(original);
int a1 = getAlpha(color1);
int a2 = getAlpha(color2);
return Math.abs(a1-a0) > Math.abs(a2-a0) ? color1 : color2;
}
/** Returns a random color.
* Example:
* <pre>
Random r = new Random();
for (int i = 0; i < tt.length; i++)
tabPanel.getContainer(i).setBackColor(Color.getRandomColor(r));
* </pre>
* @since TotalCross 3.0
*/
public static int getRandomColor(Random r)
{
return getRGBEnsureRange(r.nextInt(256),r.nextInt(256),r.nextInt(256));
}
}