1 package com.dotmarketing.servlets.image; 2 3 import java.awt.Color ; 4 import java.awt.Font ; 5 import java.awt.Graphics2D ; 6 import java.awt.RenderingHints ; 7 import java.awt.font.FontRenderContext ; 8 import java.awt.geom.Rectangle2D ; 9 import java.awt.image.BufferedImage ; 10 import java.io.BufferedInputStream ; 11 import java.io.BufferedOutputStream ; 12 import java.io.File ; 13 import java.io.FileInputStream ; 14 import java.io.FileOutputStream ; 15 import java.io.IOException ; 16 import java.io.OutputStream ; 17 import java.io.PrintWriter ; 18 import java.net.URLDecoder ; 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.Map ; 22 import java.util.StringTokenizer ; 23 24 import javax.imageio.ImageIO ; 25 import javax.servlet.ServletConfig ; 26 import javax.servlet.ServletContext ; 27 import javax.servlet.ServletException ; 28 import javax.servlet.http.HttpServlet ; 29 import javax.servlet.http.HttpServletRequest ; 30 import javax.servlet.http.HttpServletResponse ; 31 32 import org.apache.commons.logging.LogFactory; 33 34 import com.dotmarketing.cms.factories.PublicEncryptionFactory; 35 import com.dotmarketing.util.Config; 36 import com.dotmarketing.util.UtilMethods; 37 38 public class TitleImage extends HttpServlet { 39 40 43 private static final long serialVersionUID = 1L; 44 private static HashMap hm = new HashMap (); 45 private static ServletContext ctx; 46 47 52 public void init(ServletConfig config) throws ServletException { 53 54 ctx = config.getServletContext(); 55 56 hm.put("&sp;", "%20"); 57 hm.put("!", "%21"); 58 hm.put(""", "%22"); 59 hm.put("#", "%23"); 60 hm.put("$", "%24"); 61 hm.put("%", "%25"); 62 hm.put("&", "%26"); 63 hm.put("'", "%27"); 64 hm.put("(", "%28"); 65 hm.put(")", "%29"); 66 hm.put("*", "%2A"); 67 hm.put("+", "%2B"); 68 hm.put(",", "%2C"); 69 hm.put("‐", "%2D"); 70 hm.put("−", "%2D"); 71 hm.put(".", "%2E"); 72 hm.put("/", "%2F"); 73 hm.put(":", "%3A"); 74 hm.put(";", "%3B"); 75 hm.put("<", "%3C"); 76 hm.put("=", "%3D"); 77 hm.put(">", "%3E"); 78 hm.put("?", "%3F"); 79 hm.put("@", "%40"); 80 hm.put("[", "%5B"); 81 hm.put("\", "%5C"); 82 hm.put("]", "%5D"); 83 hm.put("ˆ", "%5E"); 84 hm.put("_", "%5F"); 85 hm.put("―", "%5F"); 86 hm.put("`", "%60"); 87 hm.put("{", "%7B"); 88 hm.put("|", "%7C"); 89 hm.put("}", "%7D"); 90 hm.put("˜", "%7E"); 91 hm.put("‚", "%82"); 92 hm.put("ƒ", "%83"); 93 hm.put("„", "%84"); 94 hm.put("…", "%85"); 95 hm.put("&ldots;", "%85"); 96 hm.put("†", "%86"); 97 hm.put("‡", "%87"); 98 hm.put("‰", "%89"); 99 hm.put("Š", "%8A"); 100 hm.put("‹", "%8B"); 101 hm.put("Œ", "%8C"); 102 hm.put("‘", "%91"); 103 hm.put("’", "%91"); 104 hm.put("’", "%92"); 105 hm.put("“", "%93"); 106 hm.put("”", "%93"); 107 hm.put("”", "%94"); 108 hm.put("•", "%95"); 109 hm.put("–", "%96"); 110 hm.put("&endash;", "%96"); 111 hm.put("—", "%97"); 112 hm.put("&emdash;", "%97"); 113 hm.put("˜", "%98"); 114 hm.put("™", "%99"); 115 hm.put("š", "%9A"); 116 hm.put("›", "%9B"); 117 hm.put("œ", "%9C"); 118 hm.put("Ÿ", "%9F"); 119 hm.put(" ", "%A0"); 120 hm.put("¡", "%a1"); 121 hm.put("¢", "%A2"); 122 hm.put("£", "%A3"); 123 hm.put("¤", "%A4"); 124 hm.put("¥", "%A5"); 125 hm.put("¦", "%A6"); 126 hm.put("&brkbar;", "%A6"); 127 hm.put("§", "%A7"); 128 hm.put("¨", "%A8"); 129 hm.put("¨", "%A8"); 130 hm.put("©", "%A9"); 131 hm.put("ª", "%AA"); 132 hm.put("«", "%AB"); 133 hm.put("¬", "%AC"); 134 hm.put("­", "%AD"); 135 hm.put("®", "%AE"); 136 hm.put("¯", "%AF"); 137 hm.put("&hibar;", "%AF"); 138 hm.put("°", "%B0"); 139 hm.put("±", "%B1"); 140 hm.put("²", "%B2"); 141 hm.put("³", "%B3"); 142 hm.put("´", "%B4"); 143 hm.put("µ", "%B5"); 144 hm.put("¶", "%B6"); 145 hm.put("·", "%B7"); 146 hm.put("¸", "%B8"); 147 hm.put("¹", "%B9"); 148 hm.put("º", "%BA"); 149 hm.put("»", "%BB"); 150 hm.put("¼", "%BC"); 151 hm.put("½", "%BD"); 152 hm.put("½", "%BD"); 153 hm.put("¾", "%BE"); 154 hm.put("¿", "%BF"); 155 hm.put("À", "%C0"); 156 hm.put("Á", "%C1"); 157 hm.put("Â", "%C2"); 158 hm.put("Ã", "%C3"); 159 hm.put("Ä", "%C4"); 160 hm.put("Å", "%C5"); 161 hm.put("Æ", "%C6"); 162 hm.put("Ç", "%C7"); 163 hm.put("È", "%C8"); 164 hm.put("É", "%C9"); 165 hm.put("Ê", "%CA"); 166 hm.put("Ë", "%CB"); 167 hm.put("Ì", "%CC"); 168 hm.put("Í", "%CD"); 169 hm.put("Î", "%CE"); 170 hm.put("Ï", "%CF"); 171 hm.put("Ð", "%D0"); 172 hm.put("Ñ", "%D1"); 173 hm.put("Ò", "%D2"); 174 hm.put("Ó", "%D3"); 175 hm.put("Ô", "%D4"); 176 hm.put("Õ", "%D5"); 177 hm.put("Ö", "%D6"); 178 hm.put("×", "%D7"); 179 hm.put("Ø", "%D8"); 180 hm.put("Ù", "%D9"); 181 hm.put("Ú", "%DA"); 182 hm.put("Û", "%DB"); 183 hm.put("Ü", "%DC"); 184 hm.put("Ý", "%DD"); 185 hm.put("Þ", "%DE"); 186 hm.put("ß", "%DF"); 187 hm.put("à", "%E0"); 188 hm.put("á", "%E1"); 189 hm.put("â", "%E2"); 190 hm.put("ã", "%E3"); 191 hm.put("ä", "%E4"); 192 hm.put("å", "%E5"); 193 hm.put("æ", "%E6"); 194 hm.put("ç", "%E7"); 195 hm.put("è", "%E8"); 196 hm.put("é", "%E9"); 197 hm.put("ê", "%EA"); 198 hm.put("ë", "%EB"); 199 hm.put("ì", "%EC"); 200 hm.put("í", "%ED"); 201 hm.put("î", "%EE"); 202 hm.put("ï", "%EF"); 203 hm.put("ð", "%F0"); 204 hm.put("ñ", "%F1"); 205 hm.put("ò", "%F2"); 206 hm.put("ó", "%F3"); 207 hm.put("ô", "%F4"); 208 hm.put("õ", "%F5"); 209 hm.put("ö", "%F6"); 210 hm.put("÷", "%F7"); 211 hm.put("ø", "%F8"); 212 hm.put("ù", "%F9"); 213 hm.put("ú", "%FA"); 214 hm.put("û", "%FB"); 215 hm.put("ü", "%FC"); 216 hm.put("ý", "%FD"); 217 hm.put("þ", "%FE"); 218 hm.put("ÿ", "%FF"); 219 220 File file = new File (config.getServletContext().getRealPath(Config.getStringProperty("PATH_TO_TITLE_IMAGES"))); 221 file.mkdirs(); 222 223 String [] filenames = file.list(); 225 226 for (int i = 0; i < filenames.length; i++) { 227 new File (config.getServletContext().getRealPath(Config.getStringProperty("PATH_TO_TITLE_IMAGES") + filenames[i])).delete(); 228 } 229 } 230 231 public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException , IOException { 232 long time = System.currentTimeMillis(); 233 234 String text = request.getParameter("text"); 235 String parsedQueryString = request.getQueryString(); 236 237 238 if (text == null) { 239 String [] fonts = new File (ctx.getRealPath("/WEB-INF/fonts/")).list(); 240 text = "accepted params: text,font,size,color,background,nocache,aa,break"; 241 response.setContentType("text/html"); 242 243 PrintWriter out = response.getWriter(); 244 out.println("<html>"); 245 out.println("<body>"); 246 out.println("<p>"); 247 out.println("Usage: " + request.getServletPath() + "?params[]<BR>"); 248 out.println("Acceptable Params are: <UL>"); 249 out.println("<LI><B>text</B><BR>"); 250 out.println("The body of the image"); 251 out.println("<LI><B>font</B><BR>"); 252 out.println("Available Fonts (in folder '/WEB-INF/fonts/') <UL>"); 253 254 for (int i = 0; i < fonts.length; i++) { 255 if (!"CVS".equals(fonts[i])) { 256 out.println("<LI>" + fonts[i]); 257 } 258 } 259 260 out.println("</UL>"); 261 262 out.println("<LI><B>size</B><BR>"); 263 out.println("An integer, i.e. size=100"); 264 out.println("<LI><B>color</B><BR>"); 265 out.println("in rgb, i.e. color=255,0,0"); 266 out.println("<LI><B>background</B><BR>"); 267 out.println("in rgb, i.e. background=0,0,255"); 268 out.println("<LI><B>aa</B><BR>"); 269 out.println("antialias (does not seem to work), aa=true"); 270 out.println("<LI><B>nocache</B><BR>"); 271 out.println("if nocache is set, we will write out the image file every hit. Otherwise, will write it the first time and then read the file"); 272 out.println("<LI><B>break</B><BR>"); 273 out.println("An integer greater than 0 (zero), i.e. break=20"); 274 out.println("</UL>"); 275 276 out.println("</UL>"); 277 278 out.println("Example:<BR>"); 279 out.println("<img border=1 SRC=\"" + request.getServletPath() 280 + "?font=arial.ttf&text=testing&color=255,0,0&size=100\"><BR>"); 281 out.println("<img border=1 SRC='" + request.getServletPath() 282 + "?font=arial.ttf&text=testing&color=255,0,0&size=100'><BR>"); 283 284 out.println("</body>"); 285 out.println("</html>"); 286 287 return; 288 } 289 290 String myFile = (request.getQueryString() == null) ? "empty" : PublicEncryptionFactory.digestString( 293 parsedQueryString).replace('\\', '_').replace('/', '_'); 294 parsedQueryString = URLDecoder.decode(parsedQueryString, "ISO-8859-1"); 295 296 297 myFile = Config.getStringProperty("PATH_TO_TITLE_IMAGES") + myFile + ".png"; 298 File file = new File (ctx.getRealPath(myFile)); 299 300 if (!file.exists() || (request.getParameter("nocache") != null)) { 302 StringTokenizer st = null; 303 Iterator i = hm.entrySet().iterator(); 305 while (i.hasNext()) { 306 Map.Entry entry = (Map.Entry ) i.next(); 307 String key = (String ) entry.getKey(); 308 if (parsedQueryString.indexOf(key) > -1) { 309 String val = (String ) entry.getValue(); 310 parsedQueryString = UtilMethods.replace(parsedQueryString, key, val); 311 } 312 } 313 314 st = new StringTokenizer (parsedQueryString, "&"); 316 while (st.hasMoreTokens()) { 317 try { 318 String x = st.nextToken(); 319 String key = x.split("=")[0]; 320 String val = x.split("=")[1]; 321 322 if ("text".equals(key)) { 323 text = val; 324 } 325 } catch (Exception e) { 326 327 } 328 } 329 text = URLDecoder.decode(text, "ISO-8859-1"); 330 331 LogFactory.getLog(this.getClass()).info("building title image:" + file.getAbsolutePath()); 332 file.createNewFile(); 333 334 try { 335 String font_file = "/WEB-INF/fonts/arial.ttf"; 338 339 if (request.getParameter("font") != null) { 340 font_file = "/WEB-INF/fonts/" + request.getParameter("font"); 341 } 342 343 font_file = ctx.getRealPath(font_file); 344 345 float size = 20.0f; 346 347 if (request.getParameter("size") != null) { 348 size = Float.parseFloat(request.getParameter("size")); 349 } 350 351 Color background = Color.white; 352 353 if (request.getParameter("background") != null) { 354 try { 355 st = new StringTokenizer (request.getParameter("background"), ","); 356 int x = Integer.parseInt(st.nextToken()); 357 int y = Integer.parseInt(st.nextToken()); 358 int z = Integer.parseInt(st.nextToken()); 359 background = new Color (x, y, z); 360 } catch (Exception e) { 361 } 362 } 363 364 Color color = Color.black; 365 366 if (request.getParameter("color") != null) { 367 try { 368 st = new StringTokenizer (request.getParameter("color"), ","); 369 int x = Integer.parseInt(st.nextToken()); 370 int y = Integer.parseInt(st.nextToken()); 371 int z = Integer.parseInt(st.nextToken()); 372 color = new Color (x, y, z); 373 } catch (Exception e) { 374 System.out.println(e); 375 } 376 } 377 378 int intBreak = 0; 379 if (request.getParameter("break") != null) { 380 try { 381 intBreak = Integer.parseInt(request.getParameter("break")); 382 } catch (Exception e) { 383 } 384 } 385 386 java.util.ArrayList <String > lines = null; 387 388 if (intBreak > 0) { 389 lines = new java.util.ArrayList <String >(10); 390 lines.ensureCapacity(10); 391 392 int start = 0; 393 String line = null; 394 int offSet; 395 396 for (;;) { 397 try { 398 for (; isWhitespace(text.charAt(start)); ++start); 399 400 if (isWhitespace(text.charAt(start+intBreak-1))) { 401 lines.add(text.substring(start, start+intBreak)); 402 start += intBreak; 403 } else { 404 for (offSet = -1; !isWhitespace(text.charAt(start+intBreak+offSet)); ++offSet); 405 lines.add(text.substring(start, start+intBreak+offSet)); 406 start += intBreak+offSet; 407 } 408 } catch (Exception e) { 409 if (text.length() > start) 410 lines.add(leftTrim(text.substring(start))); 411 break; 412 } 413 } 414 } else { 415 java.util.StringTokenizer tokens = new java.util.StringTokenizer (text, "|"); 416 417 if (tokens.hasMoreTokens()) { 418 lines = new java.util.ArrayList <String >(10); 419 lines.ensureCapacity(10); 420 421 for (; tokens.hasMoreTokens();) 422 lines.add(leftTrim(tokens.nextToken())); 423 } 424 } 425 426 Font font = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream (font_file)); 427 font = font.deriveFont(size); 428 429 BufferedImage buffer = new BufferedImage (1, 1, BufferedImage.TYPE_INT_RGB); 430 Graphics2D g2 = buffer.createGraphics(); 431 432 if (request.getParameter("aa") != null) { 433 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 434 } else { 435 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); 436 } 437 438 FontRenderContext fc = g2.getFontRenderContext(); 439 440 Rectangle2D bounds = null; 441 442 444 int width = 0; 445 int height = 0; 446 int offSet = 0; 447 if (1 < lines.size()) { 448 449 int heightMultiplier = 0; 450 int maxWidth = 0; 451 for (; heightMultiplier < lines.size(); ++heightMultiplier) { 452 bounds = font.getStringBounds(lines.get(heightMultiplier), fc); 453 if (maxWidth < bounds.getWidth()) 454 maxWidth = (int) bounds.getWidth(); 455 } 456 457 width = maxWidth; 458 height = ((int) bounds.getHeight())*lines.size(); 459 offSet = ((int) (bounds.getHeight()*0.2))*(lines.size()-1); 460 } else { 461 bounds = font.getStringBounds(text, fc); 462 width = (int) bounds.getWidth(); 463 height = (int) bounds.getHeight(); 464 } 465 466 buffer = new BufferedImage (width, height-offSet, BufferedImage.TYPE_INT_RGB); 468 g2 = buffer.createGraphics(); 469 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 470 g2.setFont(font); 471 472 g2.setColor(background); 474 g2.fillRect(0, 0, width, height); 475 g2.setColor(color); 476 477 if (0 < lines.size()) { 478 for (int numLine = 0; numLine < lines.size(); ++numLine) 479 g2.drawString(lines.get(numLine), 0, (int) -bounds.getY()*(numLine+1)); 480 } else { 481 g2.drawString(text, 0, (int) -bounds.getY()); 482 } 483 484 BufferedOutputStream out = new BufferedOutputStream (new FileOutputStream (file)); 485 486 ImageIO.write(buffer, "png", out); 488 out.close(); 489 } catch (Exception ex) { 490 System.out.println(ex); 491 } 492 } 493 494 response.setContentType("image/png"); 496 497 BufferedInputStream bis = new BufferedInputStream (new FileInputStream (file)); 498 OutputStream os = response.getOutputStream(); 499 byte[] buf = new byte[4096]; 500 int i = 0; 501 502 while ((i = bis.read(buf)) != -1) { 503 os.write(buf, 0, i); 504 } 505 506 os.close(); 507 bis.close(); 508 LogFactory.getLog(this.getClass()).debug("time to build title: " + (System.currentTimeMillis() - time) + "ms"); 509 510 return; 511 } 512 513 520 private boolean isWhitespace(char c) { 521 int ic = (int) c; 522 char temp = '\u0020'; 523 int itemp = (int) temp; 524 return (((int) c) <= ((int) '\u0020')); 525 } 526 527 534 private String leftTrim(String string) { 535 int i = 0; 536 for (; i < string.length(); ++i) { 537 if (!isWhitespace(string.charAt(i))) 538 break; 539 } 540 return string.substring(i); 541 } 542 543 } | Popular Tags |