| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000 | 
							- <!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-Surface'>/**
 
- </span> * A Surface is an interface to render methods inside {@link Ext.draw.Component}.
 
-  *
 
-  * Most of the Surface methods are abstract and they have a concrete implementation
 
-  * in {@link Ext.draw.engine.Vml VML} or {@link Ext.draw.engine.Svg SVG} engines.
 
-  *
 
-  * A Surface contains methods to render {@link Ext.draw.Sprite sprites}, get bounding
 
-  * boxes of sprites, add sprites to the canvas, initialize other graphic components, etc.
 
-  *
 
-  * ## Adding sprites to surface
 
-  *
 
-  * One of the most used methods for this class is the {@link #add} method, to add Sprites to
 
-  * the surface. For example:
 
-  *
 
-  *     drawComponent.surface.add({
 
-  *         type: 'circle',
 
-  *         fill: '#ffc',
 
-  *         radius: 100,
 
-  *         x: 100,
 
-  *         y: 100
 
-  *     });
 
-  *
 
-  * The configuration object passed in the `add` method is the same as described in the
 
-  * {@link Ext.draw.Sprite} class documentation.
 
-  *
 
-  * Sprites can also be added to surface by setting their surface config at creation time:
 
-  *
 
-  *     var sprite = Ext.create('Ext.draw.Sprite', {
 
-  *         type: 'circle',
 
-  *         fill: '#ff0',
 
-  *         surface: drawComponent.surface,
 
-  *         radius: 5
 
-  *     });
 
-  *
 
-  * In order to properly apply properties and render the sprite we have to
 
-  * `show` the sprite setting the option `redraw` to `true`:
 
-  *
 
-  *     sprite.show(true);
 
-  *
 
-  */
 
- Ext.define('Ext.draw.Surface', {
 
-     /* Begin Definitions */
 
-     mixins: {
 
-         observable: 'Ext.util.Observable'
 
-     },
 
-     requires: ['Ext.draw.CompositeSprite'],
 
-     uses: ['Ext.draw.engine.Svg', 'Ext.draw.engine.Vml', 'Ext.draw.engine.SvgExporter', 'Ext.draw.engine.ImageExporter'],
 
-     separatorRe: /[, ]+/,
 
-     statics: {
 
- <span id='Ext-draw-Surface-static-method-create'>        /**
 
- </span>         * Creates and returns a new concrete Surface instance appropriate for the current environment.
 
-          * @param {Object} config Initial configuration for the Surface instance
 
-          * @param {String[]} enginePriority (Optional) order of implementations to use; the first one that is
 
-          * available in the current environment will be used. Defaults to `['Svg', 'Vml']`.
 
-          * @return {Object} The created Surface or false.
 
-          * @static
 
-          */
 
-         create: function(config, enginePriority) {
 
-             enginePriority = enginePriority || ['Svg', 'Vml'];
 
-             var i = 0,
 
-                 len = enginePriority.length,
 
-                 surfaceClass;
 
-             for (; i < len; i++) {
 
-                 if (Ext.supports[enginePriority[i]] !== false) {
 
-                     return Ext.create('Ext.draw.engine.' + enginePriority[i], config);
 
-                 }
 
-             }
 
-             return false;
 
-         },
 
-         
 
- <span id='Ext-draw-Surface-static-method-save'>        /**
 
- </span>         * Exports a {@link Ext.draw.Surface surface} in a different format.
 
-          * The surface may be exported to an SVG string, using the
 
-          * {@link Ext.draw.engine.SvgExporter}. It may also be exported
 
-          * as an image using the {@link Ext.draw.engine.ImageExporter ImageExporter}.
 
-          * Note that this requires sending data to a remote server to process
 
-          * the SVG into an image, see the {@link Ext.draw.engine.ImageExporter} for
 
-          * more details.
 
-          * @param {Ext.draw.Surface} surface The surface to export.
 
-          * @param {Object} [config] The configuration to be passed to the exporter.
 
-          * See the export method for the appropriate exporter for the relevant
 
-          * configuration options
 
-          * @return {Object} See the return types for the appropriate exporter
 
-          * @static
 
-          */
 
-         save: function(surface, config) {
 
-             config = config || {};
 
-             var exportTypes = {
 
-                     'image/png': 'Image',
 
-                     'image/jpeg': 'Image',
 
-                     'image/svg+xml': 'Svg'
 
-                 },
 
-                 prefix = exportTypes[config.type] || 'Svg',
 
-                 exporter = Ext.draw.engine[prefix + 'Exporter'];           
 
-             return exporter.generate(surface, config);
 
-             
 
-         }
 
-     },
 
-     /* End Definitions */
 
-     // @private
 
-     availableAttrs: {
 
-         blur: 0,
 
-         "clip-rect": "0 0 1e9 1e9",
 
-         cursor: "default",
 
-         cx: 0,
 
-         cy: 0,
 
-         'dominant-baseline': 'auto',
 
-         fill: "none",
 
-         "fill-opacity": 1,
 
-         font: '10px "Arial"',
 
-         "font-family": '"Arial"',
 
-         "font-size": "10",
 
-         "font-style": "normal",
 
-         "font-weight": 400,
 
-         gradient: "",
 
-         height: 0,
 
-         hidden: false,
 
-         href: "http://sencha.com/",
 
-         opacity: 1,
 
-         path: "M0,0",
 
-         radius: 0,
 
-         rx: 0,
 
-         ry: 0,
 
-         scale: "1 1",
 
-         src: "",
 
-         stroke: "none",
 
-         "stroke-dasharray": "",
 
-         "stroke-linecap": "butt",
 
-         "stroke-linejoin": "butt",
 
-         "stroke-miterlimit": 0,
 
-         "stroke-opacity": 1,
 
-         "stroke-width": 1,
 
-         target: "_blank",
 
-         text: "",
 
-         "text-anchor": "middle",
 
-         title: "Ext Draw",
 
-         width: 0,
 
-         x: 0,
 
-         y: 0,
 
-         zIndex: 0
 
-     },
 
- <span id='Ext-draw-Surface-cfg-height'>    /**
 
- </span>     * @cfg {Number} height
 
-      * The height of this component in pixels (defaults to auto).
 
-      */
 
- <span id='Ext-draw-Surface-cfg-width'>    /**
 
- </span>     * @cfg {Number} width
 
-      * The width of this component in pixels (defaults to auto).
 
-      */
 
-     container: undefined,
 
-     height: 352,
 
-     width: 512,
 
-     x: 0,
 
-     y: 0,
 
- <span id='Ext-draw-Surface-cfg-items'>    /**
 
- </span>     * @cfg {Ext.draw.Sprite[]} items
 
-      * Array of sprites or sprite config objects to add initially to the surface.
 
-      */
 
- <span id='Ext-draw-Surface-property-orderSpritesByZIndex'>    /**
 
- </span>     * @private Flag indicating that the surface implementation requires sprites to be maintained
 
-      * in order of their zIndex. Impls that don't require this can set it to false.
 
-      */
 
-     orderSpritesByZIndex: true,
 
- <span id='Ext-draw-Surface-method-constructor'>    /**
 
- </span>     * Creates new Surface.
 
-      * @param {Object} config (optional) Config object.
 
-      */
 
-     constructor: function(config) {
 
-         var me = this;
 
-         config = config || {};
 
-         Ext.apply(me, config);
 
-         me.domRef = Ext.getDoc().dom;
 
-         me.customAttributes = {};
 
-         me.addEvents(
 
- <span id='Ext-draw-Surface-event-mousedown'>            /**
 
- </span>             * @event
 
-              * Fires when a mousedown is detected within the surface.
 
-              * @param {Ext.EventObject} e An object encapsulating the DOM event.
 
-              */
 
-             'mousedown',
 
- <span id='Ext-draw-Surface-event-mouseup'>            /**
 
- </span>             * @event
 
-              * Fires when a mouseup is detected within the surface.
 
-              * @param {Ext.EventObject} e An object encapsulating the DOM event.
 
-              */
 
-             'mouseup',
 
- <span id='Ext-draw-Surface-event-mouseover'>            /**
 
- </span>             * @event
 
-              * Fires when a mouseover is detected within the surface.
 
-              * @param {Ext.EventObject} e An object encapsulating the DOM event.
 
-              */
 
-             'mouseover',
 
- <span id='Ext-draw-Surface-event-mouseout'>            /**
 
- </span>             * @event
 
-              * Fires when a mouseout is detected within the surface.
 
-              * @param {Ext.EventObject} e An object encapsulating the DOM event.
 
-              */
 
-             'mouseout',
 
- <span id='Ext-draw-Surface-event-mousemove'>            /**
 
- </span>             * @event
 
-              * Fires when a mousemove is detected within the surface.
 
-              * @param {Ext.EventObject} e An object encapsulating the DOM event.
 
-              */
 
-             'mousemove',
 
- <span id='Ext-draw-Surface-event-mouseenter'>            /**
 
- </span>             * @event
 
-              * Fires when a mouseenter is detected within the surface.
 
-              * @param {Ext.EventObject} e An object encapsulating the DOM event.
 
-              */
 
-             'mouseenter',
 
- <span id='Ext-draw-Surface-event-mouseleave'>            /**
 
- </span>             * @event
 
-              * Fires when a mouseleave is detected within the surface.
 
-              * @param {Ext.EventObject} e An object encapsulating the DOM event.
 
-              */
 
-             'mouseleave',
 
- <span id='Ext-draw-Surface-event-click'>            /**
 
- </span>             * @event
 
-              * Fires when a click is detected within the surface.
 
-              * @param {Ext.EventObject} e An object encapsulating the DOM event.
 
-              */
 
-             'click',
 
- <span id='Ext-draw-Surface-event-dblclick'>            /**
 
- </span>             * @event
 
-              * Fires when a dblclick is detected within the surface.
 
-              * @param {Ext.EventObject} e An object encapsulating the DOM event.
 
-              */
 
-             'dblclick'
 
-         );
 
-         me.mixins.observable.constructor.call(me);
 
-         me.getId();
 
-         me.initGradients();
 
-         me.initItems();
 
-         if (me.renderTo) {
 
-             me.render(me.renderTo);
 
-             delete me.renderTo;
 
-         }
 
-         me.initBackground(config.background);
 
-     },
 
-     // @private called to initialize components in the surface
 
-     // this is dependent on the underlying implementation.
 
-     initSurface: Ext.emptyFn,
 
-     // @private called to setup the surface to render an item
 
-     //this is dependent on the underlying implementation.
 
-     renderItem: Ext.emptyFn,
 
-     // @private
 
-     renderItems: Ext.emptyFn,
 
-     // @private
 
-     setViewBox: function (x, y, width, height) {
 
-         if (isFinite(x) && isFinite(y) && isFinite(width) && isFinite(height)) {
 
-             this.viewBox = {x: x, y: y, width: width, height: height};
 
-             this.applyViewBox();
 
-         }
 
-     },
 
- <span id='Ext-draw-Surface-method-addCls'>    /**
 
- </span>     * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out.
 
-      *
 
-      * For example:
 
-      *
 
-      *     drawComponent.surface.addCls(sprite, 'x-visible');
 
-      *
 
-      * @param {Object} sprite The sprite to add the class to.
 
-      * @param {String/String[]} className The CSS class to add, or an array of classes
 
-      * @method
 
-      */
 
-     addCls: Ext.emptyFn,
 
- <span id='Ext-draw-Surface-method-removeCls'>    /**
 
- </span>     * Removes one or more CSS classes from the element.
 
-      *
 
-      * For example:
 
-      *
 
-      *     drawComponent.surface.removeCls(sprite, 'x-visible');
 
-      *
 
-      * @param {Object} sprite The sprite to remove the class from.
 
-      * @param {String/String[]} className The CSS class to remove, or an array of classes
 
-      * @method
 
-      */
 
-     removeCls: Ext.emptyFn,
 
- <span id='Ext-draw-Surface-method-setStyle'>    /**
 
- </span>     * Sets CSS style attributes to an element.
 
-      *
 
-      * For example:
 
-      *
 
-      *     drawComponent.surface.setStyle(sprite, {
 
-      *         'cursor': 'pointer'
 
-      *     });
 
-      *
 
-      * @param {Object} sprite The sprite to add, or an array of classes to
 
-      * @param {Object} styles An Object with CSS styles.
 
-      * @method
 
-      */
 
-     setStyle: Ext.emptyFn,
 
-     // @private
 
-     initGradients: function() {
 
-         if (this.hasOwnProperty('gradients')) {
 
-             var gradients = this.gradients,
 
-                 gLen      = gradients.length,
 
-                 fn        = this.addGradient,
 
-                 g;
 
-             if (gradients) {
 
-                 for (g = 0; g < gLen; g++) {
 
-                     if (fn.call(this, gradients[g], g, gLen) === false) {
 
-                         break;
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-     },
 
-     // @private
 
-     initItems: function() {
 
-         var items = this.items;
 
-         this.items = new Ext.draw.CompositeSprite();
 
-         this.items.autoDestroy = true;
 
-         this.groups = new Ext.draw.CompositeSprite();
 
-         if (items) {
 
-             this.add(items);
 
-         }
 
-     },
 
-     // @private
 
-     initBackground: function(config) {
 
-         var me = this,
 
-             width = me.width,
 
-             height = me.height,
 
-             gradientId, gradient, backgroundSprite;
 
-         if (Ext.isString(config)) {
 
-             config = {
 
-                 fill : config
 
-             };
 
-         }
 
-         if (config) {
 
-             if (config.gradient) {
 
-                 gradient = config.gradient;
 
-                 gradientId = gradient.id;
 
-                 me.addGradient(gradient);
 
-                 me.background = me.add({
 
-                     type: 'rect',
 
-                     x: 0,
 
-                     y: 0,
 
-                     width: width,
 
-                     height: height,
 
-                     fill: 'url(#' + gradientId + ')',
 
-                     zIndex: -1
 
-                 });
 
-             } else if (config.fill) {
 
-                 me.background = me.add({
 
-                     type: 'rect',
 
-                     x: 0,
 
-                     y: 0,
 
-                     width: width,
 
-                     height: height,
 
-                     fill: config.fill,
 
-                     zIndex: -1
 
-                 });
 
-             } else if (config.image) {
 
-                 me.background = me.add({
 
-                     type: 'image',
 
-                     x: 0,
 
-                     y: 0,
 
-                     width: width,
 
-                     height: height,
 
-                     src: config.image,
 
-                     zIndex: -1
 
-                 });
 
-             }
 
-             // prevent me.background to jeopardize me.items.getBBox
 
-             me.background.bboxExcluded = true;
 
-         }
 
-     },
 
- <span id='Ext-draw-Surface-method-setSize'>    /**
 
- </span>     * Sets the size of the surface. Accomodates the background (if any) to fit the new size too.
 
-      *
 
-      * For example:
 
-      *
 
-      *     drawComponent.surface.setSize(500, 500);
 
-      *
 
-      * This method is generally called when also setting the size of the draw Component.
 
-      *
 
-      * @param {Number} w The new width of the canvas.
 
-      * @param {Number} h The new height of the canvas.
 
-      */
 
-     setSize: function(w, h) {
 
-         this.applyViewBox();
 
-     },
 
-     // @private
 
-     scrubAttrs: function(sprite) {
 
-         var i,
 
-             attrs = {},
 
-             exclude = {},
 
-             sattr = sprite.attr;
 
-         for (i in sattr) {
 
-             // Narrow down attributes to the main set
 
-             if (this.translateAttrs.hasOwnProperty(i)) {
 
-                 // Translated attr
 
-                 attrs[this.translateAttrs[i]] = sattr[i];
 
-                 exclude[this.translateAttrs[i]] = true;
 
-             }
 
-             else if (this.availableAttrs.hasOwnProperty(i) && !exclude[i]) {
 
-                 // Passtrhough attr
 
-                 attrs[i] = sattr[i];
 
-             }
 
-         }
 
-         return attrs;
 
-     },
 
-     // @private
 
-     onClick: function(e) {
 
-         this.processEvent('click', e);
 
-     },
 
-     
 
-     // @private
 
-     onDblClick: function(e) {
 
-         this.processEvent('dblclick', e);
 
-     },
 
-     // @private
 
-     onMouseUp: function(e) {
 
-         this.processEvent('mouseup', e);
 
-     },
 
-     // @private
 
-     onMouseDown: function(e) {
 
-         this.processEvent('mousedown', e);
 
-     },
 
-     // @private
 
-     onMouseOver: function(e) {
 
-         this.processEvent('mouseover', e);
 
-     },
 
-     // @private
 
-     onMouseOut: function(e) {
 
-         this.processEvent('mouseout', e);
 
-     },
 
-     // @private
 
-     onMouseMove: function(e) {
 
-         this.fireEvent('mousemove', e);
 
-     },
 
-     // @private
 
-     onMouseEnter: Ext.emptyFn,
 
-     // @private
 
-     onMouseLeave: Ext.emptyFn,
 
- <span id='Ext-draw-Surface-method-addGradient'>    /**
 
- </span>     * Adds a gradient definition to the Surface. Note that in some surface engines, adding
 
-      * a gradient via this method will not take effect if the surface has already been rendered.
 
-      * Therefore, it is preferred to pass the gradients as an item to the surface config, rather
 
-      * than calling this method, especially if the surface is rendered immediately (e.g. due to
 
-      * 'renderTo' in its config). For more information on how to create gradients in the Chart
 
-      * configuration object please refer to {@link Ext.chart.Chart}.
 
-      *
 
-      * The gradient object to be passed into this method is composed by:
 
-      *
 
-      * - **id** - string - The unique name of the gradient.
 
-      * - **angle** - number, optional - The angle of the gradient in degrees.
 
-      * - **stops** - object - An object with numbers as keys (from 0 to 100) and style objects as values.
 
-      *
 
-      * For example:
 
-      *
 
-      *    drawComponent.surface.addGradient({
 
-      *        id: 'gradientId',
 
-      *        angle: 45,
 
-      *        stops: {
 
-      *            0: {
 
-      *                color: '#555'
 
-      *            },
 
-      *            100: {
 
-      *                color: '#ddd'
 
-      *            }
 
-      *        }
 
-      *    });
 
-      *
 
-      * @param {Object} gradient A gradient config.
 
-      * @method
 
-      */
 
-     addGradient: Ext.emptyFn,
 
- <span id='Ext-draw-Surface-method-add'>    /**
 
- </span>     * Adds a Sprite to the surface. See {@link Ext.draw.Sprite} for the configuration object to be
 
-      * passed into this method.
 
-      *
 
-      * For example:
 
-      *
 
-      *     drawComponent.surface.add({
 
-      *         type: 'circle',
 
-      *         fill: '#ffc',
 
-      *         radius: 100,
 
-      *         x: 100,
 
-      *         y: 100
 
-      *     });
 
-      *
 
-      * @param {Ext.draw.Sprite[]/Ext.draw.Sprite...} args One or more Sprite objects or configs.
 
-      * @return {Ext.draw.Sprite[]/Ext.draw.Sprite} The sprites added.
 
-      */
 
-     add: function() {
 
-         var args = Array.prototype.slice.call(arguments),
 
-             sprite,
 
-             index,
 
-             hasMultipleArgs = args.length > 1,
 
-             items,
 
-             results,
 
-             i,
 
-             ln,
 
-             item;
 
-             
 
-         if (hasMultipleArgs || Ext.isArray(args[0])) {
 
-             items = hasMultipleArgs ? args : args[0];
 
-             results = [];
 
-             for (i = 0, ln = items.length; i < ln; i++) {
 
-                 item = items[i];
 
-                 item = this.add(item);
 
-                 results.push(item);
 
-             }
 
-             return results;
 
-         }
 
-         sprite = this.prepareItems(args[0], true)[0];
 
-         this.insertByZIndex(sprite);
 
-         this.onAdd(sprite);
 
-         return sprite;
 
-     },
 
- <span id='Ext-draw-Surface-method-insertByZIndex'>    /**
 
- </span>     * @private
 
-      * Inserts a given sprite into the correct position in the items collection, according to
 
-      * its zIndex. It will be inserted at the end of an existing series of sprites with the same or
 
-      * lower zIndex. By ensuring sprites are always ordered, this allows surface subclasses to render
 
-      * the sprites in the correct order for proper z-index stacking.
 
-      * @param {Ext.draw.Sprite} sprite
 
-      * @return {Number} the sprite's new index in the list
 
-      */
 
-     insertByZIndex: function(sprite) {
 
-         var me = this,
 
-             sprites = me.items.items,
 
-             len = sprites.length,
 
-             ceil = Math.ceil,
 
-             zIndex = sprite.attr.zIndex,
 
-             idx = len,
 
-             high = idx - 1,
 
-             low = 0,
 
-             otherZIndex;
 
-         if (me.orderSpritesByZIndex && len && zIndex < sprites[high].attr.zIndex) {
 
-             // Find the target index via a binary search for speed
 
-             while (low <= high) {
 
-                 idx = ceil((low + high) / 2);
 
-                 otherZIndex = sprites[idx].attr.zIndex;
 
-                 if (otherZIndex > zIndex) {
 
-                     high = idx - 1;
 
-                 }
 
-                 else if (otherZIndex < zIndex) {
 
-                     low = idx + 1;
 
-                 }
 
-                 else {
 
-                     break;
 
-                 }
 
-             }
 
-             // Step forward to the end of a sequence of the same or lower z-index
 
-             while (idx < len && sprites[idx].attr.zIndex <= zIndex) {
 
-                 idx++;
 
-             }
 
-         }
 
-         me.items.insert(idx, sprite);
 
-         return idx;
 
-     },
 
-     onAdd: function(sprite) {
 
-         var group = sprite.group,
 
-             draggable = sprite.draggable,
 
-             groups, ln, i;
 
-         if (group) {
 
-             groups = [].concat(group);
 
-             ln = groups.length;
 
-             for (i = 0; i < ln; i++) {
 
-                 group = groups[i];
 
-                 this.getGroup(group).add(sprite);
 
-             }
 
-             delete sprite.group;
 
-         }
 
-         if (draggable) {
 
-             sprite.initDraggable();
 
-         }
 
-     },
 
- <span id='Ext-draw-Surface-method-remove'>    /**
 
- </span>     * Removes a given sprite from the surface, optionally destroying the sprite in the process.
 
-      * You can also call the sprite own `remove` method.
 
-      *
 
-      * For example:
 
-      *
 
-      *     drawComponent.surface.remove(sprite);
 
-      *     //or...
 
-      *     sprite.remove();
 
-      *
 
-      * @param {Ext.draw.Sprite} sprite
 
-      * @param {Boolean} destroySprite
 
-      */
 
-     remove: function(sprite, destroySprite) {
 
-         if (sprite) {
 
-             this.items.remove(sprite);
 
-             var groups = [].concat(this.groups.items),
 
-                 gLen   = groups.length,
 
-                 g;
 
-             for (g = 0; g < gLen; g++) {
 
-                 groups[g].remove(sprite);
 
-             }
 
-             sprite.onRemove();
 
-             if (destroySprite === true) {
 
-                 sprite.destroy();
 
-             }
 
-         }
 
-     },
 
- <span id='Ext-draw-Surface-method-removeAll'>    /**
 
- </span>     * Removes all sprites from the surface, optionally destroying the sprites in the process.
 
-      *
 
-      * For example:
 
-      *
 
-      *     drawComponent.surface.removeAll();
 
-      *
 
-      * @param {Boolean} destroySprites Whether to destroy all sprites when removing them.
 
-      */
 
-     removeAll: function(destroySprites) {
 
-         var items = this.items.items,
 
-             ln = items.length,
 
-             i;
 
-         for (i = ln - 1; i > -1; i--) {
 
-             this.remove(items[i], destroySprites);
 
-         }
 
-     },
 
-     onRemove: Ext.emptyFn,
 
-     onDestroy: Ext.emptyFn,
 
- <span id='Ext-draw-Surface-method-applyViewBox'>    /**
 
- </span>     * @private Using the current viewBox property and the surface's width and height, calculate the
 
-      * appropriate viewBoxShift that will be applied as a persistent transform to all sprites.
 
-      */
 
-     applyViewBox: function() {
 
-         var me = this,
 
-             viewBox = me.viewBox,
 
-             width = me.width || 1, // Avoid problems in division
 
-             height = me.height || 1,
 
-             viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight,
 
-             relativeHeight, relativeWidth, size;
 
-         if (viewBox && (width || height)) {
 
-             viewBoxX = viewBox.x;
 
-             viewBoxY = viewBox.y;
 
-             viewBoxWidth = viewBox.width;
 
-             viewBoxHeight = viewBox.height;
 
-             relativeHeight = height / viewBoxHeight;
 
-             relativeWidth = width / viewBoxWidth;
 
-             size = Math.min(relativeWidth, relativeHeight);
 
-             if (viewBoxWidth * size < width) {
 
-                 viewBoxX -= (width - viewBoxWidth * size) / 2 / size;
 
-             }
 
-             if (viewBoxHeight * size < height) {
 
-                 viewBoxY -= (height - viewBoxHeight * size) / 2 / size;
 
-             }
 
-             me.viewBoxShift = {
 
-                 dx: -viewBoxX,
 
-                 dy: -viewBoxY,
 
-                 scale: size
 
-             };
 
-             
 
-             if (me.background) {
 
-                 me.background.setAttributes(Ext.apply({}, {
 
-                     x: viewBoxX,
 
-                     y: viewBoxY,
 
-                     width: width / size,
 
-                     height: height / size
 
-                 }, { hidden: false }), true);
 
-             }
 
-         } else {
 
-             if (me.background && width && height) {
 
-                 me.background.setAttributes(Ext.apply({x: 0, y: 0, width: width, height: height}, { hidden: false }), true);
 
-             }
 
-         }
 
-     },
 
-     getBBox: function (sprite, isWithoutTransform) {
 
-         var realPath = this["getPath" + sprite.type](sprite);
 
-         if (isWithoutTransform) {
 
-             sprite.bbox.plain = sprite.bbox.plain || Ext.draw.Draw.pathDimensions(realPath);
 
-             return sprite.bbox.plain;
 
-         }
 
-         if (sprite.dirtyTransform) {
 
-             this.applyTransformations(sprite, true);
 
-         }
 
-         sprite.bbox.transform = sprite.bbox.transform || Ext.draw.Draw.pathDimensions(Ext.draw.Draw.mapPath(realPath, sprite.matrix));
 
-         return sprite.bbox.transform;
 
-     },
 
-     
 
-     transformToViewBox: function (x, y) {
 
-         if (this.viewBoxShift) {
 
-             var me = this, shift = me.viewBoxShift;
 
-             return [x / shift.scale - shift.dx, y / shift.scale - shift.dy];
 
-         } else {
 
-             return [x, y];
 
-         }
 
-     },
 
-     // @private
 
-     applyTransformations: function(sprite, onlyMatrix) {
 
-         if (sprite.type == 'text') {
 
-             // TODO: getTextBBox function always take matrix into account no matter whether `isWithoutTransform` is true. Fix that.
 
-             sprite.bbox.transform = 0;
 
-             this.transform(sprite, false);
 
-         }
 
-         sprite.dirtyTransform = false;
 
-         
 
-         var me = this,
 
-             attr = sprite.attr;
 
-         if (attr.translation.x != null || attr.translation.y != null) {
 
-             me.translate(sprite);
 
-         }
 
-         if (attr.scaling.x != null || attr.scaling.y != null) {
 
-             me.scale(sprite);
 
-         }
 
-         if (attr.rotation.degrees != null) {
 
-             me.rotate(sprite);
 
-         }
 
-         
 
-         sprite.bbox.transform = 0;
 
-         this.transform(sprite, onlyMatrix);
 
-         sprite.transformations = [];
 
-     },
 
-     // @private
 
-     rotate: function (sprite) {
 
-         var bbox,
 
-             deg = sprite.attr.rotation.degrees,
 
-             centerX = sprite.attr.rotation.x,
 
-             centerY = sprite.attr.rotation.y;
 
-         if (!Ext.isNumber(centerX) || !Ext.isNumber(centerY)) {
 
-             bbox = this.getBBox(sprite, true);
 
-             centerX = !Ext.isNumber(centerX) ? bbox.x + bbox.width / 2 : centerX;
 
-             centerY = !Ext.isNumber(centerY) ? bbox.y + bbox.height / 2 : centerY;
 
-         }
 
-         sprite.transformations.push({
 
-             type: "rotate",
 
-             degrees: deg,
 
-             x: centerX,
 
-             y: centerY
 
-         });
 
-     },
 
-     // @private
 
-     translate: function(sprite) {
 
-         var x = sprite.attr.translation.x || 0,
 
-             y = sprite.attr.translation.y || 0;
 
-         sprite.transformations.push({
 
-             type: "translate",
 
-             x: x,
 
-             y: y
 
-         });
 
-     },
 
-     // @private
 
-     scale: function(sprite) {
 
-         var bbox,
 
-             x = sprite.attr.scaling.x || 1,
 
-             y = sprite.attr.scaling.y || 1,
 
-             centerX = sprite.attr.scaling.centerX,
 
-             centerY = sprite.attr.scaling.centerY;
 
-         if (!Ext.isNumber(centerX) || !Ext.isNumber(centerY)) {
 
-             bbox = this.getBBox(sprite, true);
 
-             centerX = !Ext.isNumber(centerX) ? bbox.x + bbox.width / 2 : centerX;
 
-             centerY = !Ext.isNumber(centerY) ? bbox.y + bbox.height / 2 : centerY;
 
-         }
 
-         sprite.transformations.push({
 
-             type: "scale",
 
-             x: x,
 
-             y: y,
 
-             centerX: centerX,
 
-             centerY: centerY
 
-         });
 
-     },
 
-     // @private
 
-     rectPath: function (x, y, w, h, r) {
 
-         if (r) {
 
-             return [["M", x + r, y], ["l", w - r * 2, 0], ["a", r, r, 0, 0, 1, r, r], ["l", 0, h - r * 2], ["a", r, r, 0, 0, 1, -r, r], ["l", r * 2 - w, 0], ["a", r, r, 0, 0, 1, -r, -r], ["l", 0, r * 2 - h], ["a", r, r, 0, 0, 1, r, -r], ["z"]];
 
-         }
 
-         return [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]];
 
-     },
 
-     // @private
 
-     ellipsePath: function (x, y, rx, ry) {
 
-         if (ry == null) {
 
-             ry = rx;
 
-         }
 
-         return [["M", x, y], ["m", 0, -ry], ["a", rx, ry, 0, 1, 1, 0, 2 * ry], ["a", rx, ry, 0, 1, 1, 0, -2 * ry], ["z"]];
 
-     },
 
-     // @private
 
-     getPathpath: function (el) {
 
-         return el.attr.path;
 
-     },
 
-     // @private
 
-     getPathcircle: function (el) {
 
-         var a = el.attr;
 
-         return this.ellipsePath(a.x, a.y, a.radius, a.radius);
 
-     },
 
-     // @private
 
-     getPathellipse: function (el) {
 
-         var a = el.attr;
 
-         return this.ellipsePath(a.x, a.y,
 
-                                 a.radiusX || (a.width / 2) || 0,
 
-                                 a.radiusY || (a.height / 2) || 0);
 
-     },
 
-     // @private
 
-     getPathrect: function (el) {
 
-         var a = el.attr;
 
-         return this.rectPath(a.x || 0, a.y || 0, a.width || 0, a.height || 0, a.r || 0);
 
-     },
 
-     // @private
 
-     getPathimage: function (el) {
 
-         var a = el.attr;
 
-         return this.rectPath(a.x || 0, a.y || 0, a.width, a.height);
 
-     },
 
-     // @private
 
-     getPathtext: function (el) {
 
-         var bbox = this.getBBoxText(el);
 
-         return this.rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
 
-     },
 
-     createGroup: function(id) {
 
-         var group = this.groups.get(id);
 
-         if (!group) {
 
-             group = new Ext.draw.CompositeSprite({
 
-                 surface: this
 
-             });
 
-             group.id = id || Ext.id(null, 'ext-surface-group-');
 
-             this.groups.add(group);
 
-         }
 
-         return group;
 
-     },
 
- <span id='Ext-draw-Surface-method-getGroup'>    /**
 
- </span>     * Returns a new group or an existent group associated with the current surface.
 
-      * The group returned is a {@link Ext.draw.CompositeSprite} group.
 
-      *
 
-      * For example:
 
-      *
 
-      *     var spriteGroup = drawComponent.surface.getGroup('someGroupId');
 
-      *
 
-      * @param {String} id The unique identifier of the group.
 
-      * @return {Object} The {@link Ext.draw.CompositeSprite}.
 
-      */
 
-     getGroup: function(id) {
 
-         var group;
 
-         if (typeof id == "string") {
 
-             group = this.groups.get(id);
 
-             if (!group) {
 
-                 group = this.createGroup(id);
 
-             }
 
-         } else {
 
-             group = id;
 
-         }
 
-         return group;
 
-     },
 
-     // @private
 
-     prepareItems: function(items, applyDefaults) {
 
-         items = [].concat(items);
 
-         // Make sure defaults are applied and item is initialized
 
-         var item, i, ln;
 
-         for (i = 0, ln = items.length; i < ln; i++) {
 
-             item = items[i];
 
-             if (!(item instanceof Ext.draw.Sprite)) {
 
-                 // Temporary, just take in configs...
 
-                 item.surface = this;
 
-                 items[i] = this.createItem(item);
 
-             } else {
 
-                 item.surface = this;
 
-             }
 
-         }
 
-         return items;
 
-     },
 
- <span id='Ext-draw-Surface-method-setText'>    /**
 
- </span>     * Changes the text in the sprite element. The sprite must be a `text` sprite.
 
-      * This method can also be called from {@link Ext.draw.Sprite}.
 
-      *
 
-      * For example:
 
-      *
 
-      *     var spriteGroup = drawComponent.surface.setText(sprite, 'my new text');
 
-      *
 
-      * @param {Object} sprite The Sprite to change the text.
 
-      * @param {String} text The new text to be set.
 
-      * @method
 
-      */
 
-     setText: Ext.emptyFn,
 
-     // @private Creates an item and appends it to the surface. Called
 
-     // as an internal method when calling `add`.
 
-     createItem: Ext.emptyFn,
 
- <span id='Ext-draw-Surface-method-getId'>    /**
 
- </span>     * Retrieves the id of this component.
 
-      * Will autogenerate an id if one has not already been set.
 
-      */
 
-     getId: function() {
 
-         return this.id || (this.id = Ext.id(null, 'ext-surface-'));
 
-     },
 
- <span id='Ext-draw-Surface-method-destroy'>    /**
 
- </span>     * Destroys the surface. This is done by removing all components from it and
 
-      * also removing its reference to a DOM element.
 
-      *
 
-      * For example:
 
-      *
 
-      *      drawComponent.surface.destroy();
 
-      */
 
-     destroy: function() {
 
-         var me = this;
 
-         delete me.domRef;
 
-         if (me.background) {
 
-             me.background.destroy();
 
-         }
 
-         me.removeAll(true);
 
-         Ext.destroy(me.groups.items);
 
-     }
 
- });
 
- </pre>
 
- </body>
 
- </html>
 
 
  |