/* coded by Kae - kae@verens.com I'd appreciate any feedback. You have the right to include this in your sites. Please retain this notice. This source has elements coded by Dean Edwards - please read his notices before copying */ getCss_done=0; getCss_leftToDo=0; getCss_rules=[]; getCss_text=''; function getCss(){ var els,i; getCss_done=1; // get external stylesheets els=document.getElementsByTagName('link'); for(i=0;i1)?parts3[0]+' '+parts3[1]:parts3[0]+' '+parts3[0]; getCss_rules[a][1]['border-top-right-radius']=m; getCss_rules[a][1]['border-top-left-radius']=m; getCss_rules[a][1]['border-bottom-right-radius']=m; getCss_rules[a][1]['border-bottom-left-radius']=m; break; case 'border-top-right-radius': m=(parts3L>1)?parts3[0]+' '+parts3[1]:parts3[0]+' '+parts3[0]; getCss_rules[a][1]['border-top-right-radius']=m; break; case 'border-top-left-radius': m=(parts3L>1)?parts3[0]+' '+parts3[1]:parts3[0]+' '+parts3[0]; getCss_rules[a][1]['border-top-left-radius']=m; break; case 'border-bottom-right-radius': m=(parts3L>1)?parts3[0]+' '+parts3[1]:parts3[0]+' '+parts3[0]; getCss_rules[a][1]['border-bottom-right-radius']=m; break; case 'border-bottom-left-radius': m=(parts3L>1)?parts3[0]+' '+parts3[1]:parts3[0]+' '+parts3[0]; getCss_rules[a][1]['border-bottom-left-radius']=m; break; case 'border-width': getCss_rules[a][1]['border-top-width']=parts3[0]; getCss_rules[a][1]['border-right-width']=parts3L>1?parts3[1]:parts3[0]; getCss_rules[a][1]['border-bottom-width']=parts3L>2?parts3[2]:parts3[0]; getCss_rules[a][1]['border-left-width']=parts3L>3?parts3[3]:(parts3L>1?parts3[1]:parts3[0]); break; default: getCss_rules[a][1][parts2[0]]=parts2[1]; } } } } if(window.addEventListener){ window.addEventListener('load',borderRadius,false); window.addEventListener('resize',borderRadius,false); }else if(window.attachEvent){ window.attachEvent('onload',borderRadius); window.attachEvent('onresize',borderRadius); } function borderRadius(){ if(getCss_done)borderRadius_generateCurves(); else{ getCss(); borderRadius_waitForCss(); } } function borderRadius_waitForCss(){ if(!getCss_done)setTimeout('borderRadius_waitForCss()',200); else borderRadius_generateCurves(); } function borderRadius_generateCurves(){ var i; for(i=0;i\+~\s]/; var STREAM = /[\s>\+~:@#\.]|[^\s>\+~:@#\.]+/g; var NAMESPACE = /\|/; var IMPLIED_SELECTOR = /([\s>\+~\,]|^)([\.:#@])/g; var ASTERISK ="$1*$2"; var WHITESPACE = /^\s+|\s*([\+\,>\s;:])\s*|\s+$/g; var TRIM = "$1"; var NODE_ELEMENT = 1; var NODE_TEXT = 3; var NODE_DOCUMENT = 9; // sniff for explorer (cos of one little bug) var isMSIE = /MSIE/.test(navigator.appVersion), isXML; // cache results for faster processing var cssCache = {}; // this is the query function function cssQuery(selector, from) { if (!selector) return []; var useCache = arguments.callee.caching && !from; from = (from) ? (from.constructor == Array) ? from : [from] : [document]; isXML = checkXML(from[0]); // process comma separated selectors var selectors = parseSelector(selector).split(","); var match = []; for (var i in selectors) { // convert the selector to a stream selector = toStream(selectors[i]); // process the stream var j = 0, token, filter, cacheSelector = "", filtered = from; while (j < selector.length) { token = selector[j++]; filter = selector[j++]; cacheSelector += token + filter; // process a token/filter pair filtered = (useCache && cssCache[cacheSelector]) ? cssCache[cacheSelector] : select(filtered, token, filter); if (useCache) cssCache[cacheSelector] = filtered; } match = match.concat(filtered); } // return the filtered selection return match; }; cssQuery.caching = false; cssQuery.reset = function() { cssCache = {}; }; cssQuery.toString = function () { return "function cssQuery() {\n [version " + version + "]\n}"; }; var checkXML = (isMSIE) ? function(node) { if (node.nodeType != NODE_DOCUMENT) node = node.document; return node.mimeType == "XML Document"; } : function(node) { if (node.nodeType == NODE_DOCUMENT) node = node.documentElement; return node.localName != "HTML"; }; function parseSelector(selector) { return selector // trim whitespace .replace(WHITESPACE, TRIM) // encode attribute selectors .replace(attributeSelector.ALL, attributeSelector.ID) // e.g. ".class1" --> "*.class1" .replace(IMPLIED_SELECTOR, ASTERISK); }; // convert css selectors to a stream of tokens and filters // it's not a real stream. it's just an array of strings. function toStream(selector) { if (STANDARD_SELECT.test(selector)) selector = " " + selector; return selector.match(STREAM) || []; }; var pseudoClasses = { // static // CSS1 "link": function(element) { for (var i = 0; i < document.links; i++) { if (document.links[i] == element) return true; } }, "visited": function(element) { // can't do this without jiggery-pokery }, // CSS2 "first-child": function(element) { return !previousElement(element); }, // CSS3 "last-child": function(element) { return !nextElement(element); }, "root": function(element) { var document = element.ownerDocument || element.document; return Boolean(element == document.documentElement); }, "empty": function(element) { for (var i = 0; i < element.childNodes.length; i++) { if (isElement(element.childNodes[i]) || element.childNodes[i].nodeType == NODE_TEXT) return false; } return true; } // add your own... }; var QUOTED = /([\'\"])[^\1]*\1/; function quote(value) {return (QUOTED.test(value)) ? value : "'" + value + "'"}; function unquote(value) {return (QUOTED.test(value)) ? value.slice(1, -1) : value}; var attributeSelectors = []; function attributeSelector(attribute, compare, value) { // properties this.id = attributeSelectors.length; // build the test expression var test = "element."; switch (attribute.toLowerCase()) { case "id": test += "id"; break; case "class": test += "className"; break; default: test += "getAttribute('" + attribute + "')"; } // continue building the test expression switch (compare) { case "=": test += "==" + quote(value); break; case "~=": test = "/(^|\\s)" + unquote(value) + "(\\s|$)/.test(" + test + ")"; break; case "|=": test = "/(^|-)" + unquote(value) + "(-|$)/.test(" + test + ")"; break; } push(attributeSelectors, new Function("element", "return " + test)); }; attributeSelector.prototype.toString = function() { return attributeSelector.PREFIX + this.id; }; // constants attributeSelector.PREFIX = "@"; attributeSelector.ALL = /\[([^~|=\]]+)([~|]?=?)([^\]]+)?\]/g; // class methods attributeSelector.ID = function(match, attribute, compare, value) { return new attributeSelector(attribute, compare, value); }; // select a set of matching elements. // "from" is an array of elements. // "token" is a character representing the type of filter // e.g. ">" means child selector // "filter" represents the tag name, id or class name that is being selected // the function returns an array of matching elements function select(from, token, filter) { var namespace = ""; if (NAMESPACE.test(filter)) { filter = filter.split("|"); namespace = filter[0]; filter = filter[1]; } var filtered = [], i; switch (token) { case " ": // descendant for (i in from) { var subset = getElementsByTagNameNS(from[i], filter, namespace); for (var j = 0; j < subset.length; j++) { if (isElement(subset[j]) && (!namespace || compareNamespace(subset[j], namespace))) push(filtered, subset[j]); } } break; case ">": // child for (i in from) { var subset = from[i].childNodes; for (var j = 0; j < subset.length; j++) if (compareTagName(subset[j], filter, namespace)) push(filtered, subset[j]); } break; case "+": // adjacent (direct) for (i in from) { var adjacent = nextElement(from[i]); if (adjacent && compareTagName(adjacent, filter, namespace)) push(filtered, adjacent); } break; case "~": // adjacent (indirect) for (i in from) { var adjacent = from[i]; while (adjacent = nextElement(adjacent)) { if (adjacent && compareTagName(adjacent, filter, namespace)) push(filtered, adjacent); } } break; case ".": // class filter = new RegExp("(^|\\s)" + filter + "(\\s|$)"); for (i in from) if (filter.test(from[i].className)) push(filtered, from[i]); break; case "#": // id for (i in from) if (from[i].id == filter) push(filtered, from[i]); break; case "@": // attribute selector filter = attributeSelectors[filter]; for (i in from) if (filter(from[i])) push(filtered, from[i]); break; case ":": // pseudo-class (static) filter = pseudoClasses[filter]; for (i in from) if (filter(from[i])) push(filtered, from[i]); break; } return filtered; }; var getElementsByTagNameNS = (isMSIE) ? function(from, tagName) { return (tagName == "*" && from.all) ? from.all : from.getElementsByTagName(tagName); } : function(from, tagName, namespace) { return (namespace) ? from.getElementsByTagNameNS("*", tagName) : from.getElementsByTagName(tagName); }; function compareTagName(element, tagName, namespace) { if (namespace && !compareNamespace(element, namespace)) return false; return (tagName == "*") ? isElement(element) : (isXML) ? (element.tagName == tagName) : (element.tagName == tagName.toUpperCase()); }; var PREFIX = (isMSIE) ? "scopeName" : "prefix"; function compareNamespace(element, namespace) { return element[PREFIX] == namespace; }; // return the previous element to the supplied element // previousSibling is not good enough as it might return a text or comment node function previousElement(element) { while ((element = element.previousSibling) && !isElement(element)) continue; return element; }; // return the next element to the supplied element function nextElement(element) { while ((element = element.nextSibling) && !isElement(element)) continue; return element; }; function isElement(node) { return Boolean(node.nodeType == NODE_ELEMENT && node.tagName != "!"); }; // use a baby push function because IE5.0 doesn't support Array.push function push(array, item) { array[array.length] = item; }; // fix IE5.0 String.replace if ("i".replace(/i/,function(){return""})) { // preserve String.replace var string_replace = String.prototype.replace; // create String.replace for handling functions var function_replace = function(regexp, replacement) { var match, newString = "", string = this; while ((match = regexp.exec(string))) { // five string replacement arguments is sufficent for cssQuery newString += string.slice(0, match.index) + replacement(match[0], match[1], match[2], match[3], match[4]); string = string.slice(match.lastIndex); } return newString + string; }; // replace String.replace String.prototype.replace = function (regexp, replacement) { this.replace = (typeof replacement == "function") ? function_replace : string_replace; return this.replace(regexp, replacement); }; } return cssQuery; }(); $by){ $r=$by/$bx; for($i=0;$i<=$bx*2;$i++){ imagearc($img,$x,$y,($rx*2)-$i,($ry*2)-$r*$i,$s,$e,$c); } }else{ $r=$bx/$by; for($i=0;$i<=$by*2;$i++){ imagearc($img,$x,$y,($rx*2)-$r*$i,($ry*2)-$i,$s,$e,$c); } } } function getColour($img,$col){ # translates CSS colours into PHP $col=strtolower($col); if(substr($col,0,1)=='#'){ if(strlen($col)==4)$col='#'.substr($col,1,1).substr($col,1,1).substr($col,2,1).substr($col,2,1).substr($col,3,1).substr($col,3,1); $rgb=array(hexdec(substr($col,1,2)),hexdec(substr($col,3,2)),hexdec(substr($col,5,2))); }else{ switch($col){ case 'red': $rgb=array(255,0,0); break; default: $rgb=array(200,255,200); } } return imagecolorallocate($img,$rgb[0],$rgb[1],$rgb[2]); } if(ereg('png',$_SERVER['HTTP_ACCEPT'])) header('Content-type: image/png'); else header('Content-type: image/gif'); $x=$_GET['x']; $y=$_GET['y']; $backgroundColour=$_GET['background-color']; $backgroundImage=preg_replace('/url\("?\'?|"?\'?\)/','',$_GET['background-image']); $borderColour=explode(' ',$_GET['border-color']); $borderRadius=explode(',',$_GET['border-radius']); for($i=0;$i<4;$i++){ $p=explode(' ',$borderRadius[$i]); $borderRadius[$i]=array((int)$p[0],(int)$p[1]); } $borderWidth=explode(' ',$_GET['border-width']); for($i=0;$i<4;$i++){ $borderWidth[$i]=(int)$borderWidth[$i]; } $x1=0; $x2=0; $y1=0; $y2=0; $x1=($borderRadius[2][0]>$borderRadius[3][0])?$borderRadius[2][0]:$borderRadius[3][0]; $x2=($borderRadius[0][0]>$borderRadius[1][0])?$borderRadius[0][0]:$borderRadius[1][0]; $y1=($borderRadius[0][1]>$borderRadius[3][1])?$borderRadius[0][1]:$borderRadius[3][1]; $y2=($borderRadius[1][1]>$borderRadius[2][1])?$borderRadius[1][1]:$borderRadius[2][1]; # initialise image $img=imagecreatetruecolor($x,$y); $colour=getColour($img,$backgroundColour); imagefilledrectangle($img,0,0,$x,$y,$colour); # initialiase mask $mask=imagecreatetruecolor($x,$y); $transparent=imagecolorallocate($mask,0,0,1); imagefilledrectangle($mask,0,0,$x,$y,$transparent); $colour=getColour($mask,'#fff'); imagefilledrectangle($mask,$borderRadius[3][0],0,$x-$borderRadius[0][0],$borderWidth[0],$colour); imagefilledrectangle($mask,$x-$borderWidth[1]-1,$borderRadius[0][1],$x,$y-$borderRadius[1][1],$colour); imagefilledrectangle($mask,$borderRadius[2][0],$y-$borderWidth[2]-1,$x-$borderRadius[1][0],$y,$colour); imagefilledrectangle($mask,0,$borderRadius[3][1],$borderWidth[3],$y-$borderRadius[2][1],$colour); drawcorner($mask,$x-$borderRadius[0][0]-1,$borderRadius[0][1]-1,$borderRadius[0][0],$borderRadius[0][1],270,360,$colour,$borderWidth[1],$borderWidth[0]); drawcorner($mask,$x-$borderRadius[1][0]-1,$y-$borderRadius[1][1]-1,$borderRadius[1][0],$borderRadius[1][1],0,90,$colour,$borderWidth[1],$borderWidth[2]); drawcorner($mask,$borderRadius[2][0]-1,$y-$borderRadius[2][1]-1,$borderRadius[2][0],$borderRadius[2][1],90,180,$colour,$borderWidth[3],$borderWidth[2]); drawcorner($mask,$borderRadius[3][0]-1,$borderRadius[3][1]-1,$borderRadius[3][0],$borderRadius[3][1],180,270,$colour,$borderWidth[3],$borderWidth[0]); if($backgroundColour!='transparent')imagefilltoborder($mask,$x/2,$y/2,$colour,$colour); # if there's an image, then merge it if($backgroundImage!='none'){ $ext=strtolower(preg_replace('/.*\./','',$backgroundImage)); if(!preg_match('/^http:/',$backgroundImage)){ $backgroundImage='http://'.$_SERVER['SERVER_NAME'].$backgroundImage; } switch($ext){ case 'png': $img2=imagecreatefrompng($backgroundImage); break; case 'jpg': case 'jpeg': $img2=imagecreatefromjpeg($backgroundImage); break; } $w=imagesx($img2); $h=imagesy($img2); for($i=0;$w*$i