00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef QGSCLIPPER_H
00020 #define QGSCLIPPER_H
00021
00022 #include "qgis.h"
00023 #include "qgspoint.h"
00024 #include "qgsrectangle.h"
00025
00026 #include <vector>
00027 #include <utility>
00028
00029 #include <QPolygonF>
00030
00041 class CORE_EXPORT QgsClipper
00042 {
00043 public:
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 static const double MAX_X;
00065 static const double MIN_X;
00066 static const double MAX_Y;
00067 static const double MIN_Y;
00068
00069
00070
00071 enum Boundary {XMax, XMin, YMax, YMin};
00072
00073
00074
00075
00076
00077 static void trimFeature( std::vector<double>& x,
00078 std::vector<double>& y,
00079 bool shapeOpen );
00080
00081 static void trimPolygon( QPolygonF& pts, const QgsRectangle& clipRect );
00082
00087 static unsigned char* clippedLineWKB( unsigned char* wkb, const QgsRectangle& clipExtent, QPolygonF& line );
00088
00089 private:
00090
00091
00092 static const double SMALL_NUM;
00093
00094
00095
00096 static void trimFeatureToBoundary( const std::vector<double>& inX,
00097 const std::vector<double>& inY,
00098 std::vector<double>& outX,
00099 std::vector<double>& outY,
00100 Boundary b,
00101 bool shapeOpen );
00102
00103 static void trimPolygonToBoundary( const QPolygonF& inPts, QPolygonF& outPts, const QgsRectangle& rect, Boundary b, double boundaryValue );
00104
00105
00106 static bool inside( const double x, const double y, Boundary b );
00107
00108 static bool inside( const QPointF& pt, Boundary b, double val );
00109
00110
00111
00112 static QgsPoint intersect( const double x1, const double y1,
00113 const double x2, const double y2,
00114 Boundary b );
00115
00116 static QPointF intersectRect( const QPointF& pt1,
00117 const QPointF& pt2,
00118 Boundary b, const QgsRectangle& rect );
00119
00120
00121 static bool clipLineSegment( double xLeft, double xRight, double yBottom, double yTop, double& x0, double& y0, double& x1, double& y1 );
00122
00131 static void connectSeparatedLines( double x0, double y0, double x1, double y1,
00132 const QgsRectangle& clipRect, QPolygonF& pts );
00133
00134
00135 static void clipStartTop( double& x0, double& y0, const double& x1, const double& y1, double yMax );
00136 static void clipStartBottom( double& x0, double& y0, const double& x1, const double& y1, double yMin );
00137 static void clipStartRight( double& x0, double& y0, const double& x1, const double& y1, double xMax );
00138 static void clipStartLeft( double& x0, double& y0, const double& x1, const double& y1, double xMin );
00139 static void clipEndTop( const double& x0, const double& y0, double& x1, double& y1, double yMax );
00140 static void clipEndBottom( const double& x0, const double& y0, double& x1, double& y1, double yMin );
00141 static void clipEndRight( const double& x0, const double& y0, double& x1, double& y1, double xMax );
00142 static void clipEndLeft( const double& x0, const double& y0, double& x1, double& y1, double xMin );
00143 };
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 inline void QgsClipper::trimFeature( std::vector<double>& x,
00158 std::vector<double>& y,
00159 bool shapeOpen )
00160 {
00161 std::vector<double> tmpX;
00162 std::vector<double> tmpY;
00163 trimFeatureToBoundary( x, y, tmpX, tmpY, XMax, shapeOpen );
00164
00165 x.clear();
00166 y.clear();
00167 trimFeatureToBoundary( tmpX, tmpY, x, y, YMax, shapeOpen );
00168
00169 tmpX.clear();
00170 tmpY.clear();
00171 trimFeatureToBoundary( x, y, tmpX, tmpY, XMin, shapeOpen );
00172
00173 x.clear();
00174 y.clear();
00175 trimFeatureToBoundary( tmpX, tmpY, x, y, YMin, shapeOpen );
00176 }
00177
00178 inline void QgsClipper::trimPolygon( QPolygonF& pts, const QgsRectangle& clipRect )
00179 {
00180 QPolygonF tmpPts;
00181 tmpPts.reserve( pts.size() );
00182
00183 trimPolygonToBoundary( pts, tmpPts, clipRect, XMax, clipRect.xMaximum() );
00184 pts.clear();
00185 trimPolygonToBoundary( tmpPts, pts, clipRect, YMax, clipRect.yMaximum() );
00186 tmpPts.clear();
00187 trimPolygonToBoundary( pts, tmpPts, clipRect, XMin, clipRect.xMinimum() );
00188 pts.clear();
00189 trimPolygonToBoundary( tmpPts, pts, clipRect, YMin, clipRect.yMinimum() );
00190 }
00191
00192
00193
00194
00195
00196
00197 inline void QgsClipper::trimFeatureToBoundary(
00198 const std::vector<double>& inX,
00199 const std::vector<double>& inY,
00200 std::vector<double>& outX,
00201 std::vector<double>& outY,
00202 Boundary b, bool shapeOpen )
00203 {
00204
00205
00206
00207
00208 unsigned int i1 = inX.size() - 1;
00209
00210
00211 for ( unsigned int i2 = 0; i2 < inX.size() ; ++i2 )
00212 {
00213
00214
00215
00216 if ( qIsNaN( inX[i2] ) || qIsNaN( inY[i2] ) || qIsInf( inX[i2] ) || qIsInf( inY[i2] )
00217 || qIsNaN( inX[i1] ) || qIsNaN( inY[i1] ) || qIsInf( inX[i1] ) || qIsInf( inY[i1] ) )
00218 {
00219 i1 = i2;
00220 continue;
00221 }
00222
00223
00224 if ( inside( inX[i2], inY[i2], b ) )
00225 {
00226 if ( inside( inX[i1], inY[i1], b ) )
00227 {
00228 outX.push_back( inX[i2] );
00229 outY.push_back( inY[i2] );
00230 }
00231 else
00232 {
00233
00234
00235 if ( !( i2 == 0 && shapeOpen ) )
00236 {
00237 QgsPoint p = intersect( inX[i1], inY[i1], inX[i2], inY[i2], b );
00238 outX.push_back( p.x() );
00239 outY.push_back( p.y() );
00240 }
00241
00242 outX.push_back( inX[i2] );
00243 outY.push_back( inY[i2] );
00244 }
00245 }
00246 else
00247 {
00248
00249 if ( inside( inX[i1], inY[i1], b ) )
00250 {
00251 if ( !( i2 == 0 && shapeOpen ) )
00252 {
00253 QgsPoint p = intersect( inX[i1], inY[i1], inX[i2], inY[i2], b );
00254 outX.push_back( p.x() );
00255 outY.push_back( p.y() );
00256 }
00257 }
00258 }
00259 i1 = i2;
00260 }
00261 }
00262
00263 inline void QgsClipper::trimPolygonToBoundary( const QPolygonF& inPts, QPolygonF& outPts, const QgsRectangle& rect, Boundary b, double boundaryValue )
00264 {
00265 unsigned int i1 = inPts.size() - 1;
00266
00267
00268 for ( int i2 = 0; i2 < inPts.size() ; ++i2 )
00269 {
00270 if ( inside( inPts[i2], b, boundaryValue ) )
00271 {
00272 if ( inside( inPts[i1], b, boundaryValue ) )
00273 {
00274 outPts.append( inPts[i2] );
00275 }
00276 else
00277 {
00278
00279
00280 outPts.append( intersectRect( inPts[i1], inPts[i2], b, rect ) );
00281 outPts.append( inPts[i2] );
00282 }
00283 }
00284 else
00285 {
00286
00287 if ( inside( inPts[i1], b, boundaryValue ) )
00288 {
00289 outPts.append( intersectRect( inPts[i1], inPts[i2], b, rect ) );
00290 }
00291 }
00292 i1 = i2;
00293 }
00294 }
00295
00296
00297
00298
00299 inline bool QgsClipper::inside( const double x, const double y, Boundary b )
00300 {
00301 switch ( b )
00302 {
00303 case XMax:
00304 if ( x < MAX_X )
00305 return true;
00306 break;
00307 case XMin:
00308 if ( x > MIN_X )
00309 return true;
00310 break;
00311 case YMax:
00312 if ( y < MAX_Y )
00313 return true;
00314 break;
00315 case YMin:
00316 if ( y > MIN_Y )
00317 return true;
00318 break;
00319 }
00320 return false;
00321 }
00322
00323 inline bool QgsClipper::inside( const QPointF& pt, Boundary b, double val )
00324 {
00325 switch ( b )
00326 {
00327 case XMax:
00328 return ( pt.x() < val );
00329 case XMin:
00330 return ( pt.x() > val );
00331 case YMax:
00332 return ( pt.y() < val );
00333 case YMin:
00334 return ( pt.y() > val );
00335 }
00336 return false;
00337 }
00338
00339
00340
00341
00342
00343
00344 inline QgsPoint QgsClipper::intersect( const double x1, const double y1,
00345 const double x2, const double y2,
00346 Boundary b )
00347 {
00348
00349
00350
00351
00352 double r_n = SMALL_NUM, r_d = SMALL_NUM;
00353
00354 switch ( b )
00355 {
00356 case XMax:
00357 r_n = -( x1 - MAX_X ) * ( MAX_Y - MIN_Y );
00358 r_d = ( x2 - x1 ) * ( MAX_Y - MIN_Y );
00359 break;
00360 case XMin:
00361 r_n = -( x1 - MIN_X ) * ( MAX_Y - MIN_Y );
00362 r_d = ( x2 - x1 ) * ( MAX_Y - MIN_Y );
00363 break;
00364 case YMax:
00365 r_n = ( y1 - MAX_Y ) * ( MAX_X - MIN_X );
00366 r_d = -( y2 - y1 ) * ( MAX_X - MIN_X );
00367 break;
00368 case YMin:
00369 r_n = ( y1 - MIN_Y ) * ( MAX_X - MIN_X );
00370 r_d = -( y2 - y1 ) * ( MAX_X - MIN_X );
00371 break;
00372 }
00373
00374 QgsPoint p;
00375
00376 if ( qAbs( r_d ) > SMALL_NUM && qAbs( r_n ) > SMALL_NUM )
00377 {
00378 double r = r_n / r_d;
00379 p.set( x1 + r*( x2 - x1 ), y1 + r*( y2 - y1 ) );
00380 }
00381 else
00382 {
00383
00384
00385 Q_ASSERT( qAbs( r_d ) > SMALL_NUM && qAbs( r_n ) > SMALL_NUM );
00386 }
00387
00388 return p;
00389 }
00390
00391 inline QPointF QgsClipper::intersectRect( const QPointF& pt1,
00392 const QPointF& pt2,
00393 Boundary b, const QgsRectangle& rect )
00394 {
00395
00396
00397
00398
00399 double r_n = SMALL_NUM, r_d = SMALL_NUM;
00400 const double x1 = pt1.x(), x2 = pt2.x();
00401 const double y1 = pt1.y(), y2 = pt2.y();
00402
00403 switch ( b )
00404 {
00405 case XMax:
00406 r_n = -( x1 - rect.xMaximum() ) * ( rect.yMaximum() - rect.yMinimum() );
00407 r_d = ( x2 - x1 ) * ( rect.yMaximum() - rect.yMinimum() );
00408 break;
00409 case XMin:
00410 r_n = -( x1 - rect.xMinimum() ) * ( rect.yMaximum() - rect.yMinimum() );
00411 r_d = ( x2 - x1 ) * ( rect.yMaximum() - rect.yMinimum() );
00412 break;
00413 case YMax:
00414 r_n = ( y1 - rect.yMaximum() ) * ( rect.xMaximum() - rect.xMinimum() );
00415 r_d = -( y2 - y1 ) * ( rect.xMaximum() - rect.xMinimum() );
00416 break;
00417 case YMin:
00418 r_n = ( y1 - rect.yMinimum() ) * ( rect.xMaximum() - rect.xMinimum() );
00419 r_d = -( y2 - y1 ) * ( rect.xMaximum() - rect.xMinimum() );
00420 break;
00421 }
00422
00423 double r = 0;
00424 if ( !doubleNear( r_d, 0.0 ) )
00425 {
00426 r = r_n / r_d;
00427 }
00428 return QPointF( x1 + r*( x2 - x1 ), y1 + r*( y2 - y1 ) );
00429 }
00430
00431 inline void QgsClipper::clipStartTop( double& x0, double& y0, const double& x1, const double& y1, double yMax )
00432 {
00433 x0 += ( x1 - x0 ) * ( yMax - y0 ) / ( y1 - y0 );
00434 y0 = yMax;
00435 }
00436
00437 inline void QgsClipper::clipStartBottom( double& x0, double& y0, const double& x1, const double& y1, double yMin )
00438 {
00439 x0 += ( x1 - x0 ) * ( yMin - y0 ) / ( y1 - y0 );
00440 y0 = yMin;
00441 }
00442
00443 inline void QgsClipper::clipStartRight( double& x0, double& y0, const double& x1, const double& y1, double xMax )
00444 {
00445 y0 += ( y1 - y0 ) * ( xMax - x0 ) / ( x1 - x0 );
00446 x0 = xMax;
00447 }
00448
00449 inline void QgsClipper::clipStartLeft( double& x0, double& y0, const double& x1, const double& y1, double xMin )
00450 {
00451 y0 += ( y1 - y0 ) * ( xMin - x0 ) / ( x1 - x0 );
00452 x0 = xMin;
00453 }
00454
00455 inline void QgsClipper::clipEndTop( const double& x0, const double& y0, double& x1, double& y1, double yMax )
00456 {
00457 x1 += ( x1 - x0 ) * ( yMax - y1 ) / ( y1 - y0 );
00458 y1 = yMax;
00459 }
00460
00461 inline void QgsClipper::clipEndBottom( const double& x0, const double& y0, double& x1, double& y1, double yMin )
00462 {
00463 x1 += ( x1 - x0 ) * ( yMin - y1 ) / ( y1 - y0 );
00464 y1 = yMin;
00465 }
00466
00467 inline void QgsClipper::clipEndRight( const double& x0, const double& y0, double& x1, double& y1, double xMax )
00468 {
00469 y1 += ( y1 - y0 ) * ( xMax - x1 ) / ( x1 - x0 );
00470 x1 = xMax;
00471 }
00472
00473 inline void QgsClipper::clipEndLeft( const double& x0, const double& y0, double& x1, double& y1, double xMin )
00474 {
00475 y1 += ( y1 - y0 ) * ( xMin - x1 ) / ( x1 - x0 );
00476 x1 = xMin;
00477 }
00478
00479
00480 inline bool QgsClipper::clipLineSegment( double xLeft, double xRight, double yBottom, double yTop, double& x0, double& y0, double& x1, double& y1 )
00481 {
00482 int lineCode = 0;
00483
00484 if ( y1 < yBottom )
00485 lineCode |= 4;
00486 else if ( y1 > yTop )
00487 lineCode |= 8;
00488
00489 if ( x1 > xRight )
00490 lineCode |= 2;
00491 else if ( x1 < xLeft )
00492 lineCode |= 1;
00493
00494 if ( y0 < yBottom )
00495 lineCode |= 64;
00496 else if ( y0 > yTop )
00497 lineCode |= 128;
00498
00499 if ( x0 > xRight )
00500 lineCode |= 32;
00501 else if ( x0 < xLeft )
00502 lineCode |= 16;
00503
00504 switch ( lineCode )
00505 {
00506 case 0:
00507 return true;
00508
00509 case 1:
00510 clipEndLeft( x0, y0, x1, y1, xLeft );
00511 return true;
00512
00513 case 2:
00514 clipEndRight( x0, y0, x1, y1, xRight );
00515 return true;
00516
00517 case 4:
00518 clipEndBottom( x0, y0, x1, y1, yBottom );
00519 return true;
00520
00521 case 5:
00522 clipEndLeft( x0, y0, x1, y1, xLeft );
00523 if ( y1 < yBottom )
00524 clipEndBottom( x0, y0, x1, y1, yBottom );
00525 return true;
00526
00527 case 6:
00528 clipEndRight( x0, y0, x1, y1, xRight );
00529 if ( y1 < yBottom )
00530 clipEndBottom( x0, y0, x1, y1, yBottom );
00531 return true;
00532
00533 case 8:
00534 clipEndTop( x0, y0, x1, y1, yTop );
00535 return true;
00536
00537 case 9:
00538 clipEndLeft( x0, y0, x1, y1, xLeft );
00539 if ( y1 > yTop )
00540 clipEndTop( x0, y0, x1, y1, yTop );
00541 return true;
00542
00543 case 10:
00544 clipEndRight( x0, y0, x1, y1, xRight );
00545 if ( y1 > yTop )
00546 clipEndTop( x0, y0, x1, y1, yTop );
00547 return true;
00548
00549 case 16:
00550 clipStartLeft( x0, y0, x1, y1, xLeft );
00551 return true;
00552
00553 case 18:
00554 clipStartLeft( x0, y0, x1, y1, xLeft );
00555 clipEndRight( x0, y0, x1, y1, xRight );
00556 return true;
00557
00558 case 20:
00559 clipStartLeft( x0, y0, x1, y1, xLeft );
00560 if ( y0 < yBottom )
00561 return false;
00562 clipEndBottom( x0, y0, x1, y1, yBottom );
00563 return true;
00564
00565 case 22:
00566 clipStartLeft( x0, y0, x1, y1, xLeft );
00567 if ( y0 < yBottom )
00568 return false;
00569 clipEndBottom( x0, y0, x1, y1, yBottom );
00570 if ( x1 > xRight )
00571 clipEndRight( x0, y0, x1, y1, xRight );
00572 return true;
00573
00574 case 24:
00575 clipStartLeft( x0, y0, x1, y1, xLeft );
00576 if ( y0 > yTop )
00577 return false;
00578 clipEndTop( x0, y0, x1, y1, yTop );
00579 return true;
00580
00581 case 26:
00582 clipStartLeft( x0, y0, x1, y1, xLeft );
00583 if ( y0 > yTop )
00584 return false;
00585 clipEndTop( x0, y0, x1, y1, yTop );
00586 if ( x1 > xRight )
00587 clipEndRight( x0, y0, x1, y1, xRight );
00588 return true;
00589
00590 case 32:
00591 clipStartRight( x0, y0, x1, y1, xRight );
00592 return true;
00593
00594 case 33:
00595 clipStartRight( x0, y0, x1, y1, xRight );
00596 clipEndLeft( x0, y0, x1, y1, xLeft );
00597 return true;
00598
00599 case 36:
00600 clipStartRight( x0, y0, x1, y1, xRight );
00601 if ( y0 < yBottom )
00602 return false;
00603 clipEndBottom( x0, y0, x1, y1, yBottom );
00604 return true;
00605
00606 case 37:
00607 clipStartRight( x0, y0, x1, y1, xRight );
00608 if ( y0 < yBottom )
00609 return false;
00610 clipEndBottom( x0, y0, x1, y1, yBottom );
00611 if ( x1 < xLeft )
00612 clipEndLeft( x0, y0, x1, y1, xLeft );
00613 return true;
00614
00615 case 40:
00616 clipStartRight( x0, y0, x1, y1, xRight );
00617 if ( y0 > yTop )
00618 return false;
00619 clipEndTop( x0, y0, x1, y1, yTop );
00620 return true;
00621
00622 case 41:
00623 clipStartRight( x0, y0, x1, y1, xRight );
00624 if ( y0 > yTop )
00625 return false;
00626 clipEndTop( x0, y0, x1, y1, yTop );
00627 if ( x1 < xLeft )
00628 clipEndLeft( x0, y0, x1, y1, xLeft );
00629 return true;
00630
00631 case 64:
00632 clipStartBottom( x0, y0, x1, y1, yBottom );
00633 return true;
00634
00635 case 65:
00636 clipStartBottom( x0, y0, x1, y1, yBottom );
00637 if ( x0 < xLeft )
00638 return false;
00639 clipEndLeft( x0, y0, x1, y1, xLeft );
00640 if ( y1 < yBottom )
00641 clipEndBottom( x0, y0, x1, y1, yBottom );
00642 return true;
00643
00644 case 66:
00645 clipStartBottom( x0, y0, x1, y1, yBottom );
00646 if ( x0 > xRight )
00647 return false;
00648 clipEndRight( x0, y0, x1, y1, xRight );
00649 return true;
00650
00651 case 72:
00652 clipStartBottom( x0, y0, x1, y1, yBottom );
00653 clipEndTop( x0, y0, x1, y1, yTop );
00654 return true;
00655
00656 case 73:
00657 clipStartBottom( x0, y0, x1, y1, yBottom );
00658 if ( x0 < xLeft )
00659 return false;
00660 clipEndLeft( x0, y0, x1, y1, xLeft );
00661 if ( y1 > yTop )
00662 clipEndTop( x0, y0, x1, y1, yTop );
00663 return true;
00664
00665 case 74:
00666 clipStartBottom( x0, y0, x1, y1, yBottom );
00667 if ( x0 > xRight )
00668 return false;
00669 clipEndRight( x0, y0, x1, y1, xRight );
00670 if ( y1 > yTop )
00671 clipEndTop( x0, y0, x1, y1, yTop );
00672 return true;
00673
00674 case 80:
00675 clipStartLeft( x0, y0, x1, y1, xLeft );
00676 if ( y0 < yBottom )
00677 clipStartBottom( x0, y0, x1, y1, yBottom );
00678 return true;
00679
00680 case 82:
00681 clipEndRight( x0, y0, x1, y1, xRight );
00682 if ( y1 < yBottom )
00683 return false;
00684 clipStartBottom( x0, y0, x1, y1, yBottom );
00685 if ( x0 < xLeft )
00686 clipStartLeft( x0, y0, x1, y1, xLeft );
00687 return true;
00688
00689 case 88:
00690 clipEndTop( x0, y0, x1, y1, yTop );
00691 if ( x1 < xLeft )
00692 return false;
00693 clipStartBottom( x0, y0, x1, y1, yBottom );
00694 if ( x0 < xLeft )
00695 clipStartLeft( x0, y0, x1, y1, xLeft );
00696 return true;
00697
00698 case 90:
00699 clipStartLeft( x0, y0, x1, y1, xLeft );
00700 if ( y0 > yTop )
00701 return false;
00702 clipEndRight( x0, y0, x1, y1, xRight );
00703 if ( y1 < yBottom )
00704 return false;
00705 if ( y0 < yBottom )
00706 clipStartBottom( x0, y0, x1, y1, yBottom );
00707 if ( y1 > yTop )
00708 clipEndTop( x0, y0, x1, y1, yTop );
00709 return true;
00710
00711 case 96:
00712 clipStartRight( x0, y0, x1, y1, xRight );
00713 if ( y0 < yBottom )
00714 clipStartBottom( x0, y0, x1, y1, yBottom );
00715 return true;
00716
00717 case 97:
00718 clipEndLeft( x0, y0, x1, y1, xLeft );
00719 if ( y1 < yBottom )
00720 return false;
00721 clipStartBottom( x0, y0, x1, y1, yBottom );
00722 if ( x0 > xRight )
00723 clipStartRight( x0, y0, x1, y1, xRight );
00724 return true;
00725
00726 case 104:
00727 clipEndTop( x0, y0, x1, y1, yTop );
00728 if ( x1 > xRight )
00729 return false;
00730 clipStartRight( x0, y0, x1, y1, xRight );
00731 if ( y0 < yBottom )
00732 clipStartBottom( x0, y0, x1, y1, yBottom );
00733 return true;
00734
00735 case 105:
00736 clipEndLeft( x0, y0, x1, y1, xLeft );
00737 if ( y1 < yBottom )
00738 return false;
00739 clipStartRight( x0, y0, x1, y1, xRight );
00740 if ( y0 > yTop )
00741 return false;
00742 if ( y1 > yTop )
00743 clipEndTop( x0, y0, x1, y1, yTop );
00744 if ( y0 < yBottom )
00745 clipStartBottom( x0, y0, x1, y1, yBottom );
00746 return true;
00747
00748 case 128:
00749 clipStartTop( x0, y0, x1, y1, yTop );
00750 return true;
00751
00752 case 129:
00753 clipStartTop( x0, y0, x1, y1, yTop );
00754 if ( x0 < xLeft )
00755 return false;
00756 clipEndLeft( x0, y0, x1, y1, xLeft );
00757 return true;
00758
00759 case 130:
00760 clipStartTop( x0, y0, x1, y1, yTop );
00761 if ( x0 > xRight )
00762 return false;
00763 clipEndRight( x0, y0, x1, y1, xRight );
00764 return true;
00765
00766 case 132:
00767 clipStartTop( x0, y0, x1, y1, yTop );
00768 clipEndBottom( x0, y0, x1, y1, yBottom );
00769 return true;
00770
00771 case 133:
00772 clipStartTop( x0, y0, x1, y1, yTop );
00773 if ( x0 < xLeft )
00774 return false;
00775 clipEndLeft( x0, y0, x1, y1, xLeft );
00776 if ( y1 < yBottom )
00777 clipEndBottom( x0, y0, x1, y1, yBottom );
00778 return true;
00779
00780 case 134:
00781 clipStartTop( x0, y0, x1, y1, yTop );
00782 if ( x0 > xRight )
00783 return false;
00784 clipEndRight( x0, y0, x1, y1, xRight );
00785 if ( y1 < yBottom )
00786 clipEndBottom( x0, y0, x1, y1, yBottom );
00787 return true;
00788
00789 case 144:
00790 clipStartLeft( x0, y0, x1, y1, xLeft );
00791 if ( y0 > yTop )
00792 clipStartTop( x0, y0, x1, y1, yTop );
00793 return true;
00794
00795 case 146:
00796 clipEndRight( x0, y0, x1, y1, xRight );
00797 if ( y1 > yTop )
00798 return false;
00799 clipStartTop( x0, y0, x1, y1, yTop );
00800 if ( x0 < xLeft )
00801 clipStartLeft( x0, y0, x1, y1, xLeft );
00802 return true;
00803
00804 case 148:
00805 clipEndBottom( x0, y0, x1, y1, yBottom );
00806 if ( x1 < xLeft )
00807 return false;
00808 clipStartLeft( x0, y0, x1, y1, xLeft );
00809 if ( y0 > yTop )
00810 clipStartTop( x0, y0, x1, y1, yTop );
00811 return true;
00812
00813 case 150:
00814 clipStartLeft( x0, y0, x1, y1, xLeft );
00815 if ( y0 < yBottom )
00816 return false;
00817 clipEndRight( x0, y0, x1, y1, xRight );
00818 if ( y1 > yTop )
00819 return false;
00820 if ( y0 > yTop )
00821 clipStartTop( x0, y0, x1, y1, yTop );
00822 if ( y1 < yBottom )
00823 clipEndBottom( x0, y0, x1, y1, yBottom );
00824 return true;
00825
00826 case 160:
00827 clipStartRight( x0, y0, x1, y1, xRight );
00828 if ( y0 > yTop )
00829 clipStartTop( x0, y0, x1, y1, yTop );
00830 return true;
00831
00832 case 161:
00833 clipEndLeft( x0, y0, x1, y1, xLeft );
00834 if ( y1 > yTop )
00835 return false;
00836 clipStartTop( x0, y0, x1, y1, yTop );
00837 if ( x0 > xRight )
00838 clipStartRight( x0, y0, x1, y1, xRight );
00839 return true;
00840
00841 case 164:
00842 clipEndBottom( x0, y0, x1, y1, yBottom );
00843 if ( x1 > xRight )
00844 return false;
00845 clipStartRight( x0, y0, x1, y1, xRight );
00846 if ( y0 > yTop )
00847 clipStartTop( x0, y0, x1, y1, yTop );
00848 return true;
00849
00850 case 165:
00851 clipEndLeft( x0, y0, x1, y1, xLeft );
00852 if ( y1 > yTop )
00853 return false;
00854 clipStartRight( x0, y0, x1, y1, xRight );
00855 if ( y0 < yBottom )
00856 return false;
00857 if ( y1 < yBottom )
00858 clipEndBottom( x0, y0, x1, y1, yBottom );
00859 if ( y0 > yTop )
00860 clipStartTop( x0, y0, x1, y1, yTop );
00861 return true;
00862 }
00863
00864 return false;
00865
00866 }
00867
00868
00869 #endif