src/font.cpp

Go to the documentation of this file.
00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU Library General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00015  */
00016  
00017 #include "font.h"
00018 
00019 FONT::FONT()
00020 {
00021         error_log.open((settings.GetSettingsDir() + "/logs/font.log").c_str());
00022         loaded = false;
00023 }
00024 
00025 extern bool verbose_output;
00026 FONT::~FONT()
00027 {
00028         if (verbose_output)
00029                 cout << "font deinit" << endl;
00030         
00031         error_log.close();
00032         
00033         if (loaded)
00034         {
00035                 glDeleteLists(base, 256);
00036                 //glDeleteTextures( 1, &texture );
00037                 //textures.Delete(texture);
00038                 //textures.Delete(settings.GetDataDir() + "/" + settings.GetSkinPath() + "/textures/newfontt3.png");
00039                 texture.Unload();
00040         }
00041 }
00042 
00043 
00044 
00045 void FONT::Load()
00046 {
00047         if (loaded)
00048         {
00049                 glDeleteLists(base, 256);
00050                 //glDeleteTextures( 1, &texture );
00051                 //textures.Delete(settings.GetDataDir() + "/" + settings.GetSkinPath() + "/textures/newfontt3.png");
00052                 texture.Unload();
00053         }
00054         
00055         loaded = true;
00056         
00057         base = glGenLists(256);
00058         
00059         ifstream spf;
00060         spf.open(settings.GetFullDataPath("lists/fontspacing.1").c_str());
00061         int c;
00062         for (c = 0; c < 128; c++)
00063         {
00064                 spf >> spacing[0][c];
00065         }
00066         spf.close();
00067         
00068         spf.open(settings.GetFullDataPath("lists/fontspacing.2").c_str());
00069         for (c = 0; c < 128; c++)
00070         {
00071                 spf >> spacing[1][c];
00072         }
00073         spf.close();
00074         
00075         //texture = utility.TexLoad("gui/newfontt3.png", GL_RGBA, true);
00076         texture.Load( settings.GetDataDir() + "/" + settings.GetSkinPath() + "/textures/newfontt3.png", true );
00077         
00078         /*// *** Load Texture ***
00079         string filepath;
00080         char buffer[1024];
00081         string filename;
00082         filename = "newfont.png";
00083         bool mipmapping = true;
00084         int format = GL_RGB;
00085         filepath = settings.GetDataDir() + "/tex/" + filename;
00086         strcpy(buffer, filepath.c_str());
00087 
00088         SDL_Surface *TextureImage[1];                                   // Create Storage Space For The Texture
00089 
00090         // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
00091         if ((TextureImage[0]=SDL_LoadBMP(buffer)))
00092         {
00093                 glGenTextures(1, &texture);                                     // Create Texture
00094                 
00095                 //mesh_error_log << filename << endl;
00096                 
00097                 // Linear Filtering, no MipMapping
00098                 glBindTexture(GL_TEXTURE_2D, texture);
00099                 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
00100                 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
00101                 #ifdef _WIN32
00102                 glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w, TextureImage[0]->h, 0, format, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
00103                 #else
00104                 glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w, TextureImage[0]->h, 0, format, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
00105                 #endif
00106                 
00107                 if (mipmapping)
00108                 {
00109                         glBindTexture(GL_TEXTURE_2D, texture);
00110                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
00111                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
00112                         gluBuild2DMipmaps( GL_TEXTURE_2D, 3, TextureImage[0]->w, TextureImage[0]->h, GL_BGR, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
00113                 }
00114         }
00115         else
00116         {
00117                 //quit, bitmap not found
00118                 error_log << "Could not find font texture: " << buffer << "\n";
00119         }*/
00120         
00121         
00122         //*** Create Display Lists ***
00123         
00124         float cx;
00125         float cy;
00126         
00127         //glBindTexture(GL_TEXTURE_2D, texture);
00128         texture.Activate();
00129         
00130         // Loop Through All 256 Lists
00131         for ( int loop = 0; loop < 256; loop++ )
00132         {
00133                 /* NOTE:
00134                  *  BMPs are stored with the top-leftmost pixel being the
00135                  * last byte and the bottom-rightmost pixel being the first
00136                  * byte. So an image that is displayed as
00137                  *    1 0
00138                  *    0 0
00139                  * is represented data-wise like
00140                  *    0 0
00141                  *    0 1
00142                  * And because SDL_LoadBMP loads the raw data without
00143                  * translating to how it is thought of when viewed we need
00144                  * to start at the bottom-right corner of the data and work
00145                  * backwards to get everything properly.
00146                  */
00147 
00148                 /* X Position Of Current Character */
00149                 cx = 1 - ( float )( loop % 16 ) / 16.0f;
00150                 /* Y Position Of Current Character */
00151                 cy = 1 - ( float )( loop / 16 ) / 16.0f;
00152 
00153                 //compute size of character
00154                 int maxx;
00155                 int loopr = ( 255 - loop );
00156                 if (loopr > 127)
00157                   maxx = spacing[1][loopr-128];
00158                 else
00159                   maxx = spacing[0][loopr];
00160                 float xscale = 1.0f/4.3f;
00161                 //float space = ((float)maxx+15)*xscale;
00162                 float space = ((float)maxx)*xscale;
00163                 
00164                 float texcspace = 0.0625f;
00165                 //float offsetamountx = 0.01f;
00166                 //float offsetamounty = 0.0025f;
00167                 
00168                 //float offsetamountx = -texcspace / 8.0f;
00169                 //float offsetamounty = -texcspace / 8.0f;
00170                 
00171                 float offsetamountx = 0.002;
00172                 float offsetamounty = 0.001;
00173                 //float texcspace = 0.06f;
00174                 /*float texcspace = 0.05f;
00175                 float offsetamount = 0.0625f - texcspace;*/
00176                 //texcspace = (float)maxx/(float)FONT_RES;
00177                 //cout << texcspace << " ";
00178 
00179                 /* Start Building A List */
00180                 glNewList( base + ( 255 - loop ), GL_COMPILE );
00181                 /* Use A Quad For Each Character */
00182                 glBegin( GL_QUADS );
00183                         /* Texture Coord (Bottom Left) */
00184                         glTexCoord2f( cx - texcspace-offsetamountx, cy -offsetamounty);
00185                         /* Vertex Coord (Bottom Left) */
00186                         glVertex2i( 0, 0 );
00187         
00188                         /* Texture Coord (Bottom Right) */
00189                         glTexCoord2f( cx-offsetamountx, cy-offsetamounty);
00190                         /* Vertex Coord (Bottom Right) */
00191                         glVertex2i( 16, 0 );
00192         
00193                         /* Texture Coord (Top Right) */
00194                         glTexCoord2f( cx-offsetamountx, cy - texcspace -offsetamounty);
00195                         /* Vertex Coord (Top Right) */
00196                         glVertex2i( 16, 16 );
00197         
00198                         /* Texture Coord (Top Left) */
00199                         glTexCoord2f( cx - texcspace-offsetamountx, cy - texcspace -offsetamounty);
00200                         /* Vertex Coord (Top Left) */
00201                         glVertex2i( 0, 16 );
00202                 glEnd( );
00203 
00204                 /* Move To The Right Of The Character */
00205                 glTranslated( space+1, 0, 0 );
00206                 //cout << maxx*xscale << " ";
00207                 glEndList( );
00208         }
00209         /*cout << endl;
00210         cout << spacing[1]['D'-32] << endl;
00211         cout << spacing[1]['i'-32] << endl;
00212         cout << spacing[1]['f'-32] << endl;*/
00213 }
00214 
00215 void FONT::Print( float px, float py, const char *string, int set, int size, float r, float g, float b )
00216 {
00217         Print(px, py, string, set, size, r, g, b, 1);
00218 }
00219 
00220 void FONT::Print( float px, float py, const char *string, int set, int size, float r, float g, float b, float trans )
00221 {
00222         int sx, sy;
00223         glPushAttrib(GL_ALL_ATTRIB_BITS);
00224         if ( set > 1 )
00225         set = 1;
00226         
00227         GetSizing(size, sx, sy);
00228         
00229         int x = (int) (px*(float)sx);
00230         int y = (int) ((1.0-py)*(float)sy)-20;
00231         
00232         // Select our texture
00233         //glBindTexture( GL_TEXTURE_2D, texture );
00234         texture.Activate();
00235 
00236         // Disable depth testing 
00237         glDisable( GL_DEPTH_TEST );
00238         //and lighting...
00239         glDisable( GL_LIGHTING);
00240         glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
00241         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00242         glEnable( GL_BLEND );
00243         
00244         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00245         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00246 
00247         // Select The Projection Matrix
00248         glMatrixMode( GL_PROJECTION );
00249         // Store The Projection Matrix
00250         glPushMatrix( );
00251 
00252         // Reset The Projection Matrix 
00253         glLoadIdentity( );
00254         // Set Up An Ortho Screen 
00255         glOrtho( 0, sx, 0, sy, -1, 1 );
00256 
00257         // Select The Modelview Matrix
00258         glMatrixMode( GL_MODELVIEW );
00259         // Stor the Modelview Matrix
00260         glPushMatrix( );
00261         // Reset The Modelview Matrix
00262         glLoadIdentity( );
00263 
00264         // Position The Text (0,0 - Bottom Left)
00265         glTranslated( x, y, 0 );
00266 
00267         /*// Choose The Font Set (0 or 1)
00268         glListBase( base - 32 + ( 128 * set ) );
00269 
00270         // Write The Text To The Screen
00271         glCallLists( strlen( string ), GL_BYTE, string );*/
00272         
00273         int num_crs = 0;
00274         
00275         glColor4f(r,g,b,trans);
00276         
00277         for (unsigned int i = 0; i < strlen(string); i++)
00278         {
00279                 if (string[i] == 32)
00280                         glTranslated( 10, 0, 0 );
00281                 else if (string[i] == '\n')
00282                 {
00283                         num_crs++;
00284                         glLoadIdentity( );
00285                         glTranslated(x,y-20*num_crs,0);
00286                 }
00287                 else
00288                 {
00289                         int pos = base - 32 + (128*set) + string[i];
00290                         if (pos < 0)
00291                                 pos = 0;
00292                         glCallList(pos);
00293                 }
00294         }
00295 
00296         // Select The Projection Matrix
00297         glMatrixMode( GL_PROJECTION );
00298         // Restore The Old Projection Matrix
00299         glPopMatrix( );
00300         
00301         // Select the Modelview Matrix
00302         glMatrixMode( GL_MODELVIEW );
00303         // Restore the Old Projection Matrix
00304         glPopMatrix( );
00305 
00306         // Re-enable Depth Testing
00307         glEnable( GL_DEPTH_TEST );
00308         //and lighting...
00309         glEnable( GL_LIGHTING);
00310         glDisable(GL_BLEND);
00311         
00312         glPopAttrib();
00313 }
00314 
00315 void FONT::Print( float px, float py, const char *string, int set, int size, float opacity )
00316 {
00317         Print( px, py, string, set, size, 1,1,1, opacity);
00318 }
00319 
00320 float FONT::Width(const char * str, int set, int size)
00321 {
00322         int sx, sy;
00323         float max_chars = 0;
00324         float num_chars = 0;
00325         
00326         bool verbose = false;
00327         
00328         /*if (strcmp(str, "Game") == 0)
00329                 verbose = true;
00330         
00331         if (strcmp(str, "Tools") == 0)
00332                 verbose = true;*/
00333         
00334         GetSizing(size, sx, sy);
00335         
00336         if (verbose)
00337                 cout << str;
00338         
00339         for (unsigned int i = 0; i < strlen(str); i++)
00340         {
00341                 if (str[i] == '\n')
00342                 {
00343                         if (num_chars > max_chars)
00344                                 max_chars = num_chars;
00345                         num_chars = 0;
00346                 }
00347                 else if (str[i] == ' ')
00348                 {
00349                         //num_chars += 5.0;
00350                         //num_chars += 10.0/4.3f;
00351                         num_chars += 7.0;
00352                         //num_chars += 10.0;
00353                 }
00354                 else
00355                 {
00356                         int pos = (128*set) + str[i] - 32;
00357                         int maxx;
00358                         //int loopr = ( 255 - pos );
00359                         int loopr = pos;
00360                         if (loopr > 127)
00361                                 maxx = spacing[1][loopr-128];
00362                         else
00363                                 maxx = spacing[0][loopr];
00364                         
00365                         //int maxx = spacing[set][str[i]-32];
00366                         
00367                         float xscale = 1.0f/4.3f;
00368                         float space = 0.0;
00369                         if( strlen( str ) == 1 )
00370                         {
00371                                 space = ((float)maxx)*xscale;
00372                                 num_chars += space + 1;
00373                         }
00374                         else
00375                         {
00376                                 xscale = 1.0f/5.3f;
00377                                 space = ((float)maxx)*xscale;
00378                                 num_chars += space + 0.5;
00379                         }
00380                         //float space = ((float)maxx+15)*xscale;
00381                         
00382                 }
00383                 
00384                 if (verbose)
00385                         cout << "," << num_chars;
00386         }
00387         
00388         if (num_chars > max_chars)
00389                 max_chars = num_chars;
00390         
00391         if (verbose)
00392                 cout << endl;
00393 
00394         return (max_chars)/(float) sy;
00395 }
00396 
00397 float FONT::Height(const char * str, int set, int size)
00398 {
00399         int sx, sy;
00400         int num_crs = 1;
00401         
00402         GetSizing(size, sx, sy);
00403         
00404         for (unsigned int i = 0; i < strlen(str); i++)
00405         {
00406                 if (str[i] == '\n')
00407                 {
00408                         num_crs++;
00409                 }
00410         }
00411         
00412         return ((float) num_crs * 25.0)/(float) sy;
00413 }
00414 
00415 void FONT::GetSizing(int size, int & sx, int & sy)
00416 {
00417         if (size < 0)
00418                 size = 0;
00419         
00420         if (size > 10)
00421                 size = 10;
00422         
00423         if (size == 0)
00424         {
00425                 sx = 1600;
00426                 sy = 1200;
00427         }
00428         else if (size == 1)
00429         {
00430                 sx = 1440;
00431                 sy = 1080;
00432         }
00433         else if (size == 2)
00434         {
00435                 sx = 1280;
00436                 sy = 960;
00437         }
00438         else if (size == 3)
00439         {
00440                 sx = 1138;
00441                 sy = 853;
00442         }
00443         else if (size == 4)
00444         {
00445                 sx = 1024;
00446                 sy = 768;
00447         }
00448         else if (size == 5)
00449         {
00450                 sx = 931;
00451                 sy = 698;
00452         }
00453         else if (size == 6)
00454         {
00455                 sx = 640;
00456                 sy = 480;
00457         }
00458         else if (size == 7)
00459         {
00460                 sx = 480;
00461                 sy = 360;
00462         }
00463         else if (size == 8)
00464         {
00465                 sx = 320;
00466                 sy = 240;
00467         }
00468         else if (size == 9)
00469         {
00470                 sx = 213;
00471                 sy = 160;
00472         }
00473         else if (size == 10)
00474         {
00475                 sx = 142;
00476                 sy = 107;
00477         }
00478         else
00479         {
00480                 sx = 1138;
00481                 sy = 853;
00482         }
00483 }

Generated on Thu Oct 19 04:05:48 2006 by  doxygen 1.4.6