001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.commons.color;
020
021import java.awt.Color;
022
023import lucee.commons.lang.NumberUtil;
024import lucee.commons.lang.StringUtil;
025import lucee.runtime.exp.ExpressionException;
026import lucee.runtime.op.Caster;
027import lucee.runtime.type.util.ListUtil;
028
029public final class ColorCaster {
030
031        /**
032         * calculate the contrast between 2 colors
033         * @param left
034         * @param right
035         * @return a int between 0 (badest) and 510 (best)
036         */
037        public static int contrast(Color left, Color right) {
038                return
039                (Math.max(left.getRed(), right.getRed())                - Math.min(left.getRed(), right.getRed())) + 
040                (Math.max(left.getGreen(), right.getGreen())    - Math.min(left.getGreen(), right.getGreen())) + 
041                (Math.max(left.getBlue(), right.getBlue())              - Math.max(left.getBlue(), right.getBlue()));
042        }
043
044        public static Color toColor(String strColor) throws ExpressionException {
045                if(StringUtil.isEmpty(strColor,true))
046                        throw new ExpressionException("can't cast empty string to a color Object");
047                
048                strColor=strColor.toLowerCase().trim();
049                char first=strColor.charAt(0);
050                
051                switch(first) {
052                        case 'a':
053                                if("aqua".equals(strColor))             return new Color(0,0xFF,0xFF); 
054                                if("aliceblue".equals(strColor))        return new Color(0xF0,0xF8,0xFF); 
055                                if("antiquewhite".equals(strColor)) return new Color(0xFA,0xEB,0xD7); 
056                                if("quamarine".equals(strColor)) return new Color(0x7F,0xFF,0xD4); 
057                                if("azure".equals(strColor)) return new Color(0xF0,0xFF,0xFF); 
058                        break;
059                        case 'b':
060                                if("black".equals(strColor))            return Color.BLACK;
061                                if("blue".equals(strColor))             return Color.BLUE;
062                                if("blue".equals(strColor))             return Color.CYAN;
063                                if("beige".equals(strColor))            return new Color(0xF5,0xF5,0xDC); 
064                                if("blueviolet".equals(strColor))       return new Color(0x8A,0x2B,0xE2); 
065                                if("brown".equals(strColor))            return new Color(0xA5,0x2A,0x2A); 
066                                if("burlywood".equals(strColor))        return new Color(0xDE,0xB8,0x87); 
067                        break;
068                        case 'c':
069                                if("cyan".equals(strColor))             return Color.CYAN;
070                                if("cadetblue".equals(strColor))        return new Color(0x5F,0x9E,0xA0); 
071                                if("chartreuse".equals(strColor))       return new Color(0x7F,0xFF,0x00); 
072                                if("chocolate".equals(strColor))        return new Color(0xD2,0x69,0x1E); 
073                                if("coral".equals(strColor))            return new Color(0xFF,0x7F,0x50); 
074                                if("cornflowerblue".equals(strColor))return new Color(0x64,0x95,0xED); 
075                                if("cornsilk".equals(strColor))         return new Color(0xFF,0xF8,0xDC); 
076                                if("crimson".equals(strColor))          return new Color(0xDC,0x14,0x3C); 
077                        break;
078                        case 'd':
079                                if("darkgray".equals(strColor))         return Color.DARK_GRAY;
080                                if("darkblue".equals(strColor))         return new Color(0x00,0x00,0x8B); 
081                                if("darkcyan".equals(strColor))         return new Color(0x00,0x8B,0x8B); 
082                                if("darkgoldenrod".equals(strColor))return new Color(0xB8,0x86,0x0B); 
083                                if("darkgreen".equals(strColor))        return new Color(0x00,0x64,0x00); 
084                                if("darkkhaki".equals(strColor))        return new Color(0xBD,0xB7,0x6B); 
085                                if("darkmagenta".equals(strColor))      return new Color(0x8B,0x00,0x8B); 
086                                if("darkolivegreen".equals(strColor))return new Color(0x55,0x6B,0x2F); 
087                                if("darkorange".equals(strColor))       return new Color(0xFF,0x8C,0x00); 
088                                if("darkorchid".equals(strColor))       return new Color(0x99,0x32,0xcc); 
089                                if("darkred".equals(strColor))          return new Color(0x8B,0x00,0x00); 
090                                if("darksalmon".equals(strColor))       return new Color(0xE9,0x96,0x7A); 
091                                if("darkseagreen".equals(strColor)) return new Color(0x8F,0xBC,0x8F); 
092                                if("darkslateblue".equals(strColor))return new Color(0x2F,0x4F,0x4F); 
093                                if("darkslategray".equals(strColor))return new Color(0x48,0x3D,0x8B); 
094                                if("darkturquoise".equals(strColor))return new Color(0x00,0xCE,0xD1); 
095                                if("darkviolet".equals(strColor))       return new Color(0x94,0x00,0xD3); 
096                                if("deeppink".equals(strColor))         return new Color(0xFF,0x14,0x93); 
097                                if("deepskyblue".equals(strColor))      return new Color(0x00,0xBF,0xFF); 
098                                if("dimgray".equals(strColor))          return new Color(0x69,0x69,0x69); 
099                                if("dodgerblue".equals(strColor))       return new Color(0x1E,0x90,0xFF); 
100                        break;
101                        case 'f':
102                                if("fuchsia".equals(strColor))          return new Color(0xFF,0,0xFF); 
103                                if("firebrick".equals(strColor))        return new Color(0xB2,0x22,0x22); 
104                                if("floralwhite".equals(strColor))      return new Color(0xFF,0xFA,0xF0); 
105                                if("forestgreen".equals(strColor))      return new Color(0x22,0x8B,0x22); 
106                        break;
107                        case 'g':
108                                if("gray".equals(strColor))             return Color.GRAY;
109                                if("green".equals(strColor))            return Color.GREEN;
110                                if("gainsboro".equals(strColor))        return new Color(0xDC,0xDC,0xDC); 
111                                if("ghostwhite".equals(strColor))       return new Color(0xF8,0xF8,0xFF); 
112                                if("gold".equals(strColor))             return new Color(0xFF,0xD7,0x00); 
113                                if("goldenrod".equals(strColor))        return new Color(0xDA,0xA5,0x20); 
114                                if("greenyellow".equals(strColor))      return new Color(0xAD,0xFF,0x2F); 
115
116                        break;
117                        case 'h':
118                                if("honeydew".equals(strColor))         return new Color(0xF0,0xFF,0xF0); 
119                                if("hotpink".equals(strColor))          return new Color(0xFF,0x69,0xB4); 
120                        break;
121                        case 'i':
122                                if("indianred".equals(strColor))        return new Color(0xCD,0x5C,0x5C); 
123                                if("indigo".equals(strColor))           return new Color(0x4B,0x00,0x82); 
124                                if("ivory".equals(strColor))            return new Color(0xFF,0xFF,0xF0); 
125                        break;
126                        case 'k':
127                                if("khaki".equals(strColor))            return new Color(0xF0,0xE6,0x8C); 
128                        break;
129                        case 'l':
130                                if("lightgray".equals(strColor))        return Color.lightGray; 
131                                if("lime".equals(strColor))             return new Color(0,0xFF,0);
132                                if("lavender".equals(strColor))         return new Color(0xE6,0xE6,0xFA); 
133                                if("lavenderblush".equals(strColor))return new Color(0xFF,0xF0,0xF5); 
134                                if("lawngreen".equals(strColor))        return new Color(0x7C,0xFC,0x00); 
135                                if("lemonchiffon".equals(strColor)) return new Color(0xFF,0xFA,0xCD); 
136                                if("lightblue".equals(strColor))        return new Color(0xAD,0xD8,0xE6);
137                                if("lightcoral".equals(strColor))       return new Color(0xF0,0x80,0x80); 
138                                if("lightcyan".equals(strColor))        return new Color(0xE0,0xFF,0xFF); 
139                                if("lightgoldenrodyellow".equals(strColor)) return new Color(0xFA,0xFA,0xD2); 
140                                if("lightgreen".equals(strColor))       return new Color(0x90,0xEE,0x90); 
141                                if("lightgrey".equals(strColor))        return new Color(0xD3,0xD3,0xD3);
142                                if("lightpink".equals(strColor))        return new Color(0xFF,0xB6,0xC1); 
143                                if("lightsalmon".equals(strColor))      return new Color(0xFF,0xA0,0x7A); 
144                                if("lightseagreen".equals(strColor))return new Color(0x20,0xB2,0xAA); 
145                                if("lightskyblue".equals(strColor)) return new Color(0x87,0xCE,0xFA); 
146                                if("lightslategray".equals(strColor))return new Color(0x77,0x88,0x99);
147                                if("lightsteelblue".equals(strColor))return new Color(0xB0,0xC4,0xDE); 
148                                if("lightyellow".equals(strColor))      return new Color(0xFF,0xFF,0xE0); 
149                                if("limegreen".equals(strColor))        return new Color(0x32,0xCD,0x32);
150                                if("linen".equals(strColor))            return new Color(0xFA,0xF0,0xE6); 
151                                
152                        break;
153                        case 'm':
154                                if("magenta".equals(strColor))          return Color.MAGENTA; 
155                                if("maroon".equals(strColor))           return new Color(0X80,0,0);
156                                if("mediumaquamarine".equals(strColor)) return new Color(0x66,0xCD,0xAA); 
157                                if("mediumblue".equals(strColor)) return new Color(0x00,0x00,0xCD);
158                                if("mediumorchid".equals(strColor)) return new Color(0xBA,0x55,0xD3); 
159                                if("mediumpurple".equals(strColor)) return new Color(0x93,0x70,0xDB); 
160                                if("mediumseagreen".equals(strColor)) return new Color(0x3C,0xB3,0x71);
161                                if("mediumslateblue".equals(strColor)) return new Color(0x7B,0x68,0xEE); 
162                                if("mediumspringgreen".equals(strColor)) return new Color(0x00,0xFA,0x9A);
163                                if("mediumturquoise".equals(strColor)) return new Color(0x48,0xD1,0xCC); 
164                                if("mediumvioletred".equals(strColor)) return new Color(0xC7,0x15,0x85); 
165                                if("midnightblue".equals(strColor)) return new Color(0x19,0x19,0x70);
166                                if("mintcream".equals(strColor)) return new Color(0xF5,0xFF,0xFA); 
167                                if("mistyrose".equals(strColor)) return new Color(0xFF,0xE4,0xE1);
168                                if("moccasin".equals(strColor)) return new Color(0xFF,0xE4,0xB5); 
169                        break;
170                        case 'n':
171                                if("navy".equals(strColor))             return new Color(0,0,0X80);
172                                if("navajowhite".equals(strColor)) return new Color(0xFF,0xDE,0xAD); 
173                        break;
174                        case 'o':
175                                if("orange".equals(strColor))           return Color.ORANGE; 
176                                if("olive".equals(strColor))            return new Color(0X80,0X80,0);
177                                if("oldlace".equals(strColor)) return new Color(0xFD,0xF5,0xE6);
178                                if("olivedrab".equals(strColor)) return new Color(0x6B,0x8E,0x23); 
179                                if("orangered".equals(strColor)) return new Color(0xFF,0x45,0x00);
180                                if("orchid".equals(strColor)) return new Color(0xDA,0x70,0xD6); 
181                        break;
182                        case 'p':
183                                if("pink".equals(strColor))             return Color.PINK; 
184                                if("purple".equals(strColor))           return new Color(0X80,0,0X80);
185                                if("palegoldenrod".equals(strColor)) return new Color(0xEE,0xE8,0xAA);
186                                if("palegreen".equals(strColor)) return new Color(0x98,0xFB,0x98); 
187                                if("paleturquoise".equals(strColor)) return new Color(0xAF,0xEE,0xEE);
188                                if("palevioletred".equals(strColor)) return new Color(0xDB,0x70,0x93); 
189                                if("papayawhip".equals(strColor)) return new Color(0xFF,0xEF,0xD5);
190                                if("peachpuff".equals(strColor)) return new Color(0xFF,0xDA,0xB9); 
191                                if("peru".equals(strColor)) return new Color(0xCD,0x85,0x3F);
192                                if("pink".equals(strColor)) return new Color(0xFF,0xC0,0xCB); 
193                                if("plum".equals(strColor)) return new Color(0xDD,0xA0,0xDD);
194                                if("powderblue".equals(strColor)) return new Color(0xB0,0xE0,0xE6);                             
195                        break;
196                        case 'r':
197                                if("red".equals(strColor))              return Color.RED; 
198                                if("rosybrown".equals(strColor)) return new Color(0xBC,0x8F,0x8F);
199                                if("royalblue".equals(strColor)) return new Color(0x41,0x69,0xE1); 
200                        break;
201                        case 's':
202                                if("silver".equals(strColor))           return new Color(0XC0,0XC0,0XC0);
203                                if("saddlebrown".equals(strColor)) return new Color(0x8B,0x45,0x13);
204                                if("salmon".equals(strColor)) return new Color(0xFA,0x80,0x72); 
205                                if("sandybrown".equals(strColor)) return new Color(0xF4,0xA4,0x60);
206                                if("seagreen".equals(strColor)) return new Color(0x2E,0x8B,0x57); 
207                                if("seashell".equals(strColor)) return new Color(0xFF,0xF5,0xEE);
208                                if("sienna".equals(strColor)) return new Color(0xA0,0x52,0x2D); 
209                                if("skyblue".equals(strColor)) return new Color(0x87,0xCE,0xEB);
210                                if("slateblue".equals(strColor)) return new Color(0x6A,0x5A,0xCD);
211                                if("slategray".equals(strColor)) return new Color(0x70,0x80,0x90); 
212                                if("snow".equals(strColor)) return new Color(0xFF,0xFA,0xFA);
213                                if("springgreen".equals(strColor)) return new Color(0x00,0xFF,0x7F); 
214                                if("steelblue".equals(strColor)) return new Color(0x46,0x82,0xB4);
215                        break;
216                        case 't':
217                                if("teal".equals(strColor))             return new Color(0,0X80,0X80);
218                                if("tan".equals(strColor)) return new Color(0xD2,0xB4,0x8C); 
219                                if("thistle".equals(strColor)) return new Color(0xD8,0xBF,0xD8);
220                                if("tomato".equals(strColor)) return new Color(0xFF,0x63,0x47);
221                                if("turquoise".equals(strColor)) return new Color(0x40,0xE0,0xD0); 
222                                //if("".equals(strColor)) return new Color(0x,0x,0x);
223                        break;
224                        case 'v': 
225                                if("violet".equals(strColor)) return new Color(0xEE,0x82,0xEE);
226                        break;
227                        case 'w':
228                                if("white".equals(strColor))            return Color.WHITE;  
229                                if("wheat".equals(strColor)) return new Color(0xF5,0xDE,0xB3); 
230                                if("whitesmoke".equals(strColor)) return new Color(0xF5,0xF5,0xF5);
231                        break;
232                        case 'y':
233                                if("yellow".equals(strColor))           return Color.YELLOW;  
234                                if("yellowgreen".equals(strColor)) return new Color(0x9A,0xCD,0x32);
235                        break;
236                }
237
238                
239                if(first=='#') {
240                        String strColor2 = strColor.substring(1);
241                        // #fff
242                        if(strColor2.length()==3) {
243                                char c1=strColor2.charAt(0);
244                                char c2=strColor2.charAt(1);
245                                char c3=strColor2.charAt(2);
246                                return new Color(NumberUtil.hexToInt(""+c1+c1),NumberUtil.hexToInt(""+c2+c2),NumberUtil.hexToInt(""+c3+c3));
247                        }
248                        // #ffffff
249                        if(strColor2.length()==6) {
250                                String s1=strColor2.substring(0,2);
251                                String s2=strColor2.substring(2,4);
252                                String s3=strColor2.substring(4,6);
253                                return new Color(NumberUtil.hexToInt(s1),NumberUtil.hexToInt(s2),NumberUtil.hexToInt(s3));
254                        }
255                        // #ffffffff
256                        if(strColor2.length()==8) {
257                                String s1=strColor2.substring(0,2);
258                                String s2=strColor2.substring(2,4);
259                                String s3=strColor2.substring(4,6);
260                                String s4=strColor2.substring(6,8);
261                                return new Color(NumberUtil.hexToInt(s1),NumberUtil.hexToInt(s2),NumberUtil.hexToInt(s3),NumberUtil.hexToInt(s4));
262                        }
263                }
264                
265                // rgb(255,0,0)
266                if(strColor.startsWith("rgb(") && strColor.endsWith(")")) {
267                        String strColor2 = strColor.substring(4,strColor.length()-1).trim();
268                        String[] arr = ListUtil.listToStringArray(strColor2,',');
269                        if(arr.length==3) {
270                                int i1 = Caster.toIntValue(arr[0]);
271                                int i2 = Caster.toIntValue(arr[1]);
272                                int i3 = Caster.toIntValue(arr[2]);
273                                return new Color(i1,i2,i3);
274                        }
275                }
276                
277                
278                
279
280                // fff
281                if(strColor.length()==3) {
282                        char c1=strColor.charAt(0);
283                        char c2=strColor.charAt(1);
284                        char c3=strColor.charAt(2);
285                        int i1=NumberUtil.hexToInt(""+c1+c1,-1);
286                        int i2=NumberUtil.hexToInt(""+c2+c2,-1);
287                        int i3=NumberUtil.hexToInt(""+c3+c3,-1);
288                        if(i1!=-1 && i2!=-1 && i3!=-1) return new Color(i1,i2,i3);
289                }
290                // ffffff
291                else if(strColor.length()==6) {
292                        String s1=strColor.substring(0,2);
293                        String s2=strColor.substring(2,4);
294                        String s3=strColor.substring(4,6);
295                        int i1=NumberUtil.hexToInt(s1,-1);
296                        int i2=NumberUtil.hexToInt(s2,-1);
297                        int i3=NumberUtil.hexToInt(s3,-1);
298                        if(i1!=-1 && i2!=-1 && i3!=-1) return new Color(i1,i2,i3);
299                }
300                // ffffffff
301                else if(strColor.length()==8) {
302                        String s1=strColor.substring(0,2);
303                        String s2=strColor.substring(2,4);
304                        String s3=strColor.substring(4,6);
305                        String s4=strColor.substring(6,8);
306                        int i1=NumberUtil.hexToInt(s1,-1);
307                        int i2=NumberUtil.hexToInt(s2,-1);
308                        int i3=NumberUtil.hexToInt(s3,-1);
309                        int i4=NumberUtil.hexToInt(s4,-1);
310                        if(i1!=-1 && i2!=-1 && i3!=-1 && i4!=-1) return new Color(i1,i2,i3,i4);
311                }
312                
313                // 255,0,0
314                String[] arr = ListUtil.listToStringArray(strColor, ',');
315                if(arr.length==3){
316                        int i1 = Caster.toIntValue(arr[0],-1);
317                        int i2 = Caster.toIntValue(arr[1],-1);
318                        int i3 = Caster.toIntValue(arr[2],-1);
319                        if(i1>-1 && i2>-1 && i3>-1) return new Color(i1,i2,i3);
320                }
321                
322                
323                throw new ExpressionException("invalid color definition ["+strColor+"]",
324                                "color must be a know constant label (blue,green,yellow ...), a hexadecimal value (#ffffff) or a RGB value (rgb(255,255,255)), 255,255,255");
325        }
326    /*private static int hexToInt(String s, boolean throwException) throws ExpressionException {
327        int[] n = new int[s.length()];
328        char c;
329        int sum = 0;
330        int koef = 1;
331        for(int i=n.length-1; i>=0; i--) {
332            c = s.charAt(i);
333            
334            if(!((c>='0' && c<='9') || (c>='a' && c<='f'))) {
335                if(!throwException) return -1;
336                throw new ExpressionException("invalid hex constant ["+c+"], hex constants are [0-9,a-f]");
337            }
338                
339            //System.out.println(c);
340            switch (c) {
341                case 48:
342                    n[i] = 0;
343                    break;
344                case 49:
345                    n[i] = 1;
346                    break;
347                case 50:
348                    n[i] = 2;
349                    break;
350                case 51:
351                    n[i] = 3;
352                    break;
353                case 52:
354                    n[i] = 4;
355                    break;
356                case 53:
357                    n[i] = 5;
358                    break;
359                case 54:
360                    n[i] = 6;
361                    break;
362                case 55:
363                    n[i] = 7;
364                    break;
365                case 56:
366                    n[i] = 8;
367                    break;
368                case 57:
369                    n[i] = 9;
370                    break;                      
371                case 97:
372                    n[i] = 10;
373                    break;
374                case 98:
375                    n[i] = 11;
376                    break;
377                case 99:
378                    n[i] = 12;
379                    break;
380                case 100:
381                    n[i] = 13;
382                    break;
383                case 101:
384                    n[i] = 14;
385                    break;
386                case 102:
387                    n[i] = 15;
388                    break;
389            }
390            
391            sum = sum + n[i]*koef;
392            koef=koef*16;
393        }
394        return sum;
395    } */
396    
397    public static void main(String[] args) throws ExpressionException {
398        System.out.println(toColor("White"));
399        System.out.println(toColor("#fff"));
400        System.out.println(toColor("#ffffff"));
401        System.out.println(toColor("#ffffffff"));
402        System.out.println(toColor("fff"));
403        System.out.println(toColor("ffffff"));
404        System.out.println(toColor("rgb(255,255,255)"));
405        }
406
407        public static String toHexString(Color color) {
408                return "#"+toHexString(color.getRed())+
409                                toHexString(color.getGreen())+
410                                toHexString(color.getBlue());
411                
412        }
413        private static String toHexString(int clr) {
414                String str = Integer.toHexString(clr);
415                if(str.length()==1)return "0"+str;
416                return str;
417        }
418
419}