0023830: BRepExtrema_DistShapeShape does not find intersection of face with edge
[occt.git] / src / Xw / Xw_draw_text.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 #define GG002   /*GG_020197
19 Renvoyer la hauteur du texte et non de la font
20 */
21
22 #define GG010   /*GG_150197
23                 Ameliorer la conformiter de l'underline vis a vis de WORLD
24 */
25
26 #include <Xw_Extension.h>
27
28         /* ifdef then trace on */
29 #ifdef TRACE
30 #define TRACE_DRAW_TEXT
31 #endif
32
33 /*
34    STATUS Xw_draw_text (awindow,x,y,text,angle,mode):
35    XW_EXT_WINDOW *awindow
36    float x,y            Position of the beginning of text in world coordinate
37    char text[]          String to display
38    float angle          Rotated text angle
39    mode                 1 si outline
40
41         Display text in current QG set by set_text_attrib .
42
43         returns ERROR if text length > MAXCHARS
44         returns SUCCESS if successful
45
46 */
47
48 #define MAXCOORD 32767
49 #define MINCOORD -32768
50
51 #define XROTATE(x,y) (x*cosa + y*sina)
52 #define YROTATE(x,y) (y*cosa - x*sina)
53
54 static XW_EXT_LTEXT *ptextlist ;
55 static XW_EXT_CHAR *ptextdesc ;
56
57 #ifdef XW_PROTOTYPE
58 XW_STATUS Xw_draw_text (void* awindow,float x,float y,char* text,float angle,int mode)
59 #else
60 XW_STATUS Xw_draw_text (awindow,x,y,text,angle,mode)
61 void *awindow;
62 float x,y ;
63 float angle ;
64 char *text ;
65 int mode ;
66 #endif /*XW_PROTOTYPE*/
67 {
68 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow;
69 XW_EXT_BUFFER *pbuffer ;
70 int ntext,nchar,length,bindex,ix,iy,textindex,textfont,texttype ;
71 XW_ATTRIB textcode;
72
73         if( !Xw_isdefine_window(pwindow) ) {
74             /*ERROR*Bad EXT_WINDOW Address*/
75             Xw_set_error(24,"Xw_draw_text",pwindow) ;
76             return (XW_ERROR) ;
77         }
78
79         length = strlen(text) ;
80         if( length+1 > MAXCHARS ) {
81             length = MAXCHARS-1 ;
82             /*ERROR*Too big text string*/
83             Xw_set_error(38,"Xw_draw_text",&length) ;
84             return (XW_ERROR) ;
85         }
86
87         bindex = _BINDEX ;
88         pbuffer = &_BUFFER(bindex) ;
89         for( ptextlist = pbuffer->pltextlist ; ptextlist ;
90                                 ptextlist = (XW_EXT_LTEXT*)ptextlist->link ) {
91             if( ptextlist->ntext < MAXLTEXTS ) break ;
92         }
93
94         if( !ptextlist ) {
95                 ptextlist = Xw_add_text_structure(pbuffer) ;
96         }
97
98         if( !ptextlist ) return XW_ERROR ;
99
100         for( ptextdesc = pbuffer->ptextdesc ; ptextdesc ;
101                                 ptextdesc = (XW_EXT_CHAR*)ptextdesc->link ) {
102             if( ptextdesc->nchar + length < MAXCHARS ) break ;
103         }
104
105         if( !ptextdesc ) {
106                 ptextdesc = Xw_add_text_desc_structure(pbuffer) ;
107         }
108
109         if( !ptextdesc ) return XW_ERROR ;
110
111 //OCC186
112         ix = PXPOINT(x, pwindow->xratio) ;
113         iy = PYPOINT(y, pwindow->attributes.height, pwindow->yratio) ;
114 //OCC186
115
116         ix = max(min(ix,MAXCOORD),MINCOORD);
117         iy = max(min(iy,MAXCOORD),MINCOORD);
118
119         textindex = pwindow->textindex ;
120         textcode = pwindow->qgtext[textindex].code ;
121         textfont = QGFONT(textcode);
122         texttype = QGTYPE(textcode);
123         if( mode ) texttype |= XW_EXTENDEDTEXT_OUTLINE ;
124
125         ntext = ptextlist->ntext ;
126         nchar = ptextdesc->nchar ;
127         ptextlist->modes[ntext] = texttype ;
128         ptextlist->texts[ntext] = length ;
129         ptextlist->ptexts[ntext] = &ptextdesc->chars[nchar] ;
130         ptextlist->rpoints[ntext].x = ix ;
131         ptextlist->rpoints[ntext].y = iy ;
132         ptextlist->rscalex[ntext] = 1. ;
133         ptextlist->rscaley[ntext] = 1. ;
134         ptextlist->slants[ntext] = 0. ;
135         strcpy(ptextlist->ptexts[ntext],text) ;
136         if( angle > 0. ) {
137             while( angle > 2.*M_PI ) angle -= 2.*M_PI ;
138         } else if( angle < 0. ) {
139             while( angle < -2.*M_PI ) angle += 2.*M_PI ;
140         }
141         ptextlist->rangles[ntext] = angle ;
142  
143         nchar += length+1 ;
144         ptextlist->ntext++ ;
145         ptextdesc->nchar = nchar ;
146
147         if( bindex > 0 ) {
148             XFontStruct *pfontinfo = _FONTMAP->fonts[textfont] ;
149 #ifdef GG002
150             int xmin,ymin,xmax,ymax,dir,fascent,fdescent;
151             XCharStruct overall;
152             XTextExtents(pfontinfo,text,length,
153                                 &dir,&fascent,&fdescent,&overall);
154             xmin = overall.lbearing;
155             xmax = overall.width;
156             ymin = -overall.ascent;
157             ymax = overall.descent;
158 #else
159             int xmin = 0 ;
160             int xmax = XTextWidth(pfontinfo,text,length) ;
161             int ymin = -pfontinfo->ascent ;
162             int ymax = pfontinfo->descent ;
163 #endif
164             pbuffer->isempty = False ;
165             if( texttype & XW_EXTENDEDTEXT_UNDERLINE ) {
166 #ifdef GG010
167               if( _FONTMAP->fratios[textfont] <= 0. )
168 #endif
169               ymax += 2*max(2,(ymax-ymin)/8) ;
170             }
171 //            if( abs(angle) > 0. ) {
172             if( fabs(angle) > 0. ) {
173               float cosa = cos((double)angle) ;
174               float sina = sin((double)angle) ; 
175               int tx,ty ; 
176               tx = (int )( ix + XROTATE(xmin,ymin) ); 
177               ty = (int )( iy + YROTATE(xmin,ymin) );  
178               pbuffer->rxmin = min(pbuffer->rxmin,tx) ;         
179               pbuffer->rymin = min(pbuffer->rymin,ty) ;         
180               pbuffer->rxmax = max(pbuffer->rxmax,tx) ;
181               pbuffer->rymax = max(pbuffer->rymax,ty) ;
182               tx = (int )( ix + XROTATE(xmax,ymax) );    
183               ty = (int )( iy + YROTATE(xmax,ymax) );  
184               pbuffer->rxmin = min(pbuffer->rxmin,tx) ;
185               pbuffer->rymin = min(pbuffer->rymin,ty) ;
186               pbuffer->rxmax = max(pbuffer->rxmax,tx) ;
187               pbuffer->rymax = max(pbuffer->rymax,ty) ;
188               tx = (int )( ix + XROTATE(xmax,ymin) );
189               ty = (int )( iy + YROTATE(xmax,ymin) );
190               pbuffer->rxmin = min(pbuffer->rxmin,tx) ;
191               pbuffer->rymin = min(pbuffer->rymin,ty) ;
192               pbuffer->rxmax = max(pbuffer->rxmax,tx) ;
193               pbuffer->rymax = max(pbuffer->rymax,ty) ;
194               tx = (int )( ix + XROTATE(xmin,ymax) );
195               ty = (int )( iy + YROTATE(xmin,ymax) );
196               pbuffer->rxmin = min(pbuffer->rxmin,tx) ;
197               pbuffer->rymin = min(pbuffer->rymin,ty) ;
198               pbuffer->rxmax = max(pbuffer->rxmax,tx) ;
199               pbuffer->rymax = max(pbuffer->rymax,ty) ;
200             } else {
201               pbuffer->rxmin = min(pbuffer->rxmin,ix+xmin) ;
202               pbuffer->rymin = min(pbuffer->rymin,iy+ymin) ;
203               pbuffer->rxmax = max(pbuffer->rxmax,ix+xmax) ;
204               pbuffer->rymax = max(pbuffer->rymax,iy+ymax) ;
205             }
206         } else {
207             int index = pwindow->textindex ;
208             Xw_draw_pixel_texts(pwindow,ptextlist,
209                         pwindow->qgtext[index].gc,
210                         pwindow->qgtext[index].code) ;
211             ptextlist->ntext = 0 ;
212             ptextdesc->nchar = 0 ;
213         }
214
215
216 #ifdef  TRACE_DRAW_TEXT
217 if( Xw_get_trace() > 2 ) {
218     printf(" Xw_draw_text(%lx,%f,%f,'%s',%f)\n",(long ) pwindow,x,y,text,angle) ;
219 }
220 #endif
221
222         return (XW_SUCCESS);
223 }
224
225 #ifdef XW_PROTOTYPE
226 void Xw_draw_pixel_texts(XW_EXT_WINDOW* pwindow,XW_EXT_LTEXT* ptextlist,
227                                                         GC gctext,XW_ATTRIB code)
228 #else
229 void Xw_draw_pixel_texts(pwindow,ptextlist,gctext,code)
230 XW_EXT_WINDOW *pwindow ;
231 XW_EXT_LTEXT *ptextlist ;
232 GC gctext ;
233 XW_ATTRIB code ;
234 #endif /*XW_PROTOTYPE*/
235 {
236 int i,ix,iy,mode,length,font = QGFONT(code),type = QGTYPE(code) ;
237 float angle,cosa,sina ;
238 char *pchar ;
239
240         for( i=0 ; i<ptextlist->ntext ; i++ ) {
241             length = ptextlist->texts[i] ;
242             if( length <= 0 ) continue ;
243             if( ptextlist->isupdated ) {
244               ix = ptextlist->upoints[i].x ;
245               iy = ptextlist->upoints[i].y ;
246               angle = ptextlist->uangles[i] ;
247             } else {
248               ix = ptextlist->rpoints[i].x ;
249               iy = ptextlist->rpoints[i].y ;
250               angle = ptextlist->rangles[i] ;
251             }
252             mode = ptextlist->modes[i] ;
253             pchar = ptextlist->ptexts[i] ;
254             if( type & XW_EXTENDEDTEXT_MINHEIGHT ) {
255 //OCC186
256               int rcx = max(4,PVALUE(FROMMILLIMETER(_FONTMAP->ssizex[font]), 
257                                      pwindow->xratio, pwindow->yratio)/3);
258               int rcy = max(4,PVALUE(FROMMILLIMETER(_FONTMAP->ssizey[font]), 
259                                      pwindow->xratio, pwindow->yratio)/3);
260 //OCC186
261              if( angle == 0. ) {
262                 XFillArc(_DISPLAY,_DRAWABLE,gctext,
263                                         ix-rcx,iy-rcy,2*rcx,2*rcy,0,360*64) ;
264               } else {
265                 int dx,dy ;
266                 cosa = cos((double)angle) ;
267                 sina = sin((double)angle) ;
268                 dx = (int )( XROTATE(0,rcx) );
269                 dy = (int )( YROTATE(0,rcy) );
270                 XFillArc(_DISPLAY,_DRAWABLE,gctext,
271                                         ix-dx,iy-dy,2*rcx,2*rcy,0,360*64) ;
272               }  
273             } else {
274               XFontStruct *pfontinfo = _FONTMAP->fonts[font] ;
275               int xmin,ymin,xmax,ymax ;
276               if( angle == 0. ) {
277                 if( type & XW_EXTENDEDTEXT_UNDERLINE ) {
278 #ifdef GG002
279                   int dir,fascent,fdescent;
280                   XCharStruct overall;
281                   XTextExtents(pfontinfo,pchar,length,
282                                 &dir,&fascent,&fdescent,&overall);
283                   xmin = overall.lbearing;
284                   xmax = overall.width;
285                   ymin = -overall.ascent;
286                   ymax = overall.descent;
287 #else
288                   xmin = 0 ;
289                   xmax = XTextWidth(pfontinfo,pchar,length) ;
290                   ymin = -pfontinfo->ascent ;
291                   ymax = pfontinfo->descent ;
292 #endif
293 #ifdef GG010
294                   if( _FONTMAP->fratios[font] > 0. ) {
295 //OCC186
296                     ymax = PVALUE(0.6*_FONTMAP->fratios[font]*
297                                         FROMMILLIMETER(_FONTMAP->ssizey[font]),
298                                   pwindow->xratio, pwindow->yratio);
299 //OCC186
300                   } else {
301                     ymax = max(2,(ymax-ymin)/8) ;
302                   }
303 #else
304                   ymax += max(2,(ymax-ymin)/8) ;
305 #endif
306                   XDrawLine(_DISPLAY,_DRAWABLE,gctext,
307                                         ix+xmin,iy+ymax,ix+xmax,iy+ymax) ;
308                 }
309                 XDrawString(_DISPLAY,_DRAWABLE,gctext,ix,iy,pchar,length) ;
310               } else {
311                 int w,j,tx,ty ;
312                 cosa = cos((double)angle) ;
313                 sina = sin((double)angle) ;
314
315                 if( type & XW_EXTENDEDTEXT_UNDERLINE ) {
316                   int x1,y1,x2,y2 ;
317 #ifdef GG002
318                   int dir,fascent,fdescent;
319                   XCharStruct overall;
320                   XTextExtents(pfontinfo,pchar,length,
321                                 &dir,&fascent,&fdescent,&overall);
322                   xmin = overall.lbearing;
323                   xmax = overall.width;
324                   ymin = -overall.ascent;
325                   ymax = overall.descent;
326 #else
327                   xmin = 0 ;
328                   xmax = XTextWidth(pfontinfo,pchar,length) ;
329                   ymin = -pfontinfo->ascent ;
330                   ymax = pfontinfo->descent ;
331 #endif
332 #ifdef GG010
333                   if( _FONTMAP->fratios[font] > 0. ) {
334 //OCC186
335                     ymax = PVALUE(0.6*_FONTMAP->fratios[font]*
336                                         FROMMILLIMETER(_FONTMAP->ssizey[font]), 
337                                   pwindow->xratio, pwindow->yratio);
338 //OCC186
339                   } else {
340                     ymax = max(2,(ymax-ymin)/8) ;
341                   }
342 #else
343                   ymax += max(2,(ymax-ymin)/8) ;
344 #endif
345                   x1 = (int )( XROTATE(xmin,ymax) );
346                   y1 = (int )( YROTATE(xmin,ymax) );
347                   x2 = (int )( XROTATE(xmax,ymax) );
348                   y2 = (int )( YROTATE(xmax,ymax) );
349                   XDrawLine(_DISPLAY,_DRAWABLE,gctext,
350                                         ix+x1,iy+y1,ix+x2,iy+y2) ;
351                 }
352                 for( j=tx=ty=0 ; j<length ; j++) {
353                     XDrawString(_DISPLAY,_DRAWABLE,gctext,
354                                                 ix+tx,iy-ty,&pchar[j],1) ;
355                     w = XTextWidth(pfontinfo,pchar,j);
356                     tx = ROUND(w*cosa) ;
357                     ty = ROUND(w*sina) ;
358                 }
359               }
360             }
361         }
362 }
363
364 #ifdef XW_PROTOTYPE
365 XW_EXT_LTEXT* Xw_add_text_structure(XW_EXT_BUFFER* pbuflist )
366 #else
367 XW_EXT_LTEXT* Xw_add_text_structure(pbuflist )
368 XW_EXT_BUFFER *pbuflist ;
369 #endif /*XW_PROTOTYPE*/
370 /*
371         Create and Insert at end one Extended text structure in the
372         text List
373
374         returns Extended text address if successful
375                 or NULL if Bad Allocation
376 */
377 {
378 XW_EXT_LTEXT *ptext ;
379
380         ptext = (XW_EXT_LTEXT*) Xw_malloc(sizeof(XW_EXT_LTEXT)) ;
381         if( ptext ) {
382             ptext->link = pbuflist->pltextlist ;
383             ptext->isupdated = False ;
384             ptext->ntext = 0 ;
385             pbuflist->pltextlist = ptext ;
386         } else {
387             /*ERROR*EXT_TEXT Allocation failed*/
388             Xw_set_error(39,"Xw_add_text_structure",NULL) ;
389         }
390
391         return (ptext) ;
392 }
393
394 #ifdef XW_PROTOTYPE
395 XW_STATUS Xw_del_text_structure(XW_EXT_BUFFER* pbuflist)
396 #else
397 XW_STATUS Xw_del_text_structure(pbuflist)
398 XW_EXT_BUFFER *pbuflist ;
399 #endif /*XW_PROTOTYPE*/
400 /*
401         Remove ALL Extended text structure in the
402         text List
403
404         SUCCESS always
405 */
406 {
407 XW_EXT_LTEXT *ptext,*qtext ;
408
409         for( ptext = pbuflist->pltextlist ; ptext ; ptext = qtext ) {
410             qtext = (XW_EXT_LTEXT*)ptext->link ;
411             Xw_free(ptext) ;
412         }
413         pbuflist->pltextlist = NULL ;
414
415         return (XW_SUCCESS) ;
416 }
417
418 #ifdef XW_PROTOTYPE
419 XW_EXT_CHAR* Xw_add_text_desc_structure(XW_EXT_BUFFER* pbuflist )
420 #else
421 XW_EXT_CHAR* Xw_add_text_desc_structure(pbuflist )
422 XW_EXT_BUFFER *pbuflist ;
423 #endif /*XW_PROTOTYPE*/
424 /*
425         Create and Insert at end one Extended char structure in the
426         char List
427
428         returns Extended char address if successful
429                 or NULL if Bad Allocation
430 */
431 {
432 XW_EXT_CHAR *pchar ;
433
434         pchar = (XW_EXT_CHAR*) Xw_malloc(sizeof(XW_EXT_CHAR)) ;
435         if( pchar ) {
436             pchar->link = pbuflist->ptextdesc ;
437             pchar->nchar = 0 ;
438             pbuflist->ptextdesc = pchar ;
439         } else {
440             /*ERROR*EXT_CHAR Allocation failed*/
441             Xw_set_error(118,"Xw_add_text_desc_structure",NULL) ;
442         }
443
444         return (pchar) ;
445 }
446
447 #ifdef XW_PROTOTYPE
448 XW_STATUS Xw_del_text_desc_structure(XW_EXT_BUFFER* pbuflist)
449 #else
450 XW_STATUS Xw_del_text_desc_structure(pbuflist)
451 XW_EXT_BUFFER *pbuflist ;
452 #endif /*XW_PROTOTYPE*/
453 /*
454         Remove ALL Extended char structure in the
455         char List
456
457         SUCCESS always
458 */
459 {
460 XW_EXT_CHAR *pchar,*qchar ;
461
462         for( pchar = pbuflist->ptextdesc ; pchar ; pchar = qchar ) {
463             qchar = (XW_EXT_CHAR*)pchar->link ;
464             Xw_free(pchar) ;
465         }
466         pbuflist->ptextdesc = NULL ;
467
468         return (XW_SUCCESS) ;
469 }