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