Merging OCC22105, OCC22354, OCC22150 , OCC22199 , OCC22391 and OCC22108
[occt.git] / src / OpenGl / OpenGl_TextRender.cxx
CommitLineData
7fd59977 1/*
2* Includes
3*/
4#include <stdio.h>
5#include <string.h>
6
7#include <TCollection_AsciiString.hxx>
8#include <TCollection_HAsciiString.hxx>
9
10#include <Standard_Stream.hxx>
11
12#include <OpenGl_FontMgr.hxx>
13#include <OpenGl_tgl_funcs.hxx>
14#include <OpenGl_TextRender.hxx>
15#include <OpenGl_telem_attri.hxx>
16#include <OpenGl_cmn_varargs.hxx>
17
18#include <OSD_Environment.hxx>
19#include <Quantity_NameOfColor.hxx>
20#include <AlienImage.hxx>
21
22#ifdef HAVE_GL2PS
23#include <gl2ps.h>
24#endif
25
26
27/*-----------------------------------------------------------------------------*/
28/*
29* Prototypes variables statiques
30*/
31
32int OpenGl_TextRender::curFont = -1;
33int OpenGl_TextRender::curSize = -1;
34int OpenGl_TextRender::curScale = -1;
35int OpenGl_TextRender::curTexFont = -1;
36
37OpenGl_TextRender::FontMapNode OpenGl_TextRender::fontMap[] = {
38
39#ifdef WNT
40
41 { "Courier" , "Courier New" , OSD_FA_Regular },
42 { "Times-Roman" , "Times New Roman", OSD_FA_Regular },
43 { "Times-Bold" , "Times New Roman", OSD_FA_Bold },
44 { "Times-Italic" , "Times New Roman", OSD_FA_Italic },
45 { "Times-BoldItalic" , "Times New Roman", OSD_FA_BoldItalic },
46 { "ZapfChancery-MediumItalic", "Script" , OSD_FA_Regular },
47 { "Symbol" , "Symbol" , OSD_FA_Regular },
48 { "ZapfDingbats" , "WingDings" , OSD_FA_Regular },
49 { "Rock" , "Arial" , OSD_FA_Regular },
50 { "Iris" , "Lucida Console" , OSD_FA_Regular }
51
52#else //X11
53
54 { "Courier" , "Courier" , OSD_FA_Regular },
55 { "Times-Roman" , "Times" , OSD_FA_Regular },
56 { "Times-Bold" , "Times" , OSD_FA_Bold },
57 { "Times-Italic" , "Times" , OSD_FA_Italic },
58 { "Times-BoldItalic" , "Times" , OSD_FA_BoldItalic },
59 { "Arial" , "Helvetica" , OSD_FA_Regular },
60 { "ZapfChancery-MediumItalic", "-adobe-itc zapf chancery-medium-i-normal--*-*-*-*-*-*-iso8859-1" , OSD_FA_Regular },
61 { "Symbol" , "-adobe-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific" , OSD_FA_Regular },
62 { "ZapfDingbats" , "-adobe-itc zapf dingbats-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific" , OSD_FA_Regular },
63 { "Rock" , "-sgi-rock-medium-r-normal--*-*-*-*-p-*-iso8859-1" , OSD_FA_Regular },
64 { "Iris" , "--iris-medium-r-normal--*-*-*-*-m-*-iso8859-1" , OSD_FA_Regular }
65#endif
66
67};
68
69OpenGl_TextRender::FontEntry OpenGl_TextRender::fontEntry[] = {
70
71 { "Courier" , "Courier New" },
72 { "Times-Roman" , "Times New Roman" },
73 { "Times-Bold" , "Times New Roman Bold" },
74 { "Times-Italic" , "Times New Roman Italic" },
75 { "Times-BoldItalic" , "Times New Roman Bold Italic" },
76 { "ZapfChancery-MediumItalic", "Script" },
77 { "Symbol" , "Symbol" },
78 { "ZapfDingbats" , "WingDings" },
79 { "Rock" , "Arial" },
80 { "Iris" , "Lucida Console" }
81
82};
83
84#define NUM_FONT_ENTRIES (sizeof(fontMap)/sizeof(FontMapNode))
85
86/*-----------------------------------------------------------------------------*/
87
88/*
89* Constants
90*/
91
92#ifdef HAVE_GL2PS
93void OpenGl_TextRender::getGL2PSFontName(char *src_font, char *ps_font)
94{
95 /*
96 Convert font name used for rendering to some "good" font names
97 that produce good vector text
98 */
99 static char const *family[] = {"Helvetica", "Courier", "Times"};
100 static char const *italic[] = {"Oblique", "Oblique", "Italic"};
101 static char const *base[] = {"", "", "-Roman"};
102
103 int font = 0;
104 int isBold = 0;
105 int isItalic = 0;
106
107
108 if( strstr( src_font, "Symbol" ) ){
109 sprintf( ps_font, "%s", "Symbol" );
110 return;
111 }
112
113 if( strstr( src_font, "ZapfDingbats" ) ){
114 sprintf( ps_font, "%s", "WingDings" );
115 return;
116 }
117
118 if ( strstr( src_font, "Courier" ) ){
119 font = 1;
120 }
121 else if ( strstr( src_font, "Times" ) ){
122 font = 2;
123 }
124
125 if ( strstr( src_font, "Bold" ) ){
126 isBold = 1;
127 }
128
129 if ( strstr( src_font, "Italic" ) || strstr( src_font, "Oblique" ) ){
130 isItalic = 1;
131 }
132
133 if ( isBold ){
134 sprintf( ps_font, "%s-%s", family[font], "Bold");
135 if ( isItalic ){
136 sprintf(ps_font, "%s%s", ps_font, italic[font]);
137 }
138 }
139 else if ( isItalic )
140 {
141 sprintf( ps_font, "%s-%s", family[font], italic[font] );
142 }
143 else
144 {
145 sprintf( ps_font, "%s%s", family[font], base[font] );
146 }
147}
148#endif
149
150/*-----------------------------------------------------------------------------*/
151
152/*
153* Constructors
154*/
155
156OpenGl_TextRender::OpenGl_TextRender()
157: _CurrentFontId(-1),
158_XCurrentScale(1.f),
159_YCurrentScale(1.f) {
160}
161
162
163
164/*-----------------------------------------------------------------------------*/
165
166/*
167* Fonctions publiques
168*/
169
170OpenGl_TextRender* OpenGl_TextRender::instance() {
171 static OpenGl_TextRender* _textRend = NULL;
172 if ( _textRend == NULL )
173 {
174 _textRend = new OpenGl_TextRender();
175 }
176
177 return _textRend;
178}
179
180
181/*----------------------------------------------------------------------*/
182OpenGl_TextRender::FontMapNode OpenGl_TextRender::searchFontInMap( Handle(TCollection_HAsciiString)& fontName ) {
183 for ( int i = 0; i < NUM_FONT_ENTRIES; ++i )
184 {
185 TCollection_AsciiString compare_String(fontMap[i].enumName) ;
186 if(compare_String.IsEqual( fontName->ToCString() ))
187 {
188 return fontMap[i];
189 }
190 }
191 //default font returns
192 return fontMap[0];
193}
194
195/*-----------------------------------------------------------------------------*/
196
197Tint OpenGl_TextRender::FindFont ( Tchar* fontName,
198 OSD_FontAspect aspect,
199 Tfloat bestSize,
200 Tfloat xScale ,
201 Tfloat yScale )
202{
203 if (!fontName)
204 return -1;
205 OpenGl_FontMgr* mgr = OpenGl_FontMgr::instance();
206
207 Handle(TCollection_HAsciiString) family_name
208 = new TCollection_HAsciiString((char*)fontName);
209
210 curFont = mgr->request_font(family_name,
211 aspect,
212 Standard_Integer(bestSize) );
213
214 if( curFont == -1 ) {
215 //try to use font names mapping
216 FontMapNode newTempFont = searchFontInMap ( family_name );
217 curFont = mgr->request_font( new TCollection_HAsciiString(newTempFont.FontName),
218 newTempFont.fontAspect,
219 Standard_Integer(bestSize) );
220 }
221
222 // Requested family name not found -> serach for any font family with given aspect and height
223 family_name = new TCollection_HAsciiString( "" );
224 if ( curFont == -1 ) {
225 curFont = mgr->request_font(family_name, aspect, Standard_Integer(bestSize) );
226 }
227
228 // The last resort: trying to use ANY font available in the system
229 if ( curFont == -1 ) {
230 curFont = mgr->request_font(family_name, OSD_FA_Undefined, -1 );
231 }
232
233 if ( curFont != -1 )
234 mgr->setCurrentScale( xScale, yScale );
235 return curFont;
236
237}
238
239/*-----------------------------------------------------------------------------*/
240void OpenGl_TextRender::StringSize(char *str, GLint *Width, GLint *Ascent, GLint *Descent)
241{
242
243 /* int dir, asc, des;*/
244 *Ascent = 0;
245 *Descent = 0;
246 *Width = 0;
247 if (curFont != -1) {
248 OpenGl_FontMgr* mgr = OpenGl_FontMgr::instance();
249 const FTFont* font = mgr->fontById( curFont );
250 if ( font ) {
251 *Width = GLint( mgr->computeWidth( curFont, str ) );
252 *Ascent = GLint( font->Ascender() );
253 *Descent = GLint( font->Descender() );
254 }
255 }
256#ifdef TRACE
257 printf("sizeString::asc = %d des = %d width = %d \n", *Ascent, *Descent, *Width);
258#endif
259
260}
261
262/*-----------------------------------------------------------------------------*/
263
264void OpenGl_TextRender::RenderText ( char* str, GLuint base, int is2d, GLfloat x, GLfloat y, GLfloat z )
265{
266 GLdouble projMatrix[4][4], modelMatrix[4][4];
267 GLint viewport[4];
268 GLint widthFont, ascentFont, descentFont;
269 GLdouble xdis = 0., ydis = 0.;
270 GLint renderMode;
271
256d4320
A
272 // FTFont changes texture state when it renders and computes size for the text
273 glPushAttrib(GL_TEXTURE_BIT);
7fd59977 274 StringSize(str, &widthFont, &ascentFont, &descentFont );
275
276 GLdouble identityMatrix[4][4] =
277 {
278 {1.,0.,0.,0.},
279 {0.,1.,0.,0.},
280 {0.,0.,1.,0.},
281 {0.,0.,0.,1.}
282 };
283
284 TEL_ALIGN_DATA align;
285
286 CMN_KEY key;
287 key.id = TelTextAlign;
288 key.data.pdata = &align;
289 TsmGetAttri( 1, &key );
290
291 Tfloat angle = 0;
292 CMN_KEY keyAngle;
293 keyAngle.id = TelTextAngle;//This flag responding about Angle text
294 TsmGetAttri( 1, &keyAngle );
295 angle = keyAngle.data.ldata;
296
297 Tint zoom = 0;
298 CMN_KEY keyZoom;
299 keyZoom.id = TelTextZoomable;//This flag responding about Zoomable text
300 TsmGetAttri( 1, &keyZoom );
301 zoom = keyZoom.data.ldata;
302
7fd59977 303 OpenGl_TextRender* textRender = OpenGl_TextRender::instance();
304 int vh = 2 ;
305 int vv = 2 ;
306
307 switch( align.Hmode )
308 {
309 case CALL_PHIGS_HOR_LEFT://0
310 xdis =0.; vh = 1;
311 break;
312 case CALL_PHIGS_HOR_CENTER://1
313 xdis = -(GLdouble)widthFont / 2.0; vh = 2;
314 break;
315 case CALL_PHIGS_HOR_RIGHT://2
316 xdis = -(GLdouble)widthFont; vh = 3;
317 break;
318 default:
319 xdis = 0.;
320 }
321
322 switch( align.Vmode )
323 {
324 case CALL_PHIGS_VERT_BOTTOM://0
325 ydis = 0.; vv = 1;
326 break;
327 case CALL_PHIGS_VERT_CENTER://1
328 ydis = -(GLdouble)(ascentFont) / 2.0 - descentFont; vv = 2;
329 break;
330 case CALL_PHIGS_VERT_TOP://2
331 ydis = -(GLdouble)ascentFont - descentFont; vv= 3;
332 break;
333 default:
334 ydis = 0.;
335 }
336
337 OpenGl_FontMgr* mgr = OpenGl_FontMgr::instance();
338
339 const FTFont* fnt = mgr->fontById( curFont );
256d4320
A
340 if ( !fnt ) {
341 glPopAttrib();
7fd59977 342 return;
256d4320 343 }
7fd59977 344
345 float export_h = 1.;
346
347 glMatrixMode(GL_MODELVIEW);
348 glPushMatrix();
349 if (is2d) {
350 glLoadIdentity();
351 glTranslatef(x, y, 0.f);
352 glRotatef( 180, 1, 0, 0 );
353 }
354 else {
355 GLdouble wx, wy, wz;
356 GLdouble x1, y1, z1;
357 GLdouble x2, y2, z2;
358
359 glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble*)modelMatrix );
360 glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble*)projMatrix );
361 glGetIntegerv( GL_VIEWPORT, (GLint*)viewport );
362
363 gluProject( x, y, z,
364 (GLdouble*)modelMatrix,
365 (GLdouble*)projMatrix,
366 (GLint*)viewport,
367 &wx, &wy, &wz );
368 glLoadIdentity();
369 gluUnProject( wx, wy, wz,
370 (GLdouble*)identityMatrix, (GLdouble*)projMatrix, (GLint*)viewport,
371 &x1, &y1 , &z1 );
372
373 GLdouble h = (GLdouble)fnt->FaceSize();
374
375
376 gluUnProject( wx, wy + h - 1., wz,
377 (GLdouble*)identityMatrix, (GLdouble*)projMatrix, (GLint*)viewport,
378 &x2, &y2, &z2 );
379
380 h = (y2-y1)/h;
381
382 glTranslated( x1, y1 , z1 );
383 glRotated(angle, 0, 0, 1);
384 glTranslated(xdis, ydis, 0);
385
386 if( ! zoom )
387 {
388 glScaled( h, h, h );
389 }
390 else
391 {
392 export_h = h;
393 }
394 }
395 glGetIntegerv(GL_RENDER_MODE, &renderMode);
396 if ( renderMode == GL_FEEDBACK )
397 {
398#ifdef HAVE_GL2PS
d4c2114a 399 CMN_KEY keyfontName;
400 keyfontName.id = TelTextFont;//This flag responding about TextFontName
401 TsmGetAttri( 1, &keyfontName );
402 char *fontName = new char[strlen((char*)keyfontName.data.pdata) + 1];
403 strcpy(fontName,(char*)keyfontName.data.pdata);
404
7fd59977 405 export_h = (GLdouble)fnt->FaceSize() / export_h;
406 int aligment = alignmentforgl2ps( vh, vv );
407 glPopMatrix();
408 ExportText( str, fontName, export_h, angle, aligment, x, y, z, is2d!=0 );
d4c2114a 409 delete [] fontName;
7fd59977 410#endif
411 }
412 else
413 {
256d4320 414 mgr->render_text( curFont, str, is2d );
7fd59977 415 glPopMatrix();
416 }
256d4320 417 glPopAttrib();
7fd59977 418 return;
419
420}
421
422#ifdef HAVE_GL2PS
423int OpenGl_TextRender::alignmentforgl2ps(int vh, int vy)
424{
425 if( vh == 1 && vy == 1)
426 {
427 return 5;
428 }
429 if( vh == 2 && vy == 1)
430 {
431 return 4;
432 }
433 if( vh == 3 && vy == 1)
434 {
435 return 6;
436 }
437
438 if( vh == 1 && vy == 2)
439 {
440 return 2;
441 }
442 if( vh == 2 && vy == 2)
443 {
444 return 1;
445 }
446 if( vh == 3 && vy == 2)
447 {
448 return 3;
449 }
450
451 if( vh == 1 && vy == 3)
452 {
453 return 8;
454 }
455 if( vh == 2 && vy == 3)
456 {
457 return 7;
458 }
459 if( vh == 3 && vy == 3)
460 {
461 return 9;
462 }
463 return 0;
464};
465#endif
466
467/*-----------------------------------------------------------------------------*/
468void OpenGl_TextRender::ExportText( char* str, char* fontname, GLfloat height, GLfloat angle, GLint alignment,
469 GLfloat x, GLfloat y, GLfloat z, GLboolean is2d )
470{
471#ifdef HAVE_GL2PS
472
473 GLubyte zero = 0;
474 char ps_font[64];
475
476 getGL2PSFontName(fontname, ps_font);
477
478 if( is2d )
479 glRasterPos2f( x, y );
480 else
481 glRasterPos3f( x, y, z );
482
483 glBitmap( 1, 1, 0, 0, 0, 0, &zero );
484
485 gl2psTextOpt( str, ps_font, height, alignment, angle);
486
487#endif
488
489}