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