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.
19 #define S3593 /*GG_130398
21 Activer le clipping de maniere optionnelle
24 #include <Xw_Extension.h>
26 /* ifdef then trace on */
28 #define TRACE_DRAW_SEGMENT
31 static XW_EXT_SEGMENT *pseglist ;
32 static int BeginSegments = False ;
35 STATUS Xw_draw_segment (awindow,x1,y1,x2,y2):
36 XW_EXT_WINDOW *awindow
37 float x1,y1 First point Coordinates defined in User Space
38 float x2,y2 Second point Coordinates defined in User Space
40 Display segment in current QG set by set_line_attrib .
41 Note that segments can be buffered depending of the DisplayMode context
42 and Flush at Xw_flush time .
44 returns SUCCESS always
49 XW_STATUS Xw_draw_segment (void* awindow,float x1,float y1,float x2,float y2)
51 XW_STATUS Xw_draw_segment (awindow,x1,y1,x2,y2)
54 #endif /*XW_PROTOTYPE*/
56 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow;
57 XW_EXT_BUFFER *pbuffer ;
62 if( !Xw_isdefine_window(pwindow) ) {
63 /*ERROR*Bad EXT_WINDOW Address*/
64 Xw_set_error(24,"Xw_draw_segment",pwindow) ;
69 pbuffer = &_BUFFER(bindex) ;
70 for( pseglist = pbuffer->pseglist ; pseglist ;
71 pseglist = (XW_EXT_SEGMENT*)pseglist->link ) {
72 if( pseglist->nseg < MAXSEGMENTS ) break ;
76 pseglist = Xw_add_segment_structure(pbuffer) ;
80 if( !pseglist ) return XW_ERROR ;
83 ix1 = PXPOINT(x1, pwindow->xratio) ;
84 iy1 = PYPOINT(y1, pwindow->attributes.height, pwindow->yratio) ;
85 ix2 = PXPOINT(x2, pwindow->xratio) ;
86 iy2 = PYPOINT(y2, pwindow->attributes.height, pwindow->yratio) ;
89 nseg = pseglist->nseg ;
92 if( pwindow->clipflag ) {
94 status = Xw_clip_segment(pwindow,ix1,iy1,ix2,iy2,
95 &pseglist->rsegments[nseg]);
96 if( status < 0 ) return (XW_SUCCESS);
99 pseglist->rsegments[nseg].x1 = ix1 ;
100 pseglist->rsegments[nseg].y1 = iy1 ;
101 pseglist->rsegments[nseg].x2 = ix2 ;
102 pseglist->rsegments[nseg].y2 = iy2 ;
108 pbuffer->isempty = False ;
110 pbuffer->rxmin = min(pbuffer->rxmin,ix1) ;
111 pbuffer->rxmax = max(pbuffer->rxmax,ix2) ;
113 pbuffer->rxmin = min(pbuffer->rxmin,ix2) ;
114 pbuffer->rxmax = max(pbuffer->rxmax,ix1) ;
117 pbuffer->rymin = min(pbuffer->rymin,iy1) ;
118 pbuffer->rymax = max(pbuffer->rymax,iy2) ;
120 pbuffer->rymin = min(pbuffer->rymin,iy2) ;
121 pbuffer->rymax = max(pbuffer->rymax,iy1) ;
123 } else if( !BeginSegments ) {
124 int index = pwindow->lineindex ;
125 Xw_draw_pixel_segments(pwindow,pseglist,pwindow->qgline[index].gc) ;
129 #ifdef TRACE_DRAW_SEGMENT
130 if( Xw_get_trace() > 2 ) {
131 printf(" Xw_draw_segment(%lx,%f,%f,%f,%f\n",(long ) pwindow,x1,y1,x2,y2) ;
139 void Xw_draw_pixel_segments(XW_EXT_WINDOW* pwindow,XW_EXT_SEGMENT *pseglist,GC gc)
141 void Xw_draw_pixel_segments(pwindow,pseglist,gc)
142 XW_EXT_WINDOW *pwindow;
143 XW_EXT_SEGMENT *pseglist;
145 #endif /*XW_PROTOTYPE*/
148 if( pseglist->isupdated ) {
149 XDrawSegments(_DISPLAY,_DRAWABLE,gc,
150 pseglist->usegments,pseglist->nseg) ;
152 XDrawSegments(_DISPLAY,_DRAWABLE,gc,
153 pseglist->rsegments,pseglist->nseg) ;
156 #ifdef TRACE_DRAW_SEGMENT
157 if( Xw_get_trace() > 2 ) {
158 printf(" %d = Xw_draw_pixel_segments(%lx,%lx,%lx\n",pseglist->nseg,(long ) pwindow,(long ) pseglist,(long ) gc) ;
164 STATUS Xw_begin_segments (awindow,nsegment):
165 XW_EXT_WINDOW *awindow
166 int nsegment Not used
169 Begin a set of segments which must be filled by Xw_draw_segment and
170 closed by Xw_close_segments
172 returns ERROR if bad extended window address
173 returns SUCCESS if successful
178 XW_STATUS Xw_begin_segments(void* awindow,int nsegment)
180 XW_STATUS Xw_begin_segments(awindow,nsegment)
183 #endif /*XW_PROTOTYPE*/
185 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
187 if( !Xw_isdefine_window(pwindow) ) {
188 /*ERROR*Bad EXT_WINDOW Address*/
189 Xw_set_error(24,"Xw_begin_segments",pwindow) ;
193 if( BeginSegments ) Xw_close_segments(pwindow);
195 BeginSegments = True;
197 #ifdef TRACE_DRAW_LINE
198 if( Xw_get_trace() > 2 ) {
199 printf(" Xw_begin_segments(%x,%d)\n",pwindow,nsegment) ;
202 return (XW_SUCCESS) ;
206 STATUS Xw_close_segments (awindow):
207 XW_EXT_WINDOW *awindow
209 Close the set of segments
211 returns ERROR if bad extended window address
212 returns SUCCESS successful
217 XW_STATUS Xw_close_segments(void* awindow)
219 XW_STATUS Xw_close_segments(awindow)
221 #endif /*XW_PROTOTYPE*/
223 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
224 XW_EXT_BUFFER *pbuffer ;
228 pbuffer = &_BUFFER(bindex) ;
229 if( BeginSegments && !bindex ) {
230 int index = pwindow->lineindex ;
231 for( pseglist = pbuffer->pseglist ; pseglist ;
232 pseglist = (XW_EXT_SEGMENT*)pseglist->link ) {
233 if( pseglist->nseg ) {
234 Xw_draw_pixel_segments(pwindow,pseglist,
235 pwindow->qgline[index].gc) ;
241 BeginSegments = False;
243 #ifdef TRACE_DRAW_SEGMENT
244 if( Xw_get_trace() > 2 ) {
245 printf(" Xw_close_segments(%lx)\n",(long ) pwindow) ;
248 return (XW_SUCCESS) ;
252 XW_EXT_SEGMENT* Xw_add_segment_structure(XW_EXT_BUFFER* pbuflist )
254 XW_EXT_SEGMENT* Xw_add_segment_structure(pbuflist )
255 XW_EXT_BUFFER *pbuflist ;
256 #endif /*XW_PROTOTYPE*/
258 Create and Insert at end one Extended segment structure in the
261 returns Extended segment address if successful
262 or NULL if Bad Allocation
265 XW_EXT_SEGMENT *pseg ;
267 pseg = (XW_EXT_SEGMENT*) Xw_malloc(sizeof(XW_EXT_SEGMENT)) ;
269 pseg->link = pbuflist->pseglist ;
270 pseg->isupdated = False ;
272 pbuflist->pseglist = pseg ;
274 /*ERROR*EXT_SEGMENT Allocation failed*/
275 Xw_set_error(35,"Xw_add_segment_structure",NULL) ;
282 XW_STATUS Xw_del_segment_structure(XW_EXT_BUFFER* pbuflist)
284 XW_STATUS Xw_del_segment_structure(pbuflist)
285 XW_EXT_BUFFER *pbuflist ;
286 #endif /*XW_PROTOTYPE*/
288 Remove ALL Extended segment structure in the
294 XW_EXT_SEGMENT *pseg,*qseg ;
296 for( pseg = pbuflist->pseglist ; pseg ; pseg = qseg ) {
297 qseg = (XW_EXT_SEGMENT*)pseg->link ;
300 pbuflist->pseglist = NULL ;
302 return (XW_SUCCESS) ;
305 #define MINXCOORD -32768
306 #define MAXXCOORD 32767
307 #define MINYCOORD -32768
308 #define MAXYCOORD 32767
311 int Xw_clip_segment (XW_EXT_WINDOW* pwindow,int x1,int y1,int x2,int y2,XSegment* pseg)
313 int Xw_clip_segment (pwindow,x1,y1,x2,y2,pseg)
314 XW_EXT_WINDOW *pwindow;
317 #endif /*XW_PROTOTYPE*/
319 Clip a segment when one coord is < MINCOORD or > MAXCOORD.
320 Returns the clipped segment and a clip bit-mask status :
323 1 X first point is clipped on MAX
324 2 X first point is clipped on MIN
325 4 Y first point is clipped on MAX
326 8 Y first point is clipped on MIN
327 16 X second point is clipped on MAX
328 32 X second point is clipped on MIN
329 64 Y second point is clipped on MAX
330 128 Y second point is clipped on MIN
331 -1 segment is out of space.
334 int xx1 = x1,yy1 = y1,xx2 = x2,yy2 = y2;
337 if( xx1 > MAXXCOORD ) {
338 if( xx2 < MAXXCOORD ) {
339 float rap = (float)(yy2 - yy1)/(xx2 - xx1);
340 yy1 += (int)((MAXXCOORD - xx1) * rap);
344 } else if( xx1 < MINXCOORD ) {
345 if( xx2 > MINXCOORD ) {
346 float rap = (float)(yy2 - yy1)/(xx2 - xx1);
347 yy1 += (int)((MINXCOORD - xx1) * rap);
353 if( yy1 > MAXYCOORD ) {
354 if( yy2 < MAXYCOORD ) {
355 float rap = (float)(xx2 - xx1)/(yy2 - yy1);
356 xx1 += (int)((MAXYCOORD - yy1) * rap);
360 } else if( yy1 < MINYCOORD ) {
361 if( yy2 > MINYCOORD ) {
362 float rap = (float)(xx2 - xx1)/(yy2 - yy1);
363 xx1 += (int)((MINYCOORD - yy1) * rap);
369 if( xx2 > MAXXCOORD ) {
370 float rap = (float)(yy2 - yy1)/(xx2 - xx1);
371 yy2 = yy1 + (int)((MAXXCOORD - xx1) * rap);
374 } else if( xx2 < MINXCOORD ) {
375 float rap = (float)(yy2 - yy1)/(xx2 - xx1);
376 yy2 = yy1 + (int)((MINXCOORD - xx1) * rap);
381 if( yy2 > MAXYCOORD ) {
382 float rap = (float)(xx2 - xx1)/(yy2 - yy1);
383 xx2 = xx1 + (int)((MAXYCOORD - yy1) * rap);
386 } else if( yy2 < MINYCOORD ) {
387 float rap = (float)(xx2 - xx1)/(yy2 - yy1);
388 xx2 = xx1 + (int)((MINYCOORD - yy1) * rap);