Logo Search packages:      
Sourcecode: vdrift version File versions

font.cpp

/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
#include "font.h"

FONT::FONT()
{
      error_log.open((settings.GetSettingsDir() + "/logs/font.log").c_str());
      loaded = false;
}

extern bool verbose_output;
FONT::~FONT()
{
      if (verbose_output)
            cout << "font deinit" << endl;
      
      error_log.close();
      
      if (loaded)
      {
            glDeleteLists(base, 256);
            //glDeleteTextures( 1, &texture );
            //textures.Delete(texture);
            //textures.Delete(settings.GetDataDir() + "/" + settings.GetSkinPath() + "/textures/newfontt3.png");
            texture.Unload();
      }
}



void FONT::Load()
{
      if (loaded)
      {
            glDeleteLists(base, 256);
            //glDeleteTextures( 1, &texture );
            //textures.Delete(settings.GetDataDir() + "/" + settings.GetSkinPath() + "/textures/newfontt3.png");
            texture.Unload();
      }
      
      loaded = true;
      
      base = glGenLists(256);
      
      ifstream spf;
      spf.open(settings.GetFullDataPath("lists/fontspacing.1").c_str());
      int c;
      for (c = 0; c < 128; c++)
      {
            spf >> spacing[0][c];
      }
      spf.close();
      
      spf.open(settings.GetFullDataPath("lists/fontspacing.2").c_str());
      for (c = 0; c < 128; c++)
      {
            spf >> spacing[1][c];
      }
      spf.close();
      
      //texture = utility.TexLoad("gui/newfontt3.png", GL_RGBA, true);
      texture.Load( settings.GetDataDir() + "/" + settings.GetSkinPath() + "/textures/newfontt3.png", true );
      
      /*// *** Load Texture ***
      string filepath;
      char buffer[1024];
      string filename;
      filename = "newfont.png";
      bool mipmapping = true;
      int format = GL_RGB;
      filepath = settings.GetDataDir() + "/tex/" + filename;
      strcpy(buffer, filepath.c_str());

      SDL_Surface *TextureImage[1];                         // Create Storage Space For The Texture

      // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
      if ((TextureImage[0]=SDL_LoadBMP(buffer)))
      {
            glGenTextures(1, &texture);                           // Create Texture
            
            //mesh_error_log << filename << endl;
            
            // Linear Filtering, no MipMapping
            glBindTexture(GL_TEXTURE_2D, texture);
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
            #ifdef _WIN32
            glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w, TextureImage[0]->h, 0, format, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
            #else
            glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w, TextureImage[0]->h, 0, format, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
            #endif
            
            if (mipmapping)
            {
                  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_MIPMAP_NEAREST);
                  gluBuild2DMipmaps( GL_TEXTURE_2D, 3, TextureImage[0]->w, TextureImage[0]->h, GL_BGR, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
            }
      }
      else
      {
            //quit, bitmap not found
            error_log << "Could not find font texture: " << buffer << "\n";
      }*/
      
      
      //*** Create Display Lists ***
      
      float cx;
      float cy;
      
      //glBindTexture(GL_TEXTURE_2D, texture);
      texture.Activate();
      
      // Loop Through All 256 Lists
      for ( int loop = 0; loop < 256; loop++ )
      {
            /* NOTE:
             *  BMPs are stored with the top-leftmost pixel being the
             * last byte and the bottom-rightmost pixel being the first
             * byte. So an image that is displayed as
             *    1 0
             *    0 0
             * is represented data-wise like
             *    0 0
             *    0 1
             * And because SDL_LoadBMP loads the raw data without
             * translating to how it is thought of when viewed we need
             * to start at the bottom-right corner of the data and work
             * backwards to get everything properly.
             */

            /* X Position Of Current Character */
            cx = 1 - ( float )( loop % 16 ) / 16.0f;
            /* Y Position Of Current Character */
            cy = 1 - ( float )( loop / 16 ) / 16.0f;

            //compute size of character
            int maxx;
            int loopr = ( 255 - loop );
            if (loopr > 127)
              maxx = spacing[1][loopr-128];
            else
              maxx = spacing[0][loopr];
            float xscale = 1.0f/4.3f;
            //float space = ((float)maxx+15)*xscale;
            float space = ((float)maxx)*xscale;
            
            float texcspace = 0.0625f;
            //float offsetamountx = 0.01f;
            //float offsetamounty = 0.0025f;
            
            //float offsetamountx = -texcspace / 8.0f;
            //float offsetamounty = -texcspace / 8.0f;
            
            float offsetamountx = 0.002;
            float offsetamounty = 0.001;
            //float texcspace = 0.06f;
            /*float texcspace = 0.05f;
            float offsetamount = 0.0625f - texcspace;*/
            //texcspace = (float)maxx/(float)FONT_RES;
            //cout << texcspace << " ";

            /* Start Building A List */
            glNewList( base + ( 255 - loop ), GL_COMPILE );
            /* Use A Quad For Each Character */
            glBegin( GL_QUADS );
                  /* Texture Coord (Bottom Left) */
                  glTexCoord2f( cx - texcspace-offsetamountx, cy -offsetamounty);
                  /* Vertex Coord (Bottom Left) */
                  glVertex2i( 0, 0 );
      
                  /* Texture Coord (Bottom Right) */
                  glTexCoord2f( cx-offsetamountx, cy-offsetamounty);
                  /* Vertex Coord (Bottom Right) */
                  glVertex2i( 16, 0 );
      
                  /* Texture Coord (Top Right) */
                  glTexCoord2f( cx-offsetamountx, cy - texcspace -offsetamounty);
                  /* Vertex Coord (Top Right) */
                  glVertex2i( 16, 16 );
      
                  /* Texture Coord (Top Left) */
                  glTexCoord2f( cx - texcspace-offsetamountx, cy - texcspace -offsetamounty);
                  /* Vertex Coord (Top Left) */
                  glVertex2i( 0, 16 );
            glEnd( );

            /* Move To The Right Of The Character */
            glTranslated( space+1, 0, 0 );
            //cout << maxx*xscale << " ";
            glEndList( );
      }
      /*cout << endl;
      cout << spacing[1]['D'-32] << endl;
      cout << spacing[1]['i'-32] << endl;
      cout << spacing[1]['f'-32] << endl;*/
}

