Salome HOME
Merge modifications for HYDRO project (origin/hydro/imps_2017 branch)
[modules/gui.git] / src / GLViewer / GLViewer_Drawer.cxx
index ece5017e4b6c3d014a26e7a56e66ea6083323186..13d5e8acbef14f0b6bbaffb3abc2e4e93ceba5ec 100644 (file)
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  Author : OPEN CASCADE
 // File:      GLViewer_Drawer.cxx
 // Created:   November, 2004
-// Author:    OCC team
-// Copyright (C) CEA 2004
-
-/***************************************************************************
-**  Class:   GLViewer_Drawer
-**  Descr:   Drawer for GLViewer_Object
-**  Module:  GLViewer
-**  Created: UI team, 01.10.01
-****************************************************************************/
-
+//#include <GLViewerAfx.h>
+//
 #include "GLViewer_Drawer.h"
 #include "GLViewer_Object.h"
+#include "GLViewer_Text.h"
 #include "GLViewer_ViewFrame.h"
 #include "GLViewer_ViewPort2d.h"
 
-//#include "OSD_Timer.hxx"
+#include <QApplication>
+#include <QImage>
+#include <QPainter>
+#include <QFile>
 
-#ifndef WIN32
+#if defined(__APPLE__)
+#include <OpenGL/CGLCurrent.h>
+#elif !defined(WIN32)
 #include <GL/glx.h>
 #endif
 
-//#include <qdir.h>
-//-----------
-#include <qpixmap.h>
-#include <qimage.h>
-#include <qfontmetrics.h>
-#include <qpainter.h>
-//-----------
+#include <gp_Pnt2d.hxx>
+
+#define TEXT_GAP    5
+// Two texture components for texmapped fonts: luminance and alpha
+#define NB_TEX_COMP 2
+// A font is split into rows each containing 32 characters
+#define TEX_ROW_LEN 32
+// Gap in pixels between two character rows in a font texture
+#define TEX_ROW_GAP 2
+
+GLfloat modelMatrix[16];
 
-#include <string>
-#include <utility>
-//#include "QAD_TMFont.h"
-//using namespace qad_tmfont;
 
+//! code of first font symbol
 static int FirstSymbolNumber = 32;
+//! code of last font symbol
 static int LastSymbolNumber = 127;
-//int GLViewer_TexFont::LastmyTexStoredId = 0;
-QMap<GLViewer_TexFindId,GLViewer_TexIdStored> GLViewer_TexFont::TexFontBase; 
-
-// Next line should be commented, if tex-mapped fonts are completely well
-// and should be used instead of bitmap ones
-#define DEB_TEX_FONT
-
-/***************************************************************************
-**  Class:   GLViewer_TexFont
-**  Descr:   Texture Font for GLViewer_Object
-**  Module:  GLViewer
-**  Created: UI team, 01.10.01
-****************************************************************************/
+
+QMap<GLViewer_TexFindId,GLViewer_TexIdStored> GLViewer_TexFont::TexFontBase;
+QMap<GLViewer_TexFindId,GLuint>               GLViewer_TexFont::BitmapFontCache; 
+
+/*!
+  Clears all generated fonts
+*/
+void GLViewer_TexFont::clearTextBases()
+{
+  //cout << "Clear font map" << endl;
+  TexFontBase.clear();
+  BitmapFontCache.clear();
+}
+
+/*!
+  Default constructor
+*/
 GLViewer_TexFont::GLViewer_TexFont()
+: myMaxRowWidth( 0 ), myFontHeight( 0 )
 {
-    myQFont = QFont::defaultFont();
-    QFontMetrics aFM( myQFont );        
-    myWidths = new int[LastSymbolNumber - FirstSymbolNumber+1];
-    myPositions = new int[LastSymbolNumber - FirstSymbolNumber+1];
+    myQFont = QApplication::font();//QFont::defaultFont();
     mySeparator = 2;
-    for( int k = FirstSymbolNumber, aWidth = 0; k <= LastSymbolNumber; k++ )
-    {
-      //char aLetter = (char)k;
-        myWidths[ k - FirstSymbolNumber ] = aFM.width( k );
-        myPositions[ k - FirstSymbolNumber ] = aWidth;
-        aWidth += myWidths[ k - FirstSymbolNumber ] + 2;//mySeparator;
-    }
+    myIsResizeable = false;
+    myMinMagFilter = GL_LINEAR;
 
-    myTexFontWidth = 0;
-    myTexFontHeight = 0;        
+    init();
 }
 
-GLViewer_TexFont::GLViewer_TexFont( QFont* theFont, int theSeparator )
+/*!
+  Constructor
+  \param theFont         - a base font
+  \param theSeparator    - separator between letters
+  \param theIsResizeable - specifies whether text drawn by this object can be scaled along with the scene
+  \param theMinMagFilter - min/mag filter, affects text sharpness
+*/
+GLViewer_TexFont::GLViewer_TexFont( QFont* theFont, int theSeparator, bool theIsResizeable, GLuint theMinMagFilter )
+: myMaxRowWidth( 0 ), myFontHeight( 0 )
 {
     myQFont = *theFont;
-    QFontMetrics aFM( myQFont );        
-    myWidths = new int[LastSymbolNumber - FirstSymbolNumber+1];
-    myPositions = new int[LastSymbolNumber - FirstSymbolNumber+1];
     mySeparator = theSeparator;
-    for( int k = FirstSymbolNumber, aWidth = 0; k <= LastSymbolNumber; k++ )
-    {
-      //char aLetter = (char)k;
-        myWidths[ k - FirstSymbolNumber ] = aFM.width( k );
-        myPositions[ k - FirstSymbolNumber ] = aWidth;
-        aWidth += myWidths[ k - FirstSymbolNumber ] + 2;//mySeparator;
-    }
+    myIsResizeable = theIsResizeable;
+    myMinMagFilter = theMinMagFilter;
 
-    myTexFontWidth = 0;
-    myTexFontHeight = 0;
-    
+    init();
 }
 
+/*!
+  Destructor
+*/
 GLViewer_TexFont::~GLViewer_TexFont()
 {
-    //delete myQFont;
     delete[] myWidths;
     delete[] myPositions;
-    //glDeleteTextures( 1, &myTexFont );
-}   
+} 
 
