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  * @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         cc.winSize.width = director._winSizeInPoints.width = _t._visibleRect.width;
458         cc.winSize.height = director._winSizeInPoints.height = _t._visibleRect.height;
459 
460         policy.postApply(_t);
461 
462         if (cc._renderType == cc._RENDER_TYPE_WEBGL) {
463             // reset director's member variables to fit visible rect
464             director._createStatsLabel();
465             director.setGLDefaultValues();
466         }
467 
468         _t._originalScaleX = _t._scaleX;
469         _t._originalScaleY = _t._scaleY;
470         // For editbox
471         if (cc.DOM)
472             cc.DOM._resetEGLViewDiv();
473         cc.visibleRect && cc.visibleRect.init(_t.getVisibleSize());
474     },
475 
476     /**
477      * Get design resolution size.
478      * Default resolution size is the same as 'getFrameSize'.
479      * @return {cc.Size}
480      */
481     getDesignResolutionSize: function () {
482         return cc.size(this._designResolutionSize.width, this._designResolutionSize.height);
483     },
484 
485     /**
486      * Set opengl view port rectangle with points.
487      * @param {Number} x
488      * @param {Number} y
489      * @param {Number} w width
490      * @param {Number} h height
491      */
492     setViewPortInPoints: function (x, y, w, h) {
493         var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY;
494         cc._renderContext.viewport((x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor),
495             (y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor),
496             (w * locScaleX * locFrameZoomFactor),
497             (h * locScaleY * locFrameZoomFactor));
498     },
499 
500     /**
501      * Set Scissor rectangle with points.
502      * @param {Number} x
503      * @param {Number} y
504      * @param {Number} w
505      * @param {Number} h
506      */
507     setScissorInPoints: function (x, y, w, h) {
508         var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY;
509         cc._renderContext.scissor((x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor),
510             (y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor),
511             (w * locScaleX * locFrameZoomFactor),
512             (h * locScaleY * locFrameZoomFactor));
513     },
514 
515     /**
516      * Get whether GL_SCISSOR_TEST is enable
517      */
518     isScissorEnabled: function () {
519         var gl = cc._renderContext;
520         return gl.isEnabled(gl.SCISSOR_TEST);
521     },
522 
523     /**
524      * Get the current scissor rectangle
525      * @return {cc.Rect}
526      */
527     getScissorRect: function () {
528         var gl = cc._renderContext, scaleX = this._scaleX, scaleY = this._scaleY;
529         var boxArr = gl.getParameter(gl.SCISSOR_BOX);
530         return cc.rect((boxArr[0] - this._viewPortRect.x) / scaleX, (boxArr[1] - this._viewPortRect.y) / scaleY,
531             boxArr[2] / scaleX, boxArr[3] / scaleY);
532     },
533 
534     /**
535      * @param {String} viewName
536      */
537     setViewName: function (viewName) {
538         if (viewName != null && viewName.length > 0) {
539             this._viewName = viewName;
540         }
541     },
542 
543     /**
544      * get view name
545      * @return {String}
546      */
547     getViewName: function () {
548         return this._viewName;
549     },
550 
551     /**
552      * Get the opengl view port rectangle.
553      */
554     getViewPortRect: function () {
555         return this._viewPortRect;
556     },
557 
558     /**
559      * Get scale factor of the horizontal direction.
560      */
561     getScaleX: function () {
562         return this._scaleX;
563     },
564 
565     /**
566      * Get scale factor of the vertical direction.
567      */
568     getScaleY: function () {
569         return this._scaleY;
570     },
571 
572     /**
573      * Get device pixel ratio for retina display.
574      */
575     getDevicePixelRatio: function() {
576         return this._devicePixelRatio;
577     },
578 
579     /**
580      * Get the real location in view
581      */
582     convertToLocationInView: function (tx, ty, relatedPos) {
583         return {x: this._devicePixelRatio * (tx - relatedPos.left), y: this._devicePixelRatio * (relatedPos.top + relatedPos.height - ty)};
584     },
585 
586     _convertMouseToLocationInView: function(point, relatedPos) {
587         var locViewPortRect = this._viewPortRect, _t = this;
588         point.x = ((_t._devicePixelRatio * (point.x - relatedPos.left)) - locViewPortRect.x) / _t._scaleX;
589         point.y = (_t._devicePixelRatio * (relatedPos.top + relatedPos.height - point.y) - locViewPortRect.y) / _t._scaleY;
590     },
591 
592     _convertTouchesWithScale: function(touches){
593         var locViewPortRect = this._viewPortRect, locScaleX = this._scaleX, locScaleY = this._scaleY, selTouch, selPoint, selPrePoint;
594         for( var i = 0; i < touches.length; i ++){
595             selTouch = touches[i];
596             selPoint = selTouch._point;
597 	        selPrePoint = selTouch._prevPoint;
598             selTouch._setPoint((selPoint.x - locViewPortRect.x) / locScaleX,
599                 (selPoint.y - locViewPortRect.y) / locScaleY);
600             selTouch._setPrevPoint((selPrePoint.x - locViewPortRect.x) / locScaleX,
601                 (selPrePoint.y - locViewPortRect.y) / locScaleY);
602         }
603     }
604 });
605 
606 cc.EGLView._getInstance = function () {
607     if (!this._instance) {
608         this._instance = this._instance || new cc.EGLView();
609         this._instance.initialize();
610     }
611     return this._instance;
612 };
613 
614 /**
615  * <p>cc.ContainerStrategy class is the root strategy class of container's scale strategy,
616  * it controls the behavior of how to scale the cc.container and cc._canvas object</p>
617  *
618  * @class
619  * @extends cc.Class
620  */
621 cc.ContainerStrategy = cc.Class.extend(/** @lends cc.ContainerStrategy# */{
622     /**
623      * Manipulation before appling the strategy
624      * @param {cc.view} The target view
625      */
626     preApply: function (view) {
627     },
628 
629     /**
630      * Function to apply this strategy
631      * @param {cc.view} view
632      * @param {cc.Size} designedResolution
633      */
634     apply: function (view, designedResolution) {
635     },
636 
637     /**
638      * Manipulation after applying the strategy
639      * @param {cc.view} view  The target view
640      */
641     postApply: function (view) {
642 
643     },
644 
645     _setupContainer: function (view, w, h) {
646         var frame = view._frame;
647         if (this._autoFullScreen && cc.sys.isMobile && frame == document.documentElement) {
648             // Automatically full screen when user touches on mobile version
649             cc.screen.autoFullScreen(frame);
650         }
651 
652         var locCanvasElement = cc._canvas, locContainer = cc.container;
653         // Setup container
654         locContainer.style.width = locCanvasElement.style.width = w + "px";
655         locContainer.style.height = locCanvasElement.style.height = h + "px";
656         // Setup pixel ratio for retina display
657         var devicePixelRatio = view._devicePixelRatio = 1;
658         if (view.isRetinaEnabled())
659             devicePixelRatio = view._devicePixelRatio = window.devicePixelRatio || 1;
660         // Setup canvas
661         locCanvasElement.width = w * devicePixelRatio;
662         locCanvasElement.height = h * devicePixelRatio;
663 
664         var body = document.body, style;
665         if (body && (style = body.style)) {
666             style.paddingTop = style.paddingTop || "0px";
667             style.paddingRight = style.paddingRight || "0px";
668             style.paddingBottom = style.paddingBottom || "0px";
669             style.paddingLeft = style.paddingLeft || "0px";
670             style.borderTop = style.borderTop || "0px";
671             style.borderRight = style.borderRight || "0px";
672             style.borderBottom = style.borderBottom || "0px";
673             style.borderLeft = style.borderLeft || "0px";
674             style.marginTop = style.marginTop || "0px";
675             style.marginRight = style.marginRight || "0px";
676             style.marginBottom = style.marginBottom || "0px";
677             style.marginLeft = style.marginLeft || "0px";
678         }
679     },
680 
681     _fixContainer: function () {
682         // Add container to document body
683         document.body.insertBefore(cc.container, document.body.firstChild);
684         // Set body's width height to window's size, and forbid overflow, so that game will be centered
685         var bs = document.body.style;
686         bs.width = window.innerWidth + "px";
687         bs.height = window.innerHeight + "px";
688         bs.overflow = "hidden";
689         // Body size solution doesn't work on all mobile browser so this is the aleternative: fixed container
690         var contStyle = cc.container.style;
691         contStyle.position = "fixed";
692         contStyle.left = contStyle.top = "0px";
693         // Reposition body
694         document.body.scrollTop = 0;
695     }
696 });
697 
698 /**
699  * <p>cc.ContentStrategy class is the root strategy class of content's scale strategy,
700  * it controls the behavior of how to scale the scene and setup the viewport for the game</p>
701  *
702  * @class
703  * @extends cc.Class
704  */
705 cc.ContentStrategy = cc.Class.extend(/** @lends cc.ContentStrategy# */{
706 
707     _result: {
708         scale: [1, 1],
709         viewport: null
710     },
711 
712     _buildResult: function (containerW, containerH, contentW, contentH, scaleX, scaleY) {
713 	    // Makes content fit better the canvas
714 	    Math.abs(containerW - contentW) < 2 && (contentW = containerW);
715 	    Math.abs(containerH - contentH) < 2 && (contentH = containerH);
716 
717         var viewport = cc.rect(Math.round((containerW - contentW) / 2),
718                                Math.round((containerH - contentH) / 2),
719                                contentW, contentH);
720 
721         // Translate the content
722         if (cc._renderType == cc._RENDER_TYPE_CANVAS)
723             cc._renderContext.translate(viewport.x, viewport.y + contentH);
724 
725         this._result.scale = [scaleX, scaleY];
726         this._result.viewport = viewport;
727         return this._result;
728     },
729 
730     /**
731      * Manipulation before applying the strategy
732      * @param {cc.view} view The target view
733      */
734     preApply: function (view) {
735     },
736 
737     /**
738      * Function to apply this strategy
739      * The return value is {scale: [scaleX, scaleY], viewport: {cc.Rect}},
740      * The target view can then apply these value to itself, it's preferred not to modify directly its private variables
741      * @param {cc.view} view
742      * @param {cc.Size} designedResolution
743      * @return {object} scaleAndViewportRect
744      */
745     apply: function (view, designedResolution) {
746         return {"scale": [1, 1]};
747     },
748 
749     /**
750      * Manipulation after applying the strategy
751      * @param {cc.view} view The target view
752      */
753     postApply: function (view) {
754     }
755 });
756 
757 (function () {
758 
759 // Container scale strategys
760     var EqualToFrame = cc.ContainerStrategy.extend({
761         apply: function (view) {
762             this._setupContainer(view, view._frameSize.width, view._frameSize.height);
763         }
764     });
765 
766     var ProportionalToFrame = cc.ContainerStrategy.extend({
767         apply: function (view, designedResolution) {
768             var frameW = view._frameSize.width, frameH = view._frameSize.height, containerStyle = cc.container.style,
769                 designW = designedResolution.width, designH = designedResolution.height,
770                 scaleX = frameW / designW, scaleY = frameH / designH,
771                 containerW, containerH;
772 
773             scaleX < scaleY ? (containerW = frameW, containerH = designH * scaleX) : (containerW = designW * scaleY, containerH = frameH);
774 
775             // Adjust container size with integer value
776             var offx = Math.round((frameW - containerW) / 2);
777             var offy = Math.round((frameH - containerH) / 2);
778             containerW = frameW - 2 * offx;
779             containerH = frameH - 2 * offy;
780 
781             this._setupContainer(view, containerW, containerH);
782             // Setup container's margin
783             containerStyle.marginLeft = offx + "px";
784             containerStyle.marginRight = offx + "px";
785             containerStyle.marginTop = offy + "px";
786             containerStyle.marginBottom = offy + "px";
787         }
788     });
789 
790     var EqualToWindow = EqualToFrame.extend({
791         preApply: function (view) {
792 	        this._super(view);
793             view._frame = document.documentElement;
794         },
795 
796         apply: function (view) {
797             this._super(view);
798             this._fixContainer();
799         }
800     });
801 
802     var ProportionalToWindow = ProportionalToFrame.extend({
803         preApply: function (view) {
804 	        this._super(view);
805             view._frame = document.documentElement;
806         },
807 
808         apply: function (view, designedResolution) {
809             this._super(view, designedResolution);
810             this._fixContainer();
811         }
812     });
813 
814     var OriginalContainer = cc.ContainerStrategy.extend({
815         apply: function (view) {
816             this._setupContainer(view, cc._canvas.width, cc._canvas.height);
817         }
818     });
819 
820 // #NOT STABLE on Android# Alias: Strategy that makes the container's size equals to the window's size
821 //    cc.ContainerStrategy.EQUAL_TO_WINDOW = new EqualToWindow();
822 // #NOT STABLE on Android# Alias: Strategy that scale proportionally the container's size to window's size
823 //    cc.ContainerStrategy.PROPORTION_TO_WINDOW = new ProportionalToWindow();
824 // Alias: Strategy that makes the container's size equals to the frame's size
825     cc.ContainerStrategy.EQUAL_TO_FRAME = new EqualToFrame();
826 // Alias: Strategy that scale proportionally the container's size to frame's size
827     cc.ContainerStrategy.PROPORTION_TO_FRAME = new ProportionalToFrame();
828 // Alias: Strategy that keeps the original container's size
829     cc.ContainerStrategy.ORIGINAL_CONTAINER = new OriginalContainer();
830 
831 // Content scale strategys
832     var ExactFit = cc.ContentStrategy.extend({
833         apply: function (view, designedResolution) {
834             var containerW = cc._canvas.width, containerH = cc._canvas.height,
835                 scaleX = containerW / designedResolution.width, scaleY = containerH / designedResolution.height;
836 
837             return this._buildResult(containerW, containerH, containerW, containerH, scaleX, scaleY);
838         }
839     });
840 
841     var ShowAll = cc.ContentStrategy.extend({
842         apply: function (view, designedResolution) {
843             var containerW = cc._canvas.width, containerH = cc._canvas.height,
844                 designW = designedResolution.width, designH = designedResolution.height,
845                 scaleX = containerW / designW, scaleY = containerH / designH, scale = 0,
846                 contentW, contentH;
847 
848 	        scaleX < scaleY ? (scale = scaleX, contentW = containerW, contentH = designH * scale)
849                 : (scale = scaleY, contentW = designW * scale, contentH = containerH);
850 
851             return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
852         }
853     });
854 
855     var NoBorder = cc.ContentStrategy.extend({
856         apply: function (view, designedResolution) {
857             var containerW = cc._canvas.width, containerH = cc._canvas.height,
858                 designW = designedResolution.width, designH = designedResolution.height,
859                 scaleX = containerW / designW, scaleY = containerH / designH, scale,
860                 contentW, contentH;
861 
862             scaleX < scaleY ? (scale = scaleY, contentW = designW * scale, contentH = containerH)
863                 : (scale = scaleX, contentW = containerW, contentH = designH * scale);
864 
865             return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
866         }
867     });
868 
869     var FixedHeight = cc.ContentStrategy.extend({
870         apply: function (view, designedResolution) {
871             var containerW = cc._canvas.width, containerH = cc._canvas.height,
872                 designH = designedResolution.height, scale = containerH / designH,
873                 contentW = containerW, contentH = containerH;
874 
875             return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
876         },
877 
878         postApply: function (view) {
879             cc.director._winSizeInPoints = view.getVisibleSize();
880         }
881     });
882 
883     var FixedWidth = cc.ContentStrategy.extend({
884         apply: function (view, designedResolution) {
885             var containerW = cc._canvas.width, containerH = cc._canvas.height,
886                 designW = designedResolution.width, scale = containerW / designW,
887                 contentW = containerW, contentH = containerH;
888 
889             return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
890         },
891 
892         postApply: function (view) {
893             cc.director._winSizeInPoints = view.getVisibleSize();
894         }
895     });
896 
897 // Alias: Strategy to scale the content's size to container's size, non proportional
898     cc.ContentStrategy.EXACT_FIT = new ExactFit();
899 // Alias: Strategy to scale the content's size proportionally to maximum size and keeps the whole content area to be visible
900     cc.ContentStrategy.SHOW_ALL = new ShowAll();
901 // Alias: Strategy to scale the content's size proportionally to fill the whole container area
902     cc.ContentStrategy.NO_BORDER = new NoBorder();
903 // Alias: Strategy to scale the content's height to container's height and proportionally scale its width
904     cc.ContentStrategy.FIXED_HEIGHT = new FixedHeight();
905 // Alias: Strategy to scale the content's width to container's width and proportionally scale its height
906     cc.ContentStrategy.FIXED_WIDTH = new FixedWidth();
907 
908 })();
909 
910 /**
911  * <p>cc.ResolutionPolicy class is the root strategy class of scale strategy,
912  * its main task is to maintain the compatibility with Cocos2d-x</p>
913  *
914  * @class
915  * @extends cc.Class
916  */
917 cc.ResolutionPolicy = cc.Class.extend(/** @lends cc.ResolutionPolicy# */{
918 	_containerStrategy: null,
919     _contentStrategy: null,
920 
921     ctor: function (containerStg, contentStg) {
922         this.setContainerStrategy(containerStg);
923         this.setContentStrategy(contentStg);
924     },
925 
926     /**
927      * Manipulation before applying the resolution policy
928      * @param {cc.view} view The target view
929      */
930     preApply: function (view) {
931         this._containerStrategy.preApply(view);
932         this._contentStrategy.preApply(view);
933     },
934 
935     /**
936      * Function to apply this resolution policy
937      * The return value is {scale: [scaleX, scaleY], viewport: {cc.Rect}},
938      * The target view can then apply these value to itself, it's preferred not to modify directly its private variables
939      * @param {cc.view} view The target view
940      * @param {cc.Size} designedResolution The user defined design resolution
941      * @return {object} An object contains the scale X/Y values and the viewport rect
942      */
943     apply: function (view, designedResolution) {
944         this._containerStrategy.apply(view, designedResolution);
945         return this._contentStrategy.apply(view, designedResolution);
946     },
947 
948     /**
949      * Manipulation after appyling the strategy
950      * @param {cc.view} view The target view
951      */
952     postApply: function (view) {
953         this._containerStrategy.postApply(view);
954         this._contentStrategy.postApply(view);
955     },
956 
957     /**
958      * Setup the container's scale strategy
959      * @param {cc.ContainerStrategy} containerStg
960      */
961     setContainerStrategy: function (containerStg) {
962         if (containerStg instanceof cc.ContainerStrategy)
963             this._containerStrategy = containerStg;
964     },
965 
966     /**
967      * Setup the content's scale strategy
968      * @param {cc.ContentStrategy} contentStg
969      */
970     setContentStrategy: function (contentStg) {
971         if (contentStg instanceof cc.ContentStrategy)
972             this._contentStrategy = contentStg;
973     }
974 });
975 
976 /*
977  * @memberOf cc.ResolutionPolicy#
978  * @name EXACT_FIT
979  * @const
980  * @static
981  * The entire application is visible in the specified area without trying to preserve the original aspect ratio.<br/>
982  * Distortion can occur, and the application may appear stretched or compressed.
983  */
984 cc.ResolutionPolicy.EXACT_FIT = 0;
985 
986 /*
987  * @memberOf cc.ResolutionPolicy#
988  * @name NO_BORDER
989  * @const
990  * @static
991  * The entire application fills the specified area, without distortion but possibly with some cropping,<br/>
992  * while maintaining the original aspect ratio of the application.
993  */
994 cc.ResolutionPolicy.NO_BORDER = 1;
995 
996 /*
997  * @memberOf cc.ResolutionPolicy#
998  * @name SHOW_ALL
999  * @const
1000  * @static
1001  * The entire application is visible in the specified area without distortion while maintaining the original<br/>
1002  * aspect ratio of the application. Borders can appear on two sides of the application.
1003  */
1004 cc.ResolutionPolicy.SHOW_ALL = 2;
1005 
1006 /*
1007  * @memberOf cc.ResolutionPolicy#
1008  * @name FIXED_HEIGHT
1009  * @const
1010  * @static
1011  * The application takes the height of the design resolution size and modifies the width of the internal<br/>
1012  * canvas so that it fits the aspect ratio of the device<br/>
1013  * no distortion will occur however you must make sure your application works on different<br/>
1014  * aspect ratios
1015  */
1016 cc.ResolutionPolicy.FIXED_HEIGHT = 3;
1017 
1018 /*
1019  * @memberOf cc.ResolutionPolicy#
1020  * @name FIXED_WIDTH
1021  * @const
1022  * @static
1023  * The application takes the width of the design resolution size and modifies the height of the internal<br/>
1024  * canvas so that it fits the aspect ratio of the device<br/>
1025  * no distortion will occur however you must make sure your application works on different<br/>
1026  * aspect ratios
1027  */
1028 cc.ResolutionPolicy.FIXED_WIDTH = 4;
1029 
1030 /*
1031  * @memberOf cc.ResolutionPolicy#
1032  * @name UNKNOWN
1033  * @const
1034  * @static
1035  * Unknow policy
1036  */
1037 cc.ResolutionPolicy.UNKNOWN = 5;