00001
00002
00003
00004
00005
00006
00007
00008 #include "clipping.h"
00009 #include "math_graphics.h"
00010 #include "GetProperty.h"
00011 #include "Xcall1.h"
00012 #include "SetProperty.h"
00013
00014
00015 SClipRegion getClipRegion( struct BCG * scilabXGC )
00016 {
00017 SClipRegion clipping ;
00018
00019 clipping.leftX = scilabXGC->CurClipRegion[0];
00020 clipping.rightX = scilabXGC->CurClipRegion[0] + scilabXGC->CurClipRegion[2];
00021 clipping.bottomY = scilabXGC->CurClipRegion[1] ;
00022 clipping.topY = scilabXGC->CurClipRegion[1] + scilabXGC->CurClipRegion[3] ;
00023
00024 return clipping ;
00025 }
00026
00027
00028
00029
00030
00031
00032
00033
00034 int sciClipPoint(integer x, integer y, SClipRegion * clipping )
00035 {
00036 integer ret_val = 0;
00037
00038 if (x < clipping->leftX) ret_val |= (char)0x01;
00039 else if (x > clipping->rightX) ret_val |= (char)0x02;
00040 if (y < clipping->bottomY) ret_val |= (char)0x04;
00041 else if (y > clipping->topY ) ret_val |= (char)0x08;
00042 return ret_val;
00043 }
00044
00045
00046
00047 void sciClipLine( integer x1 ,
00048 integer yy1 ,
00049 integer x2 ,
00050 integer y2 ,
00051 integer * x1n ,
00052 integer * yy1n ,
00053 integer * x2n ,
00054 integer * y2n ,
00055 integer * flag ,
00056 SClipRegion * clipping )
00057 {
00058 integer x_intr[2], y_intr[2];
00059
00060
00061 integer x, y, dx, dy, count, pos1, pos2;
00062
00063 *x1n=x1 ;
00064 *yy1n=yy1;
00065 *x2n=x2 ;
00066 *y2n=y2 ;
00067 *flag=4 ;
00068
00069 pos1 = sciClipPoint(x1, yy1, clipping ) ;
00070 pos2 = sciClipPoint(x2, y2 , clipping ) ;
00071 if (pos1 || pos2) {
00072 if (pos1 & pos2) { *flag=0;return;}
00073
00074
00075
00076
00077
00078
00079 count = 0;
00080 dx = x2 - x1;
00081 dy = y2 - yy1;
00082
00083
00084 if (dy != 0) {
00085 x = (integer) ((int) (clipping->bottomY - y2) * ((double) dx / (double) dy) + x2);
00086
00087 if (x >= clipping->leftX && x <= clipping->rightX ) {
00088 x_intr[count] = x;
00089 y_intr[count++] = clipping->bottomY ;
00090 }
00091 x = (integer)((clipping->topY - y2) * ((double) dx / (double) dy) + x2);
00092
00093 if ( x >= clipping->leftX && x <= clipping->rightX ) {
00094 x_intr[count] = x;
00095 y_intr[count++] = clipping->topY;
00096 }
00097 }
00098 if ( count < 2 )
00099 {
00100
00101 if (dx != 0) {
00102 y = (integer)((clipping->leftX - x2) * ((double) dy / (double) dx) + y2);
00103
00104 if (y >= clipping->bottomY && y <= clipping->topY) {
00105 x_intr[count] = clipping->leftX;
00106 y_intr[count++] = y;
00107 }
00108 if ( count < 2 )
00109 {
00110 y = (integer)((clipping->rightX - x2) * ((double) dy / (double) dx) + y2);
00111
00112 if (y >= clipping->bottomY && y <= clipping->topY) {
00113 x_intr[count] = clipping->rightX;
00114 y_intr[count++] = y;
00115 }
00116 }
00117 }
00118 }
00119
00120 if (count == 2) {
00121 if (pos1 && pos2) {
00122 *x1n = x_intr[0];
00123 *yy1n = y_intr[0];
00124 *x2n = x_intr[1];
00125 *y2n = y_intr[1];
00126 *flag=3;return;
00127 }
00128 else if (pos1) {
00129 if (dx * (x2 - x_intr[0]) + dy * (y2 - y_intr[0]) >= 0) {
00130 *x1n = x_intr[0];
00131 *yy1n = y_intr[0];
00132 *flag=1;return;
00133 }
00134 else {
00135 *x1n = x_intr[1];
00136 *yy1n = y_intr[1];
00137 *flag=1;return;
00138 }
00139 }
00140 else {
00141 if (dx * (x_intr[0] - x1) + dy * (y_intr[0] - yy1) >= 0) {
00142 *x2n = x_intr[0];
00143 *y2n = y_intr[0];
00144 *flag=2;return;
00145 }
00146 else {
00147 *x2n = x_intr[1];
00148 *y2n = y_intr[1];
00149 *flag=2;return;
00150 }
00151 }
00152 }
00153 else
00154 {
00155
00156 *flag=0;
00157 return;
00158 }
00159 }
00160 }
00161
00162
00163
00164 void sciDrawInsideSegments( integer iib,
00165 integer iif,
00166 integer * vx ,
00167 integer * vy ,
00168 SClipRegion * clipping )
00169 {
00170 integer x1n,y1n,x11n,y11n,x2n,y2n,flag2=0,flag1=0;
00171 integer npts;
00172 integer * vxNew ;
00173 integer * vyNew ;
00174 int close = 0 ;
00175
00176
00177 int prevBounds[4] ;
00178
00179 npts = ( iib > 0) ? iif-iib+2 : iif-iib+1;
00180
00181 if ( iib > 0)
00182 {
00183 sciClipLine( vx[iib-1], vy[iib-1],
00184 vx[iib] , vy[iib] ,
00185 &x1n , &y1n ,
00186 &x2n , &y2n ,
00187 &flag1 , clipping ) ;
00188 }
00189 sciClipLine( vx[iif-1], vy[iif-1],
00190 vx[iif] , vy[iif] ,
00191 &x11n , &y11n ,
00192 &x2n , &y2n ,
00193 &flag2 , clipping ) ;
00194 vxNew = &vx[Max(0,iib-1)] ;
00195 vyNew = &vy[Max(0,iib-1)] ;
00196
00197 prevBounds[0] = vxNew[0] ;
00198 prevBounds[1] = vyNew[0] ;
00199 prevBounds[2] = vxNew[npts-1] ;
00200 prevBounds[3] = vyNew[npts-1] ;
00201
00202 if ( iib > 0 && (flag1==1||flag1==3) )
00203 {
00204 vxNew[0] = x1n ;
00205 vyNew[0] = y1n ;
00206 }
00207 if ( flag2==2 || flag2==3 )
00208 {
00209 vxNew[npts-1] = x2n ;
00210 vyNew[npts-1] = y2n ;
00211 }
00212
00213
00214 C2F (dr) ("xuclines", "xv", &npts, vxNew, vyNew, &close, PI0, PI0, PD0, PD0, PD0, PD0,6L,2L);
00215
00216
00217 vxNew[0] = prevBounds[0] ;
00218 vyNew[0] = prevBounds[1] ;
00219 vxNew[npts-1] = prevBounds[2] ;
00220 vyNew[npts-1] = prevBounds[3] ;
00221
00222 }
00223
00224
00225
00226
00227 void sciDrawOutsideSegment( integer ind,
00228 integer *vx,
00229 integer *vy,
00230 SClipRegion * clipping )
00231 {
00233 integer segX[2],segY[2],flag;
00234 sciClipLine( vx[ind-1], vy[ind-1] ,
00235 vx[ind] , vy[ind] ,
00236 &segX[0] , &segY[0],
00237 &segX[1] , &segY[1] ,
00238 &flag , clipping ) ;
00239 if ( flag == 3 )
00240 {
00241 int nbPoints = 2 ;
00242 int close = 0 ;
00243 C2F (dr) ("xuclines", "xv", &nbPoints, segX, segY, &close, PI0, PI0, PD0, PD0, PD0, PD0,6L,2L);
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 integer sciFirstInClipRegion( integer n ,
00256 integer ideb,
00257 integer * vx ,
00258 integer * vy ,
00259 SClipRegion * clipping )
00260 {
00261 integer i;
00262 for (i=ideb ; i < n ; i++)
00263 {
00264 if ( vx[i] >= clipping->leftX
00265 && vx[i] <= clipping->rightX
00266 && vy[i] >= clipping->bottomY
00267 && vy[i] <= clipping->topY )
00268 {
00269 return(i);
00270 }
00271 }
00272 return(-1);
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282 integer sciFirstOutClipRegion( integer n ,
00283 integer ideb,
00284 integer * vx ,
00285 integer * vy ,
00286 SClipRegion * clipping )
00287 {
00288 integer i;
00289 for ( i=ideb ; i < n ; i++ )
00290 {
00291 if ( vx[i] < clipping->leftX
00292 || vx[i] > clipping->rightX
00293 || vy[i] < clipping->bottomY
00294 || vy[i] > clipping->topY )
00295 {
00296 return(i);
00297 }
00298 }
00299 return(-1);
00300 }
00301
00302
00303
00304
00305
00306 void C2F(clipPolyLine)( integer n ,
00307 integer * vx ,
00308 integer * vy ,
00309 integer closed,
00310 SClipRegion * clipping )
00311 {
00312 integer iib,iif,ideb=0,vxl[2],vyl[2];
00313
00314 while (1)
00315 {
00316 integer j;
00317 iib = sciFirstInClipRegion( n, ideb, vx, vy, clipping ) ;
00318 if (iib == -1)
00319 {
00320 for (j=ideb+1; j < n; j++)
00321 {
00322 sciDrawOutsideSegment( j, vx, vy, clipping ) ;
00323 }
00324 break;
00325 }
00326 else
00327 {
00328 if ( iib - ideb > 1)
00329 {
00330
00331
00332 for ( j = ideb + 1 ; j < iib; j++ )
00333 {
00334 sciDrawOutsideSegment(j,vx,vy, clipping ) ;
00335 }
00336 }
00337 }
00338 iif = sciFirstOutClipRegion( n, iib, vx, vy, clipping ) ;
00339 if ( iif == -1 )
00340 {
00341
00342 if (iib == 0)
00343 {
00344 C2F (dr) ("xuclines", "xv", &n, vx, vy, &closed, PI0, PI0, PD0, PD0, PD0, PD0,6L,2L) ;
00345 return ;
00346 }
00347 else
00348 {
00349 sciDrawInsideSegments( iib, n-1, vx, vy, clipping ) ;
00350 }
00351 break;
00352 }
00353
00354 sciDrawInsideSegments( iib, iif, vx, vy, clipping ) ;
00355 ideb=iif;
00356 }
00357 if ( closed )
00358 {
00359
00360 integer x1n,y1n,x2n,y2n,flag1=0;
00361 vxl[0]=vx[n-1];vxl[1]=vx[0];vyl[0]=vy[n-1];vyl[1]=vy[0];
00362 sciClipLine( vxl[0], vyl[0],
00363 vxl[1], vyl[1],
00364 &x1n , &y1n ,
00365 &x2n , &y2n ,
00366 &flag1, clipping ) ;
00367
00368 if ( flag1==0 ) { return ; }
00369
00370 if ( flag1==1 || flag1==3 )
00371 {
00372 vxl[0] = x1n ;
00373 vyl[0] = y1n ;
00374 }
00375 if ( flag1==2 || flag1==3 )
00376 {
00377 vxl[1] = x2n ;
00378 vyl[1] = y2n ;
00379 }
00380
00381 {
00382 int nbPoints = 2 ;
00383 int close = 0 ;
00384 C2F (dr) ("xuclines", "xv", &nbPoints, vxl, vyl, &close, PI0, PI0, PD0, PD0, PD0, PD0,6L,2L);
00385 }
00386
00387
00388 }
00389 }
00390
00391
00392
00393
00394
00395
00396 void getPixelClipping( sciPointObj * pObj, SClipRegion * clipping )
00397 {
00398 double * clipRegion = sciGetClipping( pObj ) ;
00399 clipping->leftX = XDouble2Pixel( clipRegion[0] ) ;
00400 clipping->rightX = XDouble2Pixel( clipRegion[0] + clipRegion[2] ) ;
00401 clipping->bottomY = YDouble2Pixel( clipRegion[1] ) ;
00402 clipping->topY = YDouble2Pixel( clipRegion[1] - clipRegion[3] ) ;
00403
00404 }
00405
00406 void sciClip (sciPointObj *pobj)
00407 {
00408 int x,y,w,h;
00409 int value;
00410 double *clip_region = NULL;
00411
00412 sciPointObj * psubwin = sciGetParentSubwin(pobj);
00413 sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin);
00414
00415 value = sciGetIsClipping(pobj);
00416
00417 if(value == -1) return;
00418 if(ppsubwin->is3d == TRUE) return;
00419
00420 clip_region = sciGetClipping(pobj);
00421
00422
00423 if(sciGetIsClipRegionValuated(pobj) == 0)
00424 value = 0;
00425
00426 if (value == 0){
00427 double clip[4];
00428 double tmpx, tmpy, tmpw, tmph;
00429
00430 tmpw = fabs(ppsubwin->FRect[2] - ppsubwin->FRect[0]);
00431 tmph = fabs(ppsubwin->FRect[3] - ppsubwin->FRect[1]);
00432
00433 tmpx = ppsubwin->FRect[0];
00434 tmpy = ppsubwin->FRect[3];
00435
00436 clip[0] = tmpx;
00437 clip[1] = tmpy;
00438 clip[2] = tmpw;
00439 clip[3] = tmph;
00440
00441 sciSetClipping(pobj,clip);
00442
00443 frame_clip_on();
00444 }
00445 else if (value > 0)
00446 {
00447 double tmpw, tmph;
00448 double tmpx, tmpy;
00449
00450 tmpw = clip_region[2];
00451 tmph = clip_region[3];
00452
00453 tmpx = clip_region[0];
00454 tmpy = clip_region[1];
00455
00456 if(ppsubwin->axes.reverse[0] == TRUE)
00457 tmpx = tmpx + tmpw;
00458
00459 if(ppsubwin->axes.reverse[1] == TRUE)
00460 tmpy = tmpy - tmph;
00461
00462 x = XDouble2Pixel( tmpx);
00463 y = YDouble2Pixel( tmpy);
00464 w = WDouble2Pixel( tmpx, tmpw);
00465 h = HDouble2Pixel( tmpy, tmph);
00466 C2F(dr)("xset","clipping",&x, &y, &w, &h,PI0,PI0,PD0,PD0,PD0,PD0,4L,8L);
00467 }
00468 }
00469
00470 void sciUnClip ( sciPointObj * pobj )
00471 {
00472 int value = sciGetIsClipping(pobj);
00473
00474 if ( value > -1 )
00475 {
00476 C2F(dr)("xset","clipoff",PI0,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,4L,7L) ;
00477 }
00478 }
00479
00480 void frame_clip_on( void )
00481 {
00482 C2F(dr)("xset","clipping",&Cscale.WIRect1[0],&Cscale.WIRect1[1],&Cscale.WIRect1[2],
00483 &Cscale.WIRect1[3],PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00484 }
00485
00486 void frame_clip_off( void )
00487 {
00488 C2F(dr)("xset","clipoff",PI0,PI0,PI0,PI0, PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00489 }
00490