-void GLViewer_TexFont::generateTexture()
+/*!
+  Initializes font parameters
+*/
+void GLViewer_TexFont::init()
 {
-    QFontMetrics aFM( myQFont );
-    //QString aFontStr = myQFont.toString();
-    //QGLContext aContext = QGLContext::currentContext();
+    myNbSymbols = LastSymbolNumber - FirstSymbolNumber + 1;
+
+    // It is unsafe to draw all characters in a single row -
+    // this leads to problems on some graphic cards with small GL_MAX_TEXTURE_SIZE.
+    // So splitting the characters into rows each containing 32 characters (or less).
+    // Assuming contant height of each row (64 pixels) to simplify texture mapping.
+    // However, this can be improved if necessary.
+    QFontMetrics aFM( myQFont ); 
+    myFontHeight = aFM.height();
+    
+    myWidths    = new int[myNbSymbols];
+    myPositions = new int[myNbSymbols];
+
+    for( int i = 0, k = FirstSymbolNumber, aWidth = 0; i < myNbSymbols; i++, k++ )
+    {
+        // is it time to start a new row?
+        if ( !( i % TEX_ROW_LEN ) )
+        {
+          if( aWidth > myMaxRowWidth )
+            myMaxRowWidth = aWidth;
+          aWidth = 0;
+        }
+        myWidths[i]    = aFM.width( k );
+        myPositions[i] = aWidth;
+        aWidth += myWidths[i] + 2;
+    }
 
+    myTexFontWidth  = 0;
+    myTexFontHeight = 0;
+}
+  
+/*!
+  Generating font texture
+*/
+bool GLViewer_TexFont::generateTexture()
+{
     GLViewer_TexFindId aFindFont;
-    aFindFont.myFontString = myQFont.toString();
-    aFindFont.myViewPortId = (int)QGLContext::currentContext();
+    aFindFont.myFontFamily = myQFont.family();//myQFont.toString();
+    aFindFont.myIsBold = myQFont.bold();
+    aFindFont.myIsItal = myQFont.italic();
+    aFindFont.myIsUndl = myQFont.underline();
+    aFindFont.myPointSize = myQFont.pointSize();
+    aFindFont.myViewPortId = size_t(QGLContext::currentContext());
         
     if( TexFontBase.contains( aFindFont ) )
     {
@@ -112,43 +169,54 @@ void GLViewer_TexFont::generateTexture()
         myTexFont = aTexture.myTexFontId;
         myTexFontWidth = aTexture.myTexFontWidth;
         myTexFontHeight = aTexture.myTexFontHeight;
-        //cout << "No generating " <<  myTexFont << "; current context " <<  QGLContext::currentContext()<< endl;
     }    
     else    
     {
-        //cout << "Is generating! current context " <<  QGLContext::currentContext() << endl;
-        
-        QString aStr;
-        int pixelsWidth = 0;
-        int pixelsHight = aFM.height();
-        myTexFontWidth = 64;
+        // Adding some pixels to have a gap between rows
+        int aRowPixelHeight = myFontHeight + TEX_ROW_GAP;
+        int aDescent = QFontMetrics( myQFont ).descent();
+
+        int aNumRows = myNbSymbols / TEX_ROW_LEN;
+        if ( myNbSymbols % TEX_ROW_LEN ) 
+          aNumRows++;
+        int pixelsHight = aNumRows * aRowPixelHeight;
+
+        myTexFontWidth  = 64;
         myTexFontHeight = 64;
-    
-        pixelsWidth = myWidths[LastSymbolNumber - FirstSymbolNumber] + 
-                      myPositions[LastSymbolNumber - FirstSymbolNumber];
 
-        while( myTexFontWidth < pixelsWidth )
-            myTexFontWidth = myTexFontWidth * 2;
+        while( myTexFontWidth < myMaxRowWidth )
+            myTexFontWidth <<= 1;
         while( myTexFontHeight < pixelsHight )
-            myTexFontHeight = myTexFontHeight * 2;
+            myTexFontHeight <<= 1;
+        
+        // Checking whether the texture dimensions for the requested font
+        // do not exceed the maximum size supported by the OpenGL implementation
+        int maxSize;
+        glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxSize );
+        if ( myTexFontWidth > maxSize || myTexFontHeight > maxSize )
+          return false;
 
         QPixmap aPixmap( myTexFontWidth, myTexFontHeight );
         aPixmap.fill( QColor( 0, 0, 0) );
         QPainter aPainter( &aPixmap );
         aPainter.setFont( myQFont );
-       for( int l = 0/*, gap = 0*/; l < LastSymbolNumber - FirstSymbolNumber; l++  )
+        int row;
+        for( int l = 0; l < myNbSymbols; l++  )
         {
+            row = l / TEX_ROW_LEN;
             QString aLetter;
             aLetter += (char)(FirstSymbolNumber + l);
             aPainter.setPen( QColor( 255,255,255) );
-            aPainter.drawText ( /*gap*/myPositions[l], pixelsHight, aLetter );
-            //gap += myWidths[l] + 2;
+            aPainter.drawText( myPositions[l], ( row + 1 ) * aRowPixelHeight - aDescent, aLetter );
         }
     
-        QImage aImage = aPixmap.convertToImage();
-        //aImage.save( "c:/work/CATHARE/pic.bmp", "BMP");
+        QImage aImage = aPixmap.toImage();
+
+        //int qqq = 0;
+        //if (qqq)
+        //  aImage.save("w:\\work\\CATHARE\\texture.png", "PNG");
 
-        char* pixels = new char[myTexFontWidth * myTexFontHeight * 2];
+        char* pixels = new char[myTexFontWidth * myTexFontHeight * NB_TEX_COMP];
 
         for( int i = 0; i < myTexFontHeight; i++ )
         {            
@@ -160,13 +228,13 @@ void GLViewer_TexFont::generateTexture()
           
                 if( aRed != 0 || aGreen != 0 || aBlue != 0 )
                 {
-                    pixels[i * myTexFontWidth * 2 + j * 2] = (GLubyte)( (aRed + aGreen + aBlue)/3 );
-                    pixels[i * myTexFontWidth * 2 + j * 2 + 1]= (GLubyte) 255;
+                    pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP] = (GLubyte)( (aRed + aGreen + aBlue)/3 );
+                    pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP + 1]= (GLubyte) 255;
                 }
                 else
                 {
-                    pixels[i * myTexFontWidth * 2 + j * 2] = (GLubyte) 0;
-                    pixels[i * myTexFontWidth * 2 + j * 2 + 1]= (GLubyte) 0;
+                    pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP] = (GLubyte) 0;
+                    pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP + 1]= (GLubyte) 0;
                 }                
             }
         }
@@ -174,13 +242,17 @@ void GLViewer_TexFont::generateTexture()
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
         glGenTextures(1, &myTexFont);
         glBindTexture(GL_TEXTURE_2D, myTexFont);  
-        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-        glTexImage2D(GL_TEXTURE_2D, 0, 2, myTexFontWidth,
-            myTexFontHeight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pixels);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myMinMagFilter);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myMinMagFilter);
+        glTexImage2D(GL_TEXTURE_2D, 
+                     0, 
+                     GL_INTENSITY, 
+                     myTexFontWidth,
+                     myTexFontHeight, 
+                     0, 
+                     GL_LUMINANCE_ALPHA, 
+                     GL_UNSIGNED_BYTE, 
+                     pixels);
     
         delete[] pixels;
         
@@ -191,58 +263,90 @@ void GLViewer_TexFont::generateTexture()
 
         TexFontBase.insert( aFindFont, aTexture );
     }
+    return true;
 }
 
-void GLViewer_TexFont::drawString( QString theStr, GLdouble theX , GLdouble theY )
+/*!
+  Drawing string in viewer
+  \param theStr - string to be drawn
+  \param theX - X position
+  \param theY - Y position
+  \param theScale - scale coefficient
+*/
+void GLViewer_TexFont::drawString( QString theStr, GLdouble theX , GLdouble theY, GLfloat theScale )
 {
+    // Adding some pixels to have a gap between rows
+    int aRowPixelHeight = myFontHeight + TEX_ROW_GAP;
+
+    float aXScale = 1.f, aYScale = 1.f;
+    if ( !myIsResizeable )
+    {
+      glGetFloatv (GL_MODELVIEW_MATRIX, modelMatrix);
+      aXScale = modelMatrix[0];
+      aYScale = modelMatrix[5];     
+    } 
+    else if ( theScale > 0.f )
+    {
+      aXScale = aXScale / theScale;
+      aYScale = aYScale / theScale;
+    }
+
+    // store attributes
+    glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
+
     glEnable(GL_TEXTURE_2D);
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
     glPixelTransferi(GL_MAP_COLOR, 0);
-    glAlphaFunc(GL_GEQUAL, 0.5F);
+
+    glAlphaFunc(GL_GEQUAL, 0.05F);
     glEnable(GL_ALPHA_TEST);
-    glBindTexture(GL_TEXTURE_2D, myTexFont);
-    glBegin(GL_QUADS);
 
-    QFontMetrics aFM( myQFont );
-    int pixelsHeight = aFM.height();
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
 
-    theY = theY - myTexFontHeight + pixelsHeight;
+    glBindTexture(GL_TEXTURE_2D, myTexFont);
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+    glBegin(GL_QUADS);
 
-    for( int i = 0, aGap = 0; i < theStr.length(); i++ )
+    float aLettBeginS, aLettEndS, aLettBeginT, aLettEndT;
+    float aDY = ( aRowPixelHeight - 1 ) / aYScale, aDX;
+    char aLetter;
+    int aLettIndex, row;
+    for ( int i = 0; i < (int)theStr.length(); i++ )
     {
-        char aLetter = theStr.data()[i];
-        int aLettIndex = (int)aLetter - FirstSymbolNumber;
+        aLetter    = theStr.data()[i].toLatin1();
+        aLettIndex = (int)aLetter - FirstSymbolNumber;
+        row        = aLettIndex / TEX_ROW_LEN;
 
-        float aLettBegin = (float)myPositions[aLettIndex];
-        float aLettEnd = aLettBegin + myWidths[aLettIndex]-1;
+        aLettBeginS = (float)myPositions[aLettIndex] / ( (float)myTexFontWidth - 1.f );
+        aLettEndS   = aLettBeginS + ( (float)myWidths[aLettIndex] - 1.f ) / ( (float)myTexFontWidth - 1.f );
+        aLettBeginT = ( myTexFontHeight - ( row + 1 ) * aRowPixelHeight ) / ( (float)myTexFontHeight - 1.f ); 
+        aLettEndT   = aLettBeginT + ( (float)aRowPixelHeight - 1.f ) / ( (float)myTexFontHeight - 1.f );
 
-        aLettBegin = aLettBegin / myTexFontWidth;
-        aLettEnd = aLettEnd / myTexFontWidth;
+        aDX = ( (float)myWidths[aLettIndex] - 1.f ) / aXScale;
 
-        glTexCoord2f( aLettBegin, 0.0 ); glVertex3f( theX + aGap, theY, 1.0 );
-        glTexCoord2f( aLettBegin, 1.0 ); glVertex3f( theX + aGap, theY + myTexFontHeight, 1.0 );
-        glTexCoord2f( aLettEnd, 1.0 ); glVertex3f( theX + aGap + myWidths[aLettIndex]-1, theY + myTexFontHeight, 1.0 );
-        glTexCoord2f( aLettEnd, 0.0 ); glVertex3f( theX + aGap + myWidths[aLettIndex]-1, theY, 1.0 );
+        glTexCoord2f( aLettBeginS, aLettBeginT ); glVertex3f( theX,       theY,       1.f );
+        glTexCoord2f( aLettBeginS, aLettEndT   ); glVertex3f( theX,       theY + aDY, 1.f );
+        glTexCoord2f( aLettEndS,   aLettEndT   ); glVertex3f( theX + aDX, theY + aDY, 1.f );
+        glTexCoord2f( aLettEndS,   aLettBeginT ); glVertex3f( theX + aDX, theY,       1.f );
 
-        aGap += myWidths[aLettIndex]-1 + mySeparator;
+        theX += aDX + mySeparator / aXScale;
     }
 
-    //cout << "the down:" << theY << endl;
-    //cout << "the top:" << theY + myTexFontHeight << endl;
-    //cout << "the text height: " <<  pixelsHeight << endl;
-
-
     glEnd();
-    glDisable(GL_ALPHA_TEST);
-    glDisable(GL_TEXTURE_2D);
+    // restore attributes
+    glPopAttrib();
 }
 
