Salome HOME
ece5017e4b6c3d014a26e7a56e66ea6083323186
[modules/gui.git] / src / GLViewer / GLViewer_Drawer.cxx
1 // File:      GLViewer_Drawer.cxx
2 // Created:   November, 2004
3 // Author:    OCC team
4 // Copyright (C) CEA 2004
5
6 /***************************************************************************
7 **  Class:   GLViewer_Drawer
8 **  Descr:   Drawer for GLViewer_Object
9 **  Module:  GLViewer
10 **  Created: UI team, 01.10.01
11 ****************************************************************************/
12
13 #include "GLViewer_Drawer.h"
14 #include "GLViewer_Object.h"
15 #include "GLViewer_ViewFrame.h"
16 #include "GLViewer_ViewPort2d.h"
17
18 //#include "OSD_Timer.hxx"
19
20 #ifndef WIN32
21 #include <GL/glx.h>
22 #endif
23
24 //#include <qdir.h>
25 //-----------
26 #include <qpixmap.h>
27 #include <qimage.h>
28 #include <qfontmetrics.h>
29 #include <qpainter.h>
30 //-----------
31
32 #include <string>
33 #include <utility>
34 //#include "QAD_TMFont.h"
35 //using namespace qad_tmfont;
36
37 static int FirstSymbolNumber = 32;
38 static int LastSymbolNumber = 127;
39 //int GLViewer_TexFont::LastmyTexStoredId = 0;
40 QMap<GLViewer_TexFindId,GLViewer_TexIdStored> GLViewer_TexFont::TexFontBase; 
41
42 // Next line should be commented, if tex-mapped fonts are completely well
43 // and should be used instead of bitmap ones
44 #define DEB_TEX_FONT
45
46 /***************************************************************************
47 **  Class:   GLViewer_TexFont
48 **  Descr:   Texture Font for GLViewer_Object
49 **  Module:  GLViewer
50 **  Created: UI team, 01.10.01
51 ****************************************************************************/
52 GLViewer_TexFont::GLViewer_TexFont()
53 {
54     myQFont = QFont::defaultFont();
55     QFontMetrics aFM( myQFont );        
56     myWidths = new int[LastSymbolNumber - FirstSymbolNumber+1];
57     myPositions = new int[LastSymbolNumber - FirstSymbolNumber+1];
58     mySeparator = 2;
59     for( int k = FirstSymbolNumber, aWidth = 0; k <= LastSymbolNumber; k++ )
60     {
61       //char aLetter = (char)k;
62         myWidths[ k - FirstSymbolNumber ] = aFM.width( k );
63         myPositions[ k - FirstSymbolNumber ] = aWidth;
64         aWidth += myWidths[ k - FirstSymbolNumber ] + 2;//mySeparator;
65     }
66
67     myTexFontWidth = 0;
68     myTexFontHeight = 0;        
69 }
70
71 GLViewer_TexFont::GLViewer_TexFont( QFont* theFont, int theSeparator )
72 {
73     myQFont = *theFont;
74     QFontMetrics aFM( myQFont );        
75     myWidths = new int[LastSymbolNumber - FirstSymbolNumber+1];
76     myPositions = new int[LastSymbolNumber - FirstSymbolNumber+1];
77     mySeparator = theSeparator;
78     for( int k = FirstSymbolNumber, aWidth = 0; k <= LastSymbolNumber; k++ )
79     {
80       //char aLetter = (char)k;
81         myWidths[ k - FirstSymbolNumber ] = aFM.width( k );
82         myPositions[ k - FirstSymbolNumber ] = aWidth;
83         aWidth += myWidths[ k - FirstSymbolNumber ] + 2;//mySeparator;
84     }
85
86     myTexFontWidth = 0;
87     myTexFontHeight = 0;
88     
89 }
90
91 GLViewer_TexFont::~GLViewer_TexFont()
92 {
93     //delete myQFont;
94     delete[] myWidths;
95     delete[] myPositions;
96     //glDeleteTextures( 1, &myTexFont );
97 }   
98
99 void GLViewer_TexFont::generateTexture()
100 {
101     QFontMetrics aFM( myQFont );
102     //QString aFontStr = myQFont.toString();
103     //QGLContext aContext = QGLContext::currentContext();
104
105     GLViewer_TexFindId aFindFont;
106     aFindFont.myFontString = myQFont.toString();
107     aFindFont.myViewPortId = (int)QGLContext::currentContext();
108         
109     if( TexFontBase.contains( aFindFont ) )
110     {
111         GLViewer_TexIdStored aTexture = TexFontBase[ aFindFont ];
112         myTexFont = aTexture.myTexFontId;
113         myTexFontWidth = aTexture.myTexFontWidth;
114         myTexFontHeight = aTexture.myTexFontHeight;
115         //cout << "No generating " <<  myTexFont << "; current context " <<  QGLContext::currentContext()<< endl;
116     }    
117     else    
118     {
119         //cout << "Is generating! current context " <<  QGLContext::currentContext() << endl;
120         
121         QString aStr;
122         int pixelsWidth = 0;
123         int pixelsHight = aFM.height();
124         myTexFontWidth = 64;
125         myTexFontHeight = 64;
126     
127         pixelsWidth = myWidths[LastSymbolNumber - FirstSymbolNumber] + 
128                       myPositions[LastSymbolNumber - FirstSymbolNumber];
129
130         while( myTexFontWidth < pixelsWidth )
131             myTexFontWidth = myTexFontWidth * 2;
132         while( myTexFontHeight < pixelsHight )
133             myTexFontHeight = myTexFontHeight * 2;
134
135         QPixmap aPixmap( myTexFontWidth, myTexFontHeight );
136         aPixmap.fill( QColor( 0, 0, 0) );
137         QPainter aPainter( &aPixmap );
138         aPainter.setFont( myQFont );
139         for( int l = 0/*, gap = 0*/; l < LastSymbolNumber - FirstSymbolNumber; l++  )
140         {
141             QString aLetter;
142             aLetter += (char)(FirstSymbolNumber + l);
143             aPainter.setPen( QColor( 255,255,255) );
144             aPainter.drawText ( /*gap*/myPositions[l], pixelsHight, aLetter );
145             //gap += myWidths[l] + 2;
146         }
147     
148         QImage aImage = aPixmap.convertToImage();
149         //aImage.save( "c:/work/CATHARE/pic.bmp", "BMP");
150
151         char* pixels = new char[myTexFontWidth * myTexFontHeight * 2];
152
153         for( int i = 0; i < myTexFontHeight; i++ )
154         {            
155             for( int j = 0; j < myTexFontWidth;  j++ )
156             {
157                 int aRed = qRed( aImage.pixel( j, myTexFontHeight - i - 1 ) );
158                 int aGreen = qGreen( aImage.pixel( j, myTexFontHeight - i - 1 ) );
159                 int aBlue = qBlue( aImage.pixel( j, myTexFontHeight - i - 1 ) );
160           
161                 if( aRed != 0 || aGreen != 0 || aBlue != 0 )
162                 {
163                     pixels[i * myTexFontWidth * 2 + j * 2] = (GLubyte)( (aRed + aGreen + aBlue)/3 );
164                     pixels[i * myTexFontWidth * 2 + j * 2 + 1]= (GLubyte) 255;
165                 }
166                 else
167                 {
168                     pixels[i * myTexFontWidth * 2 + j * 2] = (GLubyte) 0;
169                     pixels[i * myTexFontWidth * 2 + j * 2 + 1]= (GLubyte) 0;
170                 }                
171             }
172         }
173
174         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
175         glGenTextures(1, &myTexFont);
176         glBindTexture(GL_TEXTURE_2D, myTexFont);  
177         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
178         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
179         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
180         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
181         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
182         glTexImage2D(GL_TEXTURE_2D, 0, 2, myTexFontWidth,
183             myTexFontHeight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pixels);
184     
185         delete[] pixels;
186         
187         GLViewer_TexIdStored aTexture;
188         aTexture.myTexFontId = myTexFont;
189         aTexture.myTexFontWidth = myTexFontWidth;
190         aTexture.myTexFontHeight = myTexFontHeight;
191
192         TexFontBase.insert( aFindFont, aTexture );
193     }
194 }
195
196 void GLViewer_TexFont::drawString( QString theStr, GLdouble theX , GLdouble theY )
197 {
198     glEnable(GL_TEXTURE_2D);
199     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
200     glPixelTransferi(GL_MAP_COLOR, 0);
201     glAlphaFunc(GL_GEQUAL, 0.5F);
202     glEnable(GL_ALPHA_TEST);
203     glBindTexture(GL_TEXTURE_2D, myTexFont);
204     glBegin(GL_QUADS);
205
206     QFontMetrics aFM( myQFont );
207     int pixelsHeight = aFM.height();
208
209     theY = theY - myTexFontHeight + pixelsHeight;
210
211     for( int i = 0, aGap = 0; i < theStr.length(); i++ )
212     {
213         char aLetter = theStr.data()[i];
214         int aLettIndex = (int)aLetter - FirstSymbolNumber;
215
216         float aLettBegin = (float)myPositions[aLettIndex];
217         float aLettEnd = aLettBegin + myWidths[aLettIndex]-1;
218
219         aLettBegin = aLettBegin / myTexFontWidth;
220         aLettEnd = aLettEnd / myTexFontWidth;
221
222         glTexCoord2f( aLettBegin, 0.0 ); glVertex3f( theX + aGap, theY, 1.0 );
223         glTexCoord2f( aLettBegin, 1.0 ); glVertex3f( theX + aGap, theY + myTexFontHeight, 1.0 );
224         glTexCoord2f( aLettEnd, 1.0 ); glVertex3f( theX + aGap + myWidths[aLettIndex]-1, theY + myTexFontHeight, 1.0 );
225         glTexCoord2f( aLettEnd, 0.0 ); glVertex3f( theX + aGap + myWidths[aLettIndex]-1, theY, 1.0 );
226
227         aGap += myWidths[aLettIndex]-1 + mySeparator;
228     }
229
230     //cout << "the down:" << theY << endl;
231     //cout << "the top:" << theY + myTexFontHeight << endl;
232     //cout << "the text height: " <<  pixelsHeight << endl;
233
234
235     glEnd();
236     glDisable(GL_ALPHA_TEST);
237     glDisable(GL_TEXTURE_2D);
238 }
239
240 int GLViewer_TexFont::getStringWidth( QString theStr )
241 {
242     int aWidth = 0;
243     for( int i = 0; i < theStr.length(); i ++ )
244     {
245         char aLetter = theStr.data()[i];
246         int aLettIndex = (int)aLetter - FirstSymbolNumber;
247         aWidth += myWidths[aLettIndex] + mySeparator;
248     }
249
250     return aWidth;
251 }
252
253 int GLViewer_TexFont::getStringHeight()
254 {
255     QFontMetrics aFM( myQFont );
256     return aFM.height();
257 }
258
259 void GLViewer_Drawer::destroyAllTextures()
260 {
261     //int aCount = GLViewer_TexFont::TexFontBase.count();
262     QMap<GLViewer_TexFindId,GLViewer_TexIdStored>::Iterator anIt= GLViewer_TexFont::TexFontBase.begin();
263     QMap<GLViewer_TexFindId,GLViewer_TexIdStored>::Iterator anEndIt= GLViewer_TexFont::TexFontBase.end();
264
265     for( ; anIt != anEndIt; anIt++ )
266         glDeleteTextures( 1, &(anIt.data().myTexFontId) );
267 }
268
269 #define TEXTURE
270
271 #define TEXT_GAP    5
272
273 #ifdef TEXTURE
274 //QAD_TMFont myTMFont;
275     GLboolean TFLoaded = GL_FALSE;
276
277     GLdouble        modelMatrix[16], projMatrix[16];
278     GLint           viewport[4];
279     GLdouble        winx, winy, winz;
280     GLint           status;
281
282     GLViewer_TexFont*  staticGlFont;
283
284 void printOrtho(GLdouble x, GLdouble y, const char *string, int set, GLdouble w, GLdouble h)
285 {
286 //  int width, heigth;
287     if (set>1)
288     {
289         set=1;
290     }
291 //d glDisable(GL_DEPTH_TEST);
292     glMatrixMode(GL_PROJECTION);
293     glPushMatrix();
294     glLoadIdentity();
295     glOrtho(0,w,0,h,-100,100);
296     glMatrixMode(GL_MODELVIEW);
297     glPushMatrix();
298     glLoadIdentity();
299
300 /* //--------abd 
301     myTMFont.Begin();
302     myTMFont.DrawString( string, x, y );
303   //--------abd */
304     staticGlFont->drawString( string, x, y );
305
306 /*  width = myTMFont.GetStringWidth( string );
307     heigth = myTMFont.GetStringHeight( string );
308     cout << "W=" << width << " H=" << heigth << endl;
309 */
310     glMatrixMode(GL_PROJECTION);
311     glPopMatrix();
312     glMatrixMode(GL_MODELVIEW);
313     glPopMatrix();
314 //d glEnable(GL_DEPTH_TEST);
315 }
316
317 void loadGLfont(/*int scalar*/)
318 {
319     if (!TFLoaded)
320     {
321 /*  //-------abd 
322         QString filename = getenv( "CSF_QADResources" );
323         filename = filename + QDir::separator() + "times.tmf";
324         if (!myTMFont.Create( filename, 19436))
325         {
326             cout << "!Texture loading error" << endl;
327             return;
328         }
329  //-------abd */
330         staticGlFont = new GLViewer_TexFont();
331         staticGlFont->generateTexture();
332         
333         TFLoaded = GL_TRUE;
334 //!     BuildFont(size);
335     }
336 }
337
338 static GLuint displayListBase( QFont* theFont )
339 {
340   GLuint aList = 0;
341   static QMap<GLViewer_TexFindId, GLuint> fontCache;
342   GLViewer_TexFindId aFindFont;
343   aFindFont.myFontString = theFont->toString();
344
345 #ifdef WIN32
346   HGLRC ctx = ::wglGetCurrentContext();
347   if ( !ctx )
348     return aList;  
349   
350   aFindFont.myViewPortId = (int)ctx;
351
352   if ( fontCache.contains( aFindFont ) )
353     aList = fontCache[aFindFont];
354   else
355   {
356     GLuint listBase = 0;
357     QMap<GLViewer_TexFindId, GLuint>::iterator it = fontCache.begin();
358     for ( ; it != fontCache.end(); ++it )
359     {
360       if ( it.key().myViewPortId == (int)ctx && it.data() > listBase )
361         listBase = it.data();
362     }
363     listBase += 256;
364
365     HDC glHdc = ::wglGetCurrentDC();
366     ::SelectObject( glHdc, theFont->handle() );
367     if ( !::wglUseFontBitmaps( glHdc, 0, 256, listBase ) )
368       listBase = 0;
369     aList = listBase;
370     fontCache[aFindFont] = aList;
371   }
372 #else //X Window
373   Display* aDisp = glXGetCurrentDisplay();
374   if( !aDisp )
375   {
376     printf( "Can't find current dislay\n" );
377     return aList;
378   }
379   
380   GLXContext aCont = glXGetCurrentContext();
381   if( !aCont )
382   {
383     printf( "Can't find current context\n" );
384     return aList;
385   }
386
387   aFindFont.myViewPortId = (int)aCont;
388
389   if ( fontCache.contains( aFindFont ) )
390     aList = fontCache[aFindFont];
391   else
392   {
393     GLuint listBase = 0;
394     QMap<GLViewer_TexFindId, GLuint>::iterator it = fontCache.begin();
395     for ( ; it != fontCache.end(); ++it )
396     {
397       if ( it.key().myViewPortId == (int)aCont && it.data() > listBase )
398         listBase = it.data();
399     }
400     listBase += 256;
401
402     glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase );
403
404     aList = listBase;
405     fontCache[aFindFont] = aList;
406   }
407
408 #endif
409
410   return aList;
411 }
412
413 /***************************************************************************
414 **  Class:   GLViewer_Drawer
415 **  Descr:   Drawer for GLViewer_Object
416 **  Module:  GLViewer
417 **  Created: UI team, 01.10.01
418 ****************************************************************************/
419 GLViewer_Drawer::GLViewer_Drawer()
420 {
421   myXScale = myYScale = 0.0;
422   myObjects.clear();
423   myTextList = -1;
424   myObjectType = "GLViewer_Object";
425 }
426
427 GLViewer_Drawer::~GLViewer_Drawer()
428 {
429   myObjects.clear();
430   glDeleteLists( myTextList, 1 );
431 }
432
433 void GLViewer_Drawer::drawText( const QString& text, GLfloat xPos, GLfloat yPos,
434                                 const QColor& color, QFont* theFont, int theSeparator, DisplayTextFormat theFormat )
435 {
436   if( theFormat == DTF_TEXTURE )
437   {
438     GLViewer_TexFont aTexFont( theFont, theSeparator );
439     aTexFont.generateTexture();
440
441     glGetIntegerv (GL_VIEWPORT, viewport);
442     glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
443     glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
444     status = gluProject (xPos, yPos, 0, modelMatrix, projMatrix, viewport, &winx, &winy, &winz);
445
446     glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT | GL_LIST_BIT );
447     glMatrixMode(GL_PROJECTION);
448     glPushMatrix();
449     glLoadIdentity();
450     glOrtho(0,viewport[2],0,viewport[3],-100,100);
451     glMatrixMode(GL_MODELVIEW);
452     glPushMatrix();
453     glLoadIdentity();
454
455     glColor3f( ( GLfloat )color.red() / 255, 
456                ( GLfloat )color.green() / 255, 
457                ( GLfloat )color.blue() / 255 );
458
459     aTexFont.drawString( text, winx, winy );
460
461     glPopMatrix();
462     glMatrixMode(GL_PROJECTION);
463     glPopMatrix();
464     glPopAttrib();
465   }
466   else if( theFormat == DTF_BITMAP )
467   {
468     glColor3f( ( GLfloat )color.red() / 255, 
469                ( GLfloat )color.green() / 255, 
470                ( GLfloat )color.blue() / 255 );
471     glRasterPos2f( xPos, yPos );
472     glListBase( displayListBase( theFont ) );
473     glCallLists( text.length(), GL_UNSIGNED_BYTE, text.local8Bit().data() );
474   }
475 }
476
477 #else //#ifdef BITMAP
478 GLuint fontOffset;
479
480 GLubyte space[] =
481     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
482
483 GLubyte letters[][13] = {
484     {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18},
485     {0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
486     {0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
487     {0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc},
488     {0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
489     {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff},
490     {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
491     {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
492     {0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e},
493     {0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06},
494     {0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3},
495     {0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
496     {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3},
497     {0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3},
498     {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e},
499     {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
500     {0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c},
501     {0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
502     {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e},
503     {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff},
504     {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
505     {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
506     {0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
507     {0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
508     {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
509     {0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff}
510 };
511
512 void makeRasterFont()
513 {
514   GLuint i, j;
515   glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
516
517   fontOffset = glGenLists( 128 );
518   for ( i = 0, j = 'A'; i < 26; i++, j++ )
519   {
520     glNewList( fontOffset + j, GL_COMPILE );
521     glBitmap( CHAR_W, CHAR_H, 0.0, 2.0, CHAR_W+WIDTH, 0.0, letters[i] );
522     glEndList();
523   }
524   glNewList( fontOffset + ' ', GL_COMPILE );
525   glBitmap( CHAR_W, CHAR_H, 0.0, 2.0, CHAR_W+WIDTH, 0.0, space );
526   glEndList();
527 }
528
529 void GLViewer_Drawer::drawText( const QString& text, int xPos, int yPos, const QColor& color, QFont theFont, int theSeparator )
530 {
531     glShadeModel( GL_FLAT );
532     makeRasterFont();
533
534     myTextList = glGenLists( 1 );
535     glNewList( myTextList, GL_COMPILE );
536     glColor3f( ( GLfloat )color.red() / 255, 
537                ( GLfloat )color.green() / 255, 
538                ( GLfloat )color.blue() / 255 );
539     glRasterPos2i( xPos + TEXT_GAP / myXScale, yPos + TEXT_GAP / myYScale );
540     printString( text );
541     glEndList();
542
543     if ( myTextList != -1 ) 
544         glCallList( myTextList );
545 }
546 #endif //BITMAP
547
548 void GLViewer_Drawer::drawText( GLViewer_Object* theObject )
549 {
550   if( !theObject )
551     return;
552
553   GLViewer_Text* aText = theObject->getGLText();
554   if( !aText )
555     return;
556
557   GLfloat aPosX, aPosY;
558   aText->getPosition( aPosX, aPosY );
559   drawText( aText->getText(), aPosX, aPosY, aText->getColor(), &(aText->getFont()), aText->getSeparator(), aText->getDisplayTextFormat() );
560 }
561
562 bool GLViewer_Drawer::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
563 {
564     bool result = true;
565     for( int i=0, n=myObjects.count(); i<n; i++ ) 
566         result &= myObjects[i]->translateToHPGL( hFile, aViewerCS, aHPGLCS );
567     return result;
568 }
569
570 bool GLViewer_Drawer::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
571 {
572     bool result = true;
573     for( int i=0, n=myObjects.count(); i<n; i++ ) 
574         result &= myObjects[i]->translateToPS( hFile, aViewerCS, aPSCS );
575     return result;
576 }
577
578 #ifdef WIN32
579 bool GLViewer_Drawer::translateToEMF( HDC hDC, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
580 {
581     bool result = true;
582     for( int i=0, n=myObjects.count(); i<n; i++ ) 
583         result &= myObjects[i]->translateToEMF( hDC, aViewerCS, aEMFCS );
584     return result;
585 }
586 #endif
587
588 /***************************************************************************
589 **  Class:   GLViewer_MarkerDrawer
590 **  Descr:   Drawer for GLViewer_MarkerSet
591 **  Module:  GLViewer
592 **  Created: UI team, 03.10.01
593 ****************************************************************************/
594 #define SEGMENTS   20
595 #define STEP       2 * PI / SEGMENTS
596
597 GLfloat sin_table[SEGMENTS];
598 GLfloat cos_table[SEGMENTS];
599
600 GLViewer_MarkerDrawer::GLViewer_MarkerDrawer()
601 : GLViewer_Drawer()
602 {
603     GLfloat angle = 0.0;
604     for ( int i = 0; i < SEGMENTS; i++ )
605     {
606         sin_table[i] = sin( angle );
607         cos_table[i] = cos( angle );
608         angle += float( STEP );
609     }
610     myTextList = 0;//-1; 
611     myObjectType = "GLViewer_MarkerSet";
612 }
613
614 GLViewer_MarkerDrawer::~GLViewer_MarkerDrawer()
615 {
616     glDeleteLists( myTextList, 1 );
617 }
618
619 void GLViewer_MarkerDrawer::create( float xScale, float yScale, bool onlyUpdate )
620 {
621 //  cout << "GLViewer_MarkerDrawer::create " << scaleX << " " << scaleY << endl;
622
623     QValueList<int>::Iterator it;
624     QValueList<int>::Iterator EndIt;
625     QValueList<GLViewer_Object*>::Iterator anObjectIt = myObjects.begin();
626     QValueList<GLViewer_Object*>::Iterator anEndObjectIt = myObjects.end();
627
628     myXScale = xScale;
629     myYScale = yScale;
630
631     QColor colorN, colorH, colorS;
632
633     GLViewer_MarkerSet* aMarkerSet = NULL;
634     GLViewer_AspectLine* anAspectLine = NULL;
635
636     for( ; anObjectIt != anEndObjectIt; anObjectIt++ )
637     {
638         aMarkerSet = ( GLViewer_MarkerSet* )(*anObjectIt);
639         anAspectLine = aMarkerSet->getAspectLine();
640         anAspectLine->getLineColors( colorN, colorH, colorS );
641
642         float* aXCoord = aMarkerSet->getXCoord();
643         float* anYCoord = aMarkerSet->getYCoord();
644         float aRadius = aMarkerSet->getMarkerSize();
645
646         QValueList<int> aHNumbers, anUHNumbers, aSelNumbers, anUSelNumbers;
647         aMarkerSet->exportNumbers( aHNumbers, anUHNumbers, aSelNumbers, anUSelNumbers );
648
649         if( onlyUpdate )
650         {
651             EndIt = anUHNumbers.end();
652             for( it = anUHNumbers.begin(); it != EndIt; ++it )
653             {
654                 drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorN, anAspectLine );
655                 //cout << "GLViewer_MarkerDrawer::create UH " << *it << endl;
656             }
657
658             EndIt = anUSelNumbers.end();
659             for( it = anUSelNumbers.begin(); it != EndIt; ++it )
660                 drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorN, anAspectLine );
661
662             EndIt = aSelNumbers.end();
663             for( it = aSelNumbers.begin(); it != EndIt; ++it )
664                 drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorS, anAspectLine );
665
666             EndIt = aHNumbers.end();
667             for( it = aHNumbers.begin(); it != EndIt; ++it )
668             {
669                 drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorH, anAspectLine );
670                 //cout << "GLViewer_MarkerDrawer::create H " << *it << endl;
671             }
672         }
673         else
674         {
675             int aNumber = aMarkerSet->getNumMarkers();
676             for( int i = 0; i < aNumber; i++ )
677                 drawMarker( aXCoord[i], anYCoord[i], aRadius, colorN, anAspectLine );
678
679             EndIt = anUSelNumbers.end();
680             for( it = anUSelNumbers.begin(); it != EndIt; ++it )
681                 drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorN, anAspectLine );
682
683             EndIt = aSelNumbers.end();
684             for( it = aSelNumbers.begin(); it != EndIt; ++it )
685                 drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorS, anAspectLine );
686         }
687         //float aXPos = 0, anYPos = 0;
688         if( aMarkerSet->getGLText()->getText() != "" )
689         {
690             //float aXPos = 0, anYPos = 0;
691             //aMarkerSet->getGLText()->getPosition( aXPos, anYPos );
692             //drawText( aMarkerSet->getGLText()->getText(), aXPos, anYPos, colorN, &aMarkerSet->getGLText()->getFont(), aMarkerSet->getGLText()->getSeparator() );
693             drawText( aMarkerSet );
694         }
695     }
696 }
697
698 void GLViewer_MarkerDrawer::drawMarker( float& theXCoord, float& theYCoord,
699                                      float& theRadius, QColor& theColor, GLViewer_AspectLine* theAspectLine )
700 {
701     glColor3f( ( GLfloat )theColor.red() / 255, 
702                ( GLfloat )theColor.green() / 255, 
703                ( GLfloat )theColor.blue() / 255 );
704
705     glLineWidth( theAspectLine->getLineWidth() );
706
707     if ( theAspectLine->getLineType() == 0 )
708         glBegin( GL_LINE_LOOP );
709     else
710         glBegin( GL_LINE_STRIP);
711
712     for ( int i = 0; i < SEGMENTS; i++ )
713         glVertex2f( theXCoord + cos_table[i] * theRadius / myXScale,
714                     theYCoord + sin_table[i] * theRadius / myYScale );
715     glEnd();
716 }
717
718 /***************************************************************************
719 **  Class:   GLViewer_PolylineDrawer
720 **  Descr:   Drawer for GLViewer_Polyline
721 **  Module:  GLViewer
722 **  Created: UI team, 03.10.01
723 ****************************************************************************/
724
725 GLViewer_PolylineDrawer::GLViewer_PolylineDrawer()
726 :GLViewer_Drawer()
727 {
728   myTextList = 0;//-1; 
729     myObjects.clear();
730     myObjectType = "GLViewer_Polyline";
731 }
732
733 GLViewer_PolylineDrawer::~GLViewer_PolylineDrawer()
734 {
735     glDeleteLists( myTextList, 1 );
736 }
737
738 void GLViewer_PolylineDrawer::create( float xScale, float yScale, bool onlyUpdate )
739 {
740     QValueList<GLViewer_Object*>::Iterator aObjectIt = myObjects.begin();
741     QValueList<GLViewer_Object*>::Iterator aObjectEndIt = myObjects.end();
742     
743     myXScale = xScale;
744     myYScale = yScale;
745
746     QColor color, colorN, colorH, colorS;
747     GLViewer_AspectLine* anAspect = NULL;
748     GLViewer_Polyline* aPolyline = NULL;
749 //    myAspectLine->getLineColors( colorN, colorH, colorS );
750     for( ; aObjectIt != aObjectEndIt; aObjectIt++ )
751     {
752         anAspect = (*aObjectIt)->getAspectLine();
753         aPolyline = (GLViewer_Polyline*)(*aObjectIt);
754
755
756         anAspect->getLineColors( colorN, colorH, colorS );
757         if( onlyUpdate )
758         {
759             if( aPolyline->isHighlighted() )
760                 color = colorH;
761             else if( aPolyline->isSelected() )
762                 color = colorS;
763             else
764                 color = colorN;
765         }
766         else
767         {
768             if( aPolyline->isSelected() )
769                 color = colorS;
770             else
771                 color = colorN;
772         }
773
774         float* aXCoord = aPolyline->getXCoord();
775         float* anYCoord = aPolyline->getYCoord();
776         int aSize = aPolyline->getNumber();        
777
778         glColor3f( ( GLfloat )color.red() / 255, 
779                    ( GLfloat )color.green() / 255, 
780                    ( GLfloat )color.blue() / 255 );
781
782         glLineWidth( anAspect->getLineWidth() );
783
784         if ( anAspect->getLineType() == 0 )
785             glBegin( GL_LINE_LOOP );
786         else
787             glBegin( GL_LINE_STRIP);
788
789         for( int i = 0; i < aSize ; i++ )
790              glVertex2f( aXCoord[ i ], anYCoord[ i ] );        
791  
792         if( aPolyline->isClosed() )
793             glVertex2f( aXCoord[ 0 ], anYCoord[ 0 ] );
794
795         glEnd();       
796
797         if( aPolyline->getGLText()->getText() != "" )
798         {
799           //float aXPos = 0, anYPos = 0;
800           //aPolyline->getGLText()->getPosition( aXPos, anYPos );
801           //drawText( aPolyline->getGLText()->getText(), aXPos, anYPos, color, &aPolyline->getGLText()->getFont(), aPolyline->getGLText()->getSeparator() );
802           drawText( aPolyline );
803         }
804     }
805 }
806
807 /***************************************************************************
808 **  Class:   GLViewer_TextDrawer
809 **  Descr:   
810 **  Module:  GLViewer
811 **  Created: UI team, 27.02.04
812 ****************************************************************************/
813
814 GLViewer_TextDrawer::GLViewer_TextDrawer()
815 : GLViewer_Drawer()
816 {
817     myTextList = 0;//-1; 
818     myObjects.clear();
819     myObjectType = "GLViewer_TextObject";
820 }
821
822 GLViewer_TextDrawer::~GLViewer_TextDrawer()
823 {
824     glDeleteLists( myTextList, 1 );
825 }
826
827 void GLViewer_TextDrawer::create( float xScale, float yScale, bool onlyUpdate )
828 {
829     QValueList<GLViewer_Object*>::Iterator aObjectIt = myObjects.begin();
830     QValueList<GLViewer_Object*>::Iterator aObjectEndIt = myObjects.end();
831     
832     myXScale = xScale;
833     myYScale = yScale;
834
835     QColor color, colorN, colorH, colorS;
836     GLViewer_AspectLine* anAspect = NULL;    
837     GLViewer_TextObject* anObject = NULL;
838     //float aXPos = 0, anYPos = 0;
839     for( ; aObjectIt != aObjectEndIt; aObjectIt++ )
840     {
841         anObject = (GLViewer_TextObject*)(*aObjectIt);
842         anAspect = anObject->getAspectLine();    
843
844         anAspect->getLineColors( colorN, colorH, colorS );
845         if( onlyUpdate )
846         {
847             if( anObject->isHighlighted() )
848                 color = colorH;
849             else if( anObject->isSelected() )
850                 color = colorS;
851             else
852                 color = colorN;
853         }
854         else
855         {
856             if( anObject->isSelected() )
857                 color = colorS;
858             else
859                 color = colorN;
860         }        
861         
862         //anObject->getGLText()->getPosition( aXPos, anYPos );
863         //drawText( anObject->getGLText()->getText(), aXPos, anYPos, color, &(anObject->getGLText()->getFont()), anObject->getGLText()->getSeparator() );
864         drawText( anObject );
865     }
866 }
867
868 void GLViewer_TextDrawer::updateObjects()
869 {
870     QValueList<GLViewer_Object*>::Iterator aObjectIt = myObjects.begin();
871     QValueList<GLViewer_Object*>::Iterator aObjectEndIt = myObjects.end();
872     for( ; aObjectIt != aObjectEndIt; aObjectIt++ )
873         (*aObjectIt)->compute();
874 }