0023414: Remove deprecated classes Xw_PixMap and WNT_PixMap
[occt.git] / src / Xw / Xw_draw_segment.cxx
CommitLineData
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
19#define S3593 /*GG_130398
b311480e 20OPTIMISATION MFT
7fd59977 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
31static XW_EXT_SEGMENT *pseglist ;
32static 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
49XW_STATUS Xw_draw_segment (void* awindow,float x1,float y1,float x2,float y2)
50#else
51XW_STATUS Xw_draw_segment (awindow,x1,y1,x2,y2)
52void *awindow;
53float x1,y1,x2,y2 ;
54#endif /*XW_PROTOTYPE*/
55{
56XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow;
57XW_EXT_BUFFER *pbuffer ;
58int status ;
59int nseg,bindex;
60int 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
130if( 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
139void Xw_draw_pixel_segments(XW_EXT_WINDOW* pwindow,XW_EXT_SEGMENT *pseglist,GC gc)
140#else
141void Xw_draw_pixel_segments(pwindow,pseglist,gc)
142XW_EXT_WINDOW *pwindow;
143XW_EXT_SEGMENT *pseglist;
144GC 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
157if( 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
178XW_STATUS Xw_begin_segments(void* awindow,int nsegment)
179#else
180XW_STATUS Xw_begin_segments(awindow,nsegment)
181void *awindow ;
182int nsegment ;
183#endif /*XW_PROTOTYPE*/
184{
185XW_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
198if( 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
217XW_STATUS Xw_close_segments(void* awindow)
218#else
219XW_STATUS Xw_close_segments(awindow)
220void *awindow ;
221#endif /*XW_PROTOTYPE*/
222{
223XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
224XW_EXT_BUFFER *pbuffer ;
225int 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
244if( 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
252XW_EXT_SEGMENT* Xw_add_segment_structure(XW_EXT_BUFFER* pbuflist )
253#else
254XW_EXT_SEGMENT* Xw_add_segment_structure(pbuflist )
255XW_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{
265XW_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
282XW_STATUS Xw_del_segment_structure(XW_EXT_BUFFER* pbuflist)
283#else
284XW_STATUS Xw_del_segment_structure(pbuflist)
285XW_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{
294XW_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
311int Xw_clip_segment (XW_EXT_WINDOW* pwindow,int x1,int y1,int x2,int y2,XSegment* pseg)
312#else
313int Xw_clip_segment (pwindow,x1,y1,x2,y2,pseg)
314XW_EXT_WINDOW *pwindow;
315int x1,y1,x2,y2;
316XSegment *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{
334int xx1 = x1,yy1 = y1,xx2 = x2,yy2 = y2;
335int 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}