1 /****************************************************************************
  2  Copyright (c) 2008-2010 Ricardo Quesada
  3  Copyright (c) 2011-2012 cocos2d-x.org
  4  Copyright (c) 2013-2014 Chukong Technologies 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  * cc.view is the shared view object.
 35  * @namespace
 36  * @name cc.view
 37  */
 38 cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
 39     _delegate: null,
 40     // Size of parent node that contains cc.container and cc._canvas
 41     _frameSize: null,
 42     // resolution size, it is the size appropriate for the app resources.
 43     _designResolutionSize: null,
 44     _originalDesignResolutionSize: null,
 45     // Viewport is the container's rect related to content's coordinates in pixel
 46     _viewPortRect: null,
 47     // The visible rect in content's coordinate in point
 48     _visibleRect: null,
 49 	_retinaEnabled: false,
 50     _autoFullScreen: true,
 51     // The device's pixel ratio (for retina displays)
 52     _devicePixelRatio: 1,
 53     // the view name
 54     _viewName: "",
 55     // Custom callback for resize event
 56     _resizeCallback: null,
 57     _scaleX: 1,
 58     _originalScaleX: 1,
 59     _scaleY: 1,
 60     _originalScaleY: 1,
 61     _indexBitsUsed: 0,
 62     _maxTouches: 5,
 63     _resolutionPolicy: null,
 64     _rpExactFit: null,
 65     _rpShowAll: null,
 66     _rpNoBorder: null,
 67     _rpFixedHeight: null,
 68     _rpFixedWidth: null,
 69     _initialized: false,
 70 
 71     _captured: false,
 72     _wnd: null,
 73     _hDC: null,
 74     _hRC: null,
 75     _supportTouch: false,
 76     _contentTranslateLeftTop: null,
 77 
 78     // Parent node that contains cc.container and cc._canvas
 79     _frame: null,
 80     _frameZoomFactor: 1.0,
 81     __resizeWithBrowserSize: false,
 82     _isAdjustViewPort: true,
 83 
 84     ctor: function () {
 85         var _t = this, d = document, _strategyer = cc.ContainerStrategy, _strategy = cc.ContentStrategy;
 86         _t._frame = (cc.container.parentNode === d.body) ? d.documentElement : cc.container.parentNode;
 87         _t._frameSize = cc.size(0, 0);
 88         _t._initFrameSize();
 89 
 90         var w = cc._canvas.width, h = cc._canvas.height;
 91         _t._designResolutionSize = cc.size(w, h);
 92         _t._originalDesignResolutionSize = cc.size(w, h);
 93         _t._viewPortRect = cc.rect(0, 0, w, h);
 94         _t._visibleRect = cc.rect(0, 0, w, h);
 95         _t._contentTranslateLeftTop = {left: 0, top: 0};
 96         _t._viewName = "Cocos2dHTML5";
 97 
 98 	    var sys = cc.sys;
 99         _t.enableRetina(sys.os == sys.OS_IOS || sys.os == sys.OS_OSX);
100         cc.visibleRect && cc.visibleRect.init(_t._visibleRect);
101 
102         // Setup system default resolution policies
103         _t._rpExactFit = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.EXACT_FIT);
104         _t._rpShowAll = new cc.ResolutionPolicy(_strategyer.PROPORTION_TO_FRAME, _strategy.SHOW_ALL);
105         _t._rpNoBorder = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.NO_BORDER);
106         _t._rpFixedHeight = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_HEIGHT);
107         _t._rpFixedWidth = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_WIDTH);
108 
109         _t._hDC = cc._canvas;
110         _t._hRC = cc._renderContext;
111     },
112 
113     // Resize helper functions
114     _resizeEvent: function () {
115         var width = this._originalDesignResolutionSize.width;
116         var height = this._originalDesignResolutionSize.height;
117         if (this._resizeCallback) {
118             this._initFrameSize();
119             this._resizeCallback.call();
120         }
121         if (width > 0)
122             this.setDesignResolutionSize(width, height, this._resolutionPolicy);
123     },
124 
125     resizeWithBrowserSize: function (enabled) {
126         var adjustSize, _t = this;
127         if (enabled) {
128             //enable
129             if (!_t.__resizeWithBrowserSize) {
130                 _t.__resizeWithBrowserSize = true;
131                 adjustSize = _t._resizeEvent.bind(_t);
132                 cc._addEventListener(window, 'resize', adjustSize, false);
133             }
134         } else {
135             //disable
136             if (_t.__resizeWithBrowserSize) {
137                 _t.__resizeWithBrowserSize = true;
138                 adjustSize = _t._resizeEvent.bind(_t);
139                 window.removeEventListener('resize', adjustSize, false);
140             }
141         }
142     },
143 
144     setResizeCallback: function (callback) {
145         if (typeof callback == "function" || callback == null) {
146             this._resizeCallback = callback;
147         }
148     },
149 
150     _initFrameSize: function () {
151         var locFrameSize = this._frameSize;
152         locFrameSize.width = this._frame.clientWidth;
153         locFrameSize.height = this._frame.clientHeight;
154     },
155 
156     // hack
157     _adjustSizeKeepCanvasSize: function () {
158         var designWidth = this._originalDesignResolutionSize.width;
159         var designHeight = this._originalDesignResolutionSize.height;
160         if (designWidth > 0)
161             this.setDesignResolutionSize(designWidth, designHeight, this._resolutionPolicy);
162     },
163 
164     _setViewPortMeta: function (width, height) {
165         if (this._isAdjustViewPort) {
166 	        var viewportMetas = {"user-scalable": "no", "maximum-scale": "1.0", "initial-scale": "1.0"}, elems = document.getElementsByName("viewport"), vp, content;
167             if (elems.length == 0) {
168                 vp = cc.newElement("meta");
169                 vp.name = "viewport";
170                 vp.content = "";
171                 document.head.appendChild(vp);
172             }
173             else vp = elems[0];
174 
175 	        // For avoiding Android Firefox issue, to remove once firefox fixes its issue.
176 	        if (cc.sys.isMobile && cc.sys.browserType == cc.sys.BROWSER_TYPE_FIREFOX) {
177 		        vp.content = "initial-scale:1";
178 		        return;
179 	        }
180 
181             content = vp.content;
182             for (var key in viewportMetas) {
183                 var pattern = new RegExp(key);
184                 if (!pattern.test(content)) {
185                     content += (content == "" ? "" : ",") + key + "=" + viewportMetas[key];
186                 }
187             }
188             /*
189             if(width<=320){
190                 width = 321;
191             }
192             if(height)
193                 content ="height="+height+","+content;
194             if(width)
195                 content ="width="+width+","+content;
196             */
197             vp.content = content;
198         }
199     },
200 
201     // RenderTexture hacker
202     _setScaleXYForRenderTexture: function () {
203         //hack for RenderTexture on canvas mode when adapting multiple resolution resources
204         var scaleFactor = cc.contentScaleFactor();
205         this._scaleX = scaleFactor;
206         this._scaleY = scaleFactor;
207     },
208 
209     // Other helper functions
210     _resetScale: function () {
211         this._scaleX = this._originalScaleX;
212         this._scaleY = this._originalScaleY;
213     },
214 
215     // Useless, just make sure the compatibility temporarily, should be removed
216     _adjustSizeToBrowser: function () {
217     },
218 
219     /**
220      * init
221      */
222     initialize: function () {
223         this._initialized = true;
224     },
225 
226     adjustViewPort: function (enabled) {
227         this._isAdjustViewPort = enabled;
228     },
229 
230 	/**
231 	 * Retina support is enabled by default for Apple device but disabled for other devices,
232 	 * it takes effect only when you called setDesignResolutionPolicy
233 	 * @param {Boolean} enabled  Enable or disable retina display
234 	 */
235 	enableRetina: function(enabled) {
236 		this._retinaEnabled = enabled ? true : false;
237 	},
238 
239 	/**
240 	 * Check whether retina display is enabled.
241 	 * @return {Boolean}
242 	 */
243 	isRetinaEnabled: function() {
244 		return this._retinaEnabled;
245 	},
246 
247     /**
248      * If enabled, the application will try automatically to enter full screen mode on mobile devices
249      * You can pass true as parameter to enable it and disable it by passing false
250      * @param {Boolean} enabled  Enable or disable auto full screen on mobile devices
251      */
252     enableAutoFullScreen: function(enabled) {
253         this._autoFullScreen = enabled ? true : false;
254     },
255 
256     /**
257      * Check whether auto full screen is enabled.
258      * @return {Boolean}
259      */
260     isAutoFullScreenEnabled: function() {
261         return this._autoFullScreen;
262     },
263 
264     /**
265      * Force destroying EGL view, subclass must implement this method.
266      */
267     end: function () {
268     },
269 
270     /**
271      * Get whether render system is ready(no matter opengl or canvas),
272      * this name is for the compatibility with cocos2d-x, subclass must implement this method.
273      * @return {Boolean}
274      */
275     isOpenGLReady: function () {
276         return (this._hDC != null && this._hRC != null);
277     },
278 
279     /*
280      * Set zoom factor for frame. This method is for debugging big resolution (e.g.new ipad) app on desktop.
281      * @param {Number} zoomFactor
282      */
283     setFrameZoomFactor: function (zoomFactor) {
284         this._frameZoomFactor = zoomFactor;
285         this.centerWindow();
286         cc.director.setProjection(cc.director.getProjection());
287     },
288 
289     /**
290      * Exchanges the front and back buffers, subclass must implement this method.
291      */
292     swapBuffers: function () {
293     },
294 
295     /**
296      * Open or close IME keyboard , subclass must implement this method.
297      */
298     setIMEKeyboardState: function (isOpen) {
299     },
300 
301     /**
302      * <p>
303      *   The resolution translate on EGLView
304      * </p>
305      * @param {Number} offsetLeft
306      * @param {Number} offsetTop
307      */
308     setContentTranslateLeftTop: function (offsetLeft, offsetTop) {
309         this._contentTranslateLeftTop = {left: offsetLeft, top: offsetTop};
310     },
311 
312     /**
313      * <p>
314      *   get the resolution translate on EGLView
315      * </p>
316      * @return {cc.Size|Object}
317      */
318     getContentTranslateLeftTop: function () {
319         return this._contentTranslateLeftTop;
320     },
321 
322     /**
323      * Get the frame size of EGL view.
324      * In general, it returns the screen size since the EGL view is a fullscreen view.
325      * @return {cc.Size}
326      */
327     getFrameSize: function () {
328         return cc.size(this._frameSize.width, this._frameSize.height);
329     },
330 
331     /**
332      * Set the frame size of EGL view.
333      * @param {Number} width
334      * @param {Number} height
335      */
336     setFrameSize: function (width, height) {
337         this._frameSize.width = width;
338         this._frameSize.height = height;
339         this._frame.style.width = width + "px";
340         this._frame.style.height = height + "px";
341         //this.centerWindow();
342         this._resizeEvent();
343         cc.director.setProjection(cc.director.getProjection());
344     },
345 
346     centerWindow: function () {
347     },
348 
349     /**
350      * Get the visible area size of OpenGL view port.
351      * @return {cc.Size}
352      */
353     getVisibleSize: function () {
354         return cc.size(this._visibleRect.width,this._visibleRect.height);
355     },
356 
357     /**
358      * Get the visible origin of OpenGL view port.
359      * @return {cc.Point}
360      */
361     getVisibleOrigin: function () {
362         return cc.p(this._visibleRect.x,this._visibleRect.y);
363     },
364 
365     canSetContentScaleFactor: function () {
366         return true;
367     },
368 
369     /**
370      * Get the current resolution policy
371      * @return {cc.ResolutionPolicy}
372      */
373     getResolutionPolicy: function () {
374         return this._resolutionPolicy;
375     },
376 
377     /**
378      * Set the current resolution policy
379      * @param {cc.ResolutionPolicy|Number} resolutionPolicy
380      */
381     setResolutionPolicy: function (resolutionPolicy) {
382         var _t = this;
383         if (resolutionPolicy instanceof cc.ResolutionPolicy) {
384             _t._resolutionPolicy = resolutionPolicy;
385         }
386         // Ensure compatibility with JSB
387         else {
388             var _locPolicy = cc.ResolutionPolicy;
389             if(resolutionPolicy === _locPolicy.EXACT_FIT)
390                 _t._resolutionPolicy = _t._rpExactFit;
391             if(resolutionPolicy === _locPolicy.SHOW_ALL)
392                 _t._resolutionPolicy = _t._rpShowAll;
393             if(resolutionPolicy === _locPolicy.NO_BORDER)
394                 _t._resolutionPolicy = _t._rpNoBorder;
395             if(resolutionPolicy === _locPolicy.FIXED_HEIGHT)
396                 _t._resolutionPolicy = _t._rpFixedHeight;
397             if(resolutionPolicy === _locPolicy.FIXED_WIDTH)
398                 _t._resolutionPolicy = _t._rpFixedWidth;
399         }
400     },
401 
402     /**
403      * Set the design resolution size.
404      * @param {Number} width Design resolution width.
405      * @param {Number} height Design resolution height.
406      * @param {cc.ResolutionPolicy|Number} resolutionPolicy The resolution policy desired, you may choose:
407      * [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.
408      * [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.
409      * [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.
410      * [4] ResolutionFixedHeight    Scale the content's height to screen's height and proportionally scale its width
411      * [5] ResolutionFixedWidth     Scale the content's width to screen's width and proportionally scale its height
412      * [cc.ResolutionPolicy]        Custom resolution policy, constructed by cc.ResolutionPolicy
413      */
414     setDesignResolutionSize: function (width, height, resolutionPolicy) {
415         // Defensive code
416         if (isNaN(width) || width == 0 || isNaN(height) || height == 0) {
417             cc.log(cc._LogInfos.EGLView_setDesignResolutionSize);
418             return;
419         }
420         var _t = this;
421         _t.setResolutionPolicy(resolutionPolicy);
422         var policy = _t._resolutionPolicy;
423         if (policy)
424             policy.preApply(_t);
425         else {
426             cc.log(cc._LogInfos.EGLView_setDesignResolutionSize_2);
427             return;
428         }
429 
430         // Reinit frame size
431         var frameW = _t._frameSize.width, frameH = _t._frameSize.height;
432         if (cc.sys.isMobile)
433             _t._setViewPortMeta(_t._frameSize.width, _t._frameSize.height);
434         _t._initFrameSize();
435         // No change
436         if (resolutionPolicy == _t._resolutionPolicy
437             && width == _t._originalDesignResolutionSize.width && height == _t._originalDesignResolutionSize.height
438             && frameW == _t._frameSize.width && frameH == _t._frameSize.height)
439             return;
440         _t._designResolutionSize = cc.size(width, height);
441         _t._originalDesignResolutionSize = cc.size(width, height);
442 
443         var result = policy.apply(_t, _t._designResolutionSize);
444         if (result.scale && result.scale.length == 2) {
445             _t._scaleX = result.scale[0];
446             _t._scaleY = result.scale[1];
447         }
448         if (result.viewport) {
449             var vp = _t._viewPortRect = result.viewport, visible = _t._visibleRect;
450             visible.width = cc._canvas.width / _t._scaleX;
451             visible.height = cc._canvas.height / _t._scaleY;
452             visible.x = -vp.x / _t._scaleX;
453             visible.y = -vp.y / _t._scaleY;
454         }
455 
456         // reset director's member variables to fit visible rect
457         var director = cc.director;
458         cc.winSize.width = director._winSizeInPoints.width = _t._visibleRect.width;
459         cc.winSize.height = director._winSizeInPoints.height = _t._visibleRect.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._visibleRect);
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 (cc.view._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;