void FONT::Print( float px, float py, const char *string, int set, int size, float r, float g, float b )
{
      Print(px, py, string, set, size, r, g, b, 1);
}

void FONT::Print( float px, float py, const char *string, int set, int size, float r, float g, float b, float trans )
{
      int sx, sy;
      glPushAttrib(GL_ALL_ATTRIB_BITS);
      if ( set > 1 )
      set = 1;
      
      GetSizing(size, sx, sy);
      
      int x = (int) (px*(float)sx);
      int y = (int) ((1.0-py)*(float)sy)-20;
      
      // Select our texture
      //glBindTexture( GL_TEXTURE_2D, texture );
      texture.Activate();

      // Disable depth testing 
      glDisable( GL_DEPTH_TEST );
      //and lighting...
      glDisable( GL_LIGHTING);
      glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
      glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glEnable( GL_BLEND );
      
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

      // Select The Projection Matrix
      glMatrixMode( GL_PROJECTION );
      // Store The Projection Matrix
      glPushMatrix( );

      // Reset The Projection Matrix 
      glLoadIdentity( );
      // Set Up An Ortho Screen 
      glOrtho( 0, sx, 0, sy, -1, 1 );

      // Select The Modelview Matrix
      glMatrixMode( GL_MODELVIEW );
      // Stor the Modelview Matrix
      glPushMatrix( );
      // Reset The Modelview Matrix
      glLoadIdentity( );

      // Position The Text (0,0 - Bottom Left)
      glTranslated( x, y, 0 );

      /*// Choose The Font Set (0 or 1)
      glListBase( base - 32 + ( 128 * set ) );

      // Write The Text To The Screen
      glCallLists( strlen( string ), GL_BYTE, string );*/
      
      int num_crs = 0;
      
      glColor4f(r,g,b,trans);
      
      for (unsigned int i = 0; i < strlen(string); i++)
      {
            if (string[i] == 32)
                  glTranslated( 10, 0, 0 );
            else if (string[i] == '\n')
            {
                  num_crs++;
                  glLoadIdentity( );
                  glTranslated(x,y-20*num_crs,0);
            }
            else
            {
                  int pos = base - 32 + (128*set) + string[i];
                  if (pos < 0)
                        pos = 0;
                  glCallList(pos);
            }
      }

      // Select The Projection Matrix
      glMatrixMode( GL_PROJECTION );
      // Restore The Old Projection Matrix
      glPopMatrix( );
      
      // Select the Modelview Matrix
      glMatrixMode( GL_MODELVIEW );
      // Restore the Old Projection Matrix
      glPopMatrix( );

      // Re-enable Depth Testing
      glEnable( GL_DEPTH_TEST );
      //and lighting...
      glEnable( GL_LIGHTING);
      glDisable(GL_BLEND);
      
      glPopAttrib();
}

