b311480e |
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 | |
7fd59977 |
18 | #define S3593 /*GG_130398 |
b311480e |
19 | OPTIMISATION MFT |
7fd59977 |
20 | Activer le clipping de maniere optionnelle |
21 | */ |
22 | |
23 | #include <Xw_Extension.h> |
24 | |
25 | /* ifdef then trace on */ |
26 | #ifdef TRACE |
27 | #define TRACE_DRAW_LINE |
28 | #endif |
29 | |
30 | /* |
31 | STATUS Xw_draw_line (awindow,npoint,x,y): |
32 | XW_EXT_WINDOW *awindow |
33 | int npoint Polyline point number |
34 | float *x,*y Points Arrays |
35 | |
36 | |
37 | Display continuous line in current QG set by set_line_attrib . |
38 | Note that lines can be buffered depending of the DisplayMode context |
39 | and Flush at Xw_flush time . |
40 | |
41 | returns ERROR if npoint > MAXPOINTS |
42 | returns SUCCESS always |
43 | |
44 | */ |
45 | |
46 | static int BeginLine = -1 ; |
47 | static XW_EXT_LINE *plinelist ; |
48 | static XW_EXT_POINT *plinedesc ; |
49 | static XSegment segment; |
50 | |
51 | #ifdef XW_PROTOTYPE |
52 | XW_STATUS Xw_draw_line (void* awindow,int npoint,float* px,float* py) |
53 | #else |
54 | XW_STATUS Xw_draw_line (awindow,npoint,px,py) |
55 | void *awindow; |
56 | int npoint ; |
57 | float *px,*py ; |
58 | #endif /*XW_PROTOTYPE*/ |
59 | { |
60 | XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*) awindow ; |
61 | XW_EXT_BUFFER *pbuffer ; |
62 | int i,nline,ldesc,bindex; |
63 | int x,y,lx=0,ly=0 ; |
64 | |
65 | if( !Xw_isdefine_window(pwindow) ) { |
66 | /*ERROR*Bad EXT_WINDOW Address*/ |
67 | Xw_set_error(24,"Xw_draw_line",pwindow) ; |
68 | return (XW_ERROR) ; |
69 | } |
70 | |
71 | if( npoint > MAXPOINTS ) { |
72 | npoint = MAXPOINTS; |
73 | /*ERROR*Too many points in LINE*/ |
74 | Xw_set_error(28,"Xw_draw_line",&npoint) ; |
75 | return (XW_ERROR) ; |
76 | } |
77 | |
78 | bindex = _BINDEX ; |
79 | pbuffer = &_BUFFER(bindex) ; |
80 | for( plinelist = pbuffer->plinelist ; plinelist ; |
81 | plinelist = (XW_EXT_LINE*)plinelist->link ) { |
82 | if( plinelist->nline < MAXLINES ) break ; |
83 | } |
84 | |
85 | if( !plinelist ) { |
86 | plinelist = Xw_add_polyline_structure(pbuffer) ; |
87 | } |
88 | |
89 | if( !plinelist ) return XW_ERROR ; |
90 | |
91 | for( plinedesc = pbuffer->plinedesc ; plinedesc ; |
92 | plinedesc = (XW_EXT_POINT*)plinedesc->link ) { |
93 | if( plinedesc->npoint + npoint <= MAXPOINTS ) break ; |
94 | } |
95 | |
96 | if( !plinedesc ) { |
97 | plinedesc = Xw_add_line_desc_structure(pbuffer) ; |
98 | } |
99 | |
100 | if( !plinedesc ) return XW_ERROR ; |
101 | |
102 | nline = plinelist->nline ; |
103 | ldesc = plinedesc->npoint ; |
104 | plinelist->plines[nline] = &plinedesc->rpoints[ldesc] ; |
105 | for( i=0 ; i<npoint ; i++ ) { |
106 | //OCC186 |
107 | x = PXPOINT(px[i], pwindow->xratio) ; |
108 | y = PYPOINT(py[i], pwindow->attributes.height, pwindow->yratio) ; |
109 | //OCC186 |
110 | #ifdef S3593 |
111 | if( pwindow->clipflag ) { |
112 | #endif |
113 | if( i > 0 ) { |
114 | int status; |
115 | status = Xw_clip_segment(pwindow,lx,ly,x,y,&segment); |
116 | if( status >= 0 ) { |
117 | if( (i < 2) || (status & 0xF ) ) { |
118 | plinedesc->rpoints[ldesc].x = segment.x1 ; |
119 | plinedesc->rpoints[ldesc].y = segment.y1 ; |
120 | ldesc++; |
121 | if( bindex > 0 ) { |
122 | int xx = segment.x1,yy = segment.y1; |
123 | pbuffer->rxmin = min(pbuffer->rxmin,xx) ; |
124 | pbuffer->rymin = min(pbuffer->rymin,yy) ; |
125 | pbuffer->rxmax = max(pbuffer->rxmax,xx) ; |
126 | pbuffer->rymax = max(pbuffer->rymax,yy) ; |
127 | } |
128 | } |
129 | plinedesc->rpoints[ldesc].x = segment.x2 ; |
130 | plinedesc->rpoints[ldesc].y = segment.y2 ; |
131 | ldesc++; |
132 | if( bindex > 0 ) { |
133 | int xx = segment.x2,yy = segment.y2; |
134 | pbuffer->rxmin = min(pbuffer->rxmin,xx) ; |
135 | pbuffer->rymin = min(pbuffer->rymin,yy) ; |
136 | pbuffer->rxmax = max(pbuffer->rxmax,xx) ; |
137 | pbuffer->rymax = max(pbuffer->rymax,yy) ; |
138 | } |
139 | } |
140 | } |
141 | lx = x; ly = y; |
142 | #ifdef S3593 |
143 | } else { |
144 | plinedesc->rpoints[ldesc].x = x ; |
145 | plinedesc->rpoints[ldesc].y = y ; |
146 | ldesc++ ; |
147 | if( bindex > 0 ) { |
148 | pbuffer->rxmin = min(pbuffer->rxmin,x) ; |
149 | pbuffer->rymin = min(pbuffer->rymin,y) ; |
150 | pbuffer->rxmax = max(pbuffer->rxmax,x) ; |
151 | pbuffer->rymax = max(pbuffer->rymax,y) ; |
152 | } |
153 | } |
154 | #endif |
155 | } |
156 | plinelist->lines[nline] = ldesc - plinedesc->npoint ; |
157 | if( plinelist->lines[nline] > 1 ) { |
158 | plinedesc->npoint = ldesc ; |
159 | plinelist->nline++ ; |
160 | if( bindex > 0 ) { |
161 | pbuffer->isempty = False ; |
162 | } else if( BeginLine < 0 ) { |
163 | int index = pwindow->lineindex ; |
164 | Xw_draw_pixel_lines(pwindow,plinelist,pwindow->qgline[index].gc); |
165 | plinelist->nline = 0 ; |
166 | plinedesc->npoint = 0 ; |
167 | } |
168 | } |
169 | |
170 | #ifdef TRACE_DRAW_LINE |
171 | if( Xw_get_trace() > 2 ) { |
172 | printf(" Xw_draw_line(%lx,%d)\n",(long ) pwindow,npoint) ; |
173 | for( i=0 ; i<npoint ; i++ ) { |
174 | printf(" Point(%d) = {%f,%f}\n",i,px[i],py[i]) ; |
175 | } |
176 | } |
177 | #endif |
178 | |
179 | return (XW_SUCCESS); |
180 | } |
181 | |
182 | #ifdef XW_PROTOTYPE |
183 | void Xw_draw_pixel_lines (XW_EXT_WINDOW* pwindow,XW_EXT_LINE *plinelist,GC gc) |
184 | #else |
185 | void Xw_draw_pixel_lines (pwindow,plinelist,gc) |
186 | XW_EXT_WINDOW *pwindow; |
187 | XW_EXT_LINE *plinelist; |
188 | GC gc ; |
189 | #endif /*XW_PROTOTYPE*/ |
190 | { |
191 | int i,npoint; |
192 | XPoint *ppoint ; |
193 | |
194 | for( i=0 ; i<plinelist->nline ; i++ ) { |
195 | npoint = plinelist->lines[i] ; |
196 | ppoint = plinelist->plines[i] ; |
197 | if( plinelist->isupdated ) { |
198 | ppoint += MAXPOINTS ; |
199 | } |
200 | if( ppoint && npoint > 1 ) { |
201 | XDrawLines(_DISPLAY,_DRAWABLE,gc,ppoint,npoint,CoordModeOrigin) ; |
202 | } |
203 | } |
204 | } |
205 | |
206 | /* |
207 | STATUS Xw_begin_line (awindow,npoint): |
208 | XW_EXT_WINDOW *awindow |
209 | int npoint Polyline point number |
210 | |
211 | |
212 | Begin Polyline which must be filled by Xw_line_point and |
213 | closed by Xw_close_line |
214 | |
215 | returns ERROR if npoint > MAXPOINTS |
216 | returns SUCCESS if successful |
217 | |
218 | */ |
219 | |
220 | static int Npoint = 0; |
221 | static int Lx,Ly; |
222 | #ifdef XW_PROTOTYPE |
223 | XW_STATUS Xw_begin_line(void* awindow,int npoint) |
224 | #else |
225 | XW_STATUS Xw_begin_line(awindow,npoint) |
226 | void *awindow ; |
227 | int npoint ; |
228 | #endif /*XW_PROTOTYPE*/ |
229 | { |
230 | XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ; |
231 | XW_EXT_BUFFER *pbuffer ; |
232 | int nline,ldesc,bindex ; |
233 | |
234 | if( !Xw_isdefine_window(pwindow) ) { |
235 | /*ERROR*Bad EXT_WINDOW Address*/ |
236 | Xw_set_error(24,"Xw_begin_line",pwindow) ; |
237 | return (XW_ERROR) ; |
238 | } |
239 | |
240 | if( npoint > MAXPOINTS ) { |
241 | npoint = MAXPOINTS ; |
242 | /*ERROR*Too many points in LINE*/ |
243 | Xw_set_error(28,"Xw_begin_line",&npoint) ; |
244 | return (XW_ERROR) ; |
245 | } |
246 | |
247 | if( BeginLine >= 0 ) Xw_close_line(pwindow); |
248 | |
249 | bindex = _BINDEX ; |
250 | pbuffer = &_BUFFER(bindex) ; |
251 | for( plinelist = pbuffer->plinelist ; plinelist ; |
252 | plinelist = (XW_EXT_LINE*)plinelist->link ) { |
253 | if( plinelist->nline < MAXLINES ) break ; |
254 | } |
255 | |
256 | if( !plinelist ) { |
257 | plinelist = Xw_add_polyline_structure(pbuffer) ; |
258 | } |
259 | |
260 | if( !plinelist ) return XW_ERROR ; |
261 | |
262 | for( plinedesc = pbuffer->plinedesc ; plinedesc ; |
263 | plinedesc = (XW_EXT_POINT*)plinedesc->link ) { |
264 | if( plinedesc->npoint + npoint <= MAXPOINTS ) break ; |
265 | } |
266 | |
267 | if( !plinedesc ) { |
268 | plinedesc = Xw_add_line_desc_structure(pbuffer) ; |
269 | } |
270 | |
271 | if( !plinedesc ) return XW_ERROR ; |
272 | |
273 | nline = plinelist->nline ; |
274 | ldesc = plinedesc->npoint ; |
275 | plinelist->lines[nline] = Npoint = 0 ; |
276 | plinelist->plines[nline] = &plinedesc->rpoints[ldesc] ; |
277 | BeginLine = ldesc ; |
278 | |
279 | #ifdef TRACE_DRAW_LINE |
280 | if( Xw_get_trace() > 2 ) { |
281 | printf(" Xw_begin_line(%lx,%d)\n",(long ) pwindow,npoint) ; |
282 | } |
283 | #endif |
284 | return (XW_SUCCESS) ; |
285 | } |
286 | |
287 | /* |
288 | STATUS Xw_line_point (awindow,x,y): |
289 | XW_EXT_WINDOW *awindow |
290 | float x,y New point to add in polyline in user-space coordinates |
291 | |
292 | Fill Polyline with one point more |
293 | |
294 | returns ERROR if Too Many Points in polylines |
295 | returns SUCCESS if successful |
296 | |
297 | */ |
298 | |
299 | #ifdef XW_PROTOTYPE |
300 | XW_STATUS Xw_line_point(void* awindow,float x,float y) |
301 | #else |
302 | XW_STATUS Xw_line_point(awindow,x,y) |
303 | void *awindow ; |
304 | float x,y ; |
305 | #endif /*XW_PROTOTYPE*/ |
306 | { |
307 | XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ; |
308 | XW_EXT_BUFFER *pbuffer ; |
309 | int bindex,xi,yi ; |
310 | |
311 | if( BeginLine >= 0 ) { |
312 | int ldesc = plinedesc->npoint ; |
313 | if( ldesc >= MAXPOINTS ) { |
314 | /*ERROR*Too many points in LINE*/ |
315 | Xw_set_error(28,"Xw_line_point",&ldesc) ; |
316 | Xw_close_line(pwindow) ; |
317 | return (XW_ERROR) ; |
318 | } |
319 | |
320 | bindex = _BINDEX ; |
321 | pbuffer = &_BUFFER(bindex) ; |
322 | //OCC186 |
323 | xi = PXPOINT(x, pwindow->xratio) ; |
324 | yi = PYPOINT(y, pwindow->attributes.height, pwindow->yratio) ; |
325 | //OCC186 |
326 | #ifdef S3593 |
327 | if( pwindow->clipflag ) { |
328 | #endif |
329 | if( Npoint > 0 ) { |
330 | int status; |
331 | status = Xw_clip_segment(pwindow,Lx,Ly,xi,yi,&segment); |
332 | if( status >= 0 ) { |
333 | if( (Npoint < 2) || (status & 0xF ) ) { |
334 | plinedesc->rpoints[ldesc].x = segment.x1 ; |
335 | plinedesc->rpoints[ldesc].y = segment.y1 ; |
336 | ldesc++; |
337 | if( bindex > 0 ) { |
338 | int xx = segment.x1,yy = segment.y1; |
339 | pbuffer->isempty = False ; |
340 | pbuffer->rxmin = min(pbuffer->rxmin,xx) ; |
341 | pbuffer->rymin = min(pbuffer->rymin,yy) ; |
342 | pbuffer->rxmax = max(pbuffer->rxmax,xx) ; |
343 | pbuffer->rymax = max(pbuffer->rymax,yy) ; |
344 | } |
345 | } |
346 | plinedesc->rpoints[ldesc].x = segment.x2 ; |
347 | plinedesc->rpoints[ldesc].y = segment.y2 ; |
348 | ldesc++; |
349 | if( bindex > 0 ) { |
350 | int xx = segment.x2,yy = segment.y2; |
351 | pbuffer->isempty = False ; |
352 | pbuffer->rxmin = min(pbuffer->rxmin,xx) ; |
353 | pbuffer->rymin = min(pbuffer->rymin,yy) ; |
354 | pbuffer->rxmax = max(pbuffer->rxmax,xx) ; |
355 | pbuffer->rymax = max(pbuffer->rymax,yy) ; |
356 | } |
357 | } |
358 | } |
359 | Lx = xi; Ly = yi; |
360 | #ifdef S3593 |
361 | } else { |
362 | plinedesc->rpoints[ldesc].x = xi ; |
363 | plinedesc->rpoints[ldesc].y = yi ; |
364 | ldesc++; |
365 | if( bindex > 0 ) { |
366 | pbuffer->isempty = False ; |
367 | pbuffer->rxmin = min(pbuffer->rxmin,xi) ; |
368 | pbuffer->rymin = min(pbuffer->rymin,yi) ; |
369 | pbuffer->rxmax = max(pbuffer->rxmax,xi) ; |
370 | pbuffer->rymax = max(pbuffer->rymax,yi) ; |
371 | } |
372 | } |
373 | #endif |
374 | Npoint++; |
375 | plinedesc->npoint = ldesc ; |
376 | } |
377 | |
378 | #ifdef TRACE_DRAW_LINE |
379 | if( Xw_get_trace() > 3 ) { |
380 | printf(" Xw_line_point(%lx,%f,%f)\n",(long ) pwindow,x,y) ; |
381 | } |
382 | #endif |
383 | return (XW_SUCCESS) ; |
384 | } |
385 | |
386 | /* |
387 | STATUS Xw_close_line (awindow): |
388 | XW_EXT_WINDOW *awindow |
389 | |
390 | Close the Polyline |
391 | |
392 | returns ERROR if Polyline is empty |
393 | returns SUCCESS if successful |
394 | |
395 | */ |
396 | |
397 | #ifdef XW_PROTOTYPE |
398 | XW_STATUS Xw_close_line(void* awindow) |
399 | #else |
400 | XW_STATUS Xw_close_line(awindow) |
401 | void *awindow ; |
402 | #endif /*XW_PROTOTYPE*/ |
403 | { |
404 | XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ; |
405 | |
406 | if( BeginLine >= 0 ) { |
407 | int nline = plinelist->nline ; |
408 | int ldesc = plinedesc->npoint ; |
409 | int bindex = _BINDEX ; |
410 | plinelist->lines[nline] = ldesc - BeginLine ; |
411 | plinelist->nline++ ; |
412 | |
413 | if( !bindex ) { |
414 | int index = pwindow->lineindex ; |
415 | Xw_draw_pixel_lines(pwindow,plinelist,pwindow->qgline[index].gc) ; |
416 | plinelist->nline = 0 ; |
417 | plinedesc->npoint = 0 ; |
418 | } |
419 | BeginLine = -1 ; |
420 | } |
421 | |
422 | #ifdef TRACE_DRAW_LINE |
423 | if( Xw_get_trace() > 2 ) { |
424 | printf(" Xw_close_line(%lx)\n",(long ) pwindow) ; |
425 | } |
426 | #endif |
427 | return (XW_SUCCESS) ; |
428 | } |
429 | |
430 | #ifdef XW_PROTOTYPE |
431 | XW_EXT_LINE* Xw_add_polyline_structure(XW_EXT_BUFFER* pbuflist ) |
432 | #else |
433 | XW_EXT_LINE* Xw_add_polyline_structure(pbuflist ) |
434 | XW_EXT_BUFFER *pbuflist ; |
435 | #endif /*XW_PROTOTYPE*/ |
436 | /* |
437 | Create and Insert at end one Extended polyline structure in the |
438 | polyline List |
439 | |
440 | returns Extended polyline address if successful |
441 | or NULL if Bad Allocation |
442 | */ |
443 | { |
444 | XW_EXT_LINE *pline ; |
445 | |
446 | pline = (XW_EXT_LINE*) Xw_malloc(sizeof(XW_EXT_LINE)) ; |
447 | if( pline ) { |
448 | pline->link = pbuflist->plinelist ; |
449 | pline->isupdated = False ; |
450 | pline->nline = 0 ; |
451 | pbuflist->plinelist = pline ; |
452 | } else { |
453 | /*ERROR*EXT_LINE allocation failed*/ |
454 | Xw_set_error(30,"Xw_add_polyline_structure",NULL) ; |
455 | } |
456 | |
457 | return (pline) ; |
458 | } |
459 | |
460 | #ifdef XW_PROTOTYPE |
461 | XW_STATUS Xw_del_polyline_structure(XW_EXT_BUFFER* pbuflist) |
462 | #else |
463 | XW_STATUS Xw_del_polyline_structure(pbuflist) |
464 | XW_EXT_BUFFER *pbuflist ; |
465 | #endif /*XW_PROTOTYPE*/ |
466 | /* |
467 | Remove ALL Extended polyline structure in the |
468 | polyline List |
469 | |
470 | SUCCESS always |
471 | */ |
472 | { |
473 | XW_EXT_LINE *pline,*qline ; |
474 | |
475 | for( pline = pbuflist->plinelist ; pline ; pline = qline ) { |
476 | qline = (XW_EXT_LINE*)pline->link ; |
477 | Xw_free(pline) ; |
478 | } |
479 | pbuflist->plinelist = NULL ; |
480 | |
481 | return (XW_SUCCESS) ; |
482 | } |
483 | |
484 | #ifdef XW_PROTOTYPE |
485 | XW_EXT_POINT* Xw_add_line_desc_structure(XW_EXT_BUFFER* pbuflist ) |
486 | #else |
487 | XW_EXT_POINT* Xw_add_line_desc_structure(pbuflist ) |
488 | XW_EXT_BUFFER *pbuflist ; |
489 | #endif /*XW_PROTOTYPE*/ |
490 | /* |
491 | Create and Insert at end one Extended line_desc structure in the |
492 | line_desc List |
493 | |
494 | returns Extended line_desc address if successful |
495 | or NULL if Bad Allocation |
496 | */ |
497 | { |
498 | XW_EXT_POINT *pdesc ; |
499 | |
500 | pdesc = (XW_EXT_POINT*) Xw_malloc(sizeof(XW_EXT_POINT)) ; |
501 | if( pdesc ) { |
502 | pdesc->link = pbuflist->plinedesc ; |
503 | pdesc->npoint = 0 ; |
504 | pbuflist->plinedesc = pdesc ; |
505 | } else { |
506 | /*ERROR*EXT_POINT allocation failed*/ |
507 | Xw_set_error(117,"Xw_add_line_desc_structure",NULL) ; |
508 | } |
509 | |
510 | return (pdesc) ; |
511 | } |
512 | |
513 | #ifdef XW_PROTOTYPE |
514 | XW_STATUS Xw_del_line_desc_structure(XW_EXT_BUFFER* pbuflist) |
515 | #else |
516 | XW_STATUS Xw_del_line_desc_structure(pbuflist) |
517 | XW_EXT_BUFFER *pbuflist ; |
518 | #endif /*XW_PROTOTYPE*/ |
519 | /* |
520 | Remove ALL Extended line_desc structure in the |
521 | line_desc List |
522 | |
523 | SUCCESS always |
524 | */ |
525 | { |
526 | XW_EXT_POINT *pdesc,*qdesc ; |
527 | |
528 | for( pdesc = pbuflist->plinedesc ; pdesc ; pdesc = qdesc ) { |
529 | qdesc = (XW_EXT_POINT*)pdesc->link ; |
530 | Xw_free(pdesc) ; |
531 | } |
532 | pbuflist->plinedesc = NULL ; |
533 | |
534 | return (XW_SUCCESS) ; |
535 | } |