Back to index

supertuxkart  0.5+dfsg1
font.cpp
Go to the documentation of this file.
00001 //  $Id: font.hpp 907 2007-02-04 01:38:54Z coz $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2006 Joerg Henrichs
00005 //
00006 //  This program is free software; you can redistribute it and/or
00007 //  modify it under the terms of the GNU General Public License
00008 //  as published by the Free Software Foundation; either version 2
00009 //  of the License, or (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020 #include <vector>
00021 
00022 #include "file_manager.hpp"
00023 #include "user_config.hpp"
00024 #include "gui/font.hpp"
00025 #include "string_utils.hpp"
00026 
00027 Font* font_gui;
00028 Font* font_race;
00029 
00030 int init_fonts()
00031 {
00032     font_gui = new Font("DomesticMannersLatin1.txf");
00033     font_race = new Font("DomesticMannersLatin1.txf");
00034     return ( font_gui && font_race );
00035 }   // init_fonts
00036 
00037 // =============================================================================
00038 int delete_fonts()
00039 {
00040     delete font_gui;
00041     delete font_race;
00042     return 0;
00043 }   // delete_fonts
00044 
00045 // =============================================================================
00046 Font::Font(const char *fontname)
00047 {
00048     m_fnt      = new fntTexFont(file_manager->getFontFile(fontname).c_str(),
00049                                 GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
00050     m_text_out = new fntRenderer();
00051     m_text_out->setFont(m_fnt);
00052 }   // Font
00053 
00054 // -----------------------------------------------------------------------------
00055 Font::~Font()
00056 {
00057     delete m_text_out;
00058     delete m_fnt;
00059 }   // ~Font
00060 
00061 // -----------------------------------------------------------------------------
00062 
00063 void Font::Print(const char *text, int size, 
00064                  int x, int y,
00065                  const GLfloat* color,
00066                  float scale_x, float scale_y,
00067                  int left, int right, int top, int bottom, bool doShadow)
00068 {
00069     
00070     // Only scale for lower resolution
00071     float fontScaling = user_config->m_width<800 ? ((float)user_config->m_width/800.0f) 
00072                                                  : 1.0f;
00073     int   sz          = (int)(size*std::max(scale_x,scale_y)*fontScaling);
00074 
00075     float l,r,t,b;
00076     m_fnt->getBBox(text, (float)sz, 0, &l, &r, &b, &t);
00077     const int W = (int)((r-l+0.99));
00078     const int H = (int)((t-b+0.99));
00079 
00080     if(x==CENTER_OF_SCREEN)
00081     {
00082         if(left ==-1) left  = 0;
00083         if(right==-1) right = user_config->m_width-1;
00084         int width = right-left+1;
00085         x         = (width - W)/2 + left;
00086     }
00087 
00088     if(y==CENTER_OF_SCREEN)
00089     {
00090         if(top    == -1) top    = user_config->m_height-1;
00091         if(bottom == -1) bottom = 0;
00092         int height = top-bottom+1;
00093         y = (height - H)/2 + bottom;
00094     }
00095 
00096     m_text_out->begin();
00097     m_text_out->setPointSize((float)sz);
00098     if(doShadow)
00099     {
00100         m_text_out->start2f((GLfloat)x-2, (GLfloat)y-2);
00101         glColor4ub(0, 0, 0, 100);
00102         m_text_out->puts(text);
00103     }
00104     m_text_out->start2f((GLfloat)x, (GLfloat)y);
00105 
00106     if( color == NULL )
00107     {
00108         glColor4f(1.0f,1.0f,1.0f,1.0f);
00109     }
00110     else
00111     {
00112         glColor4fv(color);
00113     }
00114     m_text_out->puts(text);
00115     m_text_out->end();
00116 
00117 }   // Print
00118 // -----------------------------------------------------------------------------
00119 
00120 void Font::PrintBold(const std::string &text, int size, int x, int y,
00121                      const GLfloat* color, float scale_x, float scale_y,
00122                      int left, int right, int top, int bottom            )
00123 {
00124     // Only scale for lower resolution
00125     float fontScaling = user_config->m_width<800 ? ((float)user_config->m_width/800.0f) 
00126                                                  : 1.0f;
00127     int   sz          = (int)(size*std::max(scale_x,scale_y)*fontScaling);
00128 
00129     float l,r,t,b;
00130     getBBoxMultiLine(text, sz, 0, &l, &r, &b, &t);
00131     const int W = (int)((r-l+0.99));
00132     const int H = (int)((t-b+0.99));
00133 
00134     if(x==CENTER_OF_SCREEN)
00135     {
00136         if(left ==-1) left  = 0;
00137         if(right==-1) right = user_config->m_width-1;
00138         int width = right-left+1;
00139         x         = (width - W)/2 + left;
00140     }
00141 
00142     if(y==CENTER_OF_SCREEN)
00143     {
00144         if(top    == -1) top    = user_config->m_height-1;
00145         if(bottom == -1) bottom = 0;
00146         int height = top-bottom+1;
00147         y = (height - H)/2 + bottom;
00148     }
00149 
00150 
00151     m_text_out->begin();
00152     m_text_out->setPointSize((float)sz);
00153 
00154     // print shadow
00155     // ------------
00156     glColor4f(0.0f,0.0f,0.0f,1.0f);
00157     float xf=(GLfloat)x+3;
00158     float yf=(GLfloat)y-3;
00159     for(float r=-1; r<=0; r+=0.5)
00160     {
00161         m_text_out->start2f(xf-r, yf-r);
00162         m_text_out->puts(text.c_str());
00163     }
00164 
00165     if( color == NULL )
00166     {
00167         glColor4f(1.0f,1.0f,1.0f,1.0f);
00168     }
00169     else
00170     {
00171         glColor4fv(color);
00172     }
00173     xf=(GLfloat)x;
00174     yf=(GLfloat)y;
00175     for(float r=-1.0f; r<=0.0f; r+=0.5f)
00176     {
00177         // This kind of simulates an outline, but it's not too good
00178         //if(r==-1.0f || r==0.0f)
00179         //    glColor4f(0.0f,0.0f,0.0f,1.0f);
00180         //else
00181         //    glColor4f(1.0f,1.0f,1.0f,1.0f);
00182 
00183         m_text_out->start2f((GLfloat)x+r, (GLfloat)y+r);
00184         m_text_out->puts(text.c_str());
00185     }
00186     m_text_out->end();
00187 
00188 }   // PrintBold
00189 
00190 // ----------------------------------------------------------------------------
00191 void Font::getBBox(const std::string &text, int size, bool italic,
00192                   float *left, float *right, float *bot, float *top)
00193 {
00194     m_fnt->getBBox(text.c_str(), (float)size, italic, left, right, bot, top);
00195     if(user_config->m_width<800) {
00196         float fract=(float)user_config->m_width/800.0f;
00197         *left  *= fract;
00198         *right *= fract;
00199         if(bot) *bot   *= fract;
00200         if(top) *top   *= fract;
00201     }
00202 
00203 }
00204 // ----------------------------------------------------------------------------
00205 
00206 void Font::getBBoxMultiLine(const std::string &text, int size, bool italic,
00207                             float *left, float *right, float *bot, float *top)
00208 {
00209     // Plib does not handle multi-lines strings as expected. So as a work
00210     // around we split strings into lines, and compute the size for each
00211     // line, and take the maximum size at the end.
00212     std::vector<std::string> s=StringUtils::split(text,'\n');
00213     m_fnt->getBBox(s[0].c_str(), (float)size, italic, left, right, bot, top);
00214     for(unsigned int i=1; i<s.size(); i++)
00215     {
00216         float l,r,b,t;
00217         m_fnt->getBBox(s[i].c_str(), (float)size, italic, &l, &r, &b, &t);
00218         if(left) *left  = std::min(*left,  l);
00219         if(bot ) *bot   = std::min(*bot,   b);
00220         if(right)*right = std::max(*right, r); 
00221         if(top)  *top   = std::max(*top,   t);
00222     }
00223     if(user_config->m_width<800) {
00224         float fract=(float)user_config->m_width/800.0f;
00225         *left  *= fract;
00226         *right *= fract;
00227         if(bot) *bot   *= fract;
00228         if(top) *top   *= fract;
00229     }
00230 
00231 }