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