Merge branch 'master' of https://source.jalview.org/git/jalviewjs.git
[jalviewjs.git] / src / javajs / util / CU.java
index 0825f80..f28657a 100644 (file)
-package javajs.util;\r
-\r
-import java.util.Hashtable;\r
-import java.util.Map;\r
-\r
-import javajs.api.GenericColor;\r
-\r
-/**\r
- * ColorUtility \r
- * \r
- */\r
-\r
-public class CU {\r
-\r
-  public static String toRGBHexString(GenericColor c) {\r
-    int rgb = c.getRGB();    \r
-    if (rgb == 0)\r
-      return "000000";\r
-    String r  = "00" + Integer.toHexString((rgb >> 16) & 0xFF);\r
-    r = r.substring(r.length() - 2);\r
-    String g  = "00" + Integer.toHexString((rgb >> 8) & 0xFF);\r
-    g = g.substring(g.length() - 2);\r
-    String b  = "00" + Integer.toHexString(rgb & 0xFF);\r
-    b = b.substring(b.length() - 2);\r
-    return r + g + b;\r
-  }\r
-\r
-  public static String toCSSString(GenericColor c) {\r
-    int opacity = c.getOpacity255();\r
-    if (opacity == 255)\r
-      return "#" + toRGBHexString(c);\r
-    int rgb = c.getRGB();\r
-    return "rgba(" + ((rgb>>16)&0xFF) + "," + ((rgb>>8)&0xff) + "," + (rgb&0xff) + "," + opacity/255f  + ")"; \r
-  }\r
-  \r
-  private final static String[] colorNames = {\r
-    "black",                // 000000\r
-    "pewhite",              // ffffff\r
-    "pecyan",               // 00ffff\r
-    "pepurple",             // d020ff\r
-    "pegreen",              // 00ff00\r
-    "peblue",               // 6060ff\r
-    "peviolet",             // ff80c0\r
-    "pebrown",              // a42028\r
-    "pepink",               // ffd8d8\r
-    "peyellow",             // ffff00\r
-    "pedarkgreen",          // 00c000\r
-    "peorange",             // ffb000\r
-    "pelightblue",          // b0b0ff\r
-    "pedarkcyan",           // 00a0a0\r
-    "pedarkgray",           // 606060\r
-  \r
-    "aliceblue",            // F0F8FF\r
-    "antiquewhite",         // FAEBD7\r
-    "aqua",                 // 00FFFF\r
-    "aquamarine",           // 7FFFD4\r
-    "azure",                // F0FFFF\r
-    "beige",                // F5F5DC\r
-    "bisque",               // FFE4C4\r
-    "blanchedalmond",       // FFEBCD\r
-    "blue",                 // 0000FF\r
-    "blueviolet",           // 8A2BE2\r
-    "brown",                // A52A2A\r
-    "burlywood",            // DEB887\r
-    "cadetblue",            // 5F9EA0\r
-    "chartreuse",           // 7FFF00\r
-    "chocolate",            // D2691E\r
-    "coral",                // FF7F50\r
-    "cornflowerblue",       // 6495ED\r
-    "cornsilk",             // FFF8DC\r
-    "crimson",              // DC143C\r
-    "cyan",                 // 00FFFF\r
-    "darkblue",             // 00008B\r
-    "darkcyan",             // 008B8B\r
-    "darkgoldenrod",        // B8860B\r
-    "darkgray",             // A9A9A9\r
-    "darkgreen",            // 006400\r
-    "darkkhaki",            // BDB76B\r
-    "darkmagenta",          // 8B008B\r
-    "darkolivegreen",       // 556B2F\r
-    "darkorange",           // FF8C00\r
-    "darkorchid",           // 9932CC\r
-    "darkred",              // 8B0000\r
-    "darksalmon",           // E9967A\r
-    "darkseagreen",         // 8FBC8F\r
-    "darkslateblue",        // 483D8B\r
-    "darkslategray",        // 2F4F4F\r
-    "darkturquoise",        // 00CED1\r
-    "darkviolet",           // 9400D3\r
-    "deeppink",             // FF1493\r
-    "deepskyblue",          // 00BFFF\r
-    "dimgray",              // 696969\r
-    "dodgerblue",           // 1E90FF\r
-    "firebrick",            // B22222\r
-    "floralwhite",          // FFFAF0 16775920\r
-    "forestgreen",          // 228B22\r
-    "fuchsia",              // FF00FF\r
-    "gainsboro",            // DCDCDC\r
-    "ghostwhite",           // F8F8FF\r
-    "gold",                 // FFD700\r
-    "goldenrod",            // DAA520\r
-    "gray",                 // 808080\r
-    "green",                // 008000\r
-    "greenyellow",          // ADFF2F\r
-    "honeydew",             // F0FFF0\r
-    "hotpink",              // FF69B4\r
-    "indianred",            // CD5C5C\r
-    "indigo",               // 4B0082\r
-    "ivory",                // FFFFF0\r
-    "khaki",                // F0E68C\r
-    "lavender",             // E6E6FA\r
-    "lavenderblush",        // FFF0F5\r
-    "lawngreen",            // 7CFC00\r
-    "lemonchiffon",         // FFFACD\r
-    "lightblue",            // ADD8E6\r
-    "lightcoral",           // F08080\r
-    "lightcyan",            // E0FFFF\r
-    "lightgoldenrodyellow", // FAFAD2\r
-    "lightgreen",           // 90EE90\r
-    "lightgrey",            // D3D3D3\r
-    "lightpink",            // FFB6C1\r
-    "lightsalmon",          // FFA07A\r
-    "lightseagreen",        // 20B2AA\r
-    "lightskyblue",         // 87CEFA\r
-    "lightslategray",       // 778899\r
-    "lightsteelblue",       // B0C4DE\r
-    "lightyellow",          // FFFFE0\r
-    "lime",                 // 00FF00\r
-    "limegreen",            // 32CD32\r
-    "linen",                // FAF0E6\r
-    "magenta",              // FF00FF\r
-    "maroon",               // 800000\r
-    "mediumaquamarine",     // 66CDAA\r
-    "mediumblue",           // 0000CD\r
-    "mediumorchid",         // BA55D3\r
-    "mediumpurple",         // 9370DB\r
-    "mediumseagreen",       // 3CB371\r
-    "mediumslateblue",      // 7B68EE\r
-    "mediumspringgreen",    // 00FA9A\r
-    "mediumturquoise",      // 48D1CC\r
-    "mediumvioletred",      // C71585\r
-    "midnightblue",         // 191970\r
-    "mintcream",            // F5FFFA\r
-    "mistyrose",            // FFE4E1\r
-    "moccasin",             // FFE4B5\r
-    "navajowhite",          // FFDEAD\r
-    "navy",                 // 000080\r
-    "oldlace",              // FDF5E6\r
-    "olive",                // 808000\r
-    "olivedrab",            // 6B8E23\r
-    "orange",               // FFA500\r
-    "orangered",            // FF4500\r
-    "orchid",               // DA70D6\r
-    "palegoldenrod",        // EEE8AA\r
-    "palegreen",            // 98FB98\r
-    "paleturquoise",        // AFEEEE\r
-    "palevioletred",        // DB7093\r
-    "papayawhip",           // FFEFD5\r
-    "peachpuff",            // FFDAB9\r
-    "peru",                 // CD853F\r
-    "pink",                 // FFC0CB\r
-    "plum",                 // DDA0DD\r
-    "powderblue",           // B0E0E6\r
-    "purple",               // 800080\r
-    "red",                  // FF0000\r
-    "rosybrown",            // BC8F8F\r
-    "royalblue",            // 4169E1\r
-    "saddlebrown",          // 8B4513\r
-    "salmon",               // FA8072\r
-    "sandybrown",           // F4A460\r
-    "seagreen",             // 2E8B57\r
-    "seashell",             // FFF5EE\r
-    "sienna",               // A0522D\r
-    "silver",               // C0C0C0\r
-    "skyblue",              // 87CEEB\r
-    "slateblue",            // 6A5ACD\r
-    "slategray",            // 708090\r
-    "snow",                 // FFFAFA 16775930\r
-    "springgreen",          // 00FF7F\r
-    "steelblue",            // 4682B4\r
-    "tan",                  // D2B48C\r
-    "teal",                 // 008080\r
-    "thistle",              // D8BFD8\r
-    "tomato",               // FF6347\r
-    "turquoise",            // 40E0D0\r
-    "violet",               // EE82EE\r
-    "wheat",                // F5DEB3\r
-    "white",                // FFFFFF 16777215\r
-    "whitesmoke",           // F5F5F5\r
-    "yellow",               // FFFF00\r
-    "yellowgreen",          // 9ACD32\r
-    // plus a few rasmol names/values\r
-    "bluetint",             // AFD7FF\r
-    "greenblue",            // 2E8B57\r
-    "greentint",            // 98FFB3\r
-    "grey",                 // 808080\r
-    "pinktint",             // FFABBB\r
-    "redorange",            // FF4500\r
-    "yellowtint",           // F6F675\r
-  };\r
-  \r
-  private final static int[] colorArgbs = {\r
-  //#FFFFC3 hover\r
-    0xFF000000, // black\r
-    // plus the PE chain colors\r
-    0xFFffffff, // pewhite\r
-    0xFF00ffff, // pecyan\r
-    0xFFd020ff, // pepurple\r
-    0xFF00ff00, // pegreen\r
-    0xFF6060ff, // peblue\r
-    0xFFff80c0, // peviolet\r
-    0xFFa42028, // pebrown\r
-    0xFFffd8d8, // pepink\r
-    0xFFffff00, // peyellow\r
-    0xFF00c000, // pedarkgreen\r
-    0xFFffb000, // peorange\r
-    0xFFb0b0ff, // pelightblue\r
-    0xFF00a0a0, // pedarkcyan\r
-    0xFF606060, // pedarkgray\r
-    // standard JavaScript\r
-    0xFFF0F8FF, // aliceblue\r
-    0xFFFAEBD7, // antiquewhite\r
-    0xFF00FFFF, // aqua\r
-    0xFF7FFFD4, // aquamarine\r
-    0xFFF0FFFF, // azure\r
-    0xFFF5F5DC, // beige\r
-    0xFFFFE4C4, // bisque\r
-    0xFFFFEBCD, // blanchedalmond\r
-    0xFF0000FF, // blue\r
-    0xFF8A2BE2, // blueviolet\r
-    0xFFA52A2A, // brown\r
-    0xFFDEB887, // burlywood\r
-    0xFF5F9EA0, // cadetblue\r
-    0xFF7FFF00, // chartreuse\r
-    0xFFD2691E, // chocolate\r
-    0xFFFF7F50, // coral\r
-    0xFF6495ED, // cornflowerblue\r
-    0xFFFFF8DC, // cornsilk\r
-    0xFFDC143C, // crimson\r
-    0xFF00FFFF, // cyan\r
-    0xFF00008B, // darkblue\r
-    0xFF008B8B, // darkcyan\r
-    0xFFB8860B, // darkgoldenrod\r
-    0xFFA9A9A9, // darkgray\r
-    0xFF006400, // darkgreen\r
-  \r
-    0xFFBDB76B, // darkkhaki\r
-    0xFF8B008B, // darkmagenta\r
-    0xFF556B2F, // darkolivegreen\r
-    0xFFFF8C00, // darkorange\r
-    0xFF9932CC, // darkorchid\r
-    0xFF8B0000, // darkred\r
-    0xFFE9967A, // darksalmon\r
-    0xFF8FBC8F, // darkseagreen\r
-    0xFF483D8B, // darkslateblue\r
-    0xFF2F4F4F, // darkslategray\r
-    0xFF00CED1, // darkturquoise\r
-    0xFF9400D3, // darkviolet\r
-    0xFFFF1493, // deeppink\r
-    0xFF00BFFF, // deepskyblue\r
-    0xFF696969, // dimgray\r
-    0xFF1E90FF, // dodgerblue\r
-    0xFFB22222, // firebrick\r
-    0xFFFFFAF0, // floralwhite\r
-    0xFF228B22, // forestgreen\r
-    0xFFFF00FF, // fuchsia\r
-    0xFFDCDCDC, // gainsboro\r
-    0xFFF8F8FF, // ghostwhite\r
-    0xFFFFD700, // gold\r
-    0xFFDAA520, // goldenrod\r
-    0xFF808080, // gray\r
-    0xFF008000, // green\r
-    0xFFADFF2F, // greenyellow\r
-    0xFFF0FFF0, // honeydew\r
-    0xFFFF69B4, // hotpink\r
-    0xFFCD5C5C, // indianred\r
-    0xFF4B0082, // indigo\r
-    0xFFFFFFF0, // ivory\r
-    0xFFF0E68C, // khaki\r
-    0xFFE6E6FA, // lavender\r
-    0xFFFFF0F5, // lavenderblush\r
-    0xFF7CFC00, // lawngreen\r
-    0xFFFFFACD, // lemonchiffon\r
-    0xFFADD8E6, // lightblue\r
-    0xFFF08080, // lightcoral\r
-    0xFFE0FFFF, // lightcyan\r
-    0xFFFAFAD2, // lightgoldenrodyellow\r
-    0xFF90EE90, // lightgreen\r
-    0xFFD3D3D3, // lightgrey\r
-    0xFFFFB6C1, // lightpink\r
-    0xFFFFA07A, // lightsalmon\r
-    0xFF20B2AA, // lightseagreen\r
-    0xFF87CEFA, // lightskyblue\r
-    0xFF778899, // lightslategray\r
-    0xFFB0C4DE, // lightsteelblue\r
-    0xFFFFFFE0, // lightyellow\r
-    0xFF00FF00, // lime\r
-    0xFF32CD32, // limegreen\r
-    0xFFFAF0E6, // linen\r
-    0xFFFF00FF, // magenta\r
-    0xFF800000, // maroon\r
-    0xFF66CDAA, // mediumaquamarine\r
-    0xFF0000CD, // mediumblue\r
-    0xFFBA55D3, // mediumorchid\r
-    0xFF9370DB, // mediumpurple\r
-    0xFF3CB371, // mediumseagreen\r
-    0xFF7B68EE, // mediumslateblue\r
-    0xFF00FA9A, // mediumspringgreen\r
-    0xFF48D1CC, // mediumturquoise\r
-    0xFFC71585, // mediumvioletred\r
-    0xFF191970, // midnightblue\r
-    0xFFF5FFFA, // mintcream\r
-    0xFFFFE4E1, // mistyrose\r
-    0xFFFFE4B5, // moccasin\r
-    0xFFFFDEAD, // navajowhite\r
-    0xFF000080, // navy\r
-    0xFFFDF5E6, // oldlace\r
-    0xFF808000, // olive\r
-    0xFF6B8E23, // olivedrab\r
-    0xFFFFA500, // orange\r
-    0xFFFF4500, // orangered\r
-    0xFFDA70D6, // orchid\r
-    0xFFEEE8AA, // palegoldenrod\r
-    0xFF98FB98, // palegreen\r
-    0xFFAFEEEE, // paleturquoise\r
-    0xFFDB7093, // palevioletred\r
-    0xFFFFEFD5, // papayawhip\r
-    0xFFFFDAB9, // peachpuff\r
-    0xFFCD853F, // peru\r
-    0xFFFFC0CB, // pink\r
-    0xFFDDA0DD, // plum\r
-    0xFFB0E0E6, // powderblue\r
-    0xFF800080, // purple\r
-    0xFFFF0000, // red\r
-    0xFFBC8F8F, // rosybrown\r
-    0xFF4169E1, // royalblue\r
-    0xFF8B4513, // saddlebrown\r
-    0xFFFA8072, // salmon\r
-    0xFFF4A460, // sandybrown\r
-    0xFF2E8B57, // seagreen\r
-    0xFFFFF5EE, // seashell\r
-    0xFFA0522D, // sienna\r
-    0xFFC0C0C0, // silver\r
-    0xFF87CEEB, // skyblue\r
-    0xFF6A5ACD, // slateblue\r
-    0xFF708090, // slategray\r
-    0xFFFFFAFA, // snow\r
-    0xFF00FF7F, // springgreen\r
-    0xFF4682B4, // steelblue\r
-    0xFFD2B48C, // tan\r
-    0xFF008080, // teal\r
-    0xFFD8BFD8, // thistle\r
-    0xFFFF6347, // tomato\r
-    0xFF40E0D0, // turquoise\r
-    0xFFEE82EE, // violet\r
-    0xFFF5DEB3, // wheat\r
-    0xFFFFFFFF, // white\r
-    0xFFF5F5F5, // whitesmoke\r
-    0xFFFFFF00, // yellow\r
-    0xFF9ACD32, // yellowgreen\r
-    // plus a few rasmol names/values\r
-    0xFFAFD7FF, // bluetint\r
-    0xFF2E8B57, // greenblue\r
-    0xFF98FFB3, // greentint\r
-    0xFF808080, // grey\r
-    0xFFFFABBB, // pinktint\r
-    0xFFFF4500, // redorange\r
-    0xFFF6F675, // yellowtint\r
-  };\r
-\r
-  private static final Map<String, Integer> mapJavaScriptColors = new Hashtable<String, Integer>();\r
-\r
-  static {\r
-    for (int i = colorNames.length; --i >= 0; )\r
-      mapJavaScriptColors.put(colorNames[i], Integer.valueOf(colorArgbs[i]));\r
-  }\r
-\r
-  /**\r
-   * accepts [xRRGGBB] or [0xRRGGBB] or [0xFFRRGGBB] or #RRGGBB or\r
-   * [red,green,blue] or a valid JavaScript color\r
-   * \r
-   * @param strColor\r
-   * @return 0 if invalid or integer color\r
-   */\r
-  public static int getArgbFromString(String strColor) {\r
-    int len = 0;\r
-    if (strColor == null || (len = strColor.length()) == 0)\r
-      return 0;\r
-    if (strColor.charAt(0) == '[' && strColor.charAt(len - 1) == ']') {\r
-      String check;\r
-      if (strColor.indexOf(",") >= 0) {\r
-        String[] tokens = PT.split(strColor.substring(1, strColor\r
-            .length() - 1), ",");\r
-        if (tokens.length != 3)\r
-          return 0;\r
-        float red = PT.parseFloat(tokens[0]);\r
-        float grn = PT.parseFloat(tokens[1]);\r
-        float blu = PT.parseFloat(tokens[2]);\r
-        return colorTriadToFFRGB(red, grn, blu);\r
-      }\r
-      switch (len) {\r
-      case 9:\r
-        check = "x";\r
-        break;\r
-      case 10:\r
-        check = "0x";\r
-        break;\r
-      default:\r
-        return 0;\r
-      }\r
-      if (strColor.indexOf(check) != 1)\r
-        return 0;\r
-      strColor = "#" + strColor.substring(len - 7, len - 1);\r
-      len = 7;\r
-    }\r
-    if (len == 7 && strColor.charAt(0) == '#') {\r
-      try {\r
-        return PT.parseIntRadix(strColor.substring(1, 7), 16) | 0xFF000000;\r
-      } catch (Exception e) {\r
-        return 0;\r
-      }\r
-    }\r
-    Integer boxedArgb = mapJavaScriptColors.get(strColor.toLowerCase());\r
-    return (boxedArgb == null ? 0 : boxedArgb.intValue());\r
-  }\r
-\r
-  public static int colorTriadToFFRGB(float x, float y, float z) {\r
-    if (x <= 1 && y <= 1 && z <= 1) {\r
-      if (x > 0)\r
-        x = x * 256 - 1;\r
-      if (y > 0)\r
-        y = y * 256 - 1;\r
-      if (z > 0)\r
-        z = z * 256 - 1;\r
-    }\r
-    return rgb((int) x, (int) y, (int) z);\r
-  }\r
-\r
-  public static int rgb(int red, int grn, int blu) {\r
-    return 0xFF000000 | (red << 16) | (grn << 8) | blu;\r
-  }\r
-\r
-  public final static P3 colorPtFromString(String colorName) {\r
-    return colorPtFromInt(getArgbFromString(colorName), null);\r
-  }\r
-\r
-  public final static P3 colorPtFromInt(int color, P3 pt) {\r
-    if (pt == null)\r
-      pt = new P3();\r
-    pt.set((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);\r
-    return pt;\r
-  }\r
-\r
-  public static int colorPtToFFRGB(T3 pt) {\r
-    return colorTriadToFFRGB(pt.x, pt.y, pt.z);\r
-  }\r
-\r
-  public static void toRGB3f(int c, float[] f) {\r
-    f[0] = ((c >> 16) & 0xFF) / 255f; // red\r
-    f[1] = ((c >> 8) & 0xFF) / 255f;\r
-    f[2] = (c & 0xFF) / 255f;\r
-  }\r
-\r
-  /**\r
-   * Return a greyscale rgb value 0-FF using NTSC color lightness algorithm\r
-   *<p>\r
-   * the alpha component is set to 0xFF. If you want a value in the\r
-   * range 0-255 then & the result with 0xFF;\r
-   *\r
-   * @param rgb the rgb value\r
-   * @return a grayscale value in the range 0 - 255 decimal\r
-   */\r
-  public static int toFFGGGfromRGB(int rgb) {\r
-    int grey = (((2989 * ((rgb >> 16) & 0xFF)) +\r
-                (5870 * ((rgb >> 8) & 0xFF)) +\r
-                (1140 * (rgb & 0xFF)) + 5000) / 10000) & 0xFFFFFF;\r
-    return rgb(grey, grey, grey);\r
-  }\r
-  \r
-  \r
-  /**\r
-   * Convert RGB values to HSL (hue/saturation/lightness)\r
-   * \r
-   * @param rgb\r
-   *        range 255 255 255\r
-   * @param doRound\r
-   *        set to false when just using this for \r
-   *        for RGB -- HSL -- HSL' -- RGB' conversion\r
-   * \r
-   * @return the HSL as P3 range 360 100 100\r
-   * @author hansonr\r
-   */\r
-\r
-  public static P3 rgbToHSL(P3 rgb, boolean doRound) {\r
-    // adapted from http://tips4java.wordpress.com/2009/07/05/hsl-color/\r
-    // see http://en.wikipedia.org/wiki/HSL_color_space\r
-    float r = rgb.x / 255;\r
-    float g = rgb.y / 255;\r
-    float b = rgb.z / 255;\r
-    float min = Math.min(r, Math.min(g, b));\r
-    float max = Math.max(r, Math.max(g, b));\r
-\r
-    //  lightness is just p * 50\r
-\r
-    float p = (max + min);\r
-    float q = (max - min);\r
-\r
-    float h = (60 * ((q == 0 ? 0 : max == r ? ((g - b) / q + 6)\r
-        : max == g ? (b - r) / q + 2 : (r - g) / q + 4))) % 360;\r
-\r
-    float s = q / (q == 0 ? 1 : p <= 1 ? p : 2 - p);\r
-\r
-    // we round to tenths for HSL so that we can  return enough\r
-    // precision to get back 1-255 in RGB\r
-    return (doRound ? P3.new3(Math.round(h*10)/10f, Math.round(s * 1000)/10f,\r
-        Math.round(p * 500)/10f) : P3.new3(h, s * 100, p * 50));\r
-  }\r
-\r
-  /**\r
-   * Convert HSL (hue/saturation/luninance) values to RGB\r
-   *\r
-   * @param hsl in the range 360, 100, 100\r
-   * @return the RGB as P3 range 0 to 255\r
-   * @author hansonr\r
-   */\r
-  public static P3 hslToRGB(P3 hsl) {\r
-    // adapted from http://tips4java.wordpress.com/2009/07/05/hsl-color/\r
-    // see http://en.wikipedia.org/wiki/HSL_color_space\r
-    \r
-    // highly condensed\r
-    \r
-    float h = Math.max(0,  Math.min(360, hsl.x)) / 60;\r
-    float s = Math.max(0,  Math.min(100, hsl.y)) / 100;\r
-    float l = Math.max(0,  Math.min(100, hsl.z)) / 100;\r
-\r
-    float p = l - (l < 0.5 ? l : 1 - l) * s;    \r
-    float q = 2 * (l - p); \r
-        \r
-    float r = toRGB(p, q, h + 2);\r
-    float g = toRGB(p, q, h);\r
-    float b = toRGB(p, q, h - 2);\r
-    return P3.new3(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));\r
-  }\r
-\r
-  private static float toRGB(float p, float q, float h) {\r
-    return ((h = (h + (h < 0 ? 6 : h > 6 ? -6 : 0))) < 1 ? p + q * h\r
-        : h < 3 ? p + q : h < 4 ? p + q * (4 - h) : p);\r
-  }\r
-\r
-}\r
+package javajs.util;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+import javajs.api.GenericColor;
+
+/**
+ * ColorUtility 
+ * 
+ */
+
+public class CU {
+
+  public static String toRGBHexString(GenericColor c) {
+    int rgb = c.getRGB();    
+    if (rgb == 0)
+      return "000000";
+    String r  = "00" + Integer.toHexString((rgb >> 16) & 0xFF);
+    r = r.substring(r.length() - 2);
+    String g  = "00" + Integer.toHexString((rgb >> 8) & 0xFF);
+    g = g.substring(g.length() - 2);
+    String b  = "00" + Integer.toHexString(rgb & 0xFF);
+    b = b.substring(b.length() - 2);
+    return r + g + b;
+  }
+
+  public static String toCSSString(GenericColor c) {
+    int opacity = c.getOpacity255();
+    if (opacity == 255)
+      return "#" + toRGBHexString(c);
+    int rgb = c.getRGB();
+    return "rgba(" + ((rgb>>16)&0xFF) + "," + ((rgb>>8)&0xff) + "," + (rgb&0xff) + "," + opacity/255f  + ")"; 
+  }
+  
+  private final static String[] colorNames = {
+    "black",                // 000000
+    "pewhite",              // ffffff
+    "pecyan",               // 00ffff
+    "pepurple",             // d020ff
+    "pegreen",              // 00ff00
+    "peblue",               // 6060ff
+    "peviolet",             // ff80c0
+    "pebrown",              // a42028
+    "pepink",               // ffd8d8
+    "peyellow",             // ffff00
+    "pedarkgreen",          // 00c000
+    "peorange",             // ffb000
+    "pelightblue",          // b0b0ff
+    "pedarkcyan",           // 00a0a0
+    "pedarkgray",           // 606060
+  
+    "aliceblue",            // F0F8FF
+    "antiquewhite",         // FAEBD7
+    "aqua",                 // 00FFFF
+    "aquamarine",           // 7FFFD4
+    "azure",                // F0FFFF
+    "beige",                // F5F5DC
+    "bisque",               // FFE4C4
+    "blanchedalmond",       // FFEBCD
+    "blue",                 // 0000FF
+    "blueviolet",           // 8A2BE2
+    "brown",                // A52A2A
+    "burlywood",            // DEB887
+    "cadetblue",            // 5F9EA0
+    "chartreuse",           // 7FFF00
+    "chocolate",            // D2691E
+    "coral",                // FF7F50
+    "cornflowerblue",       // 6495ED
+    "cornsilk",             // FFF8DC
+    "crimson",              // DC143C
+    "cyan",                 // 00FFFF
+    "darkblue",             // 00008B
+    "darkcyan",             // 008B8B
+    "darkgoldenrod",        // B8860B
+    "darkgray",             // A9A9A9
+    "darkgreen",            // 006400
+    "darkkhaki",            // BDB76B
+    "darkmagenta",          // 8B008B
+    "darkolivegreen",       // 556B2F
+    "darkorange",           // FF8C00
+    "darkorchid",           // 9932CC
+    "darkred",              // 8B0000
+    "darksalmon",           // E9967A
+    "darkseagreen",         // 8FBC8F
+    "darkslateblue",        // 483D8B
+    "darkslategray",        // 2F4F4F
+    "darkturquoise",        // 00CED1
+    "darkviolet",           // 9400D3
+    "deeppink",             // FF1493
+    "deepskyblue",          // 00BFFF
+    "dimgray",              // 696969
+    "dodgerblue",           // 1E90FF
+    "firebrick",            // B22222
+    "floralwhite",          // FFFAF0 16775920
+    "forestgreen",          // 228B22
+    "fuchsia",              // FF00FF
+    "gainsboro",            // DCDCDC
+    "ghostwhite",           // F8F8FF
+    "gold",                 // FFD700
+    "goldenrod",            // DAA520
+    "gray",                 // 808080
+    "green",                // 008000
+    "greenyellow",          // ADFF2F
+    "honeydew",             // F0FFF0
+    "hotpink",              // FF69B4
+    "indianred",            // CD5C5C
+    "indigo",               // 4B0082
+    "ivory",                // FFFFF0
+    "khaki",                // F0E68C
+    "lavender",             // E6E6FA
+    "lavenderblush",        // FFF0F5
+    "lawngreen",            // 7CFC00
+    "lemonchiffon",         // FFFACD
+    "lightblue",            // ADD8E6
+    "lightcoral",           // F08080
+    "lightcyan",            // E0FFFF
+    "lightgoldenrodyellow", // FAFAD2
+    "lightgreen",           // 90EE90
+    "lightgrey",            // D3D3D3
+    "lightpink",            // FFB6C1
+    "lightsalmon",          // FFA07A
+    "lightseagreen",        // 20B2AA
+    "lightskyblue",         // 87CEFA
+    "lightslategray",       // 778899
+    "lightsteelblue",       // B0C4DE
+    "lightyellow",          // FFFFE0
+    "lime",                 // 00FF00
+    "limegreen",            // 32CD32
+    "linen",                // FAF0E6
+    "magenta",              // FF00FF
+    "maroon",               // 800000
+    "mediumaquamarine",     // 66CDAA
+    "mediumblue",           // 0000CD
+    "mediumorchid",         // BA55D3
+    "mediumpurple",         // 9370DB
+    "mediumseagreen",       // 3CB371
+    "mediumslateblue",      // 7B68EE
+    "mediumspringgreen",    // 00FA9A
+    "mediumturquoise",      // 48D1CC
+    "mediumvioletred",      // C71585
+    "midnightblue",         // 191970
+    "mintcream",            // F5FFFA
+    "mistyrose",            // FFE4E1
+    "moccasin",             // FFE4B5
+    "navajowhite",          // FFDEAD
+    "navy",                 // 000080
+    "oldlace",              // FDF5E6
+    "olive",                // 808000
+    "olivedrab",            // 6B8E23
+    "orange",               // FFA500
+    "orangered",            // FF4500
+    "orchid",               // DA70D6
+    "palegoldenrod",        // EEE8AA
+    "palegreen",            // 98FB98
+    "paleturquoise",        // AFEEEE
+    "palevioletred",        // DB7093
+    "papayawhip",           // FFEFD5
+    "peachpuff",            // FFDAB9
+    "peru",                 // CD853F
+    "pink",                 // FFC0CB
+    "plum",                 // DDA0DD
+    "powderblue",           // B0E0E6
+    "purple",               // 800080
+    "red",                  // FF0000
+    "rosybrown",            // BC8F8F
+    "royalblue",            // 4169E1
+    "saddlebrown",          // 8B4513
+    "salmon",               // FA8072
+    "sandybrown",           // F4A460
+    "seagreen",             // 2E8B57
+    "seashell",             // FFF5EE
+    "sienna",               // A0522D
+    "silver",               // C0C0C0
+    "skyblue",              // 87CEEB
+    "slateblue",            // 6A5ACD
+    "slategray",            // 708090
+    "snow",                 // FFFAFA 16775930
+    "springgreen",          // 00FF7F
+    "steelblue",            // 4682B4
+    "tan",                  // D2B48C
+    "teal",                 // 008080
+    "thistle",              // D8BFD8
+    "tomato",               // FF6347
+    "turquoise",            // 40E0D0
+    "violet",               // EE82EE
+    "wheat",                // F5DEB3
+    "white",                // FFFFFF 16777215
+    "whitesmoke",           // F5F5F5
+    "yellow",               // FFFF00
+    "yellowgreen",          // 9ACD32
+    // plus a few rasmol names/values
+    "bluetint",             // AFD7FF
+    "greenblue",            // 2E8B57
+    "greentint",            // 98FFB3
+    "grey",                 // 808080
+    "pinktint",             // FFABBB
+    "redorange",            // FF4500
+    "yellowtint",           // F6F675
+  };
+  
+  private final static int[] colorArgbs = {
+  //#FFFFC3 hover
+    0xFF000000, // black
+    // plus the PE chain colors
+    0xFFffffff, // pewhite
+    0xFF00ffff, // pecyan
+    0xFFd020ff, // pepurple
+    0xFF00ff00, // pegreen
+    0xFF6060ff, // peblue
+    0xFFff80c0, // peviolet
+    0xFFa42028, // pebrown
+    0xFFffd8d8, // pepink
+    0xFFffff00, // peyellow
+    0xFF00c000, // pedarkgreen
+    0xFFffb000, // peorange
+    0xFFb0b0ff, // pelightblue
+    0xFF00a0a0, // pedarkcyan
+    0xFF606060, // pedarkgray
+    // standard JavaScript
+    0xFFF0F8FF, // aliceblue
+    0xFFFAEBD7, // antiquewhite
+    0xFF00FFFF, // aqua
+    0xFF7FFFD4, // aquamarine
+    0xFFF0FFFF, // azure
+    0xFFF5F5DC, // beige
+    0xFFFFE4C4, // bisque
+    0xFFFFEBCD, // blanchedalmond
+    0xFF0000FF, // blue
+    0xFF8A2BE2, // blueviolet
+    0xFFA52A2A, // brown
+    0xFFDEB887, // burlywood
+    0xFF5F9EA0, // cadetblue
+    0xFF7FFF00, // chartreuse
+    0xFFD2691E, // chocolate
+    0xFFFF7F50, // coral
+    0xFF6495ED, // cornflowerblue
+    0xFFFFF8DC, // cornsilk
+    0xFFDC143C, // crimson
+    0xFF00FFFF, // cyan
+    0xFF00008B, // darkblue
+    0xFF008B8B, // darkcyan
+    0xFFB8860B, // darkgoldenrod
+    0xFFA9A9A9, // darkgray
+    0xFF006400, // darkgreen
+  
+    0xFFBDB76B, // darkkhaki
+    0xFF8B008B, // darkmagenta
+    0xFF556B2F, // darkolivegreen
+    0xFFFF8C00, // darkorange
+    0xFF9932CC, // darkorchid
+    0xFF8B0000, // darkred
+    0xFFE9967A, // darksalmon
+    0xFF8FBC8F, // darkseagreen
+    0xFF483D8B, // darkslateblue
+    0xFF2F4F4F, // darkslategray
+    0xFF00CED1, // darkturquoise
+    0xFF9400D3, // darkviolet
+    0xFFFF1493, // deeppink
+    0xFF00BFFF, // deepskyblue
+    0xFF696969, // dimgray
+    0xFF1E90FF, // dodgerblue
+    0xFFB22222, // firebrick
+    0xFFFFFAF0, // floralwhite
+    0xFF228B22, // forestgreen
+    0xFFFF00FF, // fuchsia
+    0xFFDCDCDC, // gainsboro
+    0xFFF8F8FF, // ghostwhite
+    0xFFFFD700, // gold
+    0xFFDAA520, // goldenrod
+    0xFF808080, // gray
+    0xFF008000, // green
+    0xFFADFF2F, // greenyellow
+    0xFFF0FFF0, // honeydew
+    0xFFFF69B4, // hotpink
+    0xFFCD5C5C, // indianred
+    0xFF4B0082, // indigo
+    0xFFFFFFF0, // ivory
+    0xFFF0E68C, // khaki
+    0xFFE6E6FA, // lavender
+    0xFFFFF0F5, // lavenderblush
+    0xFF7CFC00, // lawngreen
+    0xFFFFFACD, // lemonchiffon
+    0xFFADD8E6, // lightblue
+    0xFFF08080, // lightcoral
+    0xFFE0FFFF, // lightcyan
+    0xFFFAFAD2, // lightgoldenrodyellow
+    0xFF90EE90, // lightgreen
+    0xFFD3D3D3, // lightgrey
+    0xFFFFB6C1, // lightpink
+    0xFFFFA07A, // lightsalmon
+    0xFF20B2AA, // lightseagreen
+    0xFF87CEFA, // lightskyblue
+    0xFF778899, // lightslategray
+    0xFFB0C4DE, // lightsteelblue
+    0xFFFFFFE0, // lightyellow
+    0xFF00FF00, // lime
+    0xFF32CD32, // limegreen
+    0xFFFAF0E6, // linen
+    0xFFFF00FF, // magenta
+    0xFF800000, // maroon
+    0xFF66CDAA, // mediumaquamarine
+    0xFF0000CD, // mediumblue
+    0xFFBA55D3, // mediumorchid
+    0xFF9370DB, // mediumpurple
+    0xFF3CB371, // mediumseagreen
+    0xFF7B68EE, // mediumslateblue
+    0xFF00FA9A, // mediumspringgreen
+    0xFF48D1CC, // mediumturquoise
+    0xFFC71585, // mediumvioletred
+    0xFF191970, // midnightblue
+    0xFFF5FFFA, // mintcream
+    0xFFFFE4E1, // mistyrose
+    0xFFFFE4B5, // moccasin
+    0xFFFFDEAD, // navajowhite
+    0xFF000080, // navy
+    0xFFFDF5E6, // oldlace
+    0xFF808000, // olive
+    0xFF6B8E23, // olivedrab
+    0xFFFFA500, // orange
+    0xFFFF4500, // orangered
+    0xFFDA70D6, // orchid
+    0xFFEEE8AA, // palegoldenrod
+    0xFF98FB98, // palegreen
+    0xFFAFEEEE, // paleturquoise
+    0xFFDB7093, // palevioletred
+    0xFFFFEFD5, // papayawhip
+    0xFFFFDAB9, // peachpuff
+    0xFFCD853F, // peru
+    0xFFFFC0CB, // pink
+    0xFFDDA0DD, // plum
+    0xFFB0E0E6, // powderblue
+    0xFF800080, // purple
+    0xFFFF0000, // red
+    0xFFBC8F8F, // rosybrown
+    0xFF4169E1, // royalblue
+    0xFF8B4513, // saddlebrown
+    0xFFFA8072, // salmon
+    0xFFF4A460, // sandybrown
+    0xFF2E8B57, // seagreen
+    0xFFFFF5EE, // seashell
+    0xFFA0522D, // sienna
+    0xFFC0C0C0, // silver
+    0xFF87CEEB, // skyblue
+    0xFF6A5ACD, // slateblue
+    0xFF708090, // slategray
+    0xFFFFFAFA, // snow
+    0xFF00FF7F, // springgreen
+    0xFF4682B4, // steelblue
+    0xFFD2B48C, // tan
+    0xFF008080, // teal
+    0xFFD8BFD8, // thistle
+    0xFFFF6347, // tomato
+    0xFF40E0D0, // turquoise
+    0xFFEE82EE, // violet
+    0xFFF5DEB3, // wheat
+    0xFFFFFFFF, // white
+    0xFFF5F5F5, // whitesmoke
+    0xFFFFFF00, // yellow
+    0xFF9ACD32, // yellowgreen
+    // plus a few rasmol names/values
+    0xFFAFD7FF, // bluetint
+    0xFF2E8B57, // greenblue
+    0xFF98FFB3, // greentint
+    0xFF808080, // grey
+    0xFFFFABBB, // pinktint
+    0xFFFF4500, // redorange
+    0xFFF6F675, // yellowtint
+  };
+
+  private static final Map<String, Integer> mapJavaScriptColors = new Hashtable<String, Integer>();
+
+  static {
+    for (int i = colorNames.length; --i >= 0; )
+      mapJavaScriptColors.put(colorNames[i], Integer.valueOf(colorArgbs[i]));
+  }
+
+  /**
+   * accepts [xRRGGBB] or [0xRRGGBB] or [0xFFRRGGBB] or #RRGGBB or
+   * [red,green,blue] or a valid JavaScript color
+   * 
+   * @param strColor
+   * @return 0 if invalid or integer color
+   */
+  public static int getArgbFromString(String strColor) {
+    int len = 0;
+    if (strColor == null || (len = strColor.length()) == 0)
+      return 0;
+    if (strColor.charAt(0) == '[' && strColor.charAt(len - 1) == ']') {
+      String check;
+      if (strColor.indexOf(",") >= 0) {
+        String[] tokens = PT.split(strColor.substring(1, strColor
+            .length() - 1), ",");
+        if (tokens.length != 3)
+          return 0;
+        float red = PT.parseFloat(tokens[0]);
+        float grn = PT.parseFloat(tokens[1]);
+        float blu = PT.parseFloat(tokens[2]);
+        return colorTriadToFFRGB(red, grn, blu);
+      }
+      switch (len) {
+      case 9:
+        check = "x";
+        break;
+      case 10:
+        check = "0x";
+        break;
+      default:
+        return 0;
+      }
+      if (strColor.indexOf(check) != 1)
+        return 0;
+      strColor = "#" + strColor.substring(len - 7, len - 1);
+      len = 7;
+    }
+    if (len == 7 && strColor.charAt(0) == '#') {
+      try {
+        return PT.parseIntRadix(strColor.substring(1, 7), 16) | 0xFF000000;
+      } catch (Exception e) {
+        return 0;
+      }
+    }
+    Integer boxedArgb = mapJavaScriptColors.get(strColor.toLowerCase());
+    return (boxedArgb == null ? 0 : boxedArgb.intValue());
+  }
+
+  public static int colorTriadToFFRGB(float x, float y, float z) {
+    if (x <= 1 && y <= 1 && z <= 1) {
+      if (x > 0)
+        x = x * 256 - 1;
+      if (y > 0)
+        y = y * 256 - 1;
+      if (z > 0)
+        z = z * 256 - 1;
+    }
+    return rgb((int) x, (int) y, (int) z);
+  }
+
+  public static int rgb(int red, int grn, int blu) {
+    return 0xFF000000 | (red << 16) | (grn << 8) | blu;
+  }
+
+  public final static P3 colorPtFromString(String colorName) {
+    return colorPtFromInt(getArgbFromString(colorName), null);
+  }
+
+  public final static P3 colorPtFromInt(int color, P3 pt) {
+    if (pt == null)
+      pt = new P3();
+    pt.set((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);
+    return pt;
+  }
+
+  public static int colorPtToFFRGB(T3 pt) {
+    return colorTriadToFFRGB(pt.x, pt.y, pt.z);
+  }
+
+  public static void toRGB3f(int c, float[] f) {
+    f[0] = ((c >> 16) & 0xFF) / 255f; // red
+    f[1] = ((c >> 8) & 0xFF) / 255f;
+    f[2] = (c & 0xFF) / 255f;
+  }
+
+  /**
+   * Return a greyscale rgb value 0-FF using NTSC color lightness algorithm
+   *<p>
+   * the alpha component is set to 0xFF. If you want a value in the
+   * range 0-255 then & the result with 0xFF;
+   *
+   * @param rgb the rgb value
+   * @return a grayscale value in the range 0 - 255 decimal
+   */
+  public static int toFFGGGfromRGB(int rgb) {
+    int grey = (((2989 * ((rgb >> 16) & 0xFF)) +
+                (5870 * ((rgb >> 8) & 0xFF)) +
+                (1140 * (rgb & 0xFF)) + 5000) / 10000) & 0xFFFFFF;
+    return rgb(grey, grey, grey);
+  }
+  
+  
+  /**
+   * Convert RGB values to HSL (hue/saturation/lightness)
+   * 
+   * @param rgb
+   *        range 255 255 255
+   * @param doRound
+   *        set to false when just using this for 
+   *        for RGB -- HSL -- HSL' -- RGB' conversion
+   * 
+   * @return the HSL as P3 range 360 100 100
+   * @author hansonr
+   */
+
+  public static P3 rgbToHSL(P3 rgb, boolean doRound) {
+    // adapted from http://tips4java.wordpress.com/2009/07/05/hsl-color/
+    // see http://en.wikipedia.org/wiki/HSL_color_space
+    float r = rgb.x / 255;
+    float g = rgb.y / 255;
+    float b = rgb.z / 255;
+    float min = Math.min(r, Math.min(g, b));
+    float max = Math.max(r, Math.max(g, b));
+
+    //  lightness is just p * 50
+
+    float p = (max + min);
+    float q = (max - min);
+
+    float h = (60 * ((q == 0 ? 0 : max == r ? ((g - b) / q + 6)
+        : max == g ? (b - r) / q + 2 : (r - g) / q + 4))) % 360;
+
+    float s = q / (q == 0 ? 1 : p <= 1 ? p : 2 - p);
+
+    // we round to tenths for HSL so that we can  return enough
+    // precision to get back 1-255 in RGB
+    return (doRound ? P3.new3(Math.round(h*10)/10f, Math.round(s * 1000)/10f,
+        Math.round(p * 500)/10f) : P3.new3(h, s * 100, p * 50));
+  }
+
+  /**
+   * Convert HSL (hue/saturation/luninance) values to RGB
+   *
+   * @param hsl in the range 360, 100, 100
+   * @return the RGB as P3 range 0 to 255
+   * @author hansonr
+   */
+  public static P3 hslToRGB(P3 hsl) {
+    // adapted from http://tips4java.wordpress.com/2009/07/05/hsl-color/
+    // see http://en.wikipedia.org/wiki/HSL_color_space
+    
+    // highly condensed
+    
+    float h = Math.max(0,  Math.min(360, hsl.x)) / 60;
+    float s = Math.max(0,  Math.min(100, hsl.y)) / 100;
+    float l = Math.max(0,  Math.min(100, hsl.z)) / 100;
+
+    float p = l - (l < 0.5 ? l : 1 - l) * s;    
+    float q = 2 * (l - p); 
+        
+    float r = toRGB(p, q, h + 2);
+    float g = toRGB(p, q, h);
+    float b = toRGB(p, q, h - 2);
+    return P3.new3(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));
+  }
+
+  private static float toRGB(float p, float q, float h) {
+    return ((h = (h + (h < 0 ? 6 : h > 6 ? -6 : 0))) < 1 ? p + q * h
+        : h < 3 ? p + q : h < 4 ? p + q * (4 - h) : p);
+  }
+
+}