1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
18 #define GG002 /*GG_020197
19 Renvoyer la hauteur du texte et non de la font
22 #define GG010 /*GG_150197
23 Ameliorer la conformiter de l'underline vis a vis de WORLD
26 #include <Xw_Extension.h>
28 /* ifdef then trace on */
30 #define TRACE_DRAW_TEXT
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
41 Display text in current QG set by set_text_attrib .
43 returns ERROR if text length > MAXCHARS
44 returns SUCCESS if successful
48 #define MAXCOORD 32767
49 #define MINCOORD -32768
51 #define XROTATE(x,y) (x*cosa + y*sina)
52 #define YROTATE(x,y) (y*cosa - x*sina)
54 static XW_EXT_LTEXT *ptextlist ;
55 static XW_EXT_CHAR *ptextdesc ;
58 XW_STATUS Xw_draw_text (void* awindow,float x,float y,char* text,float angle,int mode)
60 XW_STATUS Xw_draw_text (awindow,x,y,text,angle,mode)
66 #endif /*XW_PROTOTYPE*/
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 ;
73 if( !Xw_isdefine_window(pwindow) ) {
74 /*ERROR*Bad EXT_WINDOW Address*/
75 Xw_set_error(24,"Xw_draw_text",pwindow) ;
79 length = strlen(text) ;
80 if( length+1 > MAXCHARS ) {
82 /*ERROR*Too big text string*/
83 Xw_set_error(38,"Xw_draw_text",&length) ;
88 pbuffer = &_BUFFER(bindex) ;
89 for( ptextlist = pbuffer->pltextlist ; ptextlist ;
90 ptextlist = (XW_EXT_LTEXT*)ptextlist->link ) {
91 if( ptextlist->ntext < MAXLTEXTS ) break ;
95 ptextlist = Xw_add_text_structure(pbuffer) ;
98 if( !ptextlist ) return XW_ERROR ;
100 for( ptextdesc = pbuffer->ptextdesc ; ptextdesc ;
101 ptextdesc = (XW_EXT_CHAR*)ptextdesc->link ) {
102 if( ptextdesc->nchar + length < MAXCHARS ) break ;
106 ptextdesc = Xw_add_text_desc_structure(pbuffer) ;
109 if( !ptextdesc ) return XW_ERROR ;
112 ix = PXPOINT(x, pwindow->xratio) ;
113 iy = PYPOINT(y, pwindow->attributes.height, pwindow->yratio) ;
116 ix = max(min(ix,MAXCOORD),MINCOORD);
117 iy = max(min(iy,MAXCOORD),MINCOORD);
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 ;
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) ;
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 ;
141 ptextlist->rangles[ntext] = angle ;
145 ptextdesc->nchar = nchar ;
148 XFontStruct *pfontinfo = _FONTMAP->fonts[textfont] ;
150 int xmin,ymin,xmax,ymax,dir,fascent,fdescent;
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;
160 int xmax = XTextWidth(pfontinfo,text,length) ;
161 int ymin = -pfontinfo->ascent ;
162 int ymax = pfontinfo->descent ;
164 pbuffer->isempty = False ;
165 if( texttype & XW_EXTENDEDTEXT_UNDERLINE ) {
167 if( _FONTMAP->fratios[textfont] <= 0. )
169 ymax += 2*max(2,(ymax-ymin)/8) ;
171 // if( abs(angle) > 0. ) {
172 if( fabs(angle) > 0. ) {
173 float cosa = cos((double)angle) ;
174 float sina = sin((double)angle) ;
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) ;
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) ;
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 ;
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) ;
226 void Xw_draw_pixel_texts(XW_EXT_WINDOW* pwindow,XW_EXT_LTEXT* ptextlist,
227 GC gctext,XW_ATTRIB code)
229 void Xw_draw_pixel_texts(pwindow,ptextlist,gctext,code)
230 XW_EXT_WINDOW *pwindow ;
231 XW_EXT_LTEXT *ptextlist ;
234 #endif /*XW_PROTOTYPE*/
236 int i,ix,iy,mode,length,font = QGFONT(code),type = QGTYPE(code) ;
237 float angle,cosa,sina ;
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] ;
248 ix = ptextlist->rpoints[i].x ;
249 iy = ptextlist->rpoints[i].y ;
250 angle = ptextlist->rangles[i] ;
252 mode = ptextlist->modes[i] ;
253 pchar = ptextlist->ptexts[i] ;
254 if( type & XW_EXTENDEDTEXT_MINHEIGHT ) {
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);
262 XFillArc(_DISPLAY,_DRAWABLE,gctext,
263 ix-rcx,iy-rcy,2*rcx,2*rcy,0,360*64) ;
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) ;
274 XFontStruct *pfontinfo = _FONTMAP->fonts[font] ;
275 int xmin,ymin,xmax,ymax ;
277 if( type & XW_EXTENDEDTEXT_UNDERLINE ) {
279 int dir,fascent,fdescent;
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;
289 xmax = XTextWidth(pfontinfo,pchar,length) ;
290 ymin = -pfontinfo->ascent ;
291 ymax = pfontinfo->descent ;
294 if( _FONTMAP->fratios[font] > 0. ) {
296 ymax = PVALUE(0.6*_FONTMAP->fratios[font]*
297 FROMMILLIMETER(_FONTMAP->ssizey[font]),
298 pwindow->xratio, pwindow->yratio);
301 ymax = max(2,(ymax-ymin)/8) ;
304 ymax += max(2,(ymax-ymin)/8) ;
306 XDrawLine(_DISPLAY,_DRAWABLE,gctext,
307 ix+xmin,iy+ymax,ix+xmax,iy+ymax) ;
309 XDrawString(_DISPLAY,_DRAWABLE,gctext,ix,iy,pchar,length) ;
312 cosa = cos((double)angle) ;
313 sina = sin((double)angle) ;
315 if( type & XW_EXTENDEDTEXT_UNDERLINE ) {
318 int dir,fascent,fdescent;
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;
328 xmax = XTextWidth(pfontinfo,pchar,length) ;
329 ymin = -pfontinfo->ascent ;
330 ymax = pfontinfo->descent ;
333 if( _FONTMAP->fratios[font] > 0. ) {
335 ymax = PVALUE(0.6*_FONTMAP->fratios[font]*
336 FROMMILLIMETER(_FONTMAP->ssizey[font]),
337 pwindow->xratio, pwindow->yratio);
340 ymax = max(2,(ymax-ymin)/8) ;
343 ymax += max(2,(ymax-ymin)/8) ;
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) ;
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);
365 XW_EXT_LTEXT* Xw_add_text_structure(XW_EXT_BUFFER* pbuflist )
367 XW_EXT_LTEXT* Xw_add_text_structure(pbuflist )
368 XW_EXT_BUFFER *pbuflist ;
369 #endif /*XW_PROTOTYPE*/
371 Create and Insert at end one Extended text structure in the
374 returns Extended text address if successful
375 or NULL if Bad Allocation
378 XW_EXT_LTEXT *ptext ;
380 ptext = (XW_EXT_LTEXT*) Xw_malloc(sizeof(XW_EXT_LTEXT)) ;
382 ptext->link = pbuflist->pltextlist ;
383 ptext->isupdated = False ;
385 pbuflist->pltextlist = ptext ;
387 /*ERROR*EXT_TEXT Allocation failed*/
388 Xw_set_error(39,"Xw_add_text_structure",NULL) ;
395 XW_STATUS Xw_del_text_structure(XW_EXT_BUFFER* pbuflist)
397 XW_STATUS Xw_del_text_structure(pbuflist)
398 XW_EXT_BUFFER *pbuflist ;
399 #endif /*XW_PROTOTYPE*/
401 Remove ALL Extended text structure in the
407 XW_EXT_LTEXT *ptext,*qtext ;
409 for( ptext = pbuflist->pltextlist ; ptext ; ptext = qtext ) {
410 qtext = (XW_EXT_LTEXT*)ptext->link ;
413 pbuflist->pltextlist = NULL ;
415 return (XW_SUCCESS) ;
419 XW_EXT_CHAR* Xw_add_text_desc_structure(XW_EXT_BUFFER* pbuflist )
421 XW_EXT_CHAR* Xw_add_text_desc_structure(pbuflist )
422 XW_EXT_BUFFER *pbuflist ;
423 #endif /*XW_PROTOTYPE*/
425 Create and Insert at end one Extended char structure in the
428 returns Extended char address if successful
429 or NULL if Bad Allocation
434 pchar = (XW_EXT_CHAR*) Xw_malloc(sizeof(XW_EXT_CHAR)) ;
436 pchar->link = pbuflist->ptextdesc ;
438 pbuflist->ptextdesc = pchar ;
440 /*ERROR*EXT_CHAR Allocation failed*/
441 Xw_set_error(118,"Xw_add_text_desc_structure",NULL) ;
448 XW_STATUS Xw_del_text_desc_structure(XW_EXT_BUFFER* pbuflist)
450 XW_STATUS Xw_del_text_desc_structure(pbuflist)
451 XW_EXT_BUFFER *pbuflist ;
452 #endif /*XW_PROTOTYPE*/
454 Remove ALL Extended char structure in the
460 XW_EXT_CHAR *pchar,*qchar ;
462 for( pchar = pbuflist->ptextdesc ; pchar ; pchar = qchar ) {
463 qchar = (XW_EXT_CHAR*)pchar->link ;
466 pbuflist->ptextdesc = NULL ;
468 return (XW_SUCCESS) ;