1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
18 #define BUC40223 /*GG_070797
19 Protection contre zoom trop grand*/
21 #include <Xw_Extension.h>
23 /* ifdef then trace on */
25 #define TRACE_DRAW_POLY
29 STATUS Xw_draw_poly (awindow,npoint,px,py):
30 XW_EXT_WINDOW *awindow
31 int npoint Polygone point number
32 float *px,*py Polygone points
35 Display continuous poly in current QG set by set_poly_attrib .
36 Note that polys can be buffered depending of the DisplayMode context
37 and Flush at Xw_flush time .
39 returns ERROR if npoint > MAXPOINTS
40 returns SUCCESS if successful
44 static int FirstPolyPoint = -1 ;
45 static int FirstPolyLine = -1 ;
46 static int FirstPathPoint = -1 ;
47 static XW_EXT_POLY *ppolylist ;
48 static XW_EXT_POINT *plinedesc ;
49 static XSegment segment;
52 XW_STATUS Xw_draw_poly (void* awindow,int npoint,float* px,float* py)
54 XW_STATUS Xw_draw_poly (awindow,npoint,px,py)
58 #endif /*XW_PROTOTYPE*/
60 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow;
61 XW_EXT_BUFFER *pbuffer ;
62 int i,npoly,ldesc,bindex;
63 int x=0,y=0,lx=0,ly=0 ;
66 if( !Xw_isdefine_window(pwindow) ) {
67 /*ERROR*Bad EXT_WINDOW Address*/
68 Xw_set_error(24,"Xw_draw_poly",pwindow) ;
72 if( npoint >= MAXPOINTS ) {
73 npoint = MAXPOINTS-1 ;
74 /*ERROR*Too many points in POLYGONE*/
75 Xw_set_error(28,"Xw_draw_poly",&npoint) ;
80 /*WARNING*POLYGONE is Empty !!!*/
81 Xw_set_error(33,"Xw_draw_poly",&npoint) ;
86 pbuffer = &_BUFFER(bindex) ;
87 for( ppolylist = pbuffer->ppolylist ; ppolylist ;
88 ppolylist = (XW_EXT_POLY*)ppolylist->link ) {
89 if( ppolylist->npoly < MAXPOLYS ) break ;
93 ppolylist = Xw_add_polygone_structure(pbuffer) ;
96 if( !ppolylist ) return XW_ERROR ;
98 for( plinedesc = pbuffer->plinedesc ; plinedesc ;
99 plinedesc = (XW_EXT_POINT*)plinedesc->link ) {
100 if( plinedesc->npoint + npoint < MAXPOINTS ) break ;
104 plinedesc = Xw_add_line_desc_structure(pbuffer) ;
107 if( !plinedesc ) return XW_ERROR ;
109 npoly = ppolylist->npoly ;
110 ldesc = plinedesc->npoint ;
111 ppolylist->ppolys[npoly] = ppoint = &plinedesc->rpoints[ldesc] ;
112 for( i=0 ; i<npoint ; i++ ) {
114 x = PXPOINT(px[i], pwindow->xratio) ;
115 y = PYPOINT(py[i], pwindow->attributes.height, pwindow->yratio) ;
120 status = Xw_clip_segment(pwindow,lx,ly,x,y,&segment);
122 if( (i < 2) || (status & 0xF ) ) {
123 plinedesc->rpoints[ldesc].x = segment.x1 ;
124 plinedesc->rpoints[ldesc].y = segment.y1 ;
127 int xx = segment.x1,yy = segment.y1;
128 pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
129 pbuffer->rymin = min(pbuffer->rymin,yy) ;
130 pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
131 pbuffer->rymax = max(pbuffer->rymax,yy) ;
134 plinedesc->rpoints[ldesc].x = segment.x2 ;
135 plinedesc->rpoints[ldesc].y = segment.y2 ;
138 int xx = segment.x2,yy = segment.y2;
139 pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
140 pbuffer->rymin = min(pbuffer->rymin,yy) ;
141 pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
142 pbuffer->rymax = max(pbuffer->rymax,yy) ;
148 plinedesc->rpoints[ldesc].x = x ;
149 plinedesc->rpoints[ldesc].y = y ;
152 pbuffer->rxmin = min(pbuffer->rxmin,x) ;
153 pbuffer->rymin = min(pbuffer->rymin,y) ;
154 pbuffer->rxmax = max(pbuffer->rxmax,x) ;
155 pbuffer->rymax = max(pbuffer->rymax,y) ;
159 if( ppoint->x != x || ppoint->y != y ) {
160 plinedesc->rpoints[ldesc].x = ppoint->x ;
161 plinedesc->rpoints[ldesc].y = ppoint->y ;
164 ppolylist->polys[npoly] = ldesc - plinedesc->npoint ;
165 ppolylist->paths[npoly] = ppolylist->polys[npoly] ;
166 if( ppolylist->polys[npoly] > 3 ) {
168 plinedesc->npoint = ldesc ;
171 pbuffer->isempty = False ;
172 } else if( FirstPolyPoint < 0 ) {
173 int polyindex = pwindow->polyindex ;
174 int lineindex = pwindow->lineindex ;
175 GC gcpoly = (QGTILE(pwindow->qgpoly[polyindex].code)) ?
176 pwindow->qgpoly[polyindex].gc : NULL ;
177 GC gcline = (QGTYPE(pwindow->qgpoly[polyindex].code)) ?
178 pwindow->qgline[lineindex].gc : NULL ;
179 Xw_draw_pixel_polys(pwindow,ppolylist,gcpoly,gcline);
180 ppolylist->npoly = 0 ;
181 plinedesc->npoint = 0 ;
185 #ifdef TRACE_DRAW_POLY
186 if( Xw_get_trace() > 2 ) {
187 printf(" Xw_draw_poly(%lx,%d)\n",(long ) pwindow,npoint) ;
188 for( i=0 ; i<npoint ; i++ ) {
189 printf(" Point(%d) = {%f,%f}\n",i,px[i],py[i]) ;
198 void Xw_draw_pixel_polys(XW_EXT_WINDOW* pwindow,XW_EXT_POLY* ppolylist,
201 void Xw_draw_pixel_polys(pwindow,ppolylist,gcpoly,gcline)
202 XW_EXT_WINDOW *pwindow ;
203 XW_EXT_POLY *ppolylist ;
207 int i,npolypoint,npathpoint,shape,npoint=0,count=0;
208 Region chr_region=NULL;
211 for( i=0 ; i<ppolylist->npoly ; i++ ) {
212 npolypoint = ppolylist->polys[i] ;
213 npathpoint = ppolylist->paths[i] ;
214 ppoint = ppolylist->ppolys[i] ;
215 if( ppolylist->isupdated ) {
216 ppoint += MAXPOINTS ;
219 if( npolypoint > 0 ) {
220 npoint = npolypoint; count = 0;
223 if( npoint > npathpoint ) {
224 if( npathpoint > 3 ) {
225 if( chr_region == 0 ) {
227 XPolygonRegion(ppoint,npathpoint-1,EvenOddRule);
230 XPolygonRegion(ppoint,npathpoint-1,EvenOddRule);
231 Region chr_xorreg = XCreateRegion ();
232 XXorRegion (chr_region, chr_pathreg, chr_xorreg);
233 XDestroyRegion (chr_region);
234 chr_region = chr_xorreg;
238 if( count >= npoint && chr_region ) {
240 XSetRegion(_DISPLAY,gcpoly,chr_region);
241 XClipBox(chr_region,&rect);
242 XFillRectangles(_DISPLAY,_DRAWABLE,gcpoly,&rect,1);
243 XDestroyRegion(chr_region);
244 XSetClipMask(_DISPLAY,gcpoly,None);
246 } else if( npoint > 3 ) {
247 shape = (npoint > 4) ? Nonconvex : Convex;
248 XFillPolygon(_DISPLAY,_DRAWABLE,gcpoly,ppoint,npoint-1,
249 shape,CoordModeOrigin) ;
253 if( gcline && (gcpoly != gcline) && (npathpoint > 3) ) {
254 XDrawLines(_DISPLAY,_DRAWABLE,gcline,
255 ppoint,npathpoint,CoordModeOrigin) ;
261 STATUS Xw_begin_poly (awindow,npoint,npath):
262 XW_EXT_WINDOW *awindow
263 int npoint Estimated polygone point number
264 int npath Estimated polygone path number
267 Begin Polygone which must be filled by Xw_poly_point and
268 closed by Xw_close_poly
270 returns ERROR if npoint > MAXPOINTS
272 returns SUCCESS if successful
276 static int Npoint = 0;
279 XW_STATUS Xw_begin_poly(void* awindow,int npoint,int npath)
281 XW_STATUS Xw_begin_poly(awindow,npoint,npath)
284 #endif /*XW_PROTOTYPE*/
286 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
287 int npoly,ldesc,bindex ;
289 if( !Xw_isdefine_window(pwindow) ) {
290 /*ERROR*Bad EXT_WINDOW Address*/
291 Xw_set_error(24,"Xw_begin_poly",pwindow) ;
295 if( npoint >= MAXPOINTS ) {
296 npoint = MAXPOINTS-1 ;
297 /*ERROR*Too many points in POLYGONE*/
298 Xw_set_error(32,"Xw_begin_poly",&npoint) ;
302 if( npath >= MAXPOLYS ) {
304 /*ERROR*Too many paths in POLYGONE*/
305 Xw_set_error(32,"Xw_begin_poly",&npath) ;
309 if( FirstPolyPoint >= 0 ) Xw_close_poly(pwindow) ;
312 for( ppolylist = _BUFFER(bindex).ppolylist ; ppolylist ;
313 ppolylist = (XW_EXT_POLY*)ppolylist->link ) {
314 if( (ppolylist->npoly + npath) < MAXPOLYS ) break ;
318 ppolylist = Xw_add_polygone_structure(&_BUFFER(bindex)) ;
321 if( !ppolylist ) return XW_ERROR ;
323 for( plinedesc = _BUFFER(bindex).plinedesc ; plinedesc ;
324 plinedesc = (XW_EXT_POINT*)plinedesc->link ) {
325 if( (plinedesc->npoint + npoint) < MAXPOINTS ) break ;
329 plinedesc = Xw_add_line_desc_structure(&_BUFFER(bindex)) ;
332 if( !plinedesc ) return XW_ERROR ;
334 npoly = ppolylist->npoly ;
335 ldesc = plinedesc->npoint ;
336 ppolylist->polys[npoly] = 0 ;
337 ppolylist->paths[npoly] = Npoint = 0 ;
338 ppolylist->ppolys[npoly] = &plinedesc->rpoints[ldesc] ;
339 FirstPolyPoint = FirstPathPoint = ldesc ;
340 FirstPolyLine = npoly;
343 #ifdef TRACE_DRAW_POLY
344 if( Xw_get_trace() > 2 ) {
345 printf(" Xw_begin_poly(%lx,%d,%d)\n",(long ) pwindow,npoint,npath) ;
348 return (XW_SUCCESS) ;
352 STATUS Xw_poly_point (awindow,x,y):
353 XW_EXT_WINDOW *awindow
354 float x,y New point to add in polygone in user-space coordinates
356 Fill Polygone with one point more
358 returns ERROR if Too Many Points in polygones
359 returns SUCCESS if successful
364 XW_STATUS Xw_poly_point(void* awindow,float x,float y)
366 XW_STATUS Xw_poly_point(awindow,x,y)
369 #endif /*XW_PROTOTYPE*/
371 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
372 XW_EXT_BUFFER *pbuffer ;
375 if( FirstPolyPoint >= 0 ) {
376 int ldesc = plinedesc->npoint ;
377 if( ldesc >= MAXPOINTS ) {
378 /*ERROR*Too many points in POLYGONE*/
379 Xw_set_error(32,"Xw_poly_point",&ldesc) ;
380 Xw_close_poly(pwindow) ;
386 xi = PXPOINT(x, pwindow->xratio) ;
387 yi = PYPOINT(y, pwindow->attributes.height, pwindow->yratio) ;
392 status = Xw_clip_segment(pwindow,Lx,Ly,xi,yi,&segment);
394 if( (Npoint < 2) || (status & 0xF ) ) {
395 plinedesc->rpoints[ldesc].x = segment.x1 ;
396 plinedesc->rpoints[ldesc].y = segment.y1 ;
397 ldesc++; plinedesc->npoint++ ;
399 int xx = segment.x1,yy = segment.y1;
400 pbuffer = &_BUFFER(bindex) ;
401 pbuffer->isempty = False ;
402 pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
403 pbuffer->rymin = min(pbuffer->rymin,yy) ;
404 pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
405 pbuffer->rymax = max(pbuffer->rymax,yy) ;
408 plinedesc->rpoints[ldesc].x = segment.x2 ;
409 plinedesc->rpoints[ldesc].y = segment.y2 ;
410 plinedesc->npoint++ ;
412 int xx = segment.x2,yy = segment.y2;
413 pbuffer = &_BUFFER(bindex) ;
414 pbuffer->isempty = False ;
415 pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
416 pbuffer->rymin = min(pbuffer->rymin,yy) ;
417 pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
418 pbuffer->rymax = max(pbuffer->rymax,yy) ;
425 plinedesc->rpoints[ldesc].x = xi ;
426 plinedesc->rpoints[ldesc].y = yi ;
427 plinedesc->npoint++ ;
429 pbuffer = &_BUFFER(bindex) ;
430 pbuffer->isempty = False ;
431 pbuffer->rxmin = min(pbuffer->rxmin,xi) ;
432 pbuffer->rymin = min(pbuffer->rymin,yi) ;
433 pbuffer->rxmax = max(pbuffer->rxmax,xi) ;
434 pbuffer->rymax = max(pbuffer->rymax,yi) ;
439 #ifdef TRACE_DRAW_POLY
440 if( Xw_get_trace() > 3 ) {
441 printf(" Xw_poly_point(%lx,%f,%f)\n",(long ) pwindow,x,y) ;
444 return (XW_SUCCESS) ;
448 STATUS Xw_close_path (awindow):
449 XW_EXT_WINDOW *awindow
451 Close the Polygone path
453 returns ERROR if TOO many path
454 returns SUCCESS if successful
459 XW_STATUS Xw_close_path(void* awindow)
461 XW_STATUS Xw_close_path(awindow)
463 #endif /*XW_PROTOTYPE*/
465 #ifdef TRACE_DRAW_POLY
466 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
469 if( FirstPolyPoint >= 0 ) {
470 int npoly = ppolylist->npoly ;
471 int ldesc = plinedesc->npoint ;
473 if( plinedesc->rpoints[FirstPathPoint].x != plinedesc->rpoints[ldesc-1].x ||
474 plinedesc->rpoints[FirstPathPoint].y != plinedesc->rpoints[ldesc-1].y ) {
475 plinedesc->rpoints[ldesc].x = plinedesc->rpoints[FirstPathPoint].x ;
476 plinedesc->rpoints[ldesc].y = plinedesc->rpoints[FirstPathPoint].y ;
477 plinedesc->npoint++ ; ldesc++ ;
479 ppolylist->polys[FirstPolyLine] = ldesc - FirstPolyPoint ;
480 ppolylist->paths[npoly] = ldesc - FirstPathPoint ;
481 FirstPathPoint = ldesc;
482 if( ppolylist->npoly < MAXPOLYS ) {
483 ppolylist->npoly = ++npoly ;
484 ppolylist->polys[npoly] = 0 ;
485 ppolylist->paths[npoly] = Npoint = 0 ;
486 ppolylist->ppolys[npoly] = &plinedesc->rpoints[ldesc] ;
488 /*ERROR*Too many paths in POLYGONE*/
489 Xw_set_error(32,"Xw_close_path",&ppolylist->npoly) ;
494 #ifdef TRACE_DRAW_POLY
495 if( Xw_get_trace() > 2 ) {
496 printf(" Xw_close_path(%lx)\n",(long ) pwindow) ;
499 return (XW_SUCCESS) ;
503 STATUS Xw_close_poly (awindow):
504 XW_EXT_WINDOW *awindow
508 returns ERROR if Polygone is empty
509 returns SUCCESS if successful
514 XW_STATUS Xw_close_poly(void* awindow)
516 XW_STATUS Xw_close_poly(awindow)
518 #endif /*XW_PROTOTYPE*/
520 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
522 if( FirstPolyPoint >= 0 ) {
524 if( plinedesc->npoint > FirstPathPoint ) Xw_close_path(pwindow);
527 int polyindex = pwindow->polyindex ;
528 int lineindex = pwindow->lineindex ;
529 GC gcpoly = (QGTILE(pwindow->qgpoly[polyindex].code)) ?
530 pwindow->qgpoly[polyindex].gc : NULL ;
531 GC gcline = (QGTYPE(pwindow->qgpoly[polyindex].code)) ?
532 pwindow->qgline[lineindex].gc : NULL ;
533 Xw_draw_pixel_polys(pwindow,ppolylist,gcpoly,gcline);
534 ppolylist->npoly = 0 ;
535 plinedesc->npoint = 0 ;
537 FirstPolyPoint = -1 ;
540 #ifdef TRACE_DRAW_POLY
541 if( Xw_get_trace() > 2 ) {
542 printf(" Xw_close_poly(%lx)\n",(long ) pwindow) ;
545 return (XW_SUCCESS) ;
549 XW_EXT_POLY* Xw_add_polygone_structure(XW_EXT_BUFFER* pbuflist )
551 XW_EXT_POLY* Xw_add_polygone_structure(pbuflist )
552 XW_EXT_BUFFER *pbuflist ;
553 #endif /*XW_PROTOTYPE*/
555 Create and Insert at end one Extended polygone structure in the
558 returns Extended polygone address if successful
559 or NULL if Bad Allocation
564 ppoly = (XW_EXT_POLY*) Xw_malloc(sizeof(XW_EXT_POLY)) ;
566 ppoly->link = pbuflist->ppolylist ;
567 ppoly->isupdated = False ;
569 pbuflist->ppolylist = ppoly ;
571 /*ERROR*EXT_POLYGONE allocation failed*/
572 Xw_set_error(34,"Xw_add_polygone_structure",NULL) ;
579 XW_STATUS Xw_del_polygone_structure(XW_EXT_BUFFER* pbuflist)
581 XW_STATUS Xw_del_polygone_structure(pbuflist)
582 XW_EXT_BUFFER *pbuflist ;
583 #endif /*XW_PROTOTYPE*/
585 Remove ALL Extended polygone structure in the
591 XW_EXT_POLY *ppoly,*qpoly ;
593 for( ppoly = pbuflist->ppolylist ; ppoly ; ppoly = qpoly ) {
594 qpoly = (XW_EXT_POLY*)ppoly->link ;
597 pbuflist->ppolylist = NULL ;
599 return (XW_SUCCESS) ;