| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>  <style type="text/css">    .highlight { display: block; background-color: #ddd; }  </style>  <script type="text/javascript">    function highlight() {      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";    }  </script></head><body onload="prettyPrint(); highlight();">  <pre class="prettyprint lang-js"><span id='Ext-draw-engine-SvgExporter'>/**</span> * A utility class for exporting a {@link Ext.draw.Surface Surface} to a string * that may be saved or used for processing on the server. * * @singleton */Ext.define('Ext.draw.engine.SvgExporter', function(){   var commaRe = /,/g,       fontRegex = /(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)\s('*.*'*)/,       rgbColorRe = /rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/g,       rgbaColorRe = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,([\d\.]+)\)/g,       surface, len, width, height,   init = function(s){       surface = s;       len = surface.length;       width = surface.width;       height = surface.height;   },   spriteProcessor = {       path: function(sprite){           var attr = sprite.attr,               path = attr.path,               pathString = '',               props, p, pLen;           if (Ext.isArray(path[0])) {               pLen = path.length;               for (p = 0; p < pLen; p++) {                   pathString += path[p].join(' ');               }           } else if (Ext.isArray(path)) {               pathString = path.join(' ');           } else {               pathString = path.replace(commaRe,' ');           }           props = toPropertyString({               d: pathString,               fill: attr.fill || 'none',               stroke: attr.stroke,               'fill-opacity': attr.opacity,               'stroke-width': attr['stroke-width'],               'stroke-opacity': attr['stroke-opacity'],               "z-index": attr.zIndex,               transform: sprite.matrix.toSvg()           });           return '<path ' + props + '/>';       },       text: function(sprite){           // TODO           // implement multi line support (@see Svg.js tuneText)           var attr = sprite.attr,               match = fontRegex.exec(attr.font),               size = (match && match[1]) || "12",               // default font family is Arial               family = (match && match[3]) || 'Arial',               text = attr.text,               factor = (Ext.isFF3_0 || Ext.isFF3_5) ? 2 : 4,               tspanString = '',               props;           sprite.getBBox();           tspanString += '<tspan x="' + (attr.x || '') + '" dy="';           tspanString += (size/factor)+'">';           tspanString += Ext.htmlEncode(text) + '</tspan>';           props = toPropertyString({               x: attr.x,               y: attr.y,               'font-size': size,               'font-family': family,               'font-weight': attr['font-weight'],               'text-anchor': attr['text-anchor'],               // if no fill property is set it will be black               fill: attr.fill || '#000',               'fill-opacity': attr.opacity,               transform: sprite.matrix.toSvg()           });           return '<text '+ props + '>' +  tspanString + '</text>';       },       rect: function(sprite){           var attr = sprite.attr,               props =  toPropertyString({                   x: attr.x,                   y: attr.y,                   rx: attr.rx,                   ry: attr.ry,                   width: attr.width,                   height: attr.height,                   fill: attr.fill || 'none',                   'fill-opacity': attr.opacity,                   stroke: attr.stroke,                   'stroke-opacity': attr['stroke-opacity'],                   'stroke-width':attr['stroke-width'],                   transform: sprite.matrix && sprite.matrix.toSvg()               });           return '<rect ' + props + '/>';       },       circle: function(sprite){           var attr = sprite.attr,               props = toPropertyString({                   cx: attr.x,                   cy: attr.y,                   r: attr.radius,                   fill: attr.translation.fill || attr.fill || 'none',                   'fill-opacity': attr.opacity,                   stroke: attr.stroke,                   'stroke-opacity': attr['stroke-opacity'],                   'stroke-width':attr['stroke-width'],                   transform: sprite.matrix.toSvg()               });           return '<circle ' + props + ' />';       },       image: function(sprite){           var attr = sprite.attr,               props = toPropertyString({                   x: attr.x - (attr.width/2 >> 0),                   y: attr.y - (attr.height/2 >> 0),                   width: attr.width,                   height: attr.height,                   'xlink:href': attr.src,                   transform: sprite.matrix.toSvg()               });           return '<image ' + props + ' />';       }   },   svgHeader = function(){       var svg = '<?xml version="1.0" standalone="yes"?>';       svg += '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';       return svg;   },   svgContent = function(){       var svg = '<svg width="'+width+'px" height="'+height+'px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">',           defs = '', item, itemsLen, items, gradient,           getSvgString, colorstops, stop,           coll, keys, colls, k, kLen, key, collI, i, j, stopsLen, sortedItems, za, zb;       items = surface.items.items;       itemsLen = items.length;       getSvgString = function(node){           var childs = node.childNodes,               childLength = childs.length,               i = 0,               attrLength,               j,               svgString = '', child, attr, tagName, attrItem;               for(; i < childLength; i++){                   child = childs[i];                   attr = child.attributes;                   tagName = child.tagName;                   svgString += '<' +tagName;                   for(j = 0, attrLength = attr.length; j < attrLength; j++){                       attrItem = attr.item(j);                       svgString += ' '+attrItem.name+'="'+attrItem.value+'"';                   }                   svgString += '>';                   if(child.childNodes.length > 0){                       svgString += getSvgString(child);                   }                   svgString += '</' + tagName + '>';               }           return svgString;       };       if(surface.getDefs){           defs = getSvgString(surface.getDefs());       }else{           // IE           coll = surface.gradientsColl;           if (coll) {               keys  = coll.keys;               colls = coll.items;               k     = 0;               kLen  = keys.length;           }           for (; k < kLen; k++) {               key   = keys[k];               collI = colls[k];               gradient = surface.gradientsColl.getByKey(key);               defs += '<linearGradient id="' + key + '" x1="0" y1="0" x2="1" y2="1">';               var color = gradient.colors.replace(rgbColorRe, 'rgb($1|$2|$3)');               color = color.replace(rgbaColorRe, 'rgba($1|$2|$3|$4)')               colorstops = color.split(',');               for(i=0, stopsLen = colorstops.length; i < stopsLen; i++){                   stop = colorstops[i].split(' ');                   color = Ext.draw.Color.fromString(stop[1].replace(/\|/g,','));                   defs += '<stop offset="'+stop[0]+'" stop-color="' + color.toString() + '" stop-opacity="1"></stop>';               }               defs += '</linearGradient>';           }       }       svg += '<defs>' + defs + '</defs>';       // thats the background rectangle       svg += spriteProcessor.rect({           attr: {                   width: '100%',                   height: '100%',                   fill: '#fff',                   stroke: 'none',                   opacity: '0'           }       });       // Sort the items (stable sort guaranteed)       sortedItems = new Array(itemsLen);       for(i = 0; i < itemsLen; i++){           sortedItems[i] = i;       }       sortedItems.sort(function (a, b) {           za = items[a].attr.zIndex || 0;           zb = items[b].attr.zIndex || 0;           if (za == zb) {               return a - b;           }           return za - zb;       });       for(i = 0; i < itemsLen; i++){           item = items[sortedItems[i]];           if(!item.attr.hidden){               svg += spriteProcessor[item.type](item);           }       }       svg += '</svg>';       return svg;   },   toPropertyString = function(obj){       var propString = '',           key;       for(key in obj){           if(obj.hasOwnProperty(key) && obj[key] != null){               propString += key +'="'+ obj[key]+'" ';           }       }       return propString;   };   return {       singleton: true,<span id='Ext-draw-engine-SvgExporter-method-generate'>       /**</span>        * Exports the passed surface to a SVG string representation        * @param {Ext.draw.Surface} surface The surface to export        * @param {Object} [config] Any configuration for the export. Currently this is        * unused but may provide more options in the future        * @return {String} The SVG as a string        */       generate: function(surface, config){           config = config || {};           init(surface);           return svgHeader() + svgContent();       }   };});</pre></body></html>
 |