void FONT::Print( float px, float py, const char *string, int set, int size, float opacity )
{
      Print( px, py, string, set, size, 1,1,1, opacity);
}

float FONT::Width(const char * str, int set, int size)
{
      int sx, sy;
      float max_chars = 0;
      float num_chars = 0;
      
      bool verbose = false;
      
      /*if (strcmp(str, "Game") == 0)
            verbose = true;
      
      if (strcmp(str, "Tools") == 0)
            verbose = true;*/
      
      GetSizing(size, sx, sy);
      
      if (verbose)
            cout << str;
      
      for (unsigned int i = 0; i < strlen(str); i++)
      {
            if (str[i] == '\n')
            {
                  if (num_chars > max_chars)
                        max_chars = num_chars;
                  num_chars = 0;
            }
            else if (str[i] == ' ')
            {
                  //num_chars += 5.0;
                  //num_chars += 10.0/4.3f;
                  num_chars += 7.0;
                  //num_chars += 10.0;
            }
            else
            {
                  int pos = (128*set) + str[i] - 32;
                  int maxx;
                  //int loopr = ( 255 - pos );
                  int loopr = pos;
                  if (loopr > 127)
                        maxx = spacing[1][loopr-128];
                  else
                        maxx = spacing[0][loopr];
                  
                  //int maxx = spacing[set][str[i]-32];
                  
                  float xscale = 1.0f/4.3f;
                  float space = 0.0;
                  if( strlen( str ) == 1 )
                  {
                        space = ((float)maxx)*xscale;
                        num_chars += space + 1;
                  }
                  else
                  {
                        xscale = 1.0f/5.3f;
                        space = ((float)maxx)*xscale;
                        num_chars += space + 0.5;
                  }
                  //float space = ((float)maxx+15)*xscale;
                  
            }
            
            if (verbose)
                  cout << "," << num_chars;
      }
      
      if (num_chars > max_chars)
            max_chars = num_chars;
      
      if (verbose)
            cout << endl;

      return (max_chars)/(float) sy;
}

float FONT::Height(const char * str, int set, int size)
{
      int sx, sy;
      int num_crs = 1;
      
      GetSizing(size, sx, sy);
      
      for (unsigned int i = 0; i < strlen(str); i++)
      {
            if (str[i] == '\n')
            {
                  num_crs++;
            }
      }
      
      return ((float) num_crs * 25.0)/(float) sy;
}

void FONT::GetSizing(int size, int & sx, int & sy)
{
      if (size < 0)
            size = 0;
      
      if (size > 10)
            size = 10;
      
      if (size == 0)
      {
            sx = 1600;
            sy = 1200;
      }
      else if (size == 1)
      {
            sx = 1440;
            sy = 1080;
      }
      else if (size == 2)
      {
            sx = 1280;
            sy = 960;
      }
      else if (size == 3)
      {
            sx = 1138;
            sy = 853;
      }
      else if (size == 4)
      {
            sx = 1024;
            sy = 768;
      }
      else if (size == 5)
      {
            sx = 931;
            sy = 698;
      }
      else if (size == 6)
      {
            sx = 640;
            sy = 480;
      }
      else if (size == 7)
      {
            sx = 480;
            sy = 360;
      }
      else if (size == 8)
      {
            sx = 320;
            sy = 240;
      }
      else if (size == 9)
      {
            sx = 213;
            sy = 160;
      }
      else if (size == 10)
      {
            sx = 142;
            sy = 107;
      }
      else
      {
            sx = 1138;
            sy = 853;
      }
}

Generated by  Doxygen 1.6.0   Back to index