0023000: Improve the way the gradient and textured background is managed in 3d viewer
[occt.git] / src / OpenGl / OpenGl_Display_1.cxx
CommitLineData
2166f0fa
SK
1// File: OpenGl_Display_1.cxx
2// Created: 25 October 2011
3// Author: Sergey ZERCHANINOV
4// Copyright: OPEN CASCADE 2011
5
6#include <OpenGl_Display.hxx>
7
8#include <TCollection_AsciiString.hxx>
9#include <TCollection_HAsciiString.hxx>
10
11#include <OpenGl_FontMgr.hxx>
12
13#include <OpenGl_AspectText.hxx>
14
15#ifdef HAVE_GL2PS
16#include <gl2ps.h>
17#endif
18
19/*-----------------------------------------------------------------------------*/
20/*
21* Prototypes variables statiques
22*/
23
24struct FontMapNode
25{
26 const char * EnumName;
27 const char * FontName;
28 OSD_FontAspect FontAspect;
29};
30
31static const FontMapNode myFontMap[] =
32{
33
34#ifdef WNT
35
36 { "Courier" , "Courier New" , OSD_FA_Regular },
37 { "Times-Roman" , "Times New Roman", OSD_FA_Regular },
38 { "Times-Bold" , "Times New Roman", OSD_FA_Bold },
39 { "Times-Italic" , "Times New Roman", OSD_FA_Italic },
40 { "Times-BoldItalic" , "Times New Roman", OSD_FA_BoldItalic },
41 { "ZapfChancery-MediumItalic", "Script" , OSD_FA_Regular },
42 { "Symbol" , "Symbol" , OSD_FA_Regular },
43 { "ZapfDingbats" , "WingDings" , OSD_FA_Regular },
44 { "Rock" , "Arial" , OSD_FA_Regular },
45 { "Iris" , "Lucida Console" , OSD_FA_Regular }
46
47#else //X11
48
49 { "Courier" , "Courier" , OSD_FA_Regular },
50 { "Times-Roman" , "Times" , OSD_FA_Regular },
51 { "Times-Bold" , "Times" , OSD_FA_Bold },
52 { "Times-Italic" , "Times" , OSD_FA_Italic },
53 { "Times-BoldItalic" , "Times" , OSD_FA_BoldItalic },
54 { "Arial" , "Helvetica" , OSD_FA_Regular },
55 { "ZapfChancery-MediumItalic", "-adobe-itc zapf chancery-medium-i-normal--*-*-*-*-*-*-iso8859-1" , OSD_FA_Regular },
56 { "Symbol" , "-adobe-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific" , OSD_FA_Regular },
57 { "ZapfDingbats" , "-adobe-itc zapf dingbats-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific" , OSD_FA_Regular },
58 { "Rock" , "-sgi-rock-medium-r-normal--*-*-*-*-p-*-iso8859-1" , OSD_FA_Regular },
59 { "Iris" , "--iris-medium-r-normal--*-*-*-*-m-*-iso8859-1" , OSD_FA_Regular }
60#endif
61
62};
63
64#define NUM_FONT_ENTRIES (sizeof(myFontMap)/sizeof(FontMapNode))
65
66/*-----------------------------------------------------------------------------*/
67
68/*
69* Constants
70*/
71
72#ifdef HAVE_GL2PS
73void OpenGl_Display::getGL2PSFontName (const char *src_font, char *ps_font)
74{
75 /*
76 Convert font name used for rendering to some "good" font names
77 that produce good vector text
78 */
79 static char const *family[] = {"Helvetica", "Courier", "Times"};
80 static char const *italic[] = {"Oblique", "Oblique", "Italic"};
81 static char const *base[] = {"", "", "-Roman"};
82
83 int font = 0;
84 int isBold = 0;
85 int isItalic = 0;
86
87 if( strstr( src_font, "Symbol" ) ){
88 sprintf( ps_font, "%s", "Symbol" );
89 return;
90 }
91
92 if( strstr( src_font, "ZapfDingbats" ) ){
93 sprintf( ps_font, "%s", "WingDings" );
94 return;
95 }
96
97 if ( strstr( src_font, "Courier" ) ){
98 font = 1;
99 }
100 else if ( strstr( src_font, "Times" ) ){
101 font = 2;
102 }
103
104 if ( strstr( src_font, "Bold" ) ){
105 isBold = 1;
106 }
107
108 if ( strstr( src_font, "Italic" ) || strstr( src_font, "Oblique" ) ){
109 isItalic = 1;
110 }
111
112 if ( isBold ){
113 sprintf( ps_font, "%s-%s", family[font], "Bold");
114 if ( isItalic ){
115 sprintf(ps_font, "%s%s", ps_font, italic[font]);
116 }
117 }
118 else if ( isItalic )
119 {
120 sprintf( ps_font, "%s-%s", family[font], italic[font] );
121 }
122 else
123 {
124 sprintf( ps_font, "%s%s", family[font], base[font] );
125 }
126}
127#endif
128
129/*-----------------------------------------------------------------------------*/
130
131/*
132* Fonctions publiques
133*/
134
135/*-----------------------------------------------------------------------------*/
136
137int OpenGl_Display::FindFont (const char* AFontName, const OSD_FontAspect AFontAspect,
138 const int ABestSize, const float AXScale, const float AYScale)
139{
140 if (!AFontName)
141 return -1;
142
143 if (ABestSize != -1)
144 myFontSize = ABestSize;
145
146 OpenGl_FontMgr* mgr = OpenGl_FontMgr::instance();
147
148 Handle(TCollection_HAsciiString) family_name = new TCollection_HAsciiString(AFontName);
149 myFont = mgr->request_font( family_name, AFontAspect, myFontSize );
150
151 if( myFont == -1 )
152 {
153 //try to use font names mapping
154 FontMapNode newTempFont = myFontMap[0];
155 for ( int i = 0; i < NUM_FONT_ENTRIES; ++i )
156 {
157 if ( TCollection_AsciiString(myFontMap[i].EnumName).IsEqual( family_name->ToCString() ) )
158 {
159 newTempFont = myFontMap[i];
160 break;
161 }
162 }
163 family_name = new TCollection_HAsciiString(newTempFont.FontName);
164 myFont = mgr->request_font( family_name, newTempFont.FontAspect, myFontSize );
165 }
166
167 // Requested family name not found -> serach for any font family with given aspect and height
168 if ( myFont == -1 )
169 {
170 family_name = new TCollection_HAsciiString( "" );
171 myFont = mgr->request_font( family_name, AFontAspect, myFontSize );
172 }
173
174 // The last resort: trying to use ANY font available in the system
175 if ( myFont == -1 )
176 {
177 myFont = mgr->request_font( family_name, OSD_FA_Undefined, -1 );
178 }
179
180 if ( myFont != -1 )
181 mgr->setCurrentScale( AXScale, AYScale );
182
183 return myFont;
184}
185
186/*-----------------------------------------------------------------------------*/
187
188void OpenGl_Display::StringSize (const wchar_t *str, int &width, int &ascent, int &descent)
189{
190 ascent = 0;
191 descent = 0;
192 width = 0;
193 if (myFont != -1) {
194 OpenGl_FontMgr* mgr = OpenGl_FontMgr::instance();
195 const FTFont* font = mgr->fontById( myFont );
196 if ( font ) {
197 width = int( mgr->computeWidth( myFont, str ) );
198 ascent = int( font->Ascender() );
199 descent = int( font->Descender() );
200 }
201 }
202}
203
204/*-----------------------------------------------------------------------------*/
205
206void OpenGl_Display::RenderText (const wchar_t* str, const int is2d, const float x, const float y, const float z,
207 const OpenGl_AspectText *aspect, const OpenGl_TextParam *param)
208{
209 OpenGl_FontMgr* mgr = OpenGl_FontMgr::instance();
210 const FTFont* fnt = mgr->fontById( myFont );
211 if ( !fnt )
212 return;
213
214 // FTFont changes texture state when it renders and computes size for the text
215 glPushAttrib(GL_TEXTURE_BIT);
216
217 int widthFont, ascentFont, descentFont;
218 StringSize( str, widthFont, ascentFont, descentFont );
219
220 GLdouble xdis = 0.;
221 switch (param->HAlign)
222 {
223 case Graphic3d_HTA_CENTER:
224 xdis = -0.5 * (GLdouble)widthFont;
225 break;
226 case Graphic3d_HTA_RIGHT:
227 xdis = -(GLdouble)widthFont;
228 break;
229 //case Graphic3d_HTA_LEFT:
230 //default: break;
231 }
232 GLdouble ydis = 0.;
233 switch (param->VAlign)
234 {
235 case Graphic3d_VTA_CENTER:
236 ydis = -0.5 * (GLdouble)ascentFont - descentFont;
237 break;
238 case Graphic3d_VTA_TOP:
239 ydis = -(GLdouble)ascentFont - descentFont;
240 break;
241 //case Graphic3d_VTA_BOTTOM:
242 //default: break;
243 }
244
245 float export_h = 1.;
246
247 glMatrixMode(GL_MODELVIEW);
248 glPushMatrix();
249 if (is2d)
250 {
251 glLoadIdentity();
252 glTranslatef(x, y, 0.f);
253 glRotatef( 180, 1, 0, 0 );
254 }
255 else
256 {
257 const GLdouble identityMatrix[4][4] =
258 {
259 {1.,0.,0.,0.},
260 {0.,1.,0.,0.},
261 {0.,0.,1.,0.},
262 {0.,0.,0.,1.}
263 };
264
265 GLdouble projMatrix[4][4], modelMatrix[4][4];
266 GLint viewport[4];
267
268 GLdouble wx, wy, wz;
269 GLdouble x1, y1, z1;
270 GLdouble x2, y2, z2;
271
272 glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble*)modelMatrix );
273 glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble*)projMatrix );
274 glGetIntegerv( GL_VIEWPORT, (GLint*)viewport );
275
276 gluProject( x, y, z,
277 (GLdouble*)modelMatrix,
278 (GLdouble*)projMatrix,
279 (GLint*)viewport,
280 &wx, &wy, &wz );
281 glLoadIdentity();
282 gluUnProject( wx, wy, wz,
283 (GLdouble*)identityMatrix, (GLdouble*)projMatrix, (GLint*)viewport,
284 &x1, &y1 , &z1 );
285
286 GLdouble h = (GLdouble)fnt->FaceSize();
287
288 gluUnProject( wx, wy + h - 1., wz,
289 (GLdouble*)identityMatrix, (GLdouble*)projMatrix, (GLint*)viewport,
290 &x2, &y2, &z2 );
291
292 h = (y2-y1)/h;
293
294 glTranslated( x1, y1 , z1 );
295 glRotated(aspect->Angle(), 0, 0, 1);
296 glTranslated(xdis, ydis, 0);
297
298 if( !aspect->IsZoomable() )
299 {
300 glScaled( h, h, h );
301 }
302 else
303 {
304 export_h = (float )h;
305 }
306 }
307
308 GLint renderMode;
309 glGetIntegerv(GL_RENDER_MODE, &renderMode);
310 if ( renderMode == GL_FEEDBACK )
311 {
312#ifdef HAVE_GL2PS
c320e557 313 export_h = (float)fnt->FaceSize() / export_h;
2166f0fa 314 glPopMatrix();
c320e557 315 ExportText( str, is2d, x, y, z, aspect, param, (short)export_h );
2166f0fa
SK
316#endif
317 }
318 else
319 {
320 mgr->render_text( myFont, str, is2d );
321 glPopMatrix();
322 }
323 glPopAttrib();
324}
325
326/*-----------------------------------------------------------------------------*/
327
328static const int alignmentforgl2ps[3][3] = { {5,2,8}, {4,1,7}, {6,3,9} };
329
330void OpenGl_Display::ExportText (const wchar_t* text, const int is2d, const float x, const float y, const float z,
c320e557 331 const OpenGl_AspectText *aspect, const OpenGl_TextParam *param, const short height)
2166f0fa
SK
332{
333#ifdef HAVE_GL2PS
334
335 int vh = 1;
336 switch (param->HAlign)
337 {
338 case Graphic3d_HTA_CENTER: vh = 2; break;
339 case Graphic3d_HTA_RIGHT: vh = 3; break;
340 //case Graphic3d_HTA_LEFT:
341 //default: break;
342 }
343
344 int vv = 1;
345 switch (param->VAlign)
346 {
347 case Graphic3d_VTA_CENTER: vv = 2; break;
348 case Graphic3d_VTA_TOP: vv = 3; break;
349 //case Graphic3d_VTA_BOTTOM:
350 //default: break;
351 }
352
353 const int alignment = alignmentforgl2ps[vh-1][vv-1];
354
355 const char* fontname = aspect->Font();
356 float angle = aspect->Angle();
357
358 GLubyte zero = 0;
359 char ps_font[64];
360
361 getGL2PSFontName(fontname, ps_font);
362
363 if( is2d )
364 glRasterPos2f( x, y );
365 else
366 glRasterPos3f( x, y, z );
367
368 glBitmap( 1, 1, 0, 0, 0, 0, &zero );
369
370 //szv: workaround for gl2ps!
371 const int len = 4 * (wcslen(text) + 1); //szv: should be more than enough
372 char *astr = new char[len];
373 wcstombs(astr,text,len);
374 gl2psTextOpt(astr, ps_font, height, alignment, angle);
375 delete[] astr;
376
377#endif
378}