1 /****************************************************************************
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3  Copyright (c) 2008-2010 Ricardo Quesada
  4  Copyright (c) 2011      Zynga Inc.
  5 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 
 27 /**
 28  * @ignore
 29  */
 30 cc.Touches = [];
 31 cc.TouchesIntergerDict = {};
 32 
 33 /**
 34  * @namespace cc.view is the shared view object.
 35  * @name cc.view
 36  */
 37 cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
 38     _delegate: null,
 39     // Size of parent node that contains cc.container and cc._canvas
 40     _frameSize: null,
 41     // resolution size, it is the size appropriate for the app resources.
 42     _designResolutionSize: null,
 43     _originalDesignResolutionSize: null,
 44     // Viewport is the container's rect related to content's coordinates in pixel
 45     _viewPortRect: null,
 46     // The visible rect in content's coordinate in point
 47     _visibleRect: null,
 48 	_retinaEnabled: false,
 49     _autoFullScreen: true,
 50     // The device's pixel ratio (for retina displays)
 51     _devicePixelRatio: 1,
 52     // the view name
 53     _viewName: "",
 54     // Custom callback for resize event
 55     _resizeCallback: null,
 56     _scaleX: 1,
 57     _originalScaleX: 1,
 58     _scaleY: 1,
 59     _originalScaleY: 1,
 60     _indexBitsUsed: 0,
 61     _maxTouches: 5,
 62     _resolutionPolicy: null,
 63     _rpExactFit: null,
 64     _rpShowAll: null,
 65     _rpNoBorder: null,
 66     _rpFixedHeight: null,
 67     _rpFixedWidth: null,
 68     _initialized: false,
 69 
 70     _captured: false,
 71     _wnd: null,
 72     _hDC: null,
 73     _hRC: null,
 74     _supportTouch: false,
 75     _contentTranslateLeftTop: null,
 76 
 77     // Parent node that contains cc.container and cc._canvas
 78     _frame: null,
 79     _frameZoomFactor: 1.0,
 80     __resizeWithBrowserSize: false,
 81     _isAdjustViewPort: true,
 82 
 83     ctor: function () {
 84         var _t = this, d = document, _strategyer = cc.ContainerStrategy, _strategy = cc.ContentStrategy;
 85         _t._frame = (cc.container.parentNode === d.body) ? d.documentElement : cc.container.parentNode;
 86         _t._frameSize = cc.size(0, 0);
 87         _t._initFrameSize();
 88 
 89         var w = cc._canvas.width, h = cc._canvas.height;
 90         _t._designResolutionSize = cc.size(w, h);
 91         _t._originalDesignResolutionSize = cc.size(w, h);
 92         _t._viewPortRect = cc.rect(0, 0, w, h);
 93         _t._visibleRect = cc.rect(0, 0, w, h);
 94         _t._contentTranslateLeftTop = {left: 0, top: 0};
 95         _t._viewName = "Cocos2dHTML5";
 96 
 97 	    var sys = cc.sys;
 98         _t.enableRetina(sys.os == sys.OS_IOS || sys.os == sys.OS_OSX);
 99         cc.visibleRect && cc.visibleRect.init(_t._designResolutionSize);
100 
101         // Setup system default resolution policies
102         _t._rpExactFit = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.EXACT_FIT);
103         _t._rpShowAll = new cc.ResolutionPolicy(_strategyer.PROPORTION_TO_FRAME, _strategy.SHOW_ALL);
104         _t._rpNoBorder = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.NO_BORDER);
105         _t._rpFixedHeight = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_HEIGHT);
106         _t._rpFixedWidth = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_WIDTH);
107 
108         _t._hDC = cc._canvas;
109         _t._hRC = cc._renderContext;
110     },
111 
112     // Resize helper functions
113     _resizeEvent: function () {
114         var width = this._originalDesignResolutionSize.width;
115         var height = this._originalDesignResolutionSize.height;
116         if (this._resizeCallback) {
117             this._initFrameSize();
118             this._resizeCallback.call();
119         }
120         if (width > 0)
121             this.setDesignResolutionSize(width, height, this._resolutionPolicy);
122     },
123 
124     resizeWithBrowserSize: function (enabled) {
125         var adjustSize, _t = this;
126         if (enabled) {
127             //enable
128             if (!_t.__resizeWithBrowserSize) {
129                 _t.__resizeWithBrowserSize = true;
130                 adjustSize = _t._resizeEvent.bind(_t);
131                 cc._addEventListener(window, 'resize', adjustSize, false);
132             }
133         } else {
134             //disable
135             if (_t.__resizeWithBrowserSize) {
136                 _t.__resizeWithBrowserSize = true;
137                 adjustSize = _t._resizeEvent.bind(_t);
138                 window.removeEventListener('resize', adjustSize, false);
139             }
140         }
141     },
142 
143     setResizeCallback: function (callback) {
144         if (typeof callback == "function" || callback == null) {
145             this._resizeCallback = callback;
146         }
147     },
148 
149     _initFrameSize: function () {
150         var locFrameSize = this._frameSize;
151         locFrameSize.width = this._frame.clientWidth;
152         locFrameSize.height = this._frame.clientHeight;
153     },
154 
155     // hack
156     _adjustSizeKeepCanvasSize: function () {
157         var designWidth = this._originalDesignResolutionSize.width;
158         var designHeight = this._originalDesignResolutionSize.height;
159         if (designWidth > 0)
160             this.setDesignResolutionSize(designWidth, designHeight, this._resolutionPolicy);
161     },
162 
163     _setViewPortMeta: function (width, height) {
164         if (this._isAdjustViewPort) {
165 	        var viewportMetas = {"user-scalable": "no", "maximum-scale": "1.0", "initial-scale": "1.0"}, elems = document.getElementsByName("viewport"), vp, content;
166             if (elems.length == 0) {
167                 vp = cc.newElement("meta");
168                 vp.name = "viewport";
169                 vp.content = "";
170                 document.head.appendChild(vp);
171             }
172             else vp = elems[0];
173 
174 	        // For avoiding Android Firefox issue, to remove once firefox fixes its issue.
175 	        if (cc.sys.isMobile && cc.sys.browserType == cc.sys.BROWSER_TYPE_FIREFOX) {
176 		        vp.content = "initial-scale:1";
177 		        return;
178 	        }
179 
180             content = vp.content;
181             for (var key in viewportMetas) {
182                 var pattern = new RegExp(key);
183                 if (!pattern.test(content)) {
184                     content += (content == "" ? "" : ",") + key + "=" + viewportMetas[key];
185                 }
186             }
187             /*
188             if(width<=320){
189                 width = 321;
190             }
191             if(height)
192                 content ="height="+height+","+content;
193             if(width)
194                 content ="width="+width+","+content;
195             */
196             vp.content = content;
197         }
198     },
199 
200     // RenderTexture hacker
201     _setScaleXYForRenderTexture: function () {
202         //hack for RenderTexture on canvas mode when adapting multiple resolution resources
203         var scaleFactor = cc.contentScaleFactor();
204         this._scaleX = scaleFactor;
205         this._scaleY = scaleFactor;
206     },
207 
208     // Other helper functions
209     _resetScale: function () {
210         this._scaleX = this._originalScaleX;
211         this._scaleY = this._originalScaleY;
212     },
213 
214     // Useless, just make sure the compatibility temporarily, should be removed
215     _adjustSizeToBrowser: function () {
216     },
217 
218     /**
219      * init
220      */
221     initialize: function () {
222         this._initialized = true;
223     },
224 
225     adjustViewPort: function (enabled) {
226         this._isAdjustViewPort = enabled;
227     },
228 
229 	/**
230 	 * Retina support is enabled by default for Apple device but disabled for other devices,
231 	 * it takes effect only when you called setDesignResolutionPolicy
232 	 * @param {Boolean} enabled  Enable or disable retina display
233 	 */
234 	enableRetina: function(enabled) {
235 		this._retinaEnabled = enabled ? true : false;
236 	},
237 
238 	/**
239 	 * Check whether retina display is enabled.
240 	 * @return {Boolean}
241 	 */
242 	isRetinaEnabled: function() {
243 		return this._retinaEnabled;
244 	},
245 
246     /**
247      * If enabled, the application will try automatically to enter full screen mode on mobile devices
248      * You can pass true as parameter to enable it and disable it by passing false
249      * @param {Boolean} enabled  Enable or disable auto full screen on mobile devices
250      */
251     enableAutoFullScreen: function(enabled) {
252         this._autoFullScreen = enabled ? true : false;
253     },
254 
255     /**
256      * Check whether auto full screen is enabled.
257      * @return {Boolean}
258      */
259     isAutoFullScreenEnabled: function() {
260         return this._autoFullScreen;
261     },
262 
263     /**
264      * Force destroying EGL view, subclass must implement this method.
265      */
266     end: function () {
267     },
268 
269     /**
270      * Get whether render system is ready(no matter opengl or canvas),
271      * this name is for the compatibility with cocos2d-x, subclass must implement this method.
272      * @return {Boolean}
273      */
274     isOpenGLReady: function () {
275         return (this._hDC != null && this._hRC != null);
276     },
277 
278     /*
279      * Set zoom factor for frame. This method is for debugging big resolution (e.g.new ipad) app on desktop.
280      * @param {Number} zoomFactor
281      */
282     setFrameZoomFactor: function (zoomFactor) {
283         this._frameZoomFactor = zoomFactor;
284         this.centerWindow();
285         cc.director.setProjection(cc.director.getProjection());
286     },
287 
288     /**
289      * Exchanges the front and back buffers, subclass must implement this method.
290      */
291     swapBuffers: function () {
292     },
293 
294     /**
295      * Open or close IME keyboard , subclass must implement this method.
296      */
297     setIMEKeyboardState: function (isOpen) {
298     },
299 
300     /**
301      * <p>
302      *   The resolution translate on EGLView
303      * </p>
304      * @param {Number} offsetLeft
305      * @param {Number} offsetTop
306      */
307     setContentTranslateLeftTop: function (offsetLeft, offsetTop) {
308         this._contentTranslateLeftTop = {left: offsetLeft, top: offsetTop};
309     },
310 
311     /**
312      * <p>
313      *   get the resolution translate on EGLView
314      * </p>
315      * @return {cc.Size|Object}
316      */
317     getContentTranslateLeftTop: function () {
318         return this._contentTranslateLeftTop;
319     },
320 
321     /**
322      * Get the frame size of EGL view.
323      * In general, it returns the screen size since the EGL view is a fullscreen view.
324      * @return {cc.Size}
325      */
326     getFrameSize: function () {
327         return cc.size(this._frameSize.width, this._frameSize.height);
328     },
329 
330     /**
331      * Set the frame size of EGL view.
332      * @param {Number} width
333      * @param {Number} height
334      */
335     setFrameSize: function (width, height) {
336         this._frameSize.width = width;
337         this._frameSize.height = height;
338         this._frame.style.width = width + "px";
339         this._frame.style.height = height + "px";
340         //this.centerWindow();
341         this._resizeEvent();
342         cc.director.setProjection(cc.director.getProjection());
343     },
344 
345     centerWindow: function () {
346     },
347 
348     /**
349      * Get the visible area size of OpenGL view port.
350      * @return {cc.Size}
351      */
352     getVisibleSize: function () {
353         return cc.size(this._visibleRect.width,this._visibleRect.height);
354     },
355 
356     /**
357      * Get the visible origin of OpenGL view port.
358      * @return {cc.Point}
359      */
360     getVisibleOrigin: function () {
361         return cc.p(this._visibleRect.x,this._visibleRect.y);
362     },
363 
364     canSetContentScaleFactor: function () {
365         return true;
366     },
367 
368     /**
369      * Get the current resolution policy
370      * @return {cc.ResolutionPolicy}
371      */
372     getResolutionPolicy: function () {
373         return this._resolutionPolicy;
374     },
375 
376     /**
377      * Set the current resolution policy
378      * @param {cc.ResolutionPolicy|Number} resolutionPolicy
379      */
380     setResolutionPolicy: function (resolutionPolicy) {
381         var _t = this;
382         if (resolutionPolicy instanceof cc.ResolutionPolicy) {
383             _t._resolutionPolicy = resolutionPolicy;
384         }
385         // Ensure compatibility with JSB
386         else {
387             var _locPolicy = cc.ResolutionPolicy;
388             if(resolutionPolicy === _locPolicy.EXACT_FIT)
389                 _t._resolutionPolicy = _t._rpExactFit;
390             if(resolutionPolicy === _locPolicy.SHOW_ALL)
391                 _t._resolutionPolicy = _t._rpShowAll;
392             if(resolutionPolicy === _locPolicy.NO_BORDER)
393                 _t._resolutionPolicy = _t._rpNoBorder;
394             if(resolutionPolicy === _locPolicy.FIXED_HEIGHT)
395                 _t._resolutionPolicy = _t._rpFixedHeight;
396             if(resolutionPolicy === _locPolicy.FIXED_WIDTH)
397                 _t._resolutionPolicy = _t._rpFixedWidth;
398         }
399     },
400 
401     /**
402      * Set the design resolution size.
403      * @param {Number} width Design resolution width.
404      * @param {Number} height Design resolution height.
405      * @param {cc.ResolutionPolicy|Number} resolutionPolicy The resolution policy desired, you may choose:
406      * [1] ResolutionExactFit       Fill screen by stretch-to-fit: if the design resolution ratio of width to height is different from the screen resolution ratio, your game view will be stretched.
407      * [2] ResolutionNoBorder       Full screen without black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two areas of your game view will be cut.
408      * [3] ResolutionShowAll        Full screen with black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two black borders will be shown.
409      * [4] ResolutionFixedHeight    Scale the content's height to screen's height and proportionally scale its width
410      * [5] ResolutionFixedWidth     Scale the content's width to screen's width and proportionally scale its height
411      * [cc.ResolutionPolicy]        Custom resolution policy, constructed by cc.ResolutionPolicy
412      */
413     setDesignResolutionSize: function (width, height, resolutionPolicy) {
414         // Defensive code
415         if (isNaN(width) || width == 0 || isNaN(height) || height == 0) {
416             cc.log(cc._LogInfos.EGLView_setDesignResolutionSize);
417             return;
418         }
419         var _t = this;
420         _t.setResolutionPolicy(resolutionPolicy);
421         var policy = _t._resolutionPolicy;
422         if (policy)
423             policy.preApply(_t);
424         else {
425             cc.log(cc._LogInfos.EGLView_setDesignResolutionSize_2);
426             return;
427         }
428 
429         // Reinit frame size
430         var frameW = _t._frameSize.width, frameH = _t._frameSize.height;
431         if (cc.sys.isMobile)
432             _t._setViewPortMeta(_t._frameSize.width, _t._frameSize.height);
433         _t._initFrameSize();
434         // No change
435         if (resolutionPolicy == _t._resolutionPolicy
436             && width == _t._originalDesignResolutionSize.width && height == _t._originalDesignResolutionSize.height
437             && frameW == _t._frameSize.width && frameH == _t._frameSize.height)
438             return;
439         _t._designResolutionSize = cc.size(width, height);
440         _t._originalDesignResolutionSize = cc.size(width, height);
441 
442         var result = policy.apply(_t, _t._designResolutionSize);
443         if (result.scale && result.scale.length == 2) {
444             _t._scaleX = result.scale[0];
445             _t._scaleY = result.scale[1];
446         }
447         if (result.viewport) {
448             var vp = _t._viewPortRect = result.viewport, visible = _t._visibleRect;
449             visible.width = cc._canvas.width / _t._scaleX;
450             visible.height = cc._canvas.height / _t._scaleY;
451             visible.x = -vp.x / _t._scaleX;
452             visible.y = -vp.y / _t._scaleY;
453         }
454 
455         // reset director's member variables to fit visible rect
456         var director = cc.director;
457         director._winSizeInPoints = _t.getDesignResolutionSize();
458         cc.winSize.width = director._winSizeInPoints.width;
459         cc.winSize.height = director._winSizeInPoints.height;
460 
461         policy.postApply(_t);
462 
463         if (cc._renderType == cc._RENDER_TYPE_WEBGL) {
464             // reset director's member variables to fit visible rect
465             director._createStatsLabel();
466             director.setGLDefaultValues();
467         }
468 
469         _t._originalScaleX = _t._scaleX;
470         _t._originalScaleY = _t._scaleY;
471         // For editbox
472         if (cc.DOM)
473             cc.DOM._resetEGLViewDiv();
474         cc.visibleRect && cc.visibleRect.init(_t.getVisibleSize());
475     },
476 
477     /**
478      * Get design resolution size.
479      * Default resolution size is the same as 'getFrameSize'.
480      * @return {cc.Size}
481      */
482     getDesignResolutionSize: function () {
483         return cc.size(this._designResolutionSize.width, this._designResolutionSize.height);
484     },
485 
486     /**
487      * Set opengl view port rectangle with points.
488      * @param {Number} x
489      * @param {Number} y
490      * @param {Number} w width
491      * @param {Number} h height
492      */
493     setViewPortInPoints: function (x, y, w, h) {
494         var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY;
495         cc._renderContext.viewport((x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor),
496             (y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor),
497             (w * locScaleX * locFrameZoomFactor),
498             (h * locScaleY * locFrameZoomFactor));
499     },
500 
501     /**
502      * Set Scissor rectangle with points.
503      * @param {Number} x
504      * @param {Number} y
505      * @param {Number} w
506      * @param {Number} h
507      */
508     setScissorInPoints: function (x, y, w, h) {
509         var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY;
510         cc._renderContext.scissor((x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor),
511             (y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor),
512             (w * locScaleX * locFrameZoomFactor),
513             (h * locScaleY * locFrameZoomFactor));
514     },
515 
516     /**
517      * Get whether GL_SCISSOR_TEST is enable
518      */
519     isScissorEnabled: function () {
520         var gl = cc._renderContext;
521         return gl.isEnabled(gl.SCISSOR_TEST);
522     },
523 
524     /**
525      * Get the current scissor rectangle
526      * @return {cc.Rect}
527      */
528     getScissorRect: function () {
529         var gl = cc._renderContext, scaleX = this._scaleX, scaleY = this._scaleY;
530         var boxArr = gl.getParameter(gl.SCISSOR_BOX);
531         return cc.rect((boxArr[0] - this._viewPortRect.x) / scaleX, (boxArr[1] - this._viewPortRect.y) / scaleY,
532             boxArr[2] / scaleX, boxArr[3] / scaleY);
533     },
534 
535     /**
536      * @param {String} viewName
537      */
538     setViewName: function (viewName) {
539         if (viewName != null && viewName.length > 0) {
540             this._viewName = viewName;
541         }
542     },
543 
544     /**
545      * get view name
546      * @return {String}
547      */
548     getViewName: function () {
549         return this._viewName;
550     },
551 
552     /**
553      * Get the opengl view port rectangle.
554      */
555     getViewPortRect: function () {
556         return this._viewPortRect;
557     },
558 
559     /**
560      * Get scale factor of the horizontal direction.
561      */
562     getScaleX: function () {
563         return this._scaleX;
564     },
565 
566     /**
567      * Get scale factor of the vertical direction.
568      */
569     getScaleY: function () {
570         return this._scaleY;
571     },
572 
573     /**
574      * Get device pixel ratio for retina display.
575      */
576     getDevicePixelRatio: function() {
577         return this._devicePixelRatio;
578     },
579 
580     /**
581      * Get the real location in view
582      */
583     convertToLocationInView: function (tx, ty, relatedPos) {
584         return {x: this._devicePixelRatio * (tx - relatedPos.left), y: this._devicePixelRatio * (relatedPos.top + relatedPos.height - ty)};
585     },
586 
587     _convertMouseToLocationInView: function(point, relatedPos) {
588         var locViewPortRect = this._viewPortRect, _t = this;
589         point.x = ((_t._devicePixelRatio * (point.x - relatedPos.left)) - locViewPortRect.x) / _t._scaleX;
590         point.y = (_t._devicePixelRatio * (relatedPos.top + relatedPos.height - point.y) - locViewPortRect.y) / _t._scaleY;
591     },
592 
593     _convertTouchesWithScale: function(touches){
594         var locViewPortRect = this._viewPortRect, locScaleX = this._scaleX, locScaleY = this._scaleY, selTouch, selPoint, selPrePoint;
595         for( var i = 0; i < touches.length; i ++){
596             selTouch = touches[i];
597             selPoint = selTouch._point;
598 	        selPrePoint = selTouch._prevPoint;
599             selTouch._setPoint((selPoint.x - locViewPortRect.x) / locScaleX,
600                 (selPoint.y - locViewPortRect.y) / locScaleY);
601             selTouch._setPrevPoint((selPrePoint.x - locViewPortRect.x) / locScaleX,
602                 (selPrePoint.y - locViewPortRect.y) / locScaleY);
603         }
604     }
605 });
606 
607 cc.EGLView._getInstance = function () {
608     if (!this._instance) {
609         this._instance = this._instance || new cc.EGLView();
610         this._instance.initialize();
611     }
612     return this._instance;
613 };
614 
615 /**
616  * <p>cc.ContainerStrategy class is the root strategy class of container's scale strategy,
617  * it controls the behavior of how to scale the cc.container and cc._canvas object</p>
618  *
619  * @class
620  * @extends cc.Class
621  */
622 cc.ContainerStrategy = cc.Class.extend(/** @lends cc.ContainerStrategy# */{
623     /**
624      * Manipulation before appling the strategy
625      * @param {cc.view} The target view
626      */
627     preApply: function (view) {
628     },
629 
630     /**
631      * Function to apply this strategy
632      * @param {cc.view} view
633      * @param {cc.Size} designedResolution
634      */
635     apply: function (view, designedResolution) {
636     },
637 
638     /**
639      * Manipulation after applying the strategy
640      * @param {cc.view} view  The target view
641      */
642     postApply: function (view) {
643 
644     },
645 
646     _setupContainer: function (view, w, h) {
647         var frame = view._frame;
648         if (this._autoFullScreen && cc.sys.isMobile && frame == document.documentElement) {
649             // Automatically full screen when user touches on mobile version
650             cc.screen.autoFullScreen(frame);
651         }
652 
653         var locCanvasElement = cc._canvas, locContainer = cc.container;
654         // Setup container
655         locContainer.style.width = locCanvasElement.style.width = w + "px";
656         locContainer.style.height = locCanvasElement.style.height = h + "px";
657         // Setup pixel ratio for retina display
658         var devicePixelRatio = view._devicePixelRatio = 1;
659         if (view.isRetinaEnabled())
660             devicePixelRatio = view._devicePixelRatio = window.devicePixelRatio || 1;
661         // Setup canvas
662         locCanvasElement.width = w * devicePixelRatio;
663         locCanvasElement.height = h * devicePixelRatio;
664 
665         var body = document.body, style;
666         if (body && (style = body.style)) {
667             style.paddingTop = style.paddingTop || "0px";
668             style.paddingRight = style.paddingRight || "0px";
669             style.paddingBottom = style.paddingBottom || "0px";
670             style.paddingLeft = style.paddingLeft || "0px";
671             style.borderTop = style.borderTop || "0px";
672             style.borderRight = style.borderRight || "0px";
673             style.borderBottom = style.borderBottom || "0px";
674             style.borderLeft = style.borderLeft || "0px";
675             style.marginTop = style.marginTop || "0px";
676             style.marginRight = style.marginRight || "0px";
677             style.marginBottom = style.marginBottom || "0px";
678             style.marginLeft = style.marginLeft || "0px";
679         }
680     },
681 
682     _fixContainer: function () {
683         // Add container to document body
684         document.body.insertBefore(cc.container, document.body.firstChild);
685         // Set body's width height to window's size, and forbid overflow, so that game will be centered
686         var bs = document.body.style;
687         bs.width = window.innerWidth + "px";
688         bs.height = window.innerHeight + "px";
689         bs.overflow = "hidden";
690         // Body size solution doesn't work on all mobile browser so this is the aleternative: fixed container
691         var contStyle = cc.container.style;
692         contStyle.position = "fixed";
693         contStyle.left = contStyle.top = "0px";
694         // Reposition body
695         document.body.scrollTop = 0;
696     }
697 });
698 
699 /**
700  * <p>cc.ContentStrategy class is the root strategy class of content's scale strategy,
701  * it controls the behavior of how to scale the scene and setup the viewport for the game</p>
702  *
703  * @class
704  * @extends cc.Class
705  */
706 cc.ContentStrategy = cc.Class.extend(/** @lends cc.ContentStrategy# */{
707 
708     _result: {
709         scale: [1, 1],
710         viewport: null
711     },
712 
713     _buildResult: function (containerW, containerH, contentW, contentH, scaleX, scaleY) {
714 	    // Makes content fit better the canvas
715 	    Math.abs(containerW - contentW) < 2 && (contentW = containerW);
716 	    Math.abs(containerH - contentH) < 2 && (contentH = containerH);
717 
718         var viewport = cc.rect(Math.round((containerW - contentW) / 2),
719                                Math.round((containerH - contentH) / 2),
720                                contentW, contentH);
721 
722         // Translate the content
723         if (cc._renderType == cc._RENDER_TYPE_CANVAS)
724             cc._renderContext.translate(viewport.x, viewport.y + contentH);
725 
726         this._result.scale = [scaleX, scaleY];
727         this._result.viewport = viewport;
728         return this._result;
729     },
730 
731     /**
732      * Manipulation before applying the strategy
733      * @param {cc.view} view The target view
734      */
735     preApply: function (view) {
736     },
737 
738     /**
739      * Function to apply this strategy
740      * The return value is {scale: [scaleX, scaleY], viewport: {cc.Rect}},
741      * The target view can then apply these value to itself, it's preferred not to modify directly its private variables
742      * @param {cc.view} view
743      * @param {cc.Size} designedResolution
744      * @return {object} scaleAndViewportRect
745      */
746     apply: function (view, designedResolution) {
747         return {"scale": [1, 1]};
748     },
749 
750     /**
751      * Manipulation after applying the strategy
752      * @param {cc.view} view The target view
753      */
754     postApply: function (view) {
755     }
756 });
757 
758 (function () {
759 
760 // Container scale strategys
761     var EqualToFrame = cc.ContainerStrategy.extend({
762         apply: function (view) {
763             this._setupContainer(view, view._frameSize.width, view._frameSize.height);
764         }
765     });
766 
767     var ProportionalToFrame = cc.ContainerStrategy.extend({
768         apply: function (view, designedResolution) {
769             var frameW = view._frameSize.width, frameH = view._frameSize.height, containerStyle = cc.container.style,
770                 designW = designedResolution.width, designH = designedResolution.height,
771                 scaleX = frameW / designW, scaleY = frameH / designH,
772                 containerW, containerH;
773 
774             scaleX < scaleY ? (containerW = frameW, containerH = designH * scaleX) : (containerW = designW * scaleY, containerH = frameH);
775 
776             // Adjust container size with integer value
777             var offx = Math.round((frameW - containerW) / 2);
778             var offy = Math.round((frameH - containerH) / 2);
779             containerW = frameW - 2 * offx;
780             containerH = frameH - 2 * offy;
781 
782             this._setupContainer(view, containerW, containerH);
783             // Setup container's margin
784             containerStyle.marginLeft = offx + "px";
785             containerStyle.marginRight = offx + "px";
786             containerStyle.marginTop = offy + "px";
787             containerStyle.marginBottom = offy + "px";
788         }
789     });
790 
791     var EqualToWindow = EqualToFrame.extend({
792         preApply: function (view) {
793 	        this._super(view);
794             view._frame = document.documentElement;
795         },
796 
797         apply: function (view) {
798             this._super(view);
799             this._fixContainer();
800         }
801     });
802 
803     var ProportionalToWindow = ProportionalToFrame.extend({
804         preApply: function (view) {
805 	        this._super(view);
806             view._frame = document.documentElement;
807         },
808 
809         apply: function (view, designedResolution) {
810             this._super(view, designedResolution);
811             this._fixContainer();
812         }
813     });
814 
815     var OriginalContainer = cc.ContainerStrategy.extend({
816         apply: function (view) {
817             this._setupContainer(view, cc._canvas.width, cc._canvas.height);
818         }
819     });
820 
821 // #NOT STABLE on Android# Alias: Strategy that makes the container's size equals to the window's size
822 //    cc.ContainerStrategy.EQUAL_TO_WINDOW = new EqualToWindow();
823 // #NOT STABLE on Android# Alias: Strategy that scale proportionally the container's size to window's size
824 //    cc.ContainerStrategy.PROPORTION_TO_WINDOW = new ProportionalToWindow();
825 // Alias: Strategy that makes the container's size equals to the frame's size
826     cc.ContainerStrategy.EQUAL_TO_FRAME = new EqualToFrame();
827 // Alias: Strategy that scale proportionally the container's size to frame's size
828     cc.ContainerStrategy.PROPORTION_TO_FRAME = new ProportionalToFrame();
829 // Alias: Strategy that keeps the original container's size
830     cc.ContainerStrategy.ORIGINAL_CONTAINER = new OriginalContainer();
831 
832 // Content scale strategys
833     var ExactFit = cc.ContentStrategy.extend({
834         apply: function (view, designedResolution) {
835             var containerW = cc._canvas.width, containerH = cc._canvas.height,
836                 scaleX = containerW / designedResolution.width, scaleY = containerH / designedResolution.height;
837 
838             return this._buildResult(containerW, containerH, containerW, containerH, scaleX, scaleY);
839         }
840     });
841 
842     var ShowAll = cc.ContentStrategy.extend({
843         apply: function (view, designedResolution) {
844             var containerW = cc._canvas.width, containerH = cc._canvas.height,
845                 designW = designedResolution.width, designH = designedResolution.height,
846                 scaleX = containerW / designW, scaleY = containerH / designH, scale = 0,
847                 contentW, contentH;
848 
849 	        scaleX < scaleY ? (scale = scaleX, contentW = containerW, contentH = designH * scale)
850                 : (scale = scaleY, contentW = designW * scale, contentH = containerH);
851 
852             return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
853         }
854     });
855 
856     var NoBorder = cc.ContentStrategy.extend({
857         apply: function (view, designedResolution) {
858             var containerW = cc._canvas.width, containerH = cc._canvas.height,
859                 designW = designedResolution.width, designH = designedResolution.height,
860                 scaleX = containerW / designW, scaleY = containerH / designH, scale,
861                 contentW, contentH;
862 
863             scaleX < scaleY ? (scale = scaleY, contentW = designW * scale, contentH = containerH)
864                 : (scale = scaleX, contentW = containerW, contentH = designH * scale);
865 
866             return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
867         }
868     });
869 
870     var FixedHeight = cc.ContentStrategy.extend({
871         apply: function (view, designedResolution) {
872             var containerW = cc._canvas.width, containerH = cc._canvas.height,
873                 designH = designedResolution.height, scale = containerH / designH,
874                 contentW = containerW, contentH = containerH;
875 
876             return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
877         },
878 
879         postApply: function (view) {
880             cc.director._winSizeInPoints = view.getVisibleSize();
881         }
882     });
883 
884     var FixedWidth = cc.ContentStrategy.extend({
885         apply: function (view, designedResolution) {
886             var containerW = cc._canvas.width, containerH = cc._canvas.height,
887                 designW = designedResolution.width, scale = containerW / designW,
888                 contentW = containerW, contentH = containerH;
889 
890             return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
891         },
892 
893         postApply: function (view) {
894             cc.director._winSizeInPoints = view.getVisibleSize();
895         }
896     });
897 
898 // Alias: Strategy to scale the content's size to container's size, non proportional
899     cc.ContentStrategy.EXACT_FIT = new ExactFit();
900 // Alias: Strategy to scale the content's size proportionally to maximum size and keeps the whole content area to be visible
901     cc.ContentStrategy.SHOW_ALL = new ShowAll();
902 // Alias: Strategy to scale the content's size proportionally to fill the whole container area
903     cc.ContentStrategy.NO_BORDER = new NoBorder();
904 // Alias: Strategy to scale the content's height to container's height and proportionally scale its width
905     cc.ContentStrategy.FIXED_HEIGHT = new FixedHeight();
906 // Alias: Strategy to scale the content's width to container's width and proportionally scale its height
907     cc.ContentStrategy.FIXED_WIDTH = new FixedWidth();
908 
909 })();
910 
911 /**
912  * <p>cc.ResolutionPolicy class is the root strategy class of scale strategy,
913  * its main task is to maintain the compatibility with Cocos2d-x</p>
914  *
915  * @class
916  * @extends cc.Class
917  */
918 cc.ResolutionPolicy = cc.Class.extend(/** @lends cc.ResolutionPolicy# */{
919 	_containerStrategy: null,
920     _contentStrategy: null,
921 
922     ctor: function (containerStg, contentStg) {
923         this.setContainerStrategy(containerStg);
924         this.setContentStrategy(contentStg);
925     },
926 
927     /**
928      * Manipulation before applying the resolution policy
929      * @param {cc.view} view The target view
930      */
931     preApply: function (view) {
932         this._containerStrategy.preApply(view);
933         this._contentStrategy.preApply(view);
934     },
935 
936     /**
937      * Function to apply this resolution policy
938      * The return value is {scale: [scaleX, scaleY], viewport: {cc.Rect}},
939      * The target view can then apply these value to itself, it's preferred not to modify directly its private variables
940      * @param {cc.view} view The target view
941      * @param {cc.Size} designedResolution The user defined design resolution
942      * @return {object} An object contains the scale X/Y values and the viewport rect
943      */
944     apply: function (view, designedResolution) {
945         this._containerStrategy.apply(view, designedResolution);
946         return this._contentStrategy.apply(view, designedResolution);
947     },
948 
949     /**
950      * Manipulation after appyling the strategy
951      * @param {cc.view} view The target view
952      */
953     postApply: function (view) {
954         this._containerStrategy.postApply(view);
955         this._contentStrategy.postApply(view);
956     },
957 
958     /**
959      * Setup the container's scale strategy
960      * @param {cc.ContainerStrategy} containerStg
961      */
962     setContainerStrategy: function (containerStg) {
963         if (containerStg instanceof cc.ContainerStrategy)
964             this._containerStrategy = containerStg;
965     },
966 
967     /**
968      * Setup the content's scale strategy
969      * @param {cc.ContentStrategy} contentStg
970      */
971     setContentStrategy: function (contentStg) {
972         if (contentStg instanceof cc.ContentStrategy)
973             this._contentStrategy = contentStg;
974     }
975 });
976 
977 /*
978  * @memberOf cc.ResolutionPolicy#
979  * @name EXACT_FIT
980  * @const
981  * @static
982  * The entire application is visible in the specified area without trying to preserve the original aspect ratio.<br/>
983  * Distortion can occur, and the application may appear stretched or compressed.
984  */
985 cc.ResolutionPolicy.EXACT_FIT = 0;
986 
987 /*
988  * @memberOf cc.ResolutionPolicy#
989  * @name NO_BORDER
990  * @const
991  * @static
992  * The entire application fills the specified area, without distortion but possibly with some cropping,<br/>
993  * while maintaining the original aspect ratio of the application.
994  */
995 cc.ResolutionPolicy.NO_BORDER = 1;
996 
997 /*
998  * @memberOf cc.ResolutionPolicy#
999  * @name SHOW_ALL
1000  * @const
1001  * @static
1002  * The entire application is visible in the specified area without distortion while maintaining the original<br/>
1003  * aspect ratio of the application. Borders can appear on two sides of the application.
1004  */
1005 cc.ResolutionPolicy.SHOW_ALL = 2;
1006 
1007 /*
1008  * @memberOf cc.ResolutionPolicy#
1009  * @name FIXED_HEIGHT
1010  * @const
1011  * @static
1012  * The application takes the height of the design resolution size and modifies the width of the internal<br/>
1013  * canvas so that it fits the aspect ratio of the device<br/>
1014  * no distortion will occur however you must make sure your application works on different<br/>
1015  * aspect ratios
1016  */
1017 cc.ResolutionPolicy.FIXED_HEIGHT = 3;
1018 
1019 /*
1020  * @memberOf cc.ResolutionPolicy#
1021  * @name FIXED_WIDTH
1022  * @const
1023  * @static
1024  * The application takes the width of the design resolution size and modifies the height of the internal<br/>
1025  * canvas so that it fits the aspect ratio of the device<br/>
1026  * no distortion will occur however you must make sure your application works on different<br/>
1027  * aspect ratios
1028  */
1029 cc.ResolutionPolicy.FIXED_WIDTH = 4;
1030 
1031 /*
1032  * @memberOf cc.ResolutionPolicy#
1033  * @name UNKNOWN
1034  * @const
1035  * @static
1036  * Unknow policy
1037  */
1038 cc.ResolutionPolicy.UNKNOWN = 5;