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