Commit | Line | Data |
---|---|---|
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 | ||
32 | int OpenGl_TextRender::curFont = -1; | |
33 | int OpenGl_TextRender::curSize = -1; | |
34 | int OpenGl_TextRender::curScale = -1; | |
35 | int OpenGl_TextRender::curTexFont = -1; | |
36 | ||
37 | OpenGl_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 | ||
69 | OpenGl_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 | |
93 | void 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 | ||
156 | OpenGl_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 | ||
170 | OpenGl_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 | /*----------------------------------------------------------------------*/ | |
182 | OpenGl_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 | ||
197 | Tint 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 | /*-----------------------------------------------------------------------------*/ | |
240 | void 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 | ||
264 | void 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 | ||
272 | StringSize(str, &widthFont, &ascentFont, &descentFont ); | |
273 | ||
274 | GLdouble identityMatrix[4][4] = | |
275 | { | |
276 | {1.,0.,0.,0.}, | |
277 | {0.,1.,0.,0.}, | |
278 | {0.,0.,1.,0.}, | |
279 | {0.,0.,0.,1.} | |
280 | }; | |
281 | ||
282 | TEL_ALIGN_DATA align; | |
283 | ||
284 | CMN_KEY key; | |
285 | key.id = TelTextAlign; | |
286 | key.data.pdata = &align; | |
287 | TsmGetAttri( 1, &key ); | |
288 | ||
289 | Tfloat angle = 0; | |
290 | CMN_KEY keyAngle; | |
291 | keyAngle.id = TelTextAngle;//This flag responding about Angle text | |
292 | TsmGetAttri( 1, &keyAngle ); | |
293 | angle = keyAngle.data.ldata; | |
294 | ||
295 | Tint zoom = 0; | |
296 | CMN_KEY keyZoom; | |
297 | keyZoom.id = TelTextZoomable;//This flag responding about Zoomable text | |
298 | TsmGetAttri( 1, &keyZoom ); | |
299 | zoom = keyZoom.data.ldata; | |
300 | ||
7fd59977 | 301 | OpenGl_TextRender* textRender = OpenGl_TextRender::instance(); |
302 | int vh = 2 ; | |
303 | int vv = 2 ; | |
304 | ||
305 | switch( align.Hmode ) | |
306 | { | |
307 | case CALL_PHIGS_HOR_LEFT://0 | |
308 | xdis =0.; vh = 1; | |
309 | break; | |
310 | case CALL_PHIGS_HOR_CENTER://1 | |
311 | xdis = -(GLdouble)widthFont / 2.0; vh = 2; | |
312 | break; | |
313 | case CALL_PHIGS_HOR_RIGHT://2 | |
314 | xdis = -(GLdouble)widthFont; vh = 3; | |
315 | break; | |
316 | default: | |
317 | xdis = 0.; | |
318 | } | |
319 | ||
320 | switch( align.Vmode ) | |
321 | { | |
322 | case CALL_PHIGS_VERT_BOTTOM://0 | |
323 | ydis = 0.; vv = 1; | |
324 | break; | |
325 | case CALL_PHIGS_VERT_CENTER://1 | |
326 | ydis = -(GLdouble)(ascentFont) / 2.0 - descentFont; vv = 2; | |
327 | break; | |
328 | case CALL_PHIGS_VERT_TOP://2 | |
329 | ydis = -(GLdouble)ascentFont - descentFont; vv= 3; | |
330 | break; | |
331 | default: | |
332 | ydis = 0.; | |
333 | } | |
334 | ||
335 | OpenGl_FontMgr* mgr = OpenGl_FontMgr::instance(); | |
336 | ||
337 | const FTFont* fnt = mgr->fontById( curFont ); | |
338 | if ( !fnt ) | |
339 | return; | |
340 | ||
341 | float export_h = 1.; | |
342 | ||
343 | glMatrixMode(GL_MODELVIEW); | |
344 | glPushMatrix(); | |
345 | if (is2d) { | |
346 | glLoadIdentity(); | |
347 | glTranslatef(x, y, 0.f); | |
348 | glRotatef( 180, 1, 0, 0 ); | |
349 | } | |
350 | else { | |
351 | GLdouble wx, wy, wz; | |
352 | GLdouble x1, y1, z1; | |
353 | GLdouble x2, y2, z2; | |
354 | ||
355 | glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble*)modelMatrix ); | |
356 | glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble*)projMatrix ); | |
357 | glGetIntegerv( GL_VIEWPORT, (GLint*)viewport ); | |
358 | ||
359 | gluProject( x, y, z, | |
360 | (GLdouble*)modelMatrix, | |
361 | (GLdouble*)projMatrix, | |
362 | (GLint*)viewport, | |
363 | &wx, &wy, &wz ); | |
364 | glLoadIdentity(); | |
365 | gluUnProject( wx, wy, wz, | |
366 | (GLdouble*)identityMatrix, (GLdouble*)projMatrix, (GLint*)viewport, | |
367 | &x1, &y1 , &z1 ); | |
368 | ||
369 | GLdouble h = (GLdouble)fnt->FaceSize(); | |
370 | ||
371 | ||
372 | gluUnProject( wx, wy + h - 1., wz, | |
373 | (GLdouble*)identityMatrix, (GLdouble*)projMatrix, (GLint*)viewport, | |
374 | &x2, &y2, &z2 ); | |
375 | ||
376 | h = (y2-y1)/h; | |
377 | ||
378 | glTranslated( x1, y1 , z1 ); | |
379 | glRotated(angle, 0, 0, 1); | |
380 | glTranslated(xdis, ydis, 0); | |
381 | ||
382 | if( ! zoom ) | |
383 | { | |
384 | glScaled( h, h, h ); | |
385 | } | |
386 | else | |
387 | { | |
388 | export_h = h; | |
389 | } | |
390 | } | |
391 | glGetIntegerv(GL_RENDER_MODE, &renderMode); | |
392 | if ( renderMode == GL_FEEDBACK ) | |
393 | { | |
394 | #ifdef HAVE_GL2PS | |
28e85034 A |
395 | CMN_KEY keyfontName; |
396 | keyfontName.id = TelTextFont;//This flag responding about TextFontName | |
397 | TsmGetAttri( 1, &keyfontName ); | |
398 | char *fontName = new char[strlen((char*)keyfontName.data.pdata) + 1]; | |
399 | strcpy(fontName,(char*)keyfontName.data.pdata); | |
400 | ||
7fd59977 | 401 | export_h = (GLdouble)fnt->FaceSize() / export_h; |
402 | int aligment = alignmentforgl2ps( vh, vv ); | |
403 | glPopMatrix(); | |
404 | ExportText( str, fontName, export_h, angle, aligment, x, y, z, is2d!=0 ); | |
28e85034 | 405 | delete [] fontName; |
7fd59977 | 406 | #endif |
407 | } | |
408 | else | |
409 | { | |
410 | mgr->render_text( curFont, str ); | |
411 | glPopMatrix(); | |
412 | } | |
7fd59977 | 413 | return; |
414 | ||
415 | } | |
416 | ||
417 | #ifdef HAVE_GL2PS | |
418 | int OpenGl_TextRender::alignmentforgl2ps(int vh, int vy) | |
419 | { | |
420 | if( vh == 1 && vy == 1) | |
421 | { | |
422 | return 5; | |
423 | } | |
424 | if( vh == 2 && vy == 1) | |
425 | { | |
426 | return 4; | |
427 | } | |
428 | if( vh == 3 && vy == 1) | |
429 | { | |
430 | return 6; | |
431 | } | |
432 | ||
433 | if( vh == 1 && vy == 2) | |
434 | { | |
435 | return 2; | |
436 | } | |
437 | if( vh == 2 && vy == 2) | |
438 | { | |
439 | return 1; | |
440 | } | |
441 | if( vh == 3 && vy == 2) | |
442 | { | |
443 | return 3; | |
444 | } | |
445 | ||
446 | if( vh == 1 && vy == 3) | |
447 | { | |
448 | return 8; | |
449 | } | |
450 | if( vh == 2 && vy == 3) | |
451 | { | |
452 | return 7; | |
453 | } | |
454 | if( vh == 3 && vy == 3) | |
455 | { | |
456 | return 9; | |
457 | } | |
458 | return 0; | |
459 | }; | |
460 | #endif | |
461 | ||
462 | /*-----------------------------------------------------------------------------*/ | |
463 | void OpenGl_TextRender::ExportText( char* str, char* fontname, GLfloat height, GLfloat angle, GLint alignment, | |
464 | GLfloat x, GLfloat y, GLfloat z, GLboolean is2d ) | |
465 | { | |
466 | #ifdef HAVE_GL2PS | |
467 | ||
468 | GLubyte zero = 0; | |
469 | char ps_font[64]; | |
470 | ||
471 | getGL2PSFontName(fontname, ps_font); | |
472 | ||
473 | if( is2d ) | |
474 | glRasterPos2f( x, y ); | |
475 | else | |
476 | glRasterPos3f( x, y, z ); | |
477 | ||
478 | glBitmap( 1, 1, 0, 0, 0, 0, &zero ); | |
479 | ||
480 | gl2psTextOpt( str, ps_font, height, alignment, angle); | |
481 | ||
482 | #endif | |
483 | ||
484 | } |