import java.util.Map;
import java.util.Random;
+import jalview.bin.Cache;
+import jalview.bin.Console;
+
public class ColorUtils
{
private static final int MAX_CACHE_SIZE = 1729;
/*
* a cache for colours generated from text strings
*/
- static Map<String, Color> myColours = new HashMap<>();
+ private static Map<String, Color> myColours = new HashMap<>();
+
+ private static Map<String, Color> myHSBSpacedColours = new HashMap<>();
+
+ public static final String ID_COLOUR_SCHEME;
+
+ static
+ {
+ ID_COLOUR_SCHEME = Cache.getDefault("ID_COLOUR_SCHEME", "NONE");
+ }
/**
* Generates a random color, will mix with input color. Code taken from
return col;
}
-}
+
+ public static Color getDefaultColourFromName(String name)
+ {
+ return getColourFromNameAndScheme(name, ID_COLOUR_SCHEME);
+ }
+
+ public static Color getColourFromNameAndScheme(String name,
+ String colourSchemes)
+ {
+ String cacheKey = name + "::" + colourSchemes;
+ if (myHSBSpacedColours.containsKey(cacheKey))
+ {
+ return myHSBSpacedColours.get(cacheKey);
+ }
+ float Hmin = 0.0f;
+ float Hmax = 1.0f;
+ float Smin = 0.7f;
+ float Smax = 1.0f;
+ float Bmin = 0.7f;
+ float Bmax = 1.0f;
+ for (String scheme : colourSchemes.split(","))
+ {
+ switch (scheme)
+ {
+ case "AVOID_RED":
+ Hmin = 0.15f;
+ Hmax = 0.85f;
+ break;
+ case "AVOID_GREEN":
+ Hmin = 0.48f;
+ Hmax = 0.18f;
+ break;
+ case "AVOID_BLUE":
+ Hmin = 0.51f;
+ Hmax = 0.81f;
+ break;
+ case "SATURATED":
+ Smin = 1.0f;
+ Smax = 1.0f;
+ break;
+ case "PALE":
+ Smin = 0.2f;
+ Smax = 0.7f;
+ break;
+ case "GREYSCALE":
+ Smin = 0.0f;
+ Smax = 0.0f;
+ case "BRIGHT":
+ Bmin = 1.0f;
+ Bmax = 0.9f;
+ break;
+ case "DARK":
+ Bmin = 0.2f;
+ Bmax = 0.6f;
+ break;
+ }
+ }
+ Color col = getHSBColourspacedColourFromName(name, Hmin, Hmax, Smin,
+ Smax, Bmin, Bmax);
+ myHSBSpacedColours.put(cacheKey, col);
+ return col;
+ }
+
+ public static Color getHSBColourspacedColourFromName(String name,
+ float Hmin, float Hmax, float Smin, float Smax, float Bmin,
+ float Bmax)
+ {
+ if (name == null)
+ {
+ return Color.white;
+ }
+
+ // use first three bytes from MD5 rather than String.hashCode() as short
+ // strings all low number hashCodes
+ byte[] hash = StringUtils.getMD5Bytes(name);
+ int bl = hash.length > 0 ? hash[0] : 0;
+ int g = hash.length > 1 ? hash[1] : 0;
+ int r = hash.length > 2 ? hash[2] : 0;
+
+ float[] hsbf = Color.RGBtoHSB(r, g, bl, null);
+
+ if (hsbf.length < 3)
+ {
+ // This really shouldn't happen
+ Console.warn("Unexpected short length of HSB float array");
+ }
+ float h0 = hsbf.length > 0 ? hsbf[0] : 0f;
+ float s0 = hsbf.length > 1 ? hsbf[1] : 0f;
+ float b0 = hsbf.length > 2 ? hsbf[2] : 0f;
+
+ // Now map these HSB values into the given ranges
+
+ // hue wraps around 1.0->0.0 so deal with a Hmin-Hmax range that goes across
+ // this
+ float h1 = 0f;
+ if (Hmin > Hmax)
+ {
+ Hmax += 1f;
+ }
+ h1 = Hmin + (Hmax - Hmin) * h0;
+ if (h1 > 1f)
+ {
+ h1 -= 1f;
+ }
+ float s1 = Smin + (Smax - Smin) * s0;
+ float b1 = Bmin + (Bmax - Bmin) * b0;
+
+ return Color.getHSBColor(h1, s1, b1);
+ }
+}
\ No newline at end of file
package jalview.util;
import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
import java.net.URLEncoder;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import jalview.bin.Console;
+
public class StringUtils
{
private static final Pattern DELIMITERS_PATTERN = Pattern
}
return max;
}
+
+ /*
+ * return an MD5 hash of the given String
+ */
+ public static byte[] getMD5Bytes(String name)
+ {
+ final String alg = "MD5";
+ try
+ {
+ MessageDigest md5 = MessageDigest.getInstance(alg);
+ return md5.digest(name.getBytes());
+ } catch (NoSuchAlgorithmException e)
+ {
+ Console.warn("Could not find hashing algorithm '" + alg + "'");
+ return null;
+ }
+ }
+
+ public static String getMD5String(String name)
+ {
+ byte[] hashBytes = getMD5Bytes(name);
+ if (hashBytes == null)
+ {
+ return null;
+ }
+ BigInteger hashNum = new BigInteger(1, hashBytes);
+ String hashString = hashNum.toString(16);
+ StringBuilder sb = new StringBuilder(32);
+ for (int i = 0; i + hashString.length() < 32; i++)
+ {
+ sb.append('0');
+ }
+ sb.append(hashString);
+ return sb.toString();
+ }
}