1 /****************************************************************************
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3  Copyright (c) 2008-2010 Ricardo Quesada
  4  Copyright (c) 2011      Zynga Inc.
  5 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 
 27 //--------------------------------------------------------
 28 //
 29 // POINT
 30 //
 31 //--------------------------------------------------------
 32 /**
 33  * @class
 34  * @param {Number|cc.Point} _x
 35  * @param {Number} _y
 36  * Constructor
 37  */
 38 cc.Point = function (_x, _y) {
 39     if(_x !== undefined && _y === undefined){
 40         this.x = _x.x;
 41         this.y = _x.y;
 42     } else {
 43         this.x = _x || 0;
 44         this.y = _y || 0;
 45     }
 46 };
 47 
 48 /**
 49  * @function
 50  * @param {Number} x
 51  * @param {Number} y
 52  * @return {cc.Point}
 53  * @deprecated
 54  */
 55 cc.PointMake = function (x, y) {
 56     cc.log("cc.PointMake will be deprecated sooner or later. Use cc.p instead.");
 57     return new cc.Point(x, y);
 58 };
 59 
 60 /**
 61  * Helper macro that creates a cc.Point.
 62  * @param {Number|cc.Point} x
 63  * @param {Number} y
 64  */
 65 cc.p = function (x, y) {
 66     // This can actually make use of "hidden classes" in JITs and thus decrease
 67     // memory usage and overall performance drastically
 68     // return new cc.Point(x, y);
 69     // but this one will instead flood the heap with newly allocated hash maps
 70     // giving little room for optimization by the JIT,
 71     // note: we have tested this item on Chrome and firefox, it is faster than new cc.Point(x, y)
 72     if (x === undefined)
 73         return {x: 0, y: 0};
 74     else if (y === undefined)
 75         return {x: x.x, y: x.y};
 76     else
 77         return {x: x || 0, y: y || 0};
 78 };
 79 
 80 // JSB compatbility: in JSB, cc._p reuses objects instead of creating new ones
 81 cc._p = cc.p;
 82 
 83 /**
 84  * The "left bottom" point -- equivalent to cc.p(0, 0).
 85  * @function
 86  * @return {cc.Point}
 87  */
 88 cc.PointZero = function () {
 89     return cc.p(0, 0);
 90 };
 91 
 92 /**
 93  * @function
 94  * @param {cc.Point} point1
 95  * @param {cc.Point} point2
 96  * @return {Boolean}
 97  */
 98 cc.pointEqualToPoint = function (point1, point2) {
 99     if (!point1 || !point2)
100         return false;
101     return ((point1.x === point2.x) && (point1.y === point2.y));
102 };
103 
104 // deprecated
105 //cc.Point.CCPointEqualToPoint = cc.pointEqualToPoint;
106 
107 
108 //--------------------------------------------------------
109 //
110 // SIZE
111 //
112 //--------------------------------------------------------
113 
114 /**
115  * @class
116  * @param {Number|cc.Size} _width
117  * @param {Number} _height
118  * Constructor
119  */
120 cc.Size = function (_width, _height) {
121     if(_width !== undefined && _height === undefined){
122         this.width = _width.width;
123         this.height = _width.height;
124     } else {
125         this.width = _width || 0;
126         this.height = _height || 0;
127     }
128 };
129 
130 /**
131  * @function
132  * @param {Number} width
133  * @param {Number} height
134  * @return {cc.Size}
135  * @deprecated
136  */
137 cc.SizeMake = function (width, height) {
138     cc.log("cc.SizeMake will be deprecated sooner or later. Use cc.size instead.");
139     return cc.size(width, height);
140 };
141 
142 /**
143  * @function
144  * @param {Number|cc.Size} w width or a size object
145  * @param {Number} h height
146  * @return {cc.Size}
147  */
148 cc.size = function (w, h) {
149     // This can actually make use of "hidden classes" in JITs and thus decrease
150     // memory usage and overall performance drastically
151     //return new cc.Size(w, h);
152     // but this one will instead flood the heap with newly allocated hash maps
153     // giving little room for optimization by the JIT
154     // note: we have tested this item on Chrome and firefox, it is faster than new cc.Size(w, h)
155     if (w === undefined)
156         return {width: 0, height: 0};
157     if (h === undefined)
158         return { width: w.width, height: w.height};
159     return { width: w || 0, height: h || 0};
160 };
161 
162 // JSB compatbility: in JSB, cc._size reuses objects instead of creating new ones
163 cc._size = cc.size;
164 
165 /**
166  * The "zero" size -- equivalent to cc.size(0, 0).
167  * @function
168  * @return {cc.Size}
169  */
170 cc.SizeZero = function () {
171     return cc.size(0, 0);
172 };
173 
174 Object.defineProperties(cc, {
175     POINT_ZERO:{
176         get:function () {
177             return cc.p();
178         }
179     },
180     SIZE_ZERO:{
181         get:function () {
182             return cc.size(0,0);
183         }
184     },
185     RECT_ZERO:{
186         get:function () {
187             return cc.rect(0, 0, 0, 0);
188         }
189     }
190 });
191 
192 
193 /**
194  * @function
195  * @param {cc.Size} size1
196  * @param {cc.Size} size2
197  * @return {Boolean}
198  */
199 cc.sizeEqualToSize = function (size1, size2) {
200     if (!size1 || !size2)
201         return false;
202     return ((size1.width == size2.width) && (size1.height == size2.height));
203 };
204 
205 // deprecated
206 //cc.Size.CCSizeEqualToSize = cc.sizeEqualToSize;
207 
208 //--------------------------------------------------------
209 //
210 // RECT
211 //
212 //--------------------------------------------------------
213 
214 /**
215  * @class
216  * @param {Number|cc.Point|cc.Rect} [x1] a Number value as x or a cc.Point object as origin or a cc.Rect clone object
217  * @param {Number|cc.Size} [y1] x1 a Number value as y or a cc.Size object as size
218  * @param {Number} [width1]
219  * @param {Number} [height1]
220  * Constructor
221  */
222 cc.Rect = function (x1, y1, width1, height1) {
223     var argLen =arguments.length;
224     if(argLen === 4){
225         this._origin = new cc.Point(x1 || 0, y1 || 0);
226         this._size = new cc.Size(width1 || 0, height1 || 0);
227         return;
228     }
229     if(argLen === 1) {
230         this._origin = new cc.Point(x1._origin.x, x1._origin.y);
231         this._size = new cc.Size(x1._size.width, x1._size.height);
232         return;
233     }
234     if(argLen === 0) {
235         this._origin = new cc.Point(0, 0);
236         this._size = new cc.Size(0,0);
237         return;
238     }
239     if(argLen === 2) {
240         this._origin = new cc.Point(x1.x, x1.y);
241         this._size = new cc.Size(y1.width,y1.height);
242         return;
243     }
244     throw "unknown argument type";
245 };
246 
247 /**
248  * @function
249  * @param {Number} x
250  * @param {Number} y
251  * @param {Number} width
252  * @param {Number} height
253  * @return {cc.Rect}
254  */
255 cc.RectMake = function (x, y, width, height) {
256     cc.log("cc.RectMake will be deprecated sooner or later. Use cc.rect instead.");
257     return cc.rect(x, y, width, height);
258 };
259 
260 // backward compatible
261 cc.rect = function (x, y, w, h) {
262     var argLen =arguments.length;
263     if(argLen === 0)
264         return new cc.Rect(0,0,0,0);
265 
266     if(argLen === 1)
267         return new cc.Rect(x.x, x.y, x.width, x.height);
268 
269     if(argLen === 2)
270         return new cc.Rect(x.x, x.y, y.width, y.height);
271 
272     if(argLen === 4)
273         return new cc.Rect(x,y,w,h);
274 
275     throw "unknown argument type";
276 };
277 
278 // JSB compatbility: in JSB, cc._rect reuses objects instead of creating new ones
279 cc._rect = cc.rect;
280 
281 /**
282  * The "zero" rectangle -- equivalent to cc.rect(0, 0, 0, 0).
283  * @function
284  * @return {cc.Rect}
285  */
286 cc.RectZero = function () {
287     return cc.rect(0, 0, 0, 0);
288 };
289 
290 /**
291  * @function
292  * @param {cc.Rect} rect1
293  * @param {cc.Rect} rect2
294  * @return {Boolean}
295  */
296 cc.rectEqualToRect = function (rect1, rect2) {
297     if(!rect1 || !rect2)
298         return false;
299     return ((cc.pointEqualToPoint(rect1._origin, rect2._origin)) &&
300         (cc.sizeEqualToSize(rect1._size, rect2._size)));
301 };
302 
303 cc._rectEqualToZero = function(rect){
304     if(!rect)
305         return false;
306     return (rect.x === 0) && (rect.y === 0) && (rect.width === 0) && (rect.height === 0);
307 };
308 
309 /**
310  * @function
311  * @param {cc.Rect} rect1
312  * @param {cc.Rect} rect2
313  * @return {Boolean}
314  */
315 cc.rectContainsRect = function (rect1, rect2) {
316     if (!rect1 || !rect2)
317         return false;
318 
319     return !((rect1.x >= rect2.x) || (rect1.y >= rect2.y) ||
320         ( rect1.x + rect1.width <= rect2.x + rect2.width) ||
321         ( rect1.y + rect1.height <= rect2.y + rect2.height));
322 };
323 
324 /**
325  * return the rightmost x-value of 'rect'
326  * @function
327  * @param {cc.Rect} rect
328  * @return {Number}
329  */
330 cc.rectGetMaxX = function (rect) {
331     return (rect.x + rect.width);
332 };
333 
334 /**
335  * return the midpoint x-value of 'rect'
336  * @function
337  * @param {cc.Rect} rect
338  * @return {Number}
339  */
340 cc.rectGetMidX = function (rect) {
341     return (rect.x + rect.width / 2.0);
342 };
343 /**
344  * return the leftmost x-value of 'rect'
345  * @function
346  * @param {cc.Rect} rect
347  * @return {Number}
348  */
349 cc.rectGetMinX = function (rect) {
350     return rect.x;
351 };
352 
353 /**
354  * Return the topmost y-value of `rect'
355  * @function
356  * @param {cc.Rect} rect
357  * @return {Number}
358  */
359 cc.rectGetMaxY = function (rect) {
360     return(rect.y + rect.height);
361 };
362 
363 /**
364  * Return the midpoint y-value of `rect'
365  * @function
366  * @param {cc.Rect} rect
367  * @return {Number}
368  */
369 cc.rectGetMidY = function (rect) {
370     return rect.y + rect.height / 2.0;
371 };
372 
373 /**
374  * Return the bottommost y-value of `rect'
375  * @function
376  * @param {cc.Rect} rect
377  * @return {Number}
378  */
379 cc.rectGetMinY = function (rect) {
380     return rect.y;
381 };
382 
383 /**
384  * @function
385  * @param {cc.Rect} rect
386  * @param {cc.Point} point
387  * @return {Boolean}
388  */
389 cc.rectContainsPoint = function (rect, point) {
390     return (point.x >= cc.rectGetMinX(rect) && point.x <= cc.rectGetMaxX(rect) &&
391         point.y >= cc.rectGetMinY(rect) && point.y <= cc.rectGetMaxY(rect)) ;
392 };
393 
394 /**
395  * @function
396  * @param {cc.Rect} rectA
397  * @param {cc.Rect} rectB
398  * @return {Boolean}
399  */
400 cc.rectIntersectsRect = function (rectA, rectB) {
401     return !(cc.rectGetMaxX(rectA) < cc.rectGetMinX(rectB) ||
402         cc.rectGetMaxX(rectB) < cc.rectGetMinX(rectA) ||
403         cc.rectGetMaxY(rectA) < cc.rectGetMinY(rectB) ||
404         cc.rectGetMaxY(rectB) < cc.rectGetMinY(rectA));
405 };
406 
407 /**
408  * @function
409  * @param {cc.Rect} rectA
410  * @param {cc.Rect} rectB
411  * @return {Boolean}
412  */
413 cc.rectOverlapsRect = function (rectA, rectB) {
414     return !((rectA.x + rectA.width < rectB.x) ||
415         (rectB.x + rectB.width < rectA.x) ||
416         (rectA.y + rectA.height < rectB.y) ||
417         (rectB.y + rectB.height < rectA.y));
418 };
419 
420 /**
421  * Returns the smallest rectangle that contains the two source rectangles.
422  * @function
423  * @param {cc.Rect} rectA
424  * @param {cc.Rect} rectB
425  * @return {cc.Rect}
426  */
427 cc.rectUnion = function (rectA, rectB) {
428     var rect = cc.rect(0, 0, 0, 0);
429     rect.x = Math.min(rectA.x, rectB.x);
430     rect.y = Math.min(rectA.y, rectB.y);
431     rect.width = Math.max(rectA.x + rectA.width, rectB.x + rectB.width) - rect.x;
432     rect.height = Math.max(rectA.y + rectA.height, rectB.y + rectB.height) - rect.y;
433     return rect;
434 };
435 
436 /**
437  * Returns the overlapping portion of 2 rectangles
438  * @function
439  * @param {cc.Rect} rectA
440  * @param {cc.Rect} rectB
441  * @return {cc.Rect}
442  */
443 cc.rectIntersection = function (rectA, rectB) {
444     var intersection = cc.rect(
445         Math.max(cc.rectGetMinX(rectA), cc.rectGetMinX(rectB)),
446         Math.max(cc.rectGetMinY(rectA), cc.rectGetMinY(rectB)),
447         0, 0);
448 
449     intersection.width = Math.min(cc.rectGetMaxX(rectA), cc.rectGetMaxX(rectB)) - cc.rectGetMinX(intersection);
450     intersection.height = Math.min(cc.rectGetMaxY(rectA), cc.rectGetMaxY(rectB)) - cc.rectGetMinY(intersection);
451     return intersection;
452 };
453 
454 //
455 // Rect JSB compatibility
456 // JSB uses:
457 //   rect.x, rect.y, rect.width and rect.height
458 // while HTML5 uses:
459 //   rect.origin, rect.size
460 //
461 cc.Rect.prototype.getX = function() {
462     return this._origin.x;
463 };
464 cc.Rect.prototype.setX = function(x) {
465     this._origin.x = x;
466 };
467 cc.Rect.prototype.getY = function() {
468     return this._origin.y;
469 };
470 cc.Rect.prototype.setY = function(y) {
471     this._origin.y = y;
472 };
473 cc.Rect.prototype.getWidth = function(){
474     return this._size.width;
475 };
476 cc.Rect.prototype.setWidth = function(w){
477     this._size.width = w;
478 };
479 cc.Rect.prototype.getHeight = function(){
480     return this._size.height;
481 };
482 cc.Rect.prototype.setHeight = function(h){
483     this._size.height = h;
484 };
485 
486 Object.defineProperties(cc.Rect.prototype,
487     {
488         "x": {
489             get: function () {
490                 return this.getX();
491             },
492             set: function (newValue) {
493                 this.setX(newValue);
494             },
495             enumerable: true,
496             configurable: true
497         },
498         "y": {
499             get: function () {
500                 return this.getY();
501             },
502             set: function (newValue) {
503                 this.setY(newValue);
504             },
505             enumerable: true,
506             configurable: true
507         },
508         "width": {
509             get: function () {
510                 return this.getWidth();
511             },
512             set: function (newValue) {
513                 this.setWidth(newValue);
514             },
515             enumerable: true,
516             configurable: true
517         },
518         "height": {
519             get: function () {
520                 return this.getHeight();
521             },
522             set: function (newValue) {
523                 this.setHeight(newValue);
524             },
525             enumerable: true,
526             configurable: true
527         }
528     }
529 );
530 
531 // Deprecated
532 /*cc.Rect.CCRectEqualToRect = cc.rectEqualToRect;
533 cc.Rect.CCRectContainsRect = cc.rectContainsRect;
534 cc.Rect.CCRectGetMaxX = cc.rectGetMaxX;
535 cc.Rect.CCRectGetMidX = cc.rectGetMidX;
536 cc.Rect.CCRectGetMinX = cc.rectGetMinX;
537 cc.Rect.CCRectGetMaxY = cc.rectGetMaxY;
538 cc.Rect.CCRectGetMidY = cc.rectGetMidY;
539 cc.Rect.CCRectGetMinY = cc.rectGetMinY;
540 cc.Rect.CCRectContainsPoint = cc.rectContainsPoint;
541 cc.Rect.CCRectIntersectsRect = cc.rectIntersectsRect;
542 cc.Rect.CCRectUnion = cc.rectUnion;
543 cc.Rect.CCRectIntersection = cc.rectIntersection;*/
544 
545