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} _x
 35  * @param {Number} _y
 36  * Constructor
 37  */
 38 cc.Point = function (_x, _y) {
 39     this.x = _x || 0;
 40     this.y = _y || 0;
 41 };
 42 
 43 /**
 44  * @function
 45  * @param {Number} x
 46  * @param {Number} y
 47  * @return {cc.Point}
 48  */
 49 cc.PointMake = function (x, y) {
 50     cc.log("cc.PointMake will be deprecated sooner or later. Use cc.p instead.");
 51     return new cc.Point(x, y);
 52 };
 53 
 54 /**
 55  * Helper macro that creates a cc.Point.
 56  * @param {Number} x
 57  * @param {Number} y
 58  */
 59 cc.p = function (x, y) {
 60     // This can actually make use of "hidden classes" in JITs and thus decrease
 61     // memory usage and overall peformance drastically
 62     return new cc.Point(x, y);
 63     // but this one will instead flood the heap with newly allocated hash maps
 64     // giving little room for optimization by the JIT
 65     // return {x:x, y:y};
 66 };
 67 
 68 // JSB compatbility: in JSB, cc._p reuses objects instead of creating new ones
 69 cc._p = cc.p;
 70 
 71 /**
 72  * The "left bottom" point -- equivalent to cc.p(0, 0).
 73  * @function
 74  * @return {cc.Point}
 75  */
 76 cc.PointZero = function () {
 77     return cc.p(0, 0);
 78 };
 79 
 80 Object.defineProperties(cc, {
 81     POINT_ZERO:{
 82         get:function () {
 83             return cc.p(0, 0);
 84         }
 85     },
 86     SIZE_ZERO:{
 87         get:function () {
 88             return cc.size(0, 0);
 89         }
 90     },
 91     RECT_ZERO:{
 92         get:function () {
 93             return cc.rect(0, 0, 0, 0);
 94         }
 95     }
 96 });
 97 
 98 /**
 99  * @function
100  * @param {cc.Point} point1
101  * @param {cc.Point} point2
102  * @return {Boolean}
103  */
104 cc.pointEqualToPoint = function (point1, point2) {
105     if (!point1 || !point2)
106         return false;
107     return ((point1.x === point2.x) && (point1.y === point2.y));
108 };
109 
110 // deprecated
111 //cc.Point.CCPointEqualToPoint = cc.pointEqualToPoint;
112 
113 
114 //--------------------------------------------------------
115 //
116 // SIZE
117 //
118 //--------------------------------------------------------
119 
120 /**
121  * @class
122  * @param {Number} _width
123  * @param {Number} _height
124  * Constructor
125  */
126 cc.Size = function (_width, _height) {
127     this.width = _width || 0;
128     this.height = _height || 0;
129 };
130 
131 /**
132  * @function
133  * @param {Number} width
134  * @param {Number} height
135  * @return {cc.Size}
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} w width
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 peformance 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     //return {width:w, height:h};
155 };
156 
157 // JSB compatbility: in JSB, cc._size reuses objects instead of creating new ones
158 cc._size = cc.size;
159 
160 /**
161  * The "zero" size -- equivalent to cc.size(0, 0).
162  * @function
163  * @return {cc.Size}
164  */
165 cc.SizeZero = function () {
166     return cc.size(0, 0);
167 };
168 
169 
170 /**
171  * @function
172  * @param {cc.Size} size1
173  * @param {cc.Size} size2
174  * @return {Boolean}
175  */
176 cc.sizeEqualToSize = function (size1, size2) {
177     if (!size1 || !size2)
178         return false;
179     return ((size1.width == size2.width) && (size1.height == size2.height));
180 };
181 
182 // deprecated
183 //cc.Size.CCSizeEqualToSize = cc.sizeEqualToSize;
184 
185 //--------------------------------------------------------
186 //
187 // RECT
188 //
189 //--------------------------------------------------------
190 
191 /**
192  * @class
193  * @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
194  * @param {Number|cc.Size} [y1] x1 a Number value as y or a cc.Size object as size
195  * @param {Number} [width1]
196  * @param {Number} [height1]
197  * Constructor
198  */
199 cc.Rect = function (x1, y1, width1, height1) {
200     var argLen =arguments.length;
201     if(argLen === 4){
202         this.origin = new cc.Point(x1 || 0, y1 || 0);
203         this.size = new cc.Size(width1 || 0, height1 || 0);
204         return;
205     }
206     if(argLen === 1) {
207         this.origin = new cc.Point(x1.origin.x, x1.origin.y);
208         this.size = new cc.Size(x1.size.width, x1.size.height);
209         return;
210     }
211     if(argLen === 0) {
212         this.origin = new cc.Point(0, 0);
213         this.size = new cc.Size(0,0);
214         return;
215     }
216     if(argLen === 2) {
217         this.origin = new cc.Point(x1.x, x1.y);
218         this.size = new cc.Size(y1.width,y1.height);
219         return;
220     }
221     throw "unknown argument type";
222 };
223 
224 /**
225  * @function
226  * @param {Number} x
227  * @param {Number} y
228  * @param {Number} width
229  * @param {Number} height
230  * @return {cc.Rect}
231  */
232 cc.RectMake = function (x, y, width, height) {
233     cc.log("cc.RectMake will be deprecated sooner or later. Use cc.rect instead.");
234     return cc.rect(x, y, width, height);
235 };
236 
237 // backward compatible
238 cc.rect = function (x, y, w, h) {
239     var argLen =arguments.length;
240     if(argLen === 0)
241         return new cc.Rect(0,0,0,0);
242 
243     if(argLen === 1)
244         return new cc.Rect(x.x, x.y, x.width, x.height);
245 
246     if(argLen === 2)
247         return new cc.Rect(x.x, x.y, y.width, y.height);
248 
249     if(argLen === 4)
250         return new cc.Rect(x,y,w,h);
251 
252     throw "unknown argument type";
253 };
254 
255 // JSB compatbility: in JSB, cc._rect reuses objects instead of creating new ones
256 cc._rect = cc.rect;
257 
258 /**
259  * The "zero" rectangle -- equivalent to cc.rect(0, 0, 0, 0).
260  * @function
261  * @return {cc.Rect}
262  */
263 cc.RectZero = function () {
264     return cc.rect(0, 0, 0, 0);
265 };
266 
267 /**
268  * @function
269  * @param {cc.Rect} rect1
270  * @param {cc.Rect} rect2
271  * @return {Boolean}
272  */
273 cc.rectEqualToRect = function (rect1, rect2) {
274     if(!rect1 || !rect2)
275         return false;
276     return ((cc.pointEqualToPoint(rect1.origin, rect2.origin)) &&
277         (cc.sizeEqualToSize(rect1.size, rect2.size)));
278 };
279 
280 cc._rectEqualToZero = function(rect){
281     if(!rect)
282         return false;
283     return (rect.x === 0) && (rect.y === 0) && (rect.width === 0) && (rect.height === 0);
284 };
285 
286 /**
287  * @function
288  * @param {cc.Rect} rect1
289  * @param {cc.Rect} rect2
290  * @return {Boolean}
291  */
292 cc.rectContainsRect = function (rect1, rect2) {
293     if (!rect1 || !rect2)
294         return false;
295 
296     return !((rect1.x >= rect2.x) || (rect1.y >= rect2.y) ||
297         ( rect1.x + rect1.width <= rect2.x + rect2.width) ||
298         ( rect1.y + rect1.height <= rect2.y + rect2.height));
299 };
300 
301 /**
302  * return the rightmost x-value of 'rect'
303  * @function
304  * @param {cc.Rect} rect
305  * @return {Number}
306  */
307 cc.rectGetMaxX = function (rect) {
308     return (rect.x + rect.width);
309 };
310 
311 /**
312  * return the midpoint x-value of 'rect'
313  * @function
314  * @param {cc.Rect} rect
315  * @return {Number}
316  */
317 cc.rectGetMidX = function (rect) {
318     return (rect.x + rect.width / 2.0);
319 };
320 /**
321  * return the leftmost x-value of 'rect'
322  * @function
323  * @param {cc.Rect} rect
324  * @return {Number}
325  */
326 cc.rectGetMinX = function (rect) {
327     return rect.x;
328 };
329 
330 /**
331  * Return the topmost y-value of `rect'
332  * @function
333  * @param {cc.Rect} rect
334  * @return {Number}
335  */
336 cc.rectGetMaxY = function (rect) {
337     return(rect.y + rect.height);
338 };
339 
340 /**
341  * Return the midpoint y-value of `rect'
342  * @function
343  * @param {cc.Rect} rect
344  * @return {Number}
345  */
346 cc.rectGetMidY = function (rect) {
347     return rect.y + rect.height / 2.0;
348 };
349 
350 /**
351  * Return the bottommost y-value of `rect'
352  * @function
353  * @param {cc.Rect} rect
354  * @return {Number}
355  */
356 cc.rectGetMinY = function (rect) {
357     return rect.y;
358 };
359 
360 /**
361  * @function
362  * @param {cc.Rect} rect
363  * @param {cc.Point} point
364  * @return {Boolean}
365  */
366 cc.rectContainsPoint = function (rect, point) {
367     return (point.x >= cc.rectGetMinX(rect) && point.x <= cc.rectGetMaxX(rect) &&
368         point.y >= cc.rectGetMinY(rect) && point.y <= cc.rectGetMaxY(rect)) ;
369 };
370 
371 /**
372  * @function
373  * @param {cc.Rect} rectA
374  * @param {cc.Rect} rectB
375  * @return {Boolean}
376  */
377 cc.rectIntersectsRect = function (rectA, rectB) {
378     return !(cc.rectGetMaxX(rectA) < cc.rectGetMinX(rectB) ||
379         cc.rectGetMaxX(rectB) < cc.rectGetMinX(rectA) ||
380         cc.rectGetMaxY(rectA) < cc.rectGetMinY(rectB) ||
381         cc.rectGetMaxY(rectB) < cc.rectGetMinY(rectA));
382 };
383 
384 /**
385  * @function
386  * @param {cc.Rect} rectA
387  * @param {cc.Rect} rectB
388  * @return {Boolean}
389  */
390 cc.rectOverlapsRect = function (rectA, rectB) {
391     return !((rectA.x + rectA.width < rectB.x) ||
392         (rectB.x + rectB.width < rectA.x) ||
393         (rectA.y + rectA.height < rectB.y) ||
394         (rectB.y + rectB.height < rectA.y));
395 };
396 
397 /**
398  * Returns the smallest rectangle that contains the two source rectangles.
399  * @function
400  * @param {cc.Rect} rectA
401  * @param {cc.Rect} rectB
402  * @return {cc.Rect}
403  */
404 cc.rectUnion = function (rectA, rectB) {
405     var rect = cc.rect(0, 0, 0, 0);
406     rect.x = Math.min(rectA.x, rectB.x);
407     rect.y = Math.min(rectA.y, rectB.y);
408     rect.width = Math.max(rectA.x + rectA.width, rectB.x + rectB.width) - rect.x;
409     rect.height = Math.max(rectA.y + rectA.height, rectB.y + rectB.height) - rect.y;
410     return rect;
411 };
412 
413 /**
414  * Returns the overlapping portion of 2 rectangles
415  * @function
416  * @param {cc.Rect} rectA
417  * @param {cc.Rect} rectB
418  * @return {cc.Rect}
419  */
420 cc.rectIntersection = function (rectA, rectB) {
421     var intersection = cc.rect(
422         Math.max(cc.rectGetMinX(rectA), cc.rectGetMinX(rectB)),
423         Math.max(cc.rectGetMinY(rectA), cc.rectGetMinY(rectB)),
424         0, 0);
425 
426     intersection.width = Math.min(cc.rectGetMaxX(rectA), cc.rectGetMaxX(rectB)) - cc.rectGetMinX(intersection);
427     intersection.height = Math.min(cc.rectGetMaxY(rectA), cc.rectGetMaxY(rectB)) - cc.rectGetMinY(intersection);
428     return intersection;
429 };
430 
431 //
432 // Rect JSB compatibility
433 // JSB uses:
434 //   rect.x, rect.y, rect.width and rect.height
435 // while HTML5 uses:
436 //   rect.origin, rect.size
437 //
438 cc.Rect.prototype.getX = function() {
439     return this.origin.x;
440 };
441 cc.Rect.prototype.setX = function(x) {
442     this.origin.x = x;
443 };
444 cc.Rect.prototype.getY = function() {
445     return this.origin.y;
446 };
447 cc.Rect.prototype.setY = function(y) {
448     this.origin.y = y;
449 };
450 cc.Rect.prototype.getWidth = function(){
451     return this.size.width;
452 };
453 cc.Rect.prototype.setWidth = function(w){
454     this.size.width = w;
455 };
456 cc.Rect.prototype.getHeight = function(){
457     return this.size.height;
458 };
459 cc.Rect.prototype.setHeight = function(h){
460     this.size.height = h;
461 };
462 
463 Object.defineProperties(cc.Rect.prototype,
464     {
465         "x": {
466             get: function () {
467                 return this.getX();
468             },
469             set: function (newValue) {
470                 this.setX(newValue);
471             },
472             enumerable: true,
473             configurable: true
474         },
475         "y": {
476             get: function () {
477                 return this.getY();
478             },
479             set: function (newValue) {
480                 this.setY(newValue);
481             },
482             enumerable: true,
483             configurable: true
484         },
485         "width": {
486             get: function () {
487                 return this.getWidth();
488             },
489             set: function (newValue) {
490                 this.setWidth(newValue);
491             },
492             enumerable: true,
493             configurable: true
494         },
495         "height": {
496             get: function () {
497                 return this.getHeight();
498             },
499             set: function (newValue) {
500                 this.setHeight(newValue);
501             },
502             enumerable: true,
503             configurable: true
504         }
505     }
506 );
507 
508 // Deprecated
509 /*cc.Rect.CCRectEqualToRect = cc.rectEqualToRect;
510 cc.Rect.CCRectContainsRect = cc.rectContainsRect;
511 cc.Rect.CCRectGetMaxX = cc.rectGetMaxX;
512 cc.Rect.CCRectGetMidX = cc.rectGetMidX;
513 cc.Rect.CCRectGetMinX = cc.rectGetMinX;
514 cc.Rect.CCRectGetMaxY = cc.rectGetMaxY;
515 cc.Rect.CCRectGetMidY = cc.rectGetMidY;
516 cc.Rect.CCRectGetMinY = cc.rectGetMinY;
517 cc.Rect.CCRectContainsPoint = cc.rectContainsPoint;
518 cc.Rect.CCRectIntersectsRect = cc.rectIntersectsRect;
519 cc.Rect.CCRectUnion = cc.rectUnion;
520 cc.Rect.CCRectIntersection = cc.rectIntersection;*/
521 
522