+/*!
+  \return width of string in pixels
+*/
 int GLViewer_TexFont::getStringWidth( QString theStr )
 {
     int aWidth = 0;
-    for( int i = 0; i < theStr.length(); i ++ )
+    for ( int i = 0; i < (int)theStr.length(); i ++ )
     {
-        char aLetter = theStr.data()[i];
+        char aLetter = theStr.data()[i].toLatin1();
         int aLettIndex = (int)aLetter - FirstSymbolNumber;
         aWidth += myWidths[aLettIndex] + mySeparator;
     }
@@ -250,159 +354,155 @@ int GLViewer_TexFont::getStringWidth( QString theStr )
     return aWidth;
 }
 
+/*!
+  \return height of string in pixels
+*/
 int GLViewer_TexFont::getStringHeight()
 {
     QFontMetrics aFM( myQFont );
     return aFM.height();
 }
 
-void GLViewer_Drawer::destroyAllTextures()
-{
-    //int aCount = GLViewer_TexFont::TexFontBase.count();
-    QMap<GLViewer_TexFindId,GLViewer_TexIdStored>::Iterator anIt= GLViewer_TexFont::TexFontBase.begin();
-    QMap<GLViewer_TexFindId,GLViewer_TexIdStored>::Iterator anEndIt= GLViewer_TexFont::TexFontBase.end();
-
-    for( ; anIt != anEndIt; anIt++ )
-        glDeleteTextures( 1, &(anIt.data().myTexFontId) );
-}
-
-#define TEXTURE
-
-#define TEXT_GAP    5
-
-#ifdef TEXTURE
-//QAD_TMFont myTMFont;
-    GLboolean TFLoaded = GL_FALSE;
-
-    GLdouble        modelMatrix[16], projMatrix[16];
-    GLint           viewport[4];
-    GLdouble        winx, winy, winz;
-    GLint           status;
-
-    GLViewer_TexFont*  staticGlFont;
-
-void printOrtho(GLdouble x, GLdouble y, const char *string, int set, GLdouble w, GLdouble h)
-{
-//  int width, heigth;
-    if (set>1)
-    {
-        set=1;
-    }
-//d glDisable(GL_DEPTH_TEST);
-    glMatrixMode(GL_PROJECTION);
-    glPushMatrix();
-    glLoadIdentity();
-    glOrtho(0,w,0,h,-100,100);
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glLoadIdentity();
-
-/* //--------abd 
-    myTMFont.Begin();
-    myTMFont.DrawString( string, x, y );
-  //--------abd */
-    staticGlFont->drawString( string, x, y );
-
-/*  width = myTMFont.GetStringWidth( string );
-    heigth = myTMFont.GetStringHeight( string );
-    cout << "W=" << width << " H=" << heigth << endl;
-*/
-    glMatrixMode(GL_PROJECTION);
-    glPopMatrix();
-    glMatrixMode(GL_MODELVIEW);
-    glPopMatrix();
-//d glEnable(GL_DEPTH_TEST);
-}
-
-void loadGLfont(/*int scalar*/)
-{
-    if (!TFLoaded)
-    {
-/*  //-------abd 
-        QString filename = getenv( "CSF_QADResources" );
-        filename = filename + QDir::separator() + "times.tmf";
-        if (!myTMFont.Create( filename, 19436))
-        {
-            cout << "!Texture loading error" << endl;
-            return;
-        }
- //-------abd */
-        staticGlFont = new GLViewer_TexFont();
-        staticGlFont->generateTexture();
-        
-        TFLoaded = GL_TRUE;
-//!     BuildFont(size);
-    }
-}
-
+/*!
+  Generates list base for bitmap fonts
+*/
 static GLuint displayListBase( QFont* theFont )
 {
+  if ( !theFont )
+    return 0;
   GLuint aList = 0;
-  static QMap<GLViewer_TexFindId, GLuint> fontCache;
+  //static QMap<GLViewer_TexFindId, GLuint> fontCache;
   GLViewer_TexFindId aFindFont;
-  aFindFont.myFontString = theFont->toString();
+  aFindFont.myFontFamily = theFont->family();//theFont->toString();
+  aFindFont.myIsBold = theFont->bold();
+  aFindFont.myIsItal = theFont->italic();
+  aFindFont.myIsUndl = theFont->underline();
+  aFindFont.myPointSize = theFont->pointSize();
 
-#ifdef WIN32
+#if defined(WIN32)
   HGLRC ctx = ::wglGetCurrentContext();
   if ( !ctx )
     return aList;  
   
   aFindFont.myViewPortId = (int)ctx;
 
-  if ( fontCache.contains( aFindFont ) )
-    aList = fontCache[aFindFont];
+  if ( GLViewer_TexFont::BitmapFontCache.contains( aFindFont ) )
+    aList = GLViewer_TexFont::BitmapFontCache[aFindFont];
   else
   {
     GLuint listBase = 0;
-    QMap<GLViewer_TexFindId, GLuint>::iterator it = fontCache.begin();
-    for ( ; it != fontCache.end(); ++it )
+    QMap<GLViewer_TexFindId, GLuint>::iterator it = GLViewer_TexFont::BitmapFontCache.begin();
+    for ( ; it != GLViewer_TexFont::BitmapFontCache.end(); ++it )
     {
-      if ( it.key().myViewPortId == (int)ctx && it.data() > listBase )
-        listBase = it.data();
+      if ( it.key().myViewPortId == (int)ctx && it.value() > listBase )
+        listBase = it.value();
     }
     listBase += 256;
 
     HDC glHdc = ::wglGetCurrentDC();
+ #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
     ::SelectObject( glHdc, theFont->handle() );
+ #endif
     if ( !::wglUseFontBitmaps( glHdc, 0, 256, listBase ) )
       listBase = 0;
     aList = listBase;
-    fontCache[aFindFont] = aList;
+    GLViewer_TexFont::BitmapFontCache[aFindFont] = aList;
+  }
+#elif defined(__APPLE__)
+  CGLContextObj ctx = ::CGLGetCurrentContext();
+  if ( !ctx )
+    return aList;
+
+  aFindFont.myViewPortId = (long)ctx;
+
+  if ( GLViewer_TexFont::BitmapFontCache.contains( aFindFont ) )
+    aList = GLViewer_TexFont::BitmapFontCache[aFindFont];
+  else
+  {
+    GLuint listBase = 0;
+    QMap<GLViewer_TexFindId, GLuint>::iterator it = GLViewer_TexFont::BitmapFontCache.begin();
+    for ( ; it != GLViewer_TexFont::BitmapFontCache.end(); ++it )
+    {
+      if ( it.key().myViewPortId == (long)ctx && it.value() > listBase )
+        listBase = it.value();
+    }
+    listBase += 256;
+
+    //HDC glHdc = ::wglGetCurrentDC();
+    //::SelectObject( glHdc, theFont->handle() );
+    //if ( !::wglUseFontBitmaps( glHdc, 0, 256, listBase ) )
+    //  listBase = 0;
+    aList = listBase;
+    GLViewer_TexFont::BitmapFontCache[aFindFont] = aList;
   }
 #else //X Window
   Display* aDisp = glXGetCurrentDisplay();
   if( !aDisp )
   {
+#ifdef _DEBUG_
     printf( "Can't find current dislay\n" );
+#endif
     return aList;
   }
   
   GLXContext aCont = glXGetCurrentContext();
   if( !aCont )
   {
+#ifdef _DEBUG_
     printf( "Can't find current context\n" );
+#endif
     return aList;
   }
 
-  aFindFont.myViewPortId = (int)aCont;
+  aFindFont.myViewPortId = size_t(aCont);
 
-  if ( fontCache.contains( aFindFont ) )
-    aList = fontCache[aFindFont];
+  if ( GLViewer_TexFont::BitmapFontCache.contains( aFindFont ) )
+    aList = GLViewer_TexFont::BitmapFontCache[aFindFont];
   else
   {
     GLuint listBase = 0;
-    QMap<GLViewer_TexFindId, GLuint>::iterator it = fontCache.begin();
-    for ( ; it != fontCache.end(); ++it )
+    QMap<GLViewer_TexFindId, GLuint>::iterator it = GLViewer_TexFont::BitmapFontCache.begin();
+    for ( ; it != GLViewer_TexFont::BitmapFontCache.end(); ++it )
     {
-      if ( it.key().myViewPortId == (int)aCont && it.data() > listBase )
-        listBase = it.data();
+      if ( it.key().myViewPortId == size_t(aCont) && it.value() > listBase )
+        listBase = it.value();
     }
     listBase += 256;
-
-    glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase );
-
+    
+    //glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase );
+    int aFontCont = 0;
+    QString aFontDef = theFont->toString();
+    char** xFontList = XListFonts( aDisp, aFontDef.toLatin1()/*aFindFont.myFontString.data()*/, 1, &aFontCont  );
+// TODO (QT5 PORTING) Below is a temporary solution, to allow compiling with Qt 5
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+    if( !theFont->handle() )
+    {
+#endif
+#ifdef _DEBUG_
+      printf( "Can't load font %s. loading default font....\n", aFontDef.toLatin1().data()/*aFindFont.myFontString.data()*/ );
+#endif
+      QString aFontMask ("-*-*-*-r-*-*-");
+      aFontMask += aFontDef/*aFindFont.myFontString*/.section( ',', 1, 1 );
+#ifdef _DEBUG_
+      printf( "Height of Default font: %s\n", aFontDef/*aFindFont.myFontString*/.section( ',', 1, 1 ).data() );
+#endif
+      aFontMask += "-*-*-*-m-*-*-*";
+      xFontList = XListFonts( aDisp, aFontMask.toLatin1().constData()/*"-*-*-*-r-*-*-12-*-*-*-m-*-*-*"*/, 1, &aFontCont  );
+      if( aFontCont == 0 )
+      {
+#ifdef _DEBUG_
+        printf( "Can't load default font\n" );
+#endif
+        return 0;
+      }
+      glXUseXFont( (Font)(XLoadFont( aDisp,xFontList[0] )), 0, 256, listBase );
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+    }
+    else
+      glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase );
+#endif
     aList = listBase;
