00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __UT_Rect_h__
00023 #define __UT_Rect_h__
00024
00025 #include <math.h>
00026 #include <SYS/SYS_Types.h>
00027 #include <iostream.h>
00028 #include "UT_Algorithm.h"
00029
00030
00031 inline int UTinclusiveFlip( int v, int d ) { return d - 1 - v; }
00032
00033 class UT_DimRectImpl;
00034 class UT_InclusiveRectImpl;
00035 class UT_ExclusiveRectImpl;
00036
00037 template <typename T> class UT_Rect;
00038
00039 typedef UT_Rect<UT_DimRectImpl> UT_DimRect;
00040 typedef UT_Rect<UT_InclusiveRectImpl> UT_InclusiveRect;
00041 typedef UT_Rect<UT_ExclusiveRectImpl> UT_ExclusiveRect;
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 template <typename T> class UT_Rect
00059 {
00060 public:
00061 UT_Rect() { clear(); }
00062 UT_Rect( int v1, int v2, int v3, int v4 ) { set( v1, v2, v3, v4 ); }
00063
00064 UT_Rect( const UT_DimRect &r ) : _r( r ) { }
00065 UT_Rect( const UT_InclusiveRect &r ) : _r( r ) { }
00066 UT_Rect( const UT_ExclusiveRect &r ) : _r( r ) { }
00067
00068 UT_Rect &operator=( const UT_DimRect &r ) { _r = r; return *this; }
00069 UT_Rect &operator=( const UT_InclusiveRect &r ) { _r = r; return *this; }
00070 UT_Rect &operator=( const UT_ExclusiveRect &r ) { _r = r; return *this; }
00071
00072
00073 void clear() { _r.clear(); }
00074
00075
00076 void set( int v1, int v2, int v3, int v4 ) { _r.set(v1, v2, v3, v4); }
00077
00078
00079 bool isEmpty() const { return (width() == 0 || height() == 0); }
00080
00081
00082 bool isValid() const { return _r.isValid(); }
00083
00084
00085 bool isInsideX( int px ) const { return (x1() <= px && px <= x2()); }
00086 bool isInsideY( int py ) const { return (y1() <= py && py <= y2()); }
00087
00088
00089 bool isInside( int px, int py ) const { return isInsideX(px) &&
00090 isInsideY(py); }
00091
00092
00093 bool contains( const T &r) const;
00094
00095
00096 void getRelative( int &px, int &py ) const { px -= x1(); py -= y1(); }
00097
00098
00099 void getAbsolute( int &px, int &py ) const { px += x1(); py += y1(); }
00100
00101
00102 void flipX(int awidth) { _r.flipX( awidth ); }
00103 void flipY(int aheight) { _r.flipY( aheight ); }
00104
00105
00106 bool intersect( const T &r );
00107
00108
00109
00110 bool overlapX( const T &r ) const;
00111 bool overlapY( const T &r ) const;
00112
00113
00114 void enlarge( const T &r );
00115
00116
00117 void enlarge( int x, int y );
00118 void enlarge( float x, float y);
00119
00120
00121 void translate( int x, int y );
00122
00123
00124 void scale( fpreal factor );
00125
00126
00127 void clamp( int &px, int &py ) const
00128 {
00129 if (px < x1())
00130 px = x1();
00131 else if (px > x2())
00132 px = x2();
00133
00134 if (py < y1())
00135 py = y1();
00136 else if (py > y2())
00137 py = y2();
00138 }
00139
00140
00141 int x() const { return _r.x(); }
00142 int y() const { return _r.y(); }
00143 int w() const { return _r.width(); }
00144 int h() const { return _r.height(); }
00145 int width() const { return _r.width(); }
00146 int height() const { return _r.height(); }
00147
00148 int x1() const { return _r.x1(); }
00149 int y1() const { return _r.y1(); }
00150 int x2() const { return _r.x2(); }
00151 int y2() const { return _r.y2(); }
00152 int x2e() const { return _r.x2e(); }
00153 int y2e() const { return _r.y2e(); }
00154
00155
00156 void setWidth(int awidth) { _r.setWidth(awidth); }
00157 void setHeight(int aheight) { _r.setHeight(aheight); }
00158
00159
00160 void setX(int x_) { _r.setX(x_); }
00161 void setY(int y_) { _r.setY(y_); }
00162
00163
00164 void setX1(int x_) { _r.setX1(x_); }
00165 void setY1(int y_) { _r.setY1(y_); }
00166 void setX2(int x_) { _r.setX2(x_); }
00167 void setY2(int y_) { _r.setY2(y_); }
00168 void setX2e(int x_) { _r.setX2e(x_); }
00169 void setY2e(int y_) { _r.setY2e(y_); }
00170
00171
00172
00173
00174
00175
00176
00177 void getDim(int &x_, int &y_, int &w_, int &h_) const
00178 { x_ = x(); y_ = y(); w_ = width(); h_ = height(); }
00179 void getIncl(int &x1_, int &y1_, int &x2_, int &y2_) const
00180 { x1_ = x(); y1_ = y(); x2_ = x2(); y2_ = y2(); }
00181 void getExcl(int &x1_, int &y1_, int &x2_, int &y2_) const
00182 { x1_ = x(); y1_ = y(); x2_ = x2e(); y2_ = y2e(); }
00183
00184
00185
00186 void setDim(int x_, int y_, int w_, int h_)
00187 { setX(x_); setY(y_); setWidth(w_); setHeight(h_); }
00188 void setIncl(int x1_, int y1_, int x2_, int y2_)
00189 { setX1(x1_); setX2(x2_); setY1(y1_); setY2(y2_); }
00190 void setExcl(int x1_, int y1_, int x2_, int y2_)
00191 { setX1(x1_); setX2e(x2_); setY1(y1_); setY2e(y2_); }
00192
00193
00194 int &operator()(int i) { return _r(i); }
00195 int operator()(int i) const { return _r(i); }
00196
00197 private:
00198 T _r;
00199 };
00200
00201
00202
00203
00204
00205
00206 class UT_BaseRectImpl
00207 {
00208 public:
00209 UT_BaseRectImpl() { }
00210 UT_BaseRectImpl( int v0, int v1, int v2, int v3 )
00211 { set( v0, v1, v2, v3 ); }
00212 UT_BaseRectImpl( const UT_BaseRectImpl &r )
00213 { set( r.myVals[0], r.myVals[1], r.myVals[2], r.myVals[3] ); }
00214
00215 UT_BaseRectImpl &operator=( const UT_BaseRectImpl &r )
00216 {
00217 if( &r != this )
00218 set( r.myVals[0], r.myVals[1], r.myVals[2], r.myVals[3] );
00219 return *this;
00220 }
00221
00222 void set( int v0, int v1, int v2, int v3 )
00223 { myVals[0] = v0; myVals[1] = v1; myVals[2] = v2; myVals[3] = v3; }
00224
00225 int &operator()(int i) { return myVals[i]; }
00226 int operator()(int i) const { return myVals[i]; }
00227
00228 protected:
00229
00230 int I2D( int v1, int v2 ) const { return v2 - v1 + 1; }
00231 int D2I( int v, int d ) const { return v + d - 1; }
00232 int E2D( int v1, int v2 ) const { return v2 - v1; }
00233 int D2E( int v, int d ) const { return v + d; }
00234 int E2I( int v2 ) const { return v2 - 1; }
00235 int I2E( int v2 ) const { return v2 + 1; }
00236
00237
00238 static int flipI( int v, int d ) { return UTinclusiveFlip( v, d ); }
00239
00240 protected:
00241 int myVals[4];
00242 };
00243
00244 class UT_DimRectImpl : public UT_BaseRectImpl
00245 {
00246 public:
00247 UT_DimRectImpl() { }
00248 UT_DimRectImpl( const UT_DimRect &r );
00249 UT_DimRectImpl( const UT_InclusiveRect &r );
00250 UT_DimRectImpl( const UT_ExclusiveRect &r );
00251
00252 UT_DimRectImpl &operator=( const UT_DimRect &r );
00253 UT_DimRectImpl &operator=( const UT_InclusiveRect &r );
00254 UT_DimRectImpl &operator=( const UT_ExclusiveRect &r );
00255
00256
00257 void clear() { set( 0, 0, 0, 0 ); }
00258
00259
00260 bool isValid() const { return width() >= 0 && height() >= 0; }
00261
00262
00263 void flipX(int w) { myVals[0] = flipI(x2(), w); }
00264 void flipY(int h) { myVals[1] = flipI(y2(), h); }
00265
00266
00267 int x() const { return myVals[0]; }
00268 int y() const { return myVals[1]; }
00269 int width() const { return myVals[2]; }
00270 int height() const { return myVals[3]; }
00271
00272 int x1() const { return x(); }
00273 int y1() const { return y(); }
00274 int x2() const { return D2I(x(), width()); }
00275 int y2() const { return D2I(y(), height()); }
00276 int x2e() const { return I2E(x2()); }
00277 int y2e() const { return I2E(y2()); }
00278
00279 void setWidth(int w) { myVals[2] = w; }
00280 void setHeight(int h) { myVals[3] = h; }
00281
00282 void setX(int x_) { myVals[0] = x_; }
00283 void setY(int y_) { myVals[1] = y_; }
00284 void setX1(int x_) { myVals[2] += myVals[0]-x_; myVals[0] = x_; }
00285 void setY1(int y_) { myVals[3] += myVals[1]-y_; myVals[1] = y_; }
00286 void setX2(int x_) { myVals[2] = I2D(myVals[0], x_); }
00287 void setY2(int y_) { myVals[3] = I2D(myVals[1], y_); }
00288 void setX2e(int x_) { myVals[2] = E2D(myVals[0], x_); }
00289 void setY2e(int y_) { myVals[3] = E2D(myVals[1], y_); }
00290 };
00291
00292
00293 class UT_InclusiveRectImpl : public UT_BaseRectImpl
00294 {
00295 public:
00296 UT_InclusiveRectImpl() { }
00297 UT_InclusiveRectImpl( const UT_DimRect &r );
00298 UT_InclusiveRectImpl( const UT_InclusiveRect &r );
00299 UT_InclusiveRectImpl( const UT_ExclusiveRect &r );
00300
00301 UT_InclusiveRectImpl &operator=( const UT_DimRect &r );
00302 UT_InclusiveRectImpl &operator=( const UT_InclusiveRect &r );
00303 UT_InclusiveRectImpl &operator=( const UT_ExclusiveRect &r );
00304
00305
00306 void clear() { set( 0, 0, -1, -1 ); }
00307
00308
00309 bool isValid() const { return (x1() <= x2e()) && (y1() <= y2e()); }
00310
00311
00312 void flipX( int w )
00313 {
00314 myVals[0] = flipI(x1(), w);
00315 myVals[2] = flipI(x2(), w);
00316 UTswap(myVals[0], myVals[2]);
00317 }
00318 void flipY( int h )
00319 {
00320 myVals[1] = flipI(y1(), h);
00321 myVals[3] = flipI(y2(), h);
00322 UTswap(myVals[1], myVals[3]);
00323 }
00324
00325
00326 int x1() const { return myVals[0]; }
00327 int y1() const { return myVals[1]; }
00328 int x2() const { return myVals[2]; }
00329 int y2() const { return myVals[3]; }
00330 int x2e() const { return I2E(x2()); }
00331 int y2e() const { return I2E(y2()); }
00332
00333 int x() const { return x1(); }
00334 int y() const { return y1(); }
00335 int width() const { return I2D(x1(), x2()); }
00336 int height() const { return I2D(y1(), y2()); }
00337
00338 void setWidth(int w) { myVals[2] = D2I(myVals[0], w); }
00339 void setHeight(int h) { myVals[3] = D2I(myVals[1], h); }
00340
00341 void setX(int x_) { myVals[2] = x_ + width()-1; myVals[0] = x_; }
00342 void setY(int y_) { myVals[3] = y_ +height()-1; myVals[1] = y_; }
00343 void setX1(int x_) { myVals[0] = x_; }
00344 void setY1(int y_) { myVals[1] = y_; }
00345 void setX2(int x_) { myVals[2] = x_; }
00346 void setY2(int y_) { myVals[3] = y_; }
00347 void setX2e(int x_) { myVals[2] = E2I(x_); }
00348 void setY2e(int y_) { myVals[3] = E2I(y_); }
00349 };
00350
00351 class UT_ExclusiveRectImpl : public UT_BaseRectImpl
00352 {
00353 public:
00354 UT_ExclusiveRectImpl() { }
00355 UT_ExclusiveRectImpl( const UT_DimRect &r );
00356 UT_ExclusiveRectImpl( const UT_InclusiveRect &r );
00357 UT_ExclusiveRectImpl( const UT_ExclusiveRect &r );
00358
00359 UT_ExclusiveRectImpl &operator=( const UT_DimRect &r );
00360 UT_ExclusiveRectImpl &operator=( const UT_InclusiveRect &r );
00361 UT_ExclusiveRectImpl &operator=( const UT_ExclusiveRect &r );
00362
00363
00364 void clear() { set( 0, 0, 0, 0 ); }
00365
00366
00367 bool isValid() const { return x1() <= x2e() && y1() <= y2e(); }
00368
00369
00370 void flipX( int w )
00371 {
00372 myVals[0] = I2E(flipI(x1(), w));
00373 myVals[2] = flipI(x2(), w);
00374 UTswap(myVals[0], myVals[2]);
00375 }
00376 void flipY( int h )
00377 {
00378 myVals[1] = I2E(flipI(y1(), h));
00379 myVals[3] = flipI(y2(), h);
00380 UTswap(myVals[1], myVals[3]);
00381 }
00382
00383
00384 int x1() const { return myVals[0]; }
00385 int y1() const { return myVals[1]; }
00386 int x2e() const { return myVals[2]; }
00387 int y2e() const { return myVals[3]; }
00388 int x2() const { return E2I(x2e()); }
00389 int y2() const { return E2I(y2e()); }
00390
00391 int x() const { return x1(); }
00392 int y() const { return y1(); }
00393 int width() const { return E2D(x1(), x2e()); }
00394 int height() const { return E2D(y1(), y2e()); }
00395
00396 void setWidth(int w) { myVals[2] = D2E(myVals[0], w); }
00397 void setHeight(int h) { myVals[3] = D2E(myVals[1], h); }
00398
00399 void setX(int x_) { myVals[2] = x_ + width(); myVals[0] = x_; }
00400 void setY(int y_) { myVals[3] = y_ + height(); myVals[1] = y_; }
00401 void setX1(int x_) { myVals[0] = x_; }
00402 void setY1(int y_) { myVals[1] = y_; }
00403 void setX2(int x_) { myVals[2] = I2E(x_); }
00404 void setY2(int y_) { myVals[3] = I2E(y_); }
00405 void setX2e(int x_) { myVals[2] = x_; }
00406 void setY2e(int y_) { myVals[3] = y_; }
00407 };
00408
00409 inline ostream &operator<<(ostream &os, const UT_DimRect &r)
00410 {
00411 os << "[" << r.x() << ","<< r.y() << "]-[" << r.x2() << "," << r.y2()
00412 << "] (" << r.w() << "x" << r.h() << ")";
00413 return os;
00414 }
00415 inline ostream &operator<<(ostream &os, const UT_InclusiveRect &r)
00416 {
00417 os << "[" << r.x() << ","<< r.y() << "]-[" << r.x2() << "," << r.y2()
00418 << "] (" << r.w() << "x" << r.h() << ")";
00419 return os;
00420 }
00421 inline ostream &operator<<(ostream &os, const UT_ExclusiveRect &r)
00422 {
00423 os << "[" << r.x() << ","<< r.y() << "]-[" << r.x2() << "," << r.y2()
00424 << "] (" << r.w() << "x" << r.h() << ")";
00425 return os;
00426 }
00427
00428
00429
00430
00431
00432 #define UT_RECT_OP_EQUALS(T1,T2) \
00433 inline bool operator==( const T1 &r1, const T2 &r2 ) \
00434 { return (r1.x() == r2.x() && r1.y() == r2.y() \
00435 && r1.width() == r2.width() \
00436 && r1.height() == r2.height()); }
00437
00438 UT_RECT_OP_EQUALS(UT_DimRect,UT_DimRect)
00439 UT_RECT_OP_EQUALS(UT_DimRect,UT_InclusiveRect)
00440 UT_RECT_OP_EQUALS(UT_DimRect,UT_ExclusiveRect)
00441 UT_RECT_OP_EQUALS(UT_InclusiveRect,UT_DimRect)
00442 UT_RECT_OP_EQUALS(UT_InclusiveRect,UT_InclusiveRect)
00443 UT_RECT_OP_EQUALS(UT_InclusiveRect,UT_ExclusiveRect)
00444 UT_RECT_OP_EQUALS(UT_ExclusiveRect,UT_DimRect)
00445 UT_RECT_OP_EQUALS(UT_ExclusiveRect,UT_InclusiveRect)
00446 UT_RECT_OP_EQUALS(UT_ExclusiveRect,UT_ExclusiveRect)
00447 #undef UT_RECT_OP_EQUALS
00448
00449 #define UT_RECT_OP_NOT_EQUALS(T1,T2) \
00450 inline bool operator!=( const T1 &r1, const T2 &r2 ) \
00451 { return !(r1 == r2); }
00452
00453 UT_RECT_OP_NOT_EQUALS(UT_DimRect,UT_DimRect)
00454 UT_RECT_OP_NOT_EQUALS(UT_DimRect,UT_InclusiveRect)
00455 UT_RECT_OP_NOT_EQUALS(UT_DimRect,UT_ExclusiveRect)
00456 UT_RECT_OP_NOT_EQUALS(UT_InclusiveRect,UT_DimRect)
00457 UT_RECT_OP_NOT_EQUALS(UT_InclusiveRect,UT_InclusiveRect)
00458 UT_RECT_OP_NOT_EQUALS(UT_InclusiveRect,UT_ExclusiveRect)
00459 UT_RECT_OP_NOT_EQUALS(UT_ExclusiveRect,UT_DimRect)
00460 UT_RECT_OP_NOT_EQUALS(UT_ExclusiveRect,UT_InclusiveRect)
00461 UT_RECT_OP_NOT_EQUALS(UT_ExclusiveRect,UT_ExclusiveRect)
00462 #undef UT_RECT_OP_NOT_EQUALS
00463
00464 #define UT_RECT_COPY_TO_DIM(T1,T2) \
00465 inline T1::T1( const T2 &r ) \
00466 : UT_BaseRectImpl( r.x(), r.y(), r.width(), r.height() ) { } \
00467 inline T1 & T1::operator=(const T2 &r) \
00468 { set( r.x(), r.y(), r.width(), r.height() ); return *this; }
00469 #define UT_RECT_COPY_TO_INCLUSIVE(T1,T2) \
00470 inline T1::T1( const T2 &r ) \
00471 : UT_BaseRectImpl( r.x1(), r.y1(), r.x2(), r.y2() ) { } \
00472 inline T1 & T1::operator=(const T2 &r) \
00473 { set( r.x1(), r.y1(), r.x2(), r.y2() ); return *this; }
00474 #define UT_RECT_COPY_TO_EXCLUSIVE(T1,T2) \
00475 inline T1::T1( const T2 &r ) \
00476 : UT_BaseRectImpl( r.x1(), r.y1(), r.x2e(), r.y2e() ) { } \
00477 inline T1 & T1::operator=(const T2 &r) \
00478 { set( r.x1(), r.y1(), r.x2e(), r.y2e() ); return *this; }
00479
00480 UT_RECT_COPY_TO_DIM(UT_DimRectImpl,UT_DimRect)
00481 UT_RECT_COPY_TO_DIM(UT_DimRectImpl,UT_InclusiveRect)
00482 UT_RECT_COPY_TO_DIM(UT_DimRectImpl,UT_ExclusiveRect)
00483 UT_RECT_COPY_TO_INCLUSIVE(UT_InclusiveRectImpl,UT_DimRect)
00484 UT_RECT_COPY_TO_INCLUSIVE(UT_InclusiveRectImpl,UT_InclusiveRect)
00485 UT_RECT_COPY_TO_INCLUSIVE(UT_InclusiveRectImpl,UT_ExclusiveRect)
00486 UT_RECT_COPY_TO_EXCLUSIVE(UT_ExclusiveRectImpl,UT_DimRect)
00487 UT_RECT_COPY_TO_EXCLUSIVE(UT_ExclusiveRectImpl,UT_InclusiveRect)
00488 UT_RECT_COPY_TO_EXCLUSIVE(UT_ExclusiveRectImpl,UT_ExclusiveRect)
00489 #undef UT_RECT_COPY_TO_DIM
00490 #undef UT_RECT_COPY_TO_INCLUSIVE
00491 #undef UT_RECT_COPY_TO_EXCLUSIVE
00492
00493
00494 #if defined( WIN32 ) || defined( LINUX ) || defined( MBSD ) || defined(GAMEOS)
00495 #include "UT_Rect.C"
00496 #endif
00497
00498 #endif // __UT_Rect_h__