001 package railo.runtime.tag; 002 003 import java.io.IOException; 004 005 import railo.commons.digest.MD5; 006 import railo.commons.io.IOUtil; 007 import railo.commons.io.res.Resource; 008 import railo.commons.io.res.util.ResourceUtil; 009 import railo.commons.lang.StringUtil; 010 import railo.runtime.PageContextImpl; 011 import railo.runtime.PageSource; 012 import railo.runtime.exp.PageException; 013 import railo.runtime.ext.tag.TagImpl; 014 import railo.runtime.functions.image.ImageNew; 015 import railo.runtime.functions.image.ImageWrite; 016 import railo.runtime.img.Image; 017 import railo.runtime.op.Caster; 018 import railo.runtime.type.util.ListUtil; 019 020 public final class Sprite extends TagImpl { 021 022 private String _id; 023 private String _ids; 024 private String _srcs; 025 026 String src; 027 028 029 030 @Override 031 public void release() { 032 this._id=null; 033 this._ids=null; 034 this.src=null; 035 this._srcs=null; 036 super.release(); 037 } 038 039 040 041 public void set_ids(String _ids){ 042 this._ids=_ids; 043 } 044 045 public void set_id(String _id){ 046 this._id=_id; 047 } 048 049 public void set_srcs(String _srcs){ 050 this._srcs=_srcs; 051 } 052 053 public void setSrc(String src){ 054 this.src=src; 055 } 056 057 @Override 058 059 public int doStartTag() throws PageException { 060 try { 061 return _doStartTag(); 062 } catch (Throwable e) { 063 throw Caster.toPageException(e); 064 } 065 } 066 067 068 public int _doStartTag() throws Throwable { 069 070 // write out div for single item 071 pageContext.write("<div id=\""+_id+"\"></div>"); 072 073 074 075 076 077 078 // handle all items 079 if(!StringUtil.isEmpty(_ids)) { 080 String[] ids=ListUtil.listToStringArray(_ids, ','); 081 String[] strSrcs=ListUtil.listToStringArray(_srcs, ','); 082 Resource[] srcs=new Resource[strSrcs.length]; 083 Image[] images=new Image[strSrcs.length]; 084 for(int i=0;i<srcs.length;i++){ 085 srcs[i]=ResourceUtil.toResourceExisting(pageContext, strSrcs[i]); 086 images[i] = new Image(srcs[i]); 087 } 088 089 // TODO use the same resource as for cfimage 090 PageSource ps = pageContext.getCurrentTemplatePageSource(); 091 Resource curr = ps.getResource(); 092 Resource dir = curr.getParentResource(); 093 Resource cssDir = dir.getRealResource("css"); 094 Resource pathdir = cssDir; 095 cssDir.mkdirs(); 096 097 098 //the base name for the files we are going to create as a css and image 099 String baseRenderedFileName = MD5.getDigestAsString(_ids); 100 Resource cssFileName = cssDir.getRealResource(baseRenderedFileName+".css"); 101 Resource imgFileName = pathdir.getRealResource(baseRenderedFileName+"."+ResourceUtil.getExtension(src,"")); 102 103 //if the files don't exist, then we create them, otherwise 104 boolean bCreate = !cssFileName.isFile() || !imgFileName.isFile(); 105 106 107 //Are we going to create it, let's say no 108 String css = ""; 109 if(bCreate){ 110 int imgMaxHeight = 0; 111 int imgMaxWidth = 0; 112 Image img; 113 int actualWidth,actualHeight; 114 //Setup the max height and width of the new image. 115 for(int i=0;i<srcs.length;i++){ 116 img = images[i]; 117 118 //set the image original height and width 119 actualWidth = img.getWidth();; 120 actualHeight = img.getHeight(); 121 122 123 124 //Check if there is a height, 125 imgMaxHeight += actualHeight; 126 if(actualWidth > imgMaxWidth) imgMaxWidth = actualWidth; 127 } 128 129 //Create the new image (hence we needed to do two of these items) 130 Image spriteImage = (Image) ImageNew.call(pageContext,"", ""+imgMaxWidth,""+imgMaxHeight, "argb"); 131 132 int placedHeight = 0; 133 //Loop again but this time, lets do the copy and paste 134 for(int i=0;i<srcs.length;i++){ 135 img = images[i]; 136 spriteImage.paste(img,1,placedHeight); 137 138 css += "#"+ids[i]+" {\n\tbackground: url("+baseRenderedFileName+"."+ResourceUtil.getExtension(strSrcs[i],"")+") 0px -"+placedHeight+"px no-repeat; width:"+img.getWidth()+"px; height:"+img.getHeight()+"px;\n} \n"; 139 placedHeight += img.getHeight(); 140 } 141 142 //Now Write the CSS and the Sprite Image 143 144 ImageWrite.call(pageContext, spriteImage, imgFileName.getAbsolutePath()); 145 IOUtil.write(cssFileName, css,"UTF-8",false); 146 147 } 148 149 150 //pageContext.write("<style>"+css+"</style>"); 151 152 try { 153 ((PageContextImpl)pageContext).getRootOut() 154 .appendHTMLHead("<link rel=\"stylesheet\" href=\"css/"+baseRenderedFileName+".css\" type=\"text/css\" media=\"screen\" title=\"no title\" charset=\"utf-8\">"); 155 } catch (IOException e) { 156 Caster.toPageException(e); 157 } 158 159 } 160 161 162 163 164 return SKIP_BODY; 165 } 166 167 168 169 @Override 170 public int doEndTag() { 171 return EVAL_PAGE; 172 } 173 }