-    fontCache[aFindFont] = aList;
+    GLViewer_TexFont::BitmapFontCache[aFindFont] = aList;
   }
 
 #endif
@@ -410,155 +510,433 @@ static GLuint displayListBase( QFont* theFont )
   return aList;
 }
 
-/***************************************************************************
-**  Class:   GLViewer_Drawer
-**  Descr:   Drawer for GLViewer_Object
-**  Module:  GLViewer
-**  Created: UI team, 01.10.01
-****************************************************************************/
+/*!
+  Default constructor
+*/
 GLViewer_Drawer::GLViewer_Drawer()
+: myFont( "Helvetica", 10, QFont::Bold )
 {
   myXScale = myYScale = 0.0;
   myObjects.clear();
-  myTextList = -1;
+  myTextList = 0/*-1*/;
   myObjectType = "GLViewer_Object";
+  myPriority = 0;
+  myTextFormat = DTF_BITMAP;
+  myTextScale = 0.125;
 }
 
+/*!
+  Destructor
+*/
 GLViewer_Drawer::~GLViewer_Drawer()
 {
   myObjects.clear();
   glDeleteLists( myTextList, 1 );
 }
 
+/*!
+  Clears all generated textures
+*/
+void GLViewer_Drawer::destroyAllTextures()
+{
+    QMap<GLViewer_TexFindId,GLViewer_TexIdStored>::Iterator anIt= GLViewer_TexFont::TexFontBase.begin();
+    QMap<GLViewer_TexFindId,GLViewer_TexIdStored>::Iterator anEndIt= GLViewer_TexFont::TexFontBase.end();
+
+    for( ; anIt != anEndIt; anIt++ )
+        glDeleteTextures( 1, &(anIt.value().myTexFontId) );
+}
+
+/*!
+  Enables and disables antialiasing in Open GL (for points, lines and polygons).
+  \param on - if it is true, antialiasing is enabled
+*/
+void GLViewer_Drawer::setAntialiasing(const bool on)
+{
+        if (on)
+        {
+    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+
+                glEnable(GL_POINT_SMOOTH);
+                glEnable(GL_LINE_SMOOTH);
+                glEnable(GL_POLYGON_SMOOTH);
+                glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
+                glEnable (GL_BLEND);
+        }
+        else
+        {
+                glDisable(GL_POINT_SMOOTH);
+                glDisable(GL_LINE_SMOOTH);
+                glDisable(GL_POLYGON_SMOOTH);
+                glBlendFunc (GL_ONE, GL_ZERO);
+                glDisable (GL_BLEND);
+        }
+}
+
+/*! Loads texture from file
+  \param fileName - the name of texture file
+  \param x_size   - the horizontal size of picture ( less or equal texture horizontal size )
+  \param y_size   - the vertical size of picture ( less or equal texture vertical size )
+  \param t_size   - the size of texture ( texture vertical size equals texture horizontal size )
+*/
+GLuint GLViewer_Drawer::loadTexture( const QString& fileName,
+                                     GLint* x_size,
+                                     GLint* y_size,
+                                     GLint* t_size )
+{
+    QImage buf;
+    if ( fileName.isEmpty() || !buf.load( fileName ) )
+        return 0;
+
+    int w = buf.width();
+    int h = buf.height();
+
+    int size = 16;
+    while( size < w || size < h )
+        size = size * 2;
+
+    GLuint texture;
+    GLubyte* pixels = new GLubyte[ size * size * 4 ];
+
+    for( int i = 0; i < size; i++ )
+    {            
+        for( int j = 0; j < size; j++ )
+        {
+            GLubyte r, g, b, a;
+            if( j < w && i < h )
+            {
+                QRgb pixel = buf.pixel( j, h - i - 1 );
+                r = (GLubyte)qRed( pixel );
+                g = (GLubyte)qGreen( pixel );
+                b = (GLubyte)qBlue( pixel );
+                a = (GLubyte)qAlpha( pixel );
+            }
+            else
+            {
+                r = (GLubyte)255;
+                g = (GLubyte)255;
+                b = (GLubyte)255;
+                a = (GLubyte)255;
+            }
+
+            int index = 4 * ( i * size + j );
+            pixels[ index ] = r;
+            pixels[ index + 1 ] = g;
+            pixels[ index + 2 ] = b;
+            pixels[ index + 3 ] = a;
+        }
+    }
+
+    //initialize texture
+    glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+    glGenTextures( 1, &texture );
+    glBindTexture( GL_TEXTURE_2D, texture );
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0,
+                  GL_RGBA, GL_UNSIGNED_BYTE, pixels );
+
+    delete[] pixels;
+
+    if ( x_size )
+      *(x_size) = w;
+
+    if ( y_size )
+      *(y_size) = h;
+
+    if ( t_size )
+      *(t_size) = size;
+
+    return texture;
+}
+
+/*! Draw square texture
+   \param texture - the texture ID
+   \param size    - the size of square texture
+   \param x       - x coord
+   \param y       - y coord
+*/
+void GLViewer_Drawer::drawTexture( GLuint texture, GLint size, GLfloat x, GLfloat y )
+{
+    /*float xScale = myXScale;
+    float yScale = myYScale;
+
+    glColor4f( 1.0, 1.0, 1.0, 1.0 );
+
+    glEnable( GL_TEXTURE_2D );
+    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+    glAlphaFunc( GL_GREATER, 0.95F );
+    glEnable( GL_ALPHA_TEST );
+    
+    glBindTexture( GL_TEXTURE_2D, texture );
+    glBegin( GL_QUADS );
+
+    glTexCoord2f( 0.0, 0.0 );
+    glVertex3f( x-size/2./xScale, y-size/2./yScale, 0.0 );
+
+    glTexCoord2f( 0.0, 1.0 );
+    glVertex3f( x-size/2./xScale, y+size/2./yScale, 0.0 );
+
+    glTexCoord2f( 1.0, 1.0 );
+    glVertex3f( x+size/2./xScale, y+size/2./yScale, 0.0 );
+
+    glTexCoord2f( 1.0, 0.0 );
+    glVertex3f( x+size/2./xScale, y-size/2./yScale, 0.0 );
+    
+    glEnd();
+    glFlush();
+
+    glDisable( GL_ALPHA_TEST );
+    glDisable( GL_TEXTURE_2D );*/
+
+  drawTexture( texture, size, size, x, y );
+}
+
+/*! Draw texture
+   \param texture - the texture ID
+   \param x_size  - the horizontal size of texture
+   \param y_size  - the vertical size of texture
+   \param x       - x coord
+   \param y       - y coord
+*/
+void GLViewer_Drawer::drawTexture( GLuint texture, GLint x_size, GLint y_size, GLfloat x, GLfloat y )
+{
+    /*float xScale = myXScale;
+    float yScale = myYScale;
+
+    glColor4f( 1.0, 1.0, 1.0, 1.0 );
+
+    glEnable( GL_TEXTURE_2D );
+    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+    glAlphaFunc( GL_GREATER, 0.95F );
+    glEnable( GL_ALPHA_TEST );
+    
+    glBindTexture( GL_TEXTURE_2D, texture );
+    glBegin( GL_QUADS );
+
+    glTexCoord2f( 0.0, 0.0 );
+    glVertex3f( x-x_size/2./xScale, y-y_size/2./yScale, 0.0 );
+
+    glTexCoord2f( 0.0, 1.0 );
+    glVertex3f( x-x_size/2./xScale, y+y_size/2./yScale, 0.0 );
+
+    glTexCoord2f( 1.0, 1.0 );
+    glVertex3f( x+x_size/2./xScale, y+y_size/2./yScale, 0.0 );
+
+    glTexCoord2f( 1.0, 0.0 );
+    glVertex3f( x+x_size/2./xScale, y-y_size/2./yScale, 0.0 );
+    
+    glEnd();
+    glFlush();
+
+    glDisable( GL_ALPHA_TEST );
+    glDisable( GL_TEXTURE_2D );*/
+  drawTexturePart( texture, 1.0, 1.0, x_size, y_size, x, y );
+}
+
+/*! Draw texture part
+   \param texture - the texture ID
+   \param x_ratio - the horizontal ratio of texture part
+   \param y_ratio - the vertical ratio of texture part
+   \param x_size  - the horizontal size of texture
+   \param y_size  - the vertical size of texture
+   \param x       - x coord
+   \param y       - y coord
+   \param scale   - common scale factor ( if = 0, use drawer scales )
+*/
+void GLViewer_Drawer::drawTexturePart( GLuint texture,
+                                       GLfloat x_ratio,
+                                       GLfloat y_ratio,
+                                       GLfloat x_size,
+                                       GLfloat y_size,
+                                       GLfloat x,
+                                       GLfloat y,
+                                       GLfloat scale )
+{
+  if( !texture )
+    return;
+
+  float xScale = scale > 0. ? 1./scale : myXScale;
+  float yScale = scale > 0. ? 1./scale : myYScale;
+
+  glColor4f( 1.0, 1.0, 1.0, 1.0 );
+
+
+  glEnable( GL_TEXTURE_2D );
+  glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
+  bool hasAlpha = glIsEnabled( GL_ALPHA_TEST );
+  glDisable( GL_ALPHA_TEST );
+
+  glBindTexture( GL_TEXTURE_2D, texture );
+  glBegin( GL_QUADS );
+
+  glTexCoord2f( 0.0, 0.0 );
+  glVertex3f( x-x_size/2./xScale, y-y_size/2./yScale, 0.0 );
+
+  glTexCoord2f( 0.0, y_ratio );
+  glVertex3f( x-x_size/2./xScale, y+y_size/2./yScale, 0.0 );
+
+  glTexCoord2f( x_ratio, y_ratio );
+  glVertex3f( x+x_size/2./xScale, y+y_size/2./yScale, 0.0 );
+
+  glTexCoord2f( x_ratio, 0.0 );
+  glVertex3f( x+x_size/2./xScale, y-y_size/2./yScale, 0.0 );
+  
+  glEnd();
+  glFlush();
+
+  if ( hasAlpha )
+    glEnable( GL_ALPHA_TEST );
+
+  glDisable( GL_TEXTURE_2D );
+}
+
+/*!
+  Draw text
+  \param text - text to be drawn
+  \param xPos - x position
+  \param yPos - y position
+  \param color - color of text
+  \param theFont - font of text
+  \param theSeparator - letter separator
+  \param theFormat - text format (by default DTF_BITMAP)
+*/
 void GLViewer_Drawer::drawText( const QString& text, GLfloat xPos, GLfloat yPos,
                                 const QColor& color, QFont* theFont, int theSeparator, DisplayTextFormat theFormat )
 {
-  if( theFormat == DTF_TEXTURE )
+  glColor3f( ( GLfloat )color.red() / 255, 
+             ( GLfloat )color.green() / 255, 
+             ( GLfloat )color.blue() / 255 );
+
+  if( theFormat != DTF_BITMAP )
   {
-    GLViewer_TexFont aTexFont( theFont, theSeparator );
-    aTexFont.generateTexture();
-
-    glGetIntegerv (GL_VIEWPORT, viewport);
-    glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
-    glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
-    status = gluProject (xPos, yPos, 0, modelMatrix, projMatrix, viewport, &winx, &winy, &winz);
-
-    glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT | GL_LIST_BIT );
-    glMatrixMode(GL_PROJECTION);
-    glPushMatrix();
-    glLoadIdentity();
-    glOrtho(0,viewport[2],0,viewport[3],-100,100);
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glLoadIdentity();
-
-    glColor3f( ( GLfloat )color.red() / 255, 
-               ( GLfloat )color.green() / 255, 
-               ( GLfloat )color.blue() / 255 );
-
-    aTexFont.drawString( text, winx, winy );
-
-    glPopMatrix();
-    glMatrixMode(GL_PROJECTION);
-    glPopMatrix();
-    glPopAttrib();
+    GLViewer_TexFont aTexFont( theFont, theSeparator, theFormat == DTF_TEXTURE_SCALABLE, GL_LINEAR );
+    // Font texture was not found or generated --> cannot draw text
+    if ( !aTexFont.generateTexture() )
+      return;
+
+    if ( theFormat == DTF_TEXTURE_SCALABLE )
+      aTexFont.drawString( text, xPos, yPos, textScale() );
+    else
+      aTexFont.drawString( text, xPos, yPos );
   }
