0023830: BRepExtrema_DistShapeShape does not find intersection of face with edge
[occt.git] / src / Xw / Xw_draw_text.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#define GG002 /*GG_020197
b311480e 19Renvoyer la hauteur du texte et non de la font
7fd59977 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
54static XW_EXT_LTEXT *ptextlist ;
55static XW_EXT_CHAR *ptextdesc ;
56
57#ifdef XW_PROTOTYPE
58XW_STATUS Xw_draw_text (void* awindow,float x,float y,char* text,float angle,int mode)
59#else
60XW_STATUS Xw_draw_text (awindow,x,y,text,angle,mode)
61void *awindow;
62float x,y ;
63float angle ;
64char *text ;
65int mode ;
66#endif /*XW_PROTOTYPE*/
67{
68XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow;
69XW_EXT_BUFFER *pbuffer ;
70int ntext,nchar,length,bindex,ix,iy,textindex,textfont,texttype ;
71XW_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. ) {
c6541a0c 137 while( angle > 2.*M_PI ) angle -= 2.*M_PI ;
7fd59977 138 } else if( angle < 0. ) {
c6541a0c 139 while( angle < -2.*M_PI ) angle += 2.*M_PI ;
7fd59977 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
217if( 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
226void Xw_draw_pixel_texts(XW_EXT_WINDOW* pwindow,XW_EXT_LTEXT* ptextlist,
227 GC gctext,XW_ATTRIB code)
228#else
229void Xw_draw_pixel_texts(pwindow,ptextlist,gctext,code)
230XW_EXT_WINDOW *pwindow ;
231XW_EXT_LTEXT *ptextlist ;
232GC gctext ;
233XW_ATTRIB code ;
234#endif /*XW_PROTOTYPE*/
235{
236int i,ix,iy,mode,length,font = QGFONT(code),type = QGTYPE(code) ;
237float angle,cosa,sina ;
238char *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
365XW_EXT_LTEXT* Xw_add_text_structure(XW_EXT_BUFFER* pbuflist )
366#else
367XW_EXT_LTEXT* Xw_add_text_structure(pbuflist )
368XW_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{
378XW_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
395XW_STATUS Xw_del_text_structure(XW_EXT_BUFFER* pbuflist)
396#else
397XW_STATUS Xw_del_text_structure(pbuflist)
398XW_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{
407XW_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
419XW_EXT_CHAR* Xw_add_text_desc_structure(XW_EXT_BUFFER* pbuflist )
420#else
421XW_EXT_CHAR* Xw_add_text_desc_structure(pbuflist )
422XW_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{
432XW_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
448XW_STATUS Xw_del_text_desc_structure(XW_EXT_BUFFER* pbuflist)
449#else
450XW_STATUS Xw_del_text_desc_structure(pbuflist)
451XW_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{
460XW_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}