JAL-1807 Bob's JalviewJS prototype first commit
[jalviewjs.git] / src / javajs / util / CU.java
1 package javajs.util;\r
2 \r
3 import java.util.Hashtable;\r
4 import java.util.Map;\r
5 \r
6 import javajs.api.GenericColor;\r
7 \r
8 /**\r
9  * ColorUtility \r
10  * \r
11  */\r
12 \r
13 public class CU {\r
14 \r
15   public static String toRGBHexString(GenericColor c) {\r
16     int rgb = c.getRGB();    \r
17     if (rgb == 0)\r
18       return "000000";\r
19     String r  = "00" + Integer.toHexString((rgb >> 16) & 0xFF);\r
20     r = r.substring(r.length() - 2);\r
21     String g  = "00" + Integer.toHexString((rgb >> 8) & 0xFF);\r
22     g = g.substring(g.length() - 2);\r
23     String b  = "00" + Integer.toHexString(rgb & 0xFF);\r
24     b = b.substring(b.length() - 2);\r
25     return r + g + b;\r
26   }\r
27 \r
28   public static String toCSSString(GenericColor c) {\r
29     int opacity = c.getOpacity255();\r
30     if (opacity == 255)\r
31       return "#" + toRGBHexString(c);\r
32     int rgb = c.getRGB();\r
33     return "rgba(" + ((rgb>>16)&0xFF) + "," + ((rgb>>8)&0xff) + "," + (rgb&0xff) + "," + opacity/255f  + ")"; \r
34   }\r
35   \r
36   private final static String[] colorNames = {\r
37     "black",                // 000000\r
38     "pewhite",              // ffffff\r
39     "pecyan",               // 00ffff\r
40     "pepurple",             // d020ff\r
41     "pegreen",              // 00ff00\r
42     "peblue",               // 6060ff\r
43     "peviolet",             // ff80c0\r
44     "pebrown",              // a42028\r
45     "pepink",               // ffd8d8\r
46     "peyellow",             // ffff00\r
47     "pedarkgreen",          // 00c000\r
48     "peorange",             // ffb000\r
49     "pelightblue",          // b0b0ff\r
50     "pedarkcyan",           // 00a0a0\r
51     "pedarkgray",           // 606060\r
52   \r
53     "aliceblue",            // F0F8FF\r
54     "antiquewhite",         // FAEBD7\r
55     "aqua",                 // 00FFFF\r
56     "aquamarine",           // 7FFFD4\r
57     "azure",                // F0FFFF\r
58     "beige",                // F5F5DC\r
59     "bisque",               // FFE4C4\r
60     "blanchedalmond",       // FFEBCD\r
61     "blue",                 // 0000FF\r
62     "blueviolet",           // 8A2BE2\r
63     "brown",                // A52A2A\r
64     "burlywood",            // DEB887\r
65     "cadetblue",            // 5F9EA0\r
66     "chartreuse",           // 7FFF00\r
67     "chocolate",            // D2691E\r
68     "coral",                // FF7F50\r
69     "cornflowerblue",       // 6495ED\r
70     "cornsilk",             // FFF8DC\r
71     "crimson",              // DC143C\r
72     "cyan",                 // 00FFFF\r
73     "darkblue",             // 00008B\r
74     "darkcyan",             // 008B8B\r
75     "darkgoldenrod",        // B8860B\r
76     "darkgray",             // A9A9A9\r
77     "darkgreen",            // 006400\r
78     "darkkhaki",            // BDB76B\r
79     "darkmagenta",          // 8B008B\r
80     "darkolivegreen",       // 556B2F\r
81     "darkorange",           // FF8C00\r
82     "darkorchid",           // 9932CC\r
83     "darkred",              // 8B0000\r
84     "darksalmon",           // E9967A\r
85     "darkseagreen",         // 8FBC8F\r
86     "darkslateblue",        // 483D8B\r
87     "darkslategray",        // 2F4F4F\r
88     "darkturquoise",        // 00CED1\r
89     "darkviolet",           // 9400D3\r
90     "deeppink",             // FF1493\r
91     "deepskyblue",          // 00BFFF\r
92     "dimgray",              // 696969\r
93     "dodgerblue",           // 1E90FF\r
94     "firebrick",            // B22222\r
95     "floralwhite",          // FFFAF0 16775920\r
96     "forestgreen",          // 228B22\r
97     "fuchsia",              // FF00FF\r
98     "gainsboro",            // DCDCDC\r
99     "ghostwhite",           // F8F8FF\r
100     "gold",                 // FFD700\r
101     "goldenrod",            // DAA520\r
102     "gray",                 // 808080\r
103     "green",                // 008000\r
104     "greenyellow",          // ADFF2F\r
105     "honeydew",             // F0FFF0\r
106     "hotpink",              // FF69B4\r
107     "indianred",            // CD5C5C\r
108     "indigo",               // 4B0082\r
109     "ivory",                // FFFFF0\r
110     "khaki",                // F0E68C\r
111     "lavender",             // E6E6FA\r
112     "lavenderblush",        // FFF0F5\r
113     "lawngreen",            // 7CFC00\r
114     "lemonchiffon",         // FFFACD\r
115     "lightblue",            // ADD8E6\r
116     "lightcoral",           // F08080\r
117     "lightcyan",            // E0FFFF\r
118     "lightgoldenrodyellow", // FAFAD2\r
119     "lightgreen",           // 90EE90\r
120     "lightgrey",            // D3D3D3\r
121     "lightpink",            // FFB6C1\r
122     "lightsalmon",          // FFA07A\r
123     "lightseagreen",        // 20B2AA\r
124     "lightskyblue",         // 87CEFA\r
125     "lightslategray",       // 778899\r
126     "lightsteelblue",       // B0C4DE\r
127     "lightyellow",          // FFFFE0\r
128     "lime",                 // 00FF00\r
129     "limegreen",            // 32CD32\r
130     "linen",                // FAF0E6\r
131     "magenta",              // FF00FF\r
132     "maroon",               // 800000\r
133     "mediumaquamarine",     // 66CDAA\r
134     "mediumblue",           // 0000CD\r
135     "mediumorchid",         // BA55D3\r
136     "mediumpurple",         // 9370DB\r
137     "mediumseagreen",       // 3CB371\r
138     "mediumslateblue",      // 7B68EE\r
139     "mediumspringgreen",    // 00FA9A\r
140     "mediumturquoise",      // 48D1CC\r
141     "mediumvioletred",      // C71585\r
142     "midnightblue",         // 191970\r
143     "mintcream",            // F5FFFA\r
144     "mistyrose",            // FFE4E1\r
145     "moccasin",             // FFE4B5\r
146     "navajowhite",          // FFDEAD\r
147     "navy",                 // 000080\r
148     "oldlace",              // FDF5E6\r
149     "olive",                // 808000\r
150     "olivedrab",            // 6B8E23\r
151     "orange",               // FFA500\r
152     "orangered",            // FF4500\r
153     "orchid",               // DA70D6\r
154     "palegoldenrod",        // EEE8AA\r
155     "palegreen",            // 98FB98\r
156     "paleturquoise",        // AFEEEE\r
157     "palevioletred",        // DB7093\r
158     "papayawhip",           // FFEFD5\r
159     "peachpuff",            // FFDAB9\r
160     "peru",                 // CD853F\r
161     "pink",                 // FFC0CB\r
162     "plum",                 // DDA0DD\r
163     "powderblue",           // B0E0E6\r
164     "purple",               // 800080\r
165     "red",                  // FF0000\r
166     "rosybrown",            // BC8F8F\r
167     "royalblue",            // 4169E1\r
168     "saddlebrown",          // 8B4513\r
169     "salmon",               // FA8072\r
170     "sandybrown",           // F4A460\r
171     "seagreen",             // 2E8B57\r
172     "seashell",             // FFF5EE\r
173     "sienna",               // A0522D\r
174     "silver",               // C0C0C0\r
175     "skyblue",              // 87CEEB\r
176     "slateblue",            // 6A5ACD\r
177     "slategray",            // 708090\r
178     "snow",                 // FFFAFA 16775930\r
179     "springgreen",          // 00FF7F\r
180     "steelblue",            // 4682B4\r
181     "tan",                  // D2B48C\r
182     "teal",                 // 008080\r
183     "thistle",              // D8BFD8\r
184     "tomato",               // FF6347\r
185     "turquoise",            // 40E0D0\r
186     "violet",               // EE82EE\r
187     "wheat",                // F5DEB3\r
188     "white",                // FFFFFF 16777215\r
189     "whitesmoke",           // F5F5F5\r
190     "yellow",               // FFFF00\r
191     "yellowgreen",          // 9ACD32\r
192     // plus a few rasmol names/values\r
193     "bluetint",             // AFD7FF\r
194     "greenblue",            // 2E8B57\r
195     "greentint",            // 98FFB3\r
196     "grey",                 // 808080\r
197     "pinktint",             // FFABBB\r
198     "redorange",            // FF4500\r
199     "yellowtint",           // F6F675\r
200   };\r
201   \r
202   private final static int[] colorArgbs = {\r
203   //#FFFFC3 hover\r
204     0xFF000000, // black\r
205     // plus the PE chain colors\r
206     0xFFffffff, // pewhite\r
207     0xFF00ffff, // pecyan\r
208     0xFFd020ff, // pepurple\r
209     0xFF00ff00, // pegreen\r
210     0xFF6060ff, // peblue\r
211     0xFFff80c0, // peviolet\r
212     0xFFa42028, // pebrown\r
213     0xFFffd8d8, // pepink\r
214     0xFFffff00, // peyellow\r
215     0xFF00c000, // pedarkgreen\r
216     0xFFffb000, // peorange\r
217     0xFFb0b0ff, // pelightblue\r
218     0xFF00a0a0, // pedarkcyan\r
219     0xFF606060, // pedarkgray\r
220     // standard JavaScript\r
221     0xFFF0F8FF, // aliceblue\r
222     0xFFFAEBD7, // antiquewhite\r
223     0xFF00FFFF, // aqua\r
224     0xFF7FFFD4, // aquamarine\r
225     0xFFF0FFFF, // azure\r
226     0xFFF5F5DC, // beige\r
227     0xFFFFE4C4, // bisque\r
228     0xFFFFEBCD, // blanchedalmond\r
229     0xFF0000FF, // blue\r
230     0xFF8A2BE2, // blueviolet\r
231     0xFFA52A2A, // brown\r
232     0xFFDEB887, // burlywood\r
233     0xFF5F9EA0, // cadetblue\r
234     0xFF7FFF00, // chartreuse\r
235     0xFFD2691E, // chocolate\r
236     0xFFFF7F50, // coral\r
237     0xFF6495ED, // cornflowerblue\r
238     0xFFFFF8DC, // cornsilk\r
239     0xFFDC143C, // crimson\r
240     0xFF00FFFF, // cyan\r
241     0xFF00008B, // darkblue\r
242     0xFF008B8B, // darkcyan\r
243     0xFFB8860B, // darkgoldenrod\r
244     0xFFA9A9A9, // darkgray\r
245     0xFF006400, // darkgreen\r
246   \r
247     0xFFBDB76B, // darkkhaki\r
248     0xFF8B008B, // darkmagenta\r
249     0xFF556B2F, // darkolivegreen\r
250     0xFFFF8C00, // darkorange\r
251     0xFF9932CC, // darkorchid\r
252     0xFF8B0000, // darkred\r
253     0xFFE9967A, // darksalmon\r
254     0xFF8FBC8F, // darkseagreen\r
255     0xFF483D8B, // darkslateblue\r
256     0xFF2F4F4F, // darkslategray\r
257     0xFF00CED1, // darkturquoise\r
258     0xFF9400D3, // darkviolet\r
259     0xFFFF1493, // deeppink\r
260     0xFF00BFFF, // deepskyblue\r
261     0xFF696969, // dimgray\r
262     0xFF1E90FF, // dodgerblue\r
263     0xFFB22222, // firebrick\r
264     0xFFFFFAF0, // floralwhite\r
265     0xFF228B22, // forestgreen\r
266     0xFFFF00FF, // fuchsia\r
267     0xFFDCDCDC, // gainsboro\r
268     0xFFF8F8FF, // ghostwhite\r
269     0xFFFFD700, // gold\r
270     0xFFDAA520, // goldenrod\r
271     0xFF808080, // gray\r
272     0xFF008000, // green\r
273     0xFFADFF2F, // greenyellow\r
274     0xFFF0FFF0, // honeydew\r
275     0xFFFF69B4, // hotpink\r
276     0xFFCD5C5C, // indianred\r
277     0xFF4B0082, // indigo\r
278     0xFFFFFFF0, // ivory\r
279     0xFFF0E68C, // khaki\r
280     0xFFE6E6FA, // lavender\r
281     0xFFFFF0F5, // lavenderblush\r
282     0xFF7CFC00, // lawngreen\r
283     0xFFFFFACD, // lemonchiffon\r
284     0xFFADD8E6, // lightblue\r
285     0xFFF08080, // lightcoral\r
286     0xFFE0FFFF, // lightcyan\r
287     0xFFFAFAD2, // lightgoldenrodyellow\r
288     0xFF90EE90, // lightgreen\r
289     0xFFD3D3D3, // lightgrey\r
290     0xFFFFB6C1, // lightpink\r
291     0xFFFFA07A, // lightsalmon\r
292     0xFF20B2AA, // lightseagreen\r
293     0xFF87CEFA, // lightskyblue\r
294     0xFF778899, // lightslategray\r
295     0xFFB0C4DE, // lightsteelblue\r
296     0xFFFFFFE0, // lightyellow\r
297     0xFF00FF00, // lime\r
298     0xFF32CD32, // limegreen\r
299     0xFFFAF0E6, // linen\r
300     0xFFFF00FF, // magenta\r
301     0xFF800000, // maroon\r
302     0xFF66CDAA, // mediumaquamarine\r
303     0xFF0000CD, // mediumblue\r
304     0xFFBA55D3, // mediumorchid\r
305     0xFF9370DB, // mediumpurple\r
306     0xFF3CB371, // mediumseagreen\r
307     0xFF7B68EE, // mediumslateblue\r
308     0xFF00FA9A, // mediumspringgreen\r
309     0xFF48D1CC, // mediumturquoise\r
310     0xFFC71585, // mediumvioletred\r
311     0xFF191970, // midnightblue\r
312     0xFFF5FFFA, // mintcream\r
313     0xFFFFE4E1, // mistyrose\r
314     0xFFFFE4B5, // moccasin\r
315     0xFFFFDEAD, // navajowhite\r
316     0xFF000080, // navy\r
317     0xFFFDF5E6, // oldlace\r
318     0xFF808000, // olive\r
319     0xFF6B8E23, // olivedrab\r
320     0xFFFFA500, // orange\r
321     0xFFFF4500, // orangered\r
322     0xFFDA70D6, // orchid\r
323     0xFFEEE8AA, // palegoldenrod\r
324     0xFF98FB98, // palegreen\r
325     0xFFAFEEEE, // paleturquoise\r
326     0xFFDB7093, // palevioletred\r
327     0xFFFFEFD5, // papayawhip\r
328     0xFFFFDAB9, // peachpuff\r
329     0xFFCD853F, // peru\r
330     0xFFFFC0CB, // pink\r
331     0xFFDDA0DD, // plum\r
332     0xFFB0E0E6, // powderblue\r
333     0xFF800080, // purple\r
334     0xFFFF0000, // red\r
335     0xFFBC8F8F, // rosybrown\r
336     0xFF4169E1, // royalblue\r
337     0xFF8B4513, // saddlebrown\r
338     0xFFFA8072, // salmon\r
339     0xFFF4A460, // sandybrown\r
340     0xFF2E8B57, // seagreen\r
341     0xFFFFF5EE, // seashell\r
342     0xFFA0522D, // sienna\r
343     0xFFC0C0C0, // silver\r
344     0xFF87CEEB, // skyblue\r
345     0xFF6A5ACD, // slateblue\r
346     0xFF708090, // slategray\r
347     0xFFFFFAFA, // snow\r
348     0xFF00FF7F, // springgreen\r
349     0xFF4682B4, // steelblue\r
350     0xFFD2B48C, // tan\r
351     0xFF008080, // teal\r
352     0xFFD8BFD8, // thistle\r
353     0xFFFF6347, // tomato\r
354     0xFF40E0D0, // turquoise\r
355     0xFFEE82EE, // violet\r
356     0xFFF5DEB3, // wheat\r
357     0xFFFFFFFF, // white\r
358     0xFFF5F5F5, // whitesmoke\r
359     0xFFFFFF00, // yellow\r
360     0xFF9ACD32, // yellowgreen\r
361     // plus a few rasmol names/values\r
362     0xFFAFD7FF, // bluetint\r
363     0xFF2E8B57, // greenblue\r
364     0xFF98FFB3, // greentint\r
365     0xFF808080, // grey\r
366     0xFFFFABBB, // pinktint\r
367     0xFFFF4500, // redorange\r
368     0xFFF6F675, // yellowtint\r
369   };\r
370 \r
371   private static final Map<String, Integer> mapJavaScriptColors = new Hashtable<String, Integer>();\r
372 \r
373   static {\r
374     for (int i = colorNames.length; --i >= 0; )\r
375       mapJavaScriptColors.put(colorNames[i], Integer.valueOf(colorArgbs[i]));\r
376   }\r
377 \r
378   /**\r
379    * accepts [xRRGGBB] or [0xRRGGBB] or [0xFFRRGGBB] or #RRGGBB or\r
380    * [red,green,blue] or a valid JavaScript color\r
381    * \r
382    * @param strColor\r
383    * @return 0 if invalid or integer color\r
384    */\r
385   public static int getArgbFromString(String strColor) {\r
386     int len = 0;\r
387     if (strColor == null || (len = strColor.length()) == 0)\r
388       return 0;\r
389     if (strColor.charAt(0) == '[' && strColor.charAt(len - 1) == ']') {\r
390       String check;\r
391       if (strColor.indexOf(",") >= 0) {\r
392         String[] tokens = PT.split(strColor.substring(1, strColor\r
393             .length() - 1), ",");\r
394         if (tokens.length != 3)\r
395           return 0;\r
396         float red = PT.parseFloat(tokens[0]);\r
397         float grn = PT.parseFloat(tokens[1]);\r
398         float blu = PT.parseFloat(tokens[2]);\r
399         return colorTriadToFFRGB(red, grn, blu);\r
400       }\r
401       switch (len) {\r
402       case 9:\r
403         check = "x";\r
404         break;\r
405       case 10:\r
406         check = "0x";\r
407         break;\r
408       default:\r
409         return 0;\r
410       }\r
411       if (strColor.indexOf(check) != 1)\r
412         return 0;\r
413       strColor = "#" + strColor.substring(len - 7, len - 1);\r
414       len = 7;\r
415     }\r
416     if (len == 7 && strColor.charAt(0) == '#') {\r
417       try {\r
418         return PT.parseIntRadix(strColor.substring(1, 7), 16) | 0xFF000000;\r
419       } catch (Exception e) {\r
420         return 0;\r
421       }\r
422     }\r
423     Integer boxedArgb = mapJavaScriptColors.get(strColor.toLowerCase());\r
424     return (boxedArgb == null ? 0 : boxedArgb.intValue());\r
425   }\r
426 \r
427   public static int colorTriadToFFRGB(float x, float y, float z) {\r
428     if (x <= 1 && y <= 1 && z <= 1) {\r
429       if (x > 0)\r
430         x = x * 256 - 1;\r
431       if (y > 0)\r
432         y = y * 256 - 1;\r
433       if (z > 0)\r
434         z = z * 256 - 1;\r
435     }\r
436     return rgb((int) x, (int) y, (int) z);\r
437   }\r
438 \r
439   public static int rgb(int red, int grn, int blu) {\r
440     return 0xFF000000 | (red << 16) | (grn << 8) | blu;\r
441   }\r
442 \r
443   public final static P3 colorPtFromString(String colorName) {\r
444     return colorPtFromInt(getArgbFromString(colorName), null);\r
445   }\r
446 \r
447   public final static P3 colorPtFromInt(int color, P3 pt) {\r
448     if (pt == null)\r
449       pt = new P3();\r
450     pt.set((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);\r
451     return pt;\r
452   }\r
453 \r
454   public static int colorPtToFFRGB(T3 pt) {\r
455     return colorTriadToFFRGB(pt.x, pt.y, pt.z);\r
456   }\r
457 \r
458   public static void toRGB3f(int c, float[] f) {\r
459     f[0] = ((c >> 16) & 0xFF) / 255f; // red\r
460     f[1] = ((c >> 8) & 0xFF) / 255f;\r
461     f[2] = (c & 0xFF) / 255f;\r
462   }\r
463 \r
464   /**\r
465    * Return a greyscale rgb value 0-FF using NTSC color lightness algorithm\r
466    *<p>\r
467    * the alpha component is set to 0xFF. If you want a value in the\r
468    * range 0-255 then & the result with 0xFF;\r
469    *\r
470    * @param rgb the rgb value\r
471    * @return a grayscale value in the range 0 - 255 decimal\r
472    */\r
473   public static int toFFGGGfromRGB(int rgb) {\r
474     int grey = (((2989 * ((rgb >> 16) & 0xFF)) +\r
475                 (5870 * ((rgb >> 8) & 0xFF)) +\r
476                 (1140 * (rgb & 0xFF)) + 5000) / 10000) & 0xFFFFFF;\r
477     return rgb(grey, grey, grey);\r
478   }\r
479   \r
480   \r
481   /**\r
482    * Convert RGB values to HSL (hue/saturation/lightness)\r
483    * \r
484    * @param rgb\r
485    *        range 255 255 255\r
486    * @param doRound\r
487    *        set to false when just using this for \r
488    *        for RGB -- HSL -- HSL' -- RGB' conversion\r
489    * \r
490    * @return the HSL as P3 range 360 100 100\r
491    * @author hansonr\r
492    */\r
493 \r
494   public static P3 rgbToHSL(P3 rgb, boolean doRound) {\r
495     // adapted from http://tips4java.wordpress.com/2009/07/05/hsl-color/\r
496     // see http://en.wikipedia.org/wiki/HSL_color_space\r
497     float r = rgb.x / 255;\r
498     float g = rgb.y / 255;\r
499     float b = rgb.z / 255;\r
500     float min = Math.min(r, Math.min(g, b));\r
501     float max = Math.max(r, Math.max(g, b));\r
502 \r
503     //  lightness is just p * 50\r
504 \r
505     float p = (max + min);\r
506     float q = (max - min);\r
507 \r
508     float h = (60 * ((q == 0 ? 0 : max == r ? ((g - b) / q + 6)\r
509         : max == g ? (b - r) / q + 2 : (r - g) / q + 4))) % 360;\r
510 \r
511     float s = q / (q == 0 ? 1 : p <= 1 ? p : 2 - p);\r
512 \r
513     // we round to tenths for HSL so that we can  return enough\r
514     // precision to get back 1-255 in RGB\r
515     return (doRound ? P3.new3(Math.round(h*10)/10f, Math.round(s * 1000)/10f,\r
516         Math.round(p * 500)/10f) : P3.new3(h, s * 100, p * 50));\r
517   }\r
518 \r
519   /**\r
520    * Convert HSL (hue/saturation/luninance) values to RGB\r
521    *\r
522    * @param hsl in the range 360, 100, 100\r
523    * @return the RGB as P3 range 0 to 255\r
524    * @author hansonr\r
525    */\r
526   public static P3 hslToRGB(P3 hsl) {\r
527     // adapted from http://tips4java.wordpress.com/2009/07/05/hsl-color/\r
528     // see http://en.wikipedia.org/wiki/HSL_color_space\r
529     \r
530     // highly condensed\r
531     \r
532     float h = Math.max(0,  Math.min(360, hsl.x)) / 60;\r
533     float s = Math.max(0,  Math.min(100, hsl.y)) / 100;\r
534     float l = Math.max(0,  Math.min(100, hsl.z)) / 100;\r
535 \r
536     float p = l - (l < 0.5 ? l : 1 - l) * s;    \r
537     float q = 2 * (l - p); \r
538         \r
539     float r = toRGB(p, q, h + 2);\r
540     float g = toRGB(p, q, h);\r
541     float b = toRGB(p, q, h - 2);\r
542     return P3.new3(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));\r
543   }\r
544 \r
545   private static float toRGB(float p, float q, float h) {\r
546     return ((h = (h + (h < 0 ? 6 : h > 6 ? -6 : 0))) < 1 ? p + q * h\r
547         : h < 3 ? p + q : h < 4 ? p + q * (4 - h) : p);\r
548   }\r
549 \r
550 }\r