-  else if( theFormat == DTF_BITMAP )
+  else
   {
-    glColor3f( ( GLfloat )color.red() / 255, 
-               ( GLfloat )color.green() / 255, 
-               ( GLfloat )color.blue() / 255 );
     glRasterPos2f( xPos, yPos );
     glListBase( displayListBase( theFont ) );
-    glCallLists( text.length(), GL_UNSIGNED_BYTE, text.local8Bit().data() );
+    glCallLists( text.length(), GL_UNSIGNED_BYTE, text.toLocal8Bit().data() );
   }
 }
 
-#else //#ifdef BITMAP
-GLuint fontOffset;
-
-GLubyte space[] =
-    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-GLubyte letters[][13] = {
-    {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18},
-    {0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
-    {0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
-    {0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc},
-    {0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
-    {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff},
-    {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
-    {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
-    {0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e},
-    {0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06},
-    {0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3},
-    {0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
-    {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3},
-    {0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3},
-    {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e},
-    {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
-    {0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c},
-    {0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
-    {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e},
-    {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff},
-    {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
-    {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
-    {0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
-    {0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
-    {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
-    {0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff}
-};
-
-void makeRasterFont()
-{
-  GLuint i, j;
-  glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
-
-  fontOffset = glGenLists( 128 );
-  for ( i = 0, j = 'A'; i < 26; i++, j++ )
+/*!
+  Draws object-text
+*/
+void GLViewer_Drawer::drawText( GLViewer_Object* theObject )
+{
+  if( !theObject )
+    return;
+
+  GLViewer_Text* aText = theObject->getGLText();
+  if( !aText )
+    return;
+
+  GLfloat aPosX, aPosY;
+  aText->getPosition( aPosX, aPosY );
+  // get temporary copy of font
+  QFont aTmpVarFont = aText->getFont();
+  drawText( aText->getText(), aPosX, aPosY, aText->getColor(), &aTmpVarFont, aText->getSeparator(), aText->getDisplayTextFormat() );
+}
+
+/*! Draw text
+   \param text      - the text string
+   \param x         - x coord
+   \param y         - y coord
+   \param hPosition - horizontal alignment
+   \param vPosition - vertical alignment
+   \param color     - text color
+   \param smallFont - font format
+*/
+void GLViewer_Drawer::drawGLText( QString text, float x, float y,
+                                  int hPosition, int vPosition, QColor color, bool smallFont )
+{
+  QFont aFont( myFont );
+  if( smallFont )
+    aFont.setPointSize( int(aFont.pointSize() * 0.8) );
+
+  GLfloat scale = textScale() > 0. ? textScale() : 1.;
+
+  QFontMetrics aFontMetrics( aFont );
+  float width  = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.width( text ) * scale : aFontMetrics.width( text ) / myXScale;
+  float height = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.height() * scale : aFontMetrics.height() / myYScale;
+  float gap = 5 / myXScale;
+
+  switch( hPosition )
+  {
+      case GLText_Left   : x -= ( gap + width ); break;
+      case GLText_Center : x -= width / 2; break;
+      case GLText_Right  : x += gap; break;
+      default : break;
+  }
+
+  switch( vPosition )
   {
-    glNewList( fontOffset + j, GL_COMPILE );
-    glBitmap( CHAR_W, CHAR_H, 0.0, 2.0, CHAR_W+WIDTH, 0.0, letters[i] );
-    glEndList();
+      case GLText_Top    : y += height * 0.5; break;
+      case GLText_Center : y -= height * 0.5; break;
+      case GLText_Bottom : y -= height * 1.5; break;
+      default : break;
   }
-  glNewList( fontOffset + ' ', GL_COMPILE );
-  glBitmap( CHAR_W, CHAR_H, 0.0, 2.0, CHAR_W+WIDTH, 0.0, space );
-  glEndList();
+
+  drawText( text, x, y, color, &aFont, 2, myTextFormat );
 }
 
-void GLViewer_Drawer::drawText( const QString& text, int xPos, int yPos, const QColor& color, QFont theFont, int theSeparator )
+/*!
+  \return a rectangle of text (without viewer scale)
+*/
+GLViewer_Rect GLViewer_Drawer::textRect( const QString& text ) const
 {
-    glShadeModel( GL_FLAT );
-    makeRasterFont();
+  GLfloat scale = textScale() > 0. ? textScale() : 1.;
 
-    myTextList = glGenLists( 1 );
-    glNewList( myTextList, GL_COMPILE );
-    glColor3f( ( GLfloat )color.red() / 255, 
-               ( GLfloat )color.green() / 255, 
-               ( GLfloat )color.blue() / 255 );
-    glRasterPos2i( xPos + TEXT_GAP / myXScale, yPos + TEXT_GAP / myYScale );
-    printString( text );
-    glEndList();
+  QFontMetrics aFontMetrics( myFont );
+  float width  = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.width( text ) * scale : aFontMetrics.width( text );
+  float height = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.height() * scale : aFontMetrics.height();
 
-    if ( myTextList != -1 ) 
-        glCallList( myTextList );
+  return GLViewer_Rect( 0, width, height, 0 );
 }
-#endif //BITMAP
 
-void GLViewer_Drawer::drawText( GLViewer_Object* theObject )
+/*!
+  Draws rectangle
+  \param rect - instance of primitive
+  \param color - color of primitive
+*/
+void GLViewer_Drawer::drawRectangle( GLViewer_Rect* rect, QColor color )
 {
-  if( !theObject )
+  if( !rect )
     return;
 
-  GLViewer_Text* aText = theObject->getGLText();
-  if( !aText )
-    return;
-
-  GLfloat aPosX, aPosY;
-  aText->getPosition( aPosX, aPosY );
-  drawText( aText->getText(), aPosX, aPosY, aText->getColor(), &(aText->getFont()), aText->getSeparator(), aText->getDisplayTextFormat() );
+  float x1 = rect->left();
+  float x2 = rect->right();
+  float y1 = rect->bottom();
+  float y2 = rect->top();
+  
+  glColor3f( ( GLfloat )color.red() / 255,
+    ( GLfloat )color.green() / 255,
+    ( GLfloat )color.blue() / 255 );
+  glLineWidth( 1.0 );
+  
+  glBegin( GL_LINE_LOOP );
+  glVertex2f( x1, y1 );
+  glVertex2f( x1, y2 );
+  glVertex2f( x2, y2 );
+  glVertex2f( x2, y1 );
+  glEnd();
 }
 
+/*!
+  Saves object to file with format of HPGL
+  \param hFile - file
+  \param aViewerCS - viewer co-ordinate system
+  \param aHPGLCS - paper co-ordinate system
+*/
 bool GLViewer_Drawer::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aHPGLCS )
 {
     bool result = true;
@@ -567,6 +945,12 @@ bool GLViewer_Drawer::translateToHPGL( QFile& hFile, GLViewer_CoordSystem* aView
     return result;
 }
 
+/*!
+  Saves object to file with format of PostScript
+  \param hFile - file
+  \param aViewerCS - viewer co-ordinate system
+  \param aPSCS - paper co-ordinate system
+*/
 bool GLViewer_Drawer::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aPSCS )
 {
     bool result = true;
@@ -576,6 +960,12 @@ bool GLViewer_Drawer::translateToPS( QFile& hFile, GLViewer_CoordSystem* aViewer
 }
 
 #ifdef WIN32
+/*!
+  Saves object to file with format of EMF
+  \param hFile - file
+  \param aViewerCS - viewer co-ordinate system
+  \param aEMFCS - paper co-ordinate system
+*/
 bool GLViewer_Drawer::translateToEMF( HDC hDC, GLViewer_CoordSystem* aViewerCS, GLViewer_CoordSystem* aEMFCS )
 {
     bool result = true;
@@ -585,290 +975,252 @@ bool GLViewer_Drawer::translateToEMF( HDC hDC, GLViewer_CoordSystem* aViewerCS,
 }
 #endif
 
-/***************************************************************************
-**  Class:   GLViewer_MarkerDrawer
-**  Descr:   Drawer for GLViewer_MarkerSet
-**  Module:  GLViewer
-**  Created: UI team, 03.10.01
-****************************************************************************/
-#define SEGMENTS   20
-#define STEP       2 * PI / SEGMENTS
-
-GLfloat sin_table[SEGMENTS];
-GLfloat cos_table[SEGMENTS];
-
-GLViewer_MarkerDrawer::GLViewer_MarkerDrawer()
-: GLViewer_Drawer()
+/*!
+  Draws rectangle
+  \param rect - instance of primitive
+  \param lineWidth - width of line
+  \param gap - gap of rectangle
+  \param color - color of primitive
+  \param filled - if it is true, then rectangle will be drawn filled with color "fillingColor"
+  \param fillingColor - color of filling
+*/
+void GLViewer_Drawer::drawRectangle( GLViewer_Rect* rect, GLfloat lineWidth, GLfloat gap,
+                                     QColor color, bool filled, QColor fillingColor )
 {
-    GLfloat angle = 0.0;
-    for ( int i = 0; i < SEGMENTS; i++ )
-    {
-        sin_table[i] = sin( angle );
-        cos_table[i] = cos( angle );
-        angle += float( STEP );
-    }
-    myTextList = 0;//-1; 
-    myObjectType = "GLViewer_MarkerSet";
-}
+  if( !rect )
+    return;
 
-GLViewer_MarkerDrawer::~GLViewer_MarkerDrawer()
-{
-    glDeleteLists( myTextList, 1 );
+  float x1 = rect->left() - gap;
+  float x2 = rect->right() + gap;
+  float y1 = rect->bottom() - gap;
+  float y2 = rect->top() + gap;
+  
+  if( filled )
+  {
+    glColor3f( ( GLfloat )fillingColor.red() / 255,
+      ( GLfloat )fillingColor.green() / 255,
+      ( GLfloat )fillingColor.blue() / 255 );
+    glBegin( GL_POLYGON );
+    glVertex2f( x1, y1 );
+    glVertex2f( x1, y2 );
+    glVertex2f( x2, y2 );
+    glVertex2f( x2, y1 );
+    glEnd();
+  }
+
+  glColor3f( ( GLfloat )color.red() / 255,
+    ( GLfloat )color.green() / 255,
+    ( GLfloat )color.blue() / 255 );
+  glLineWidth( lineWidth );
+  
+  glBegin( GL_LINE_LOOP );
+  glVertex2f( x1, y1 );
+  glVertex2f( x1, y2 );
+  glVertex2f( x2, y2 );
+  glVertex2f( x2, y1 );
+  glEnd();
 }
 
-void GLViewer_MarkerDrawer::create( float xScale, float yScale, bool onlyUpdate )
+/*!
+  Draws contour
+  \param pntList - list of points
+  \param color - color of contour
+  \param lineWidth - width of line
+*/
+void GLViewer_Drawer::drawContour( const GLViewer_PntList& pntList, QColor color, GLfloat lineWidth )
 {
-//  cout << "GLViewer_MarkerDrawer::create " << scaleX << " " << scaleY << endl;
-
-    QValueList<int>::Iterator it;
-    QValueList<int>::Iterator EndIt;
-    QValueList<GLViewer_Object*>::Iterator anObjectIt = myObjects.begin();
-    QValueList<GLViewer_Object*>::Iterator anEndObjectIt = myObjects.end();
-
-    myXScale = xScale;
-    myYScale = yScale;
-
-    QColor colorN, colorH, colorS;
-
-    GLViewer_MarkerSet* aMarkerSet = NULL;
-    GLViewer_AspectLine* anAspectLine = NULL;
-
-    for( ; anObjectIt != anEndObjectIt; anObjectIt++ )
-    {
-        aMarkerSet = ( GLViewer_MarkerSet* )(*anObjectIt);
-        anAspectLine = aMarkerSet->getAspectLine();
-        anAspectLine->getLineColors( colorN, colorH, colorS );
-
-        float* aXCoord = aMarkerSet->getXCoord();
-        float* anYCoord = aMarkerSet->getYCoord();
-        float aRadius = aMarkerSet->getMarkerSize();
-
-        QValueList<int> aHNumbers, anUHNumbers, aSelNumbers, anUSelNumbers;
-        aMarkerSet->exportNumbers( aHNumbers, anUHNumbers, aSelNumbers, anUSelNumbers );
-
-        if( onlyUpdate )
-        {
-            EndIt = anUHNumbers.end();
-            for( it = anUHNumbers.begin(); it != EndIt; ++it )
-            {
-                drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorN, anAspectLine );
-                //cout << "GLViewer_MarkerDrawer::create UH " << *it << endl;
-            }
-
-            EndIt = anUSelNumbers.end();
-            for( it = anUSelNumbers.begin(); it != EndIt; ++it )
-                drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorN, anAspectLine );
-
-            EndIt = aSelNumbers.end();
-            for( it = aSelNumbers.begin(); it != EndIt; ++it )
-                drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorS, anAspectLine );
-
-            EndIt = aHNumbers.end();
-            for( it = aHNumbers.begin(); it != EndIt; ++it )
-            {
-                drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorH, anAspectLine );
-                //cout << "GLViewer_MarkerDrawer::create H " << *it << endl;
-            }
-        }
-        else
-        {
-            int aNumber = aMarkerSet->getNumMarkers();
-            for( int i = 0; i < aNumber; i++ )
-                drawMarker( aXCoord[i], anYCoord[i], aRadius, colorN, anAspectLine );
-
-            EndIt = anUSelNumbers.end();
-            for( it = anUSelNumbers.begin(); it != EndIt; ++it )
-                drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorN, anAspectLine );
-
-            EndIt = aSelNumbers.end();
-            for( it = aSelNumbers.begin(); it != EndIt; ++it )
-                drawMarker( aXCoord[*it], anYCoord[*it], aRadius, colorS, anAspectLine );
-        }
-        //float aXPos = 0, anYPos = 0;
-        if( aMarkerSet->getGLText()->getText() != "" )
-        {
-            //float aXPos = 0, anYPos = 0;
-            //aMarkerSet->getGLText()->getPosition( aXPos, anYPos );
-            //drawText( aMarkerSet->getGLText()->getText(), aXPos, anYPos, colorN, &aMarkerSet->getGLText()->getFont(), aMarkerSet->getGLText()->getSeparator() );
-            drawText( aMarkerSet );
-        }
-    }
+  glColor3f( ( GLfloat )color.red() / 255,
+    ( GLfloat )color.green() / 255,
+    ( GLfloat )color.blue() / 255 );
+  glLineWidth( lineWidth );
+  
+  glBegin( GL_LINES );
+  QList<GLViewer_Pnt>::const_iterator it = pntList.begin();
+  for( ; it != pntList.end(); ++it )
+    glVertex2f( (*it).x(), (*it).y() );
+  glEnd();
 }
 
-void GLViewer_MarkerDrawer::drawMarker( float& theXCoord, float& theYCoord,
-                                     float& theRadius, QColor& theColor, GLViewer_AspectLine* theAspectLine )
+/*!
+  Draws rectangular contour
+  \param rect - instance of rectangle
+  \param color - color of primitive
+  \param lineWidth - width of line
+  \param pattern - pattern of line
+  \param isStripe - enables line stipple
+*/
+void GLViewer_Drawer::drawContour( GLViewer_Rect* rect, QColor color, GLfloat lineWidth,
+                                   GLushort pattern, bool isStripe )
 {
-    glColor3f( ( GLfloat )theColor.red() / 255, 
-               ( GLfloat )theColor.green() / 255, 
-               ( GLfloat )theColor.blue() / 255 );
-
-    glLineWidth( theAspectLine->getLineWidth() );
-
-    if ( theAspectLine->getLineType() == 0 )
-        glBegin( GL_LINE_LOOP );
-    else
-        glBegin( GL_LINE_STRIP);
+  float x1 = rect->left();
+  float x2 = rect->right();
+  float y1 = rect->bottom();
+  float y2 = rect->top();
+  
+  glColor3f( ( GLfloat )color.red() / 255,
+    ( GLfloat )color.green() / 255,
+    ( GLfloat )color.blue() / 255 );
+  glLineWidth( lineWidth );
+  
+  if ( isStripe )
+  {
+    glEnable( GL_LINE_STIPPLE );
+    glLineStipple( 1, pattern );
+  }
 
-    for ( int i = 0; i < SEGMENTS; i++ )
-        glVertex2f( theXCoord + cos_table[i] * theRadius / myXScale,
-                    theYCoord + sin_table[i] * theRadius / myYScale );
-    glEnd();
-}
+  glBegin( GL_LINE_LOOP );
 
-/***************************************************************************
-**  Class:   GLViewer_PolylineDrawer
-**  Descr:   Drawer for GLViewer_Polyline
-**  Module:  GLViewer
-**  Created: UI team, 03.10.01
-****************************************************************************/
+  glVertex2f( x1, y1 );
+  glVertex2f( x1, y2 );
+  glVertex2f( x2, y2 );
+  glVertex2f( x2, y1 );
 
-GLViewer_PolylineDrawer::GLViewer_PolylineDrawer()
-:GLViewer_Drawer()
-{
-  myTextList = 0;//-1; 
-    myObjects.clear();
-    myObjectType = "GLViewer_Polyline";
+  glEnd();
+  glDisable( GL_LINE_STIPPLE );
 }
 
-GLViewer_PolylineDrawer::~GLViewer_PolylineDrawer()
+/*!
+  Draws polygon
+  \param pntList - list of points
+  \param color - color of polygon
+*/
+void GLViewer_Drawer::drawPolygon( const GLViewer_PntList& pntList, QColor color )
 {
-    glDeleteLists( myTextList, 1 );
+  glColor3f( ( GLfloat )color.red() / 255,
+    ( GLfloat )color.green() / 255,
+    ( GLfloat )color.blue() / 255 );
+  glBegin( GL_POLYGON );
+  QList<GLViewer_Pnt>::const_iterator it = pntList.begin();
+  for( ; it != pntList.end(); ++it )
+    glVertex2f( (*it).x(), (*it).y() );
+  glEnd();
 }
 
-void GLViewer_PolylineDrawer::create( float xScale, float yScale, bool onlyUpdate )
+/*!
+  Draws rectangle
+  \param rect - instance of rectangle
+  \param color - color of polygon
+  \param pattern - pattern of line
+  \param isStripe - enables line stipple
+*/
+void GLViewer_Drawer::drawPolygon( GLViewer_Rect* rect, QColor color,
+                                      GLushort pattern, bool isStripe )
 {
-    QValueList<GLViewer_Object*>::Iterator aObjectIt = myObjects.begin();
-    QValueList<GLViewer_Object*>::Iterator aObjectEndIt = myObjects.end();
-    
-    myXScale = xScale;
-    myYScale = yScale;
-
-    QColor color, colorN, colorH, colorS;
-    GLViewer_AspectLine* anAspect = NULL;
-    GLViewer_Polyline* aPolyline = NULL;
-//    myAspectLine->getLineColors( colorN, colorH, colorS );
-    for( ; aObjectIt != aObjectEndIt; aObjectIt++ )
-    {
-        anAspect = (*aObjectIt)->getAspectLine();
-        aPolyline = (GLViewer_Polyline*)(*aObjectIt);
-
-
-        anAspect->getLineColors( colorN, colorH, colorS );
-        if( onlyUpdate )
-        {
-            if( aPolyline->isHighlighted() )
-                color = colorH;
-            else if( aPolyline->isSelected() )
-                color = colorS;
-            else
-                color = colorN;
-        }
-        else
-        {
-            if( aPolyline->isSelected() )
-                color = colorS;
-            else
-                color = colorN;
-        }
-
-        float* aXCoord = aPolyline->getXCoord();
-        float* anYCoord = aPolyline->getYCoord();
-        int aSize = aPolyline->getNumber();        
-
-        glColor3f( ( GLfloat )color.red() / 255, 
-                   ( GLfloat )color.green() / 255, 
-                   ( GLfloat )color.blue() / 255 );
-
-        glLineWidth( anAspect->getLineWidth() );
-
-        if ( anAspect->getLineType() == 0 )
-            glBegin( GL_LINE_LOOP );
-        else
-            glBegin( GL_LINE_STRIP);
-
-        for( int i = 0; i < aSize ; i++ )
-             glVertex2f( aXCoord[ i ], anYCoord[ i ] );        
-        if( aPolyline->isClosed() )
-            glVertex2f( aXCoord[ 0 ], anYCoord[ 0 ] );
+  float x1 = rect->left();
+  float x2 = rect->right();
+  float y1 = rect->bottom();
+  float y2 = rect->top();
+  glColor3f( ( GLfloat )color.red() / 255,
+    ( GLfloat )color.green() / 255,
+    ( GLfloat )color.blue() / 255 );
+
+  if ( isStripe )
+  {
+    glEnable( GL_LINE_STIPPLE );
+    glLineStipple( 1, pattern );
+  }
+  glBegin( GL_POLYGON );
 
-        glEnd();       
+  glVertex2f( x1, y1 );
+  glVertex2f( x1, y2 );
+  glVertex2f( x2, y2 );
+  glVertex2f( x2, y1 );
 
-        if( aPolyline->getGLText()->getText() != "" )
-        {
-         //float aXPos = 0, anYPos = 0;
-         //aPolyline->getGLText()->getPosition( aXPos, anYPos );
-         //drawText( aPolyline->getGLText()->getText(), aXPos, anYPos, color, &aPolyline->getGLText()->getFont(), aPolyline->getGLText()->getSeparator() );
-          drawText( aPolyline );
-        }
-    }
+  glEnd();
+  glDisable( GL_LINE_STIPPLE );
 }
 
-/***************************************************************************
-**  Class:   GLViewer_TextDrawer
-**  Descr:   
-**  Module:  GLViewer
-**  Created: UI team, 27.02.04
-****************************************************************************/
+GLubyte rasterVertex[5] = { 0x70, 0xf8, 0xf8, 0xf8, 0x70 };
 
-GLViewer_TextDrawer::GLViewer_TextDrawer()
-: GLViewer_Drawer()
+/*!
+  Draws vertex
+  \param x - x position
+  \param y - y position
+  \param color - color of vertex
+*/
+void GLViewer_Drawer::drawVertex( GLfloat x, GLfloat y, QColor color )
 {
-    myTextList = 0;//-1; 
-    myObjects.clear();
-    myObjectType = "GLViewer_TextObject";
+  glColor3f( ( GLfloat )color.red() / 255, ( GLfloat )color.green() / 255, ( GLfloat )color.blue() / 255 );
+  glRasterPos2f( x, y );
+  glBitmap( 5, 5, 2, 2, 0, 0, rasterVertex );
 }
 
-GLViewer_TextDrawer::~GLViewer_TextDrawer()
+GLubyte rasterCross[7] =  { 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82 };
+
+/*!
+  Draws cross
+  \param x - x position
+  \param y - y position
+  \param color - color of cross
+*/
+void GLViewer_Drawer::drawCross( GLfloat x, GLfloat y, QColor color )
 {
-    glDeleteLists( myTextList, 1 );
+  glColor3f( ( GLfloat )color.red() / 255, ( GLfloat )color.green() / 255, ( GLfloat )color.blue() / 255 );
+  glRasterPos2f( x, y );
+  glBitmap( 7, 7, 3, 3, 0, 0, rasterCross );
 }
 
-void GLViewer_TextDrawer::create( float xScale, float yScale, bool onlyUpdate )
+/*!
+  Draws arrow
+  \param red, green, blue - components of color
+  \param lineWidth - width of line
+  \param staff - 
+  \param length - length of arrow
+  \param width - width of arrow
+  \param x - x position
+  \param y - y position
+  \param angle - angle of arrow
+  \param filled - drawn as filled
+*/
+void GLViewer_Drawer::drawArrow( const GLfloat red, const GLfloat green, const GLfloat blue,
+                                 GLfloat lineWidth,
+                                 GLfloat staff, GLfloat length, GLfloat width,
+                                 GLfloat x, GLfloat y, GLfloat angle, GLboolean filled )
 {
-    QValueList<GLViewer_Object*>::Iterator aObjectIt = myObjects.begin();
-    QValueList<GLViewer_Object*>::Iterator aObjectEndIt = myObjects.end();
-    
-    myXScale = xScale;
-    myYScale = yScale;
-
-    QColor color, colorN, colorH, colorS;
-    GLViewer_AspectLine* anAspect = NULL;    
-    GLViewer_TextObject* anObject = NULL;
-    //float aXPos = 0, anYPos = 0;
-    for( ; aObjectIt != aObjectEndIt; aObjectIt++ )
-    {
-        anObject = (GLViewer_TextObject*)(*aObjectIt);
-        anAspect = anObject->getAspectLine();    
+  GLfloat vx1 = x;
+  GLfloat vy1 = y + staff + length;
+  GLfloat vx2 = vx1 - width / 2;
+  GLfloat vy2 = vy1 - length;
+  GLfloat vx3 = vx1 + width / 2;
+  GLfloat vy3 = vy1 - length;
+
+  gp_Pnt2d p0( x, y );
+  gp_Pnt2d p1( vx1, vy1 );
+  gp_Pnt2d p2( vx2, vy2 );
+  gp_Pnt2d p3( vx3, vy3 );
+
+  p1.Rotate( p0, angle );
+  p2.Rotate( p0, angle );
+  p3.Rotate( p0, angle );
+  
+  vx1 = p1.X(); vy1 = p1.Y();
+  vx2 = p2.X(); vy2 = p2.Y();
+  vx3 = p3.X(); vy3 = p3.Y();
 
-        anAspect->getLineColors( colorN, colorH, colorS );
-        if( onlyUpdate )
-        {
-            if( anObject->isHighlighted() )
-                color = colorH;
-            else if( anObject->isSelected() )
-                color = colorS;
-            else
-                color = colorN;
-        }
-        else
-        {
-            if( anObject->isSelected() )
-                color = colorS;
-            else
-                color = colorN;
-        }        
-        
-        //anObject->getGLText()->getPosition( aXPos, anYPos );
-        //drawText( anObject->getGLText()->getText(), aXPos, anYPos, color, &(anObject->getGLText()->getFont()), anObject->getGLText()->getSeparator() );
-        drawText( anObject );
-    }
-}
+  glColor3f( red, green, blue );
+  glLineWidth( lineWidth );
 
-void GLViewer_TextDrawer::updateObjects()
-{
-    QValueList<GLViewer_Object*>::Iterator aObjectIt = myObjects.begin();
-    QValueList<GLViewer_Object*>::Iterator aObjectEndIt = myObjects.end();
-    for( ; aObjectIt != aObjectEndIt; aObjectIt++ )
-        (*aObjectIt)->compute();
+  glBegin( GL_LINES );
+  glVertex2f( x, y );
+  glVertex2f( vx1, vy1 );
+  glEnd();
+
+  filled = true;
+  if( !filled )
+  {
+    glBegin( GL_LINES );
+    glVertex2f( vx1, vy1 );
+    glVertex2f( vx2, vy2 );
+    glVertex2f( vx1, vy1 );
+    glVertex2f( vx3, vy3 );
+    glEnd();
+  }
+  else
+  {
+    glBegin( GL_POLYGON );
+    glVertex2f( vx1, vy1 );
+    glVertex2f( vx2, vy2 );
+    glVertex2f( vx3, vy3 );
+    glEnd();
+  }
 }