0023426: Tool to compare two runs of tests on the same station
[occt.git] / src / Xw / Xw_draw_segment.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
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.
7 //
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.
10 //
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.
17
18
19 #define S3593           /*GG_130398
20 OPTIMISATION MFT
21                         Activer le clipping de maniere optionnelle
22 */
23
24 #include <Xw_Extension.h>
25
26         /* ifdef then trace on */
27 #ifdef TRACE
28 #define TRACE_DRAW_SEGMENT
29 #endif
30
31 static XW_EXT_SEGMENT *pseglist ;
32 static int BeginSegments = False ;
33
34 /*
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
39
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 .
43
44         returns SUCCESS always
45
46 */
47
48 #ifdef XW_PROTOTYPE
49 XW_STATUS Xw_draw_segment (void* awindow,float x1,float y1,float x2,float y2)
50 #else
51 XW_STATUS Xw_draw_segment (awindow,x1,y1,x2,y2)
52 void *awindow;
53 float x1,y1,x2,y2 ;
54 #endif /*XW_PROTOTYPE*/
55 {
56 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow;
57 XW_EXT_BUFFER *pbuffer ;
58 int status ;
59 int nseg,bindex;
60 int ix1,iy1,ix2,iy2 ;
61
62         if( !Xw_isdefine_window(pwindow) ) {
63            /*ERROR*Bad EXT_WINDOW Address*/
64            Xw_set_error(24,"Xw_draw_segment",pwindow) ;
65            return (XW_ERROR) ;
66         }
67
68         bindex = _BINDEX ;
69         pbuffer = &_BUFFER(bindex) ;
70         for( pseglist = pbuffer->pseglist ; pseglist ;
71                         pseglist = (XW_EXT_SEGMENT*)pseglist->link ) {
72             if( pseglist->nseg < MAXSEGMENTS ) break ;
73         }
74              
75         if( !pseglist ) {
76             pseglist = Xw_add_segment_structure(pbuffer) ;
77         }
78
79
80         if( !pseglist ) return XW_ERROR ;
81
82 //OCC186
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) ;
87 //OCC186
88
89         nseg = pseglist->nseg ;
90
91 #ifdef S3593
92         if( pwindow->clipflag ) {
93 #endif
94           status = Xw_clip_segment(pwindow,ix1,iy1,ix2,iy2,
95                                         &pseglist->rsegments[nseg]);
96           if( status < 0 ) return (XW_SUCCESS);
97 #ifdef S3593
98         } else {
99           pseglist->rsegments[nseg].x1 = ix1 ;
100           pseglist->rsegments[nseg].y1 = iy1 ;
101           pseglist->rsegments[nseg].x2 = ix2 ;
102           pseglist->rsegments[nseg].y2 = iy2 ;
103         }
104 #endif
105         pseglist->nseg++ ;
106
107         if( bindex > 0 ) {
108             pbuffer->isempty = False ;
109             if( ix1 < ix2 ) {
110               pbuffer->rxmin = min(pbuffer->rxmin,ix1) ;
111               pbuffer->rxmax = max(pbuffer->rxmax,ix2) ;
112             } else {
113               pbuffer->rxmin = min(pbuffer->rxmin,ix2) ;
114               pbuffer->rxmax = max(pbuffer->rxmax,ix1) ;
115             }
116             if( iy1 < iy2 ) {
117               pbuffer->rymin = min(pbuffer->rymin,iy1) ;
118               pbuffer->rymax = max(pbuffer->rymax,iy2) ;
119             } else {
120               pbuffer->rymin = min(pbuffer->rymin,iy2) ;
121               pbuffer->rymax = max(pbuffer->rymax,iy1) ;
122             }
123         } else if( !BeginSegments ) {
124             int index = pwindow->lineindex ;
125             Xw_draw_pixel_segments(pwindow,pseglist,pwindow->qgline[index].gc) ;
126             pseglist->nseg = 0 ;
127         }
128
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) ;
132 }
133 #endif
134
135         return (XW_SUCCESS);
136 }
137
138 #ifdef XW_PROTOTYPE
139 void Xw_draw_pixel_segments(XW_EXT_WINDOW* pwindow,XW_EXT_SEGMENT *pseglist,GC gc)
140 #else
141 void Xw_draw_pixel_segments(pwindow,pseglist,gc)
142 XW_EXT_WINDOW *pwindow;
143 XW_EXT_SEGMENT *pseglist;
144 GC gc ;
145 #endif /*XW_PROTOTYPE*/
146 {
147
148         if( pseglist->isupdated ) {
149           XDrawSegments(_DISPLAY,_DRAWABLE,gc,
150                         pseglist->usegments,pseglist->nseg) ;
151         } else {
152           XDrawSegments(_DISPLAY,_DRAWABLE,gc,
153                         pseglist->rsegments,pseglist->nseg) ;
154         }
155
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) ;
159 }
160 #endif
161 }
162
163 /*
164    STATUS Xw_begin_segments (awindow,nsegment):
165    XW_EXT_WINDOW *awindow
166    int nsegment           Not used
167
168
169         Begin a set of segments which must be filled by Xw_draw_segment and
170                                      closed by Xw_close_segments 
171
172         returns ERROR if bad extended window address 
173         returns SUCCESS if successful
174
175 */
176  
177 #ifdef XW_PROTOTYPE
178 XW_STATUS Xw_begin_segments(void* awindow,int nsegment)
179 #else
180 XW_STATUS Xw_begin_segments(awindow,nsegment)
181 void *awindow ;
182 int nsegment ;
183 #endif /*XW_PROTOTYPE*/
184 {
185 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
186  
187         if( !Xw_isdefine_window(pwindow) ) {
188             /*ERROR*Bad EXT_WINDOW Address*/
189             Xw_set_error(24,"Xw_begin_segments",pwindow) ;
190             return (XW_ERROR) ;
191         }    
192
193         if( BeginSegments ) Xw_close_segments(pwindow);
194         
195         BeginSegments = True;
196  
197 #ifdef  TRACE_DRAW_LINE
198 if( Xw_get_trace() > 2 ) {
199     printf(" Xw_begin_segments(%x,%d)\n",pwindow,nsegment) ;
200 }
201 #endif
202         return (XW_SUCCESS) ;
203 }
204
205 /*
206    STATUS Xw_close_segments (awindow):
207    XW_EXT_WINDOW *awindow
208
209         Close the set of segments 
210
211         returns ERROR if bad extended window address 
212         returns SUCCESS successful
213
214 */
215  
216 #ifdef XW_PROTOTYPE
217 XW_STATUS Xw_close_segments(void* awindow)
218 #else
219 XW_STATUS Xw_close_segments(awindow)
220 void *awindow ;
221 #endif /*XW_PROTOTYPE*/
222 {
223 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
224 XW_EXT_BUFFER *pbuffer ;
225 int bindex ;
226  
227         bindex = _BINDEX ; 
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) ;
236               pseglist->nseg = 0 ;
237             } else break ;
238           }
239         }
240  
241         BeginSegments = False; 
242
243 #ifdef  TRACE_DRAW_SEGMENT
244 if( Xw_get_trace() > 2 ) {
245     printf(" Xw_close_segments(%lx)\n",(long ) pwindow) ;
246 }
247 #endif
248         return (XW_SUCCESS) ;
249 }
250  
251 #ifdef XW_PROTOTYPE
252 XW_EXT_SEGMENT* Xw_add_segment_structure(XW_EXT_BUFFER* pbuflist )
253 #else
254 XW_EXT_SEGMENT* Xw_add_segment_structure(pbuflist )
255 XW_EXT_BUFFER *pbuflist ;
256 #endif /*XW_PROTOTYPE*/
257 /*
258         Create and Insert at end one Extended segment structure in the
259         segment List
260
261         returns Extended segment address if successful
262                 or NULL if Bad Allocation
263 */
264 {
265 XW_EXT_SEGMENT *pseg ;
266
267         pseg = (XW_EXT_SEGMENT*) Xw_malloc(sizeof(XW_EXT_SEGMENT)) ;
268         if( pseg ) {
269             pseg->link = pbuflist->pseglist ;
270             pseg->isupdated = False ;
271             pseg->nseg = 0 ;
272             pbuflist->pseglist = pseg ;
273         } else {
274             /*ERROR*EXT_SEGMENT Allocation failed*/
275             Xw_set_error(35,"Xw_add_segment_structure",NULL) ;
276         }
277
278         return (pseg) ;
279 }
280
281 #ifdef XW_PROTOTYPE
282 XW_STATUS Xw_del_segment_structure(XW_EXT_BUFFER* pbuflist)
283 #else
284 XW_STATUS Xw_del_segment_structure(pbuflist)
285 XW_EXT_BUFFER *pbuflist ;
286 #endif /*XW_PROTOTYPE*/
287 /*
288         Remove ALL Extended segment structure in the
289         segment List
290
291         SUCCESS always
292 */
293 {
294 XW_EXT_SEGMENT *pseg,*qseg ;
295
296         for( pseg = pbuflist->pseglist ; pseg ; pseg = qseg ) {
297             qseg = (XW_EXT_SEGMENT*)pseg->link ;
298             Xw_free(pseg) ;
299         }
300         pbuflist->pseglist = NULL ;
301         
302         return (XW_SUCCESS) ;
303 }
304
305 #define MINXCOORD -32768
306 #define MAXXCOORD 32767 
307 #define MINYCOORD -32768
308 #define MAXYCOORD 32767 
309
310 #ifdef XW_PROTOTYPE
311 int Xw_clip_segment (XW_EXT_WINDOW* pwindow,int x1,int y1,int x2,int y2,XSegment* pseg)
312 #else
313 int Xw_clip_segment (pwindow,x1,y1,x2,y2,pseg)
314 XW_EXT_WINDOW *pwindow;
315 int x1,y1,x2,y2;
316 XSegment *pseg; 
317 #endif /*XW_PROTOTYPE*/
318 /*
319         Clip a segment when one coord is < MINCOORD or > MAXCOORD.
320         Returns the clipped segment and a clip bit-mask status :
321
322           0   Nothing is clipped
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.
332 */
333 {
334 int xx1 = x1,yy1 = y1,xx2 = x2,yy2 = y2;
335 int status = 0;
336
337         if( xx1 > MAXXCOORD ) {
338           if( xx2 < MAXXCOORD ) {
339             float rap = (float)(yy2 - yy1)/(xx2 - xx1);
340             yy1 += (int)((MAXXCOORD - xx1) * rap); 
341             xx1 = MAXXCOORD;
342             status |= 1;
343           } else return -1;
344         } else if( xx1 < MINXCOORD ) { 
345           if( xx2 > MINXCOORD ) {
346             float rap = (float)(yy2 - yy1)/(xx2 - xx1);
347             yy1 += (int)((MINXCOORD - xx1) * rap); 
348             xx1 = MINXCOORD;
349             status |= 2;
350           } else return -1;
351         } 
352
353         if( yy1 > MAXYCOORD ) {
354           if( yy2 < MAXYCOORD ) {
355             float rap = (float)(xx2 - xx1)/(yy2 - yy1);
356             xx1 += (int)((MAXYCOORD - yy1) * rap); 
357             yy1 = MAXYCOORD;
358             status |= 4;
359           } else return -1;
360         } else if( yy1 < MINYCOORD ) { 
361           if( yy2 > MINYCOORD ) {
362             float rap = (float)(xx2 - xx1)/(yy2 - yy1);
363             xx1 += (int)((MINYCOORD - yy1) * rap); 
364             yy1 = MINYCOORD;
365             status |= 8;
366           } else return -1;
367         }
368
369         if( xx2 > MAXXCOORD ) {
370           float rap = (float)(yy2 - yy1)/(xx2 - xx1);
371           yy2 = yy1 + (int)((MAXXCOORD - xx1) * rap); 
372           xx2 = MAXXCOORD;
373           status |= 16;
374         } else if( xx2 < MINXCOORD ) { 
375           float rap = (float)(yy2 - yy1)/(xx2 - xx1);
376           yy2 = yy1 + (int)((MINXCOORD - xx1) * rap); 
377           xx2 = MINXCOORD;
378           status |= 32;
379         } 
380
381         if( yy2 > MAXYCOORD ) {
382           float rap = (float)(xx2 - xx1)/(yy2 - yy1);
383           xx2 = xx1 + (int)((MAXYCOORD - yy1) * rap); 
384           yy2 = MAXYCOORD;
385           status |= 64;
386         } else if( yy2 < MINYCOORD ) { 
387           float rap = (float)(xx2 - xx1)/(yy2 - yy1);
388           xx2 = xx1 + (int)((MINYCOORD - yy1) * rap); 
389           yy2 = MINYCOORD;
390           status |= 128;
391         }
392
393         pseg->x1 = xx1;
394         pseg->y1 = yy1;
395         pseg->x2 = xx2;
396         pseg->y2 = yy2;
397
398         return status;
399 }