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} 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  */
241 cc.RectMake = function (x, y, width, height) {
242     cc.log("cc.RectMake will be deprecated sooner or later. Use cc.rect instead.");
243     return cc.rect(x, y, width, height);
244 };
245 
246 // backward compatible
247 cc.rect = function (x, y, w, h) {
248     return new cc.Rect(x,y,w,h);
249 };
250 
251 // JSB compatbility: in JSB, cc._rect reuses objects instead of creating new ones
252 cc._rect = cc.rect;
253 
254 /**
255  * The "zero" rectangle -- equivalent to cc.rect(0, 0, 0, 0).
256  * @function
257  * @return {cc.Rect}
258  */
259 cc.RectZero = function () {
260     return cc.rect(0, 0, 0, 0);
261 };
262 
263 /**
264  * @function
265  * @param {cc.Rect} rect1
266  * @param {cc.Rect} rect2
267  * @return {Boolean}
268  */
269 cc.rectEqualToRect = function (rect1, rect2) {
270     if(!rect1 || !rect2)
271         return false;
272     return ((cc.pointEqualToPoint(rect1.origin, rect2.origin)) &&
273         (cc.sizeEqualToSize(rect1.size, rect2.size)));
274 };
275 
276 cc._rectEqualToZero = function(rect){
277     if(!rect)
278         return false;
279     return (rect.x === 0) && (rect.y === 0) && (rect.width === 0) && (rect.height === 0);
280 };
281 
282 /**
283  * @function
284  * @param {cc.Rect} rect1
285  * @param {cc.Rect} rect2
286  * @return {Boolean}
287  */
288 cc.rectContainsRect = function (rect1, rect2) {
289     if (!rect1 || !rect2)
290         return false;
291 
292     return !((rect1.x >= rect2.x) || (rect1.y >= rect2.y) ||
293         ( rect1.x + rect1.width <= rect2.x + rect2.width) ||
294         ( rect1.y + rect1.height <= rect2.y + rect2.height));
295 };
296 
297 /**
298  * return the rightmost x-value of 'rect'
299  * @function
300  * @param {cc.Rect} rect
301  * @return {Number}
302  */
303 cc.rectGetMaxX = function (rect) {
304     return (rect.x + rect.width);
305 };
306 
307 /**
308  * return the midpoint x-value of 'rect'
309  * @function
310  * @param {cc.Rect} rect
311  * @return {Number}
312  */
313 cc.rectGetMidX = function (rect) {
314     return (rect.x + rect.width / 2.0);
315 };
316 /**
317  * return the leftmost x-value of 'rect'
318  * @function
319  * @param {cc.Rect} rect
320  * @return {Number}
321  */
322 cc.rectGetMinX = function (rect) {
323     return rect.x;
324 };
325 
326 /**
327  * Return the topmost y-value of `rect'
328  * @function
329  * @param {cc.Rect} rect
330  * @return {Number}
331  */
332 cc.rectGetMaxY = function (rect) {
333     return(rect.y + rect.height);
334 };
335 
336 /**
337  * Return the midpoint y-value of `rect'
338  * @function
339  * @param {cc.Rect} rect
340  * @return {Number}
341  */
342 cc.rectGetMidY = function (rect) {
343     return rect.y + rect.height / 2.0;
344 };
345 
346 /**
347  * Return the bottommost y-value of `rect'
348  * @function
349  * @param {cc.Rect} rect
350  * @return {Number}
351  */
352 cc.rectGetMinY = function (rect) {
353     return rect.y;
354 };
355 
356 /**
357  * @function
358  * @param {cc.Rect} rect
359  * @param {cc.Point} point
360  * @return {Boolean}
361  */
362 cc.rectContainsPoint = function (rect, point) {
363     return (point.x >= cc.rectGetMinX(rect) && point.x <= cc.rectGetMaxX(rect) &&
364         point.y >= cc.rectGetMinY(rect) && point.y <= cc.rectGetMaxY(rect)) ;
365 };
366 
367 /**
368  * @function
369  * @param {cc.Rect} rectA
370  * @param {cc.Rect} rectB
371  * @return {Boolean}
372  */
373 cc.rectIntersectsRect = function (rectA, rectB) {
374     return !(cc.rectGetMaxX(rectA) < cc.rectGetMinX(rectB) ||
375         cc.rectGetMaxX(rectB) < cc.rectGetMinX(rectA) ||
376         cc.rectGetMaxY(rectA) < cc.rectGetMinY(rectB) ||
377         cc.rectGetMaxY(rectB) < cc.rectGetMinY(rectA));
378 };
379 
380 /**
381  * @function
382  * @param {cc.Rect} rectA
383  * @param {cc.Rect} rectB
384  * @return {Boolean}
385  */
386 cc.rectOverlapsRect = function (rectA, rectB) {
387     return !((rectA.x + rectA.width < rectB.x) ||
388         (rectB.x + rectB.width < rectA.x) ||
389         (rectA.y + rectA.height < rectB.y) ||
390         (rectB.y + rectB.height < rectA.y));
391 };
392 
393 /**
394  * Returns the smallest rectangle that contains the two source rectangles.
395  * @function
396  * @param {cc.Rect} rectA
397  * @param {cc.Rect} rectB
398  * @return {cc.Rect}
399  */
400 cc.rectUnion = function (rectA, rectB) {
401     var rect = cc.rect(0, 0, 0, 0);
402     rect.x = Math.min(rectA.x, rectB.x);
403     rect.y = Math.min(rectA.y, rectB.y);
404     rect.width = Math.max(rectA.x + rectA.width, rectB.x + rectB.width) - rect.x;
405     rect.height = Math.max(rectA.y + rectA.height, rectB.y + rectB.height) - rect.y;
406     return rect;
407 };
408 
409 /**
410  * Returns the overlapping portion of 2 rectangles
411  * @function
412  * @param {cc.Rect} rectA
413  * @param {cc.Rect} rectB
414  * @return {cc.Rect}
415  */
416 cc.rectIntersection = function (rectA, rectB) {
417     var intersection = cc.rect(
418         Math.max(cc.rectGetMinX(rectA), cc.rectGetMinX(rectB)),
419         Math.max(cc.rectGetMinY(rectA), cc.rectGetMinY(rectB)),
420         0, 0);
421 
422     intersection.width = Math.min(cc.rectGetMaxX(rectA), cc.rectGetMaxX(rectB)) - cc.rectGetMinX(intersection);
423     intersection.height = Math.min(cc.rectGetMaxY(rectA), cc.rectGetMaxY(rectB)) - cc.rectGetMinY(intersection);
424     return intersection;
425 };
426 
427 //
428 // Rect JSB compatibility
429 // JSB uses:
430 //   rect.x, rect.y, rect.width and rect.height
431 // while HTML5 uses:
432 //   rect.origin, rect.size
433 //
434 cc.Rect.prototype.getX = function() {
435     return this.origin.x;
436 };
437 cc.Rect.prototype.setX = function(x) {
438     this.origin.x = x;
439 };
440 cc.Rect.prototype.getY = function() {
441     return this.origin.y;
442 };
443 cc.Rect.prototype.setY = function(y) {
444     this.origin.y = y;
445 };
446 cc.Rect.prototype.getWidth = function(){
447     return this.size.width;
448 };
449 cc.Rect.prototype.setWidth = function(w){
450     this.size.width = w;
451 };
452 cc.Rect.prototype.getHeight = function(){
453     return this.size.height;
454 };
455 cc.Rect.prototype.setHeight = function(h){
456     this.size.height = h;
457 };
458 
459 Object.defineProperties(cc.Rect.prototype,
460     {
461         "x": {
462             get: function () {
463                 return this.getX();
464             },
465             set: function (newValue) {
466                 this.setX(newValue);
467             },
468             enumerable: true,
469             configurable: true
470         },
471         "y": {
472             get: function () {
473                 return this.getY();
474             },
475             set: function (newValue) {
476                 this.setY(newValue);
477             },
478             enumerable: true,
479             configurable: true
480         },
481         "width": {
482             get: function () {
483                 return this.getWidth();
484             },
485             set: function (newValue) {
486                 this.setWidth(newValue);
487             },
488             enumerable: true,
489             configurable: true
490         },
491         "height": {
492             get: function () {
493                 return this.getHeight();
494             },
495             set: function (newValue) {
496                 this.setHeight(newValue);
497             },
498             enumerable: true,
499             configurable: true
500         }
501     }
502 );
503 
504 // Deprecated
505 /*cc.Rect.CCRectEqualToRect = cc.rectEqualToRect;
506 cc.Rect.CCRectContainsRect = cc.rectContainsRect;
507 cc.Rect.CCRectGetMaxX = cc.rectGetMaxX;
508 cc.Rect.CCRectGetMidX = cc.rectGetMidX;
509 cc.Rect.CCRectGetMinX = cc.rectGetMinX;
510 cc.Rect.CCRectGetMaxY = cc.rectGetMaxY;
511 cc.Rect.CCRectGetMidY = cc.rectGetMidY;
512 cc.Rect.CCRectGetMinY = cc.rectGetMinY;
513 cc.Rect.CCRectContainsPoint = cc.rectContainsPoint;
514 cc.Rect.CCRectIntersectsRect = cc.rectIntersectsRect;
515 cc.Rect.CCRectUnion = cc.rectUnion;
516 cc.Rect.CCRectIntersection = cc.rectIntersection;*/
517 
518