# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

font_manager.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "std3d.h"
00027 
00028 #include <string>
00029 #include <sstream>
00030 
00031 #include "3d/font_manager.h"
00032 #include "3d/font_generator.h"
00033 #include "3d/texture_font.h"
00034 #include "3d/computed_string.h"
00035 #include "3d/primitive_block.h"
00036 #include "3d/material.h"
00037 #include "nel/misc/smart_ptr.h"
00038 #include "nel/misc/debug.h"
00039 
00040 #include "nel/misc/file.h"
00041 
00042 using namespace std;
00043 
00044 namespace NL3D {
00045 
00046 
00047 
00048 /*------------------------------------------------------------------*\
00049                                                         getFontMaterial()
00050 \*------------------------------------------------------------------*/
00051 CMaterial* CFontManager::getFontMaterial()
00052 {
00053         if (_TexFont == NULL)
00054         {
00055                 _TexFont = new CTextureFont;
00056         }
00057 
00058         if (_MatFont == NULL)
00059         {
00060                 _MatFont= new CMaterial;
00061                 _MatFont->initUnlit();
00062                 _MatFont->setSrcBlend(CMaterial::srcalpha);
00063                 _MatFont->setDstBlend(CMaterial::invsrcalpha);
00064                 _MatFont->setBlend(true);
00065                 _MatFont->setTexture(0, _TexFont);
00066                 _MatFont->texEnvOpRGB(0, CMaterial::Replace);
00067                 _MatFont->texEnvArg0RGB(0, CMaterial::Diffuse, CMaterial::SrcColor);
00068         }
00069         return _MatFont;
00070 }
00071 
00072 
00073 
00078 /*
00079 template  <class T> static void NL3DcomputeString (CFontManager *fm, const std::basic_string<T> &s,
00080                                 CFontGenerator *fontGen,
00081                                 const NLMISC::CRGBA &color,
00082                                 uint32 fontSize,
00083                                 IDriver *driver,
00084                                 CComputedString &output,
00085                                 bool    keep800x600Ratio)
00086 {
00087 
00088         float FontRatio = 1.0;
00089         uint32 width, height;
00090 
00091         output.Color = color;
00092         driver->getWindowSize (width, height);
00093         if (height > 0)
00094                 FontRatio = FontRatio / height;
00095         
00096         // resize fontSize if window not of 800x600.
00097         if (keep800x600Ratio)
00098         {
00099                 // keep the 800*600 ratio
00100                 fontSize = (uint32)floor(fontSize*height/600.f);
00101                 fontSize = max(fontSize, (uint32)2);
00102         }
00103         
00104         // Setting vertices format
00105         output.Vertices.setNumVertices (4 * s.size());
00106         
00107         // 1 character <-> 1 primitive block
00108         sint32 penx = 0, dx;
00109         sint32 penz = 0, dz;
00110         float x1, z1, x2, z2;
00111         float u1, v1, u2, v2;
00112         CMaterial               *pMatFont = fm->getFontMaterial();
00113         CTextureFont    *pTexFont = (CTextureFont*)(pMatFont->getTexture (0));
00114         float hlfW = 0.5f / pTexFont->getWidth();
00115         float hlfH = 0.5f / pTexFont->getHeight();
00116         float hlfPix = 0.5f;
00117         if (height > 0)
00118                 hlfPix = hlfPix / height;
00119         CTextureFont::SLetterKey k;
00120 
00121         output.StringHeight = 0;
00122         uint j = 0;
00123         for (uint i = 0; i < s.size(); i++)
00124         {
00125                 // Creating font
00126                 k.Char = s[i];
00127                 k.FontGenerator = fontGen;
00128                 k.Size = fontSize;
00129                 CTextureFont::SLetterInfo *pLI = pTexFont->getLetterInfo (k);
00130                 if(pLI != NULL)
00131                 {
00132                         if ((pLI->CharWidth > 0) && (pLI->CharHeight > 0))
00133                         {
00134                                 // Creating vertices
00135                                 dx = pLI->Left;
00136                                 dz = -((sint32)pLI->CharHeight-(sint32)(pLI->Top));
00137                                 u1 = pLI->U - hlfW;
00138                                 v1 = pLI->V - hlfH;
00139                                 u2 = pLI->U + ((float)pLI->CharWidth) / pTexFont->getWidth() + hlfW;
00140                                 v2 = pLI->V + ((float)pLI->CharHeight) / pTexFont->getHeight() + hlfH;
00141 
00142                                 x1 = (penx + dx) * FontRatio - hlfPix;
00143                                 z1 = (penz + dz) * FontRatio - hlfPix;
00144                                 x2 = (penx + dx + (sint32)pLI->CharWidth)  * FontRatio + hlfPix;
00145                                 z2 = (penz + dz + (sint32)pLI->CharHeight) * FontRatio + hlfPix;
00146 
00147                                 output.Vertices.setVertexCoord  (j, x1, 0, z1);
00148                                 output.Vertices.setTexCoord             (j, 0, u1, v2);
00149                                 ++j;
00150 
00151                                 output.Vertices.setVertexCoord  (j, x2, 0, z1);
00152                                 output.Vertices.setTexCoord             (j, 0, u2, v2);
00153                                 ++j;
00154 
00155                                 output.Vertices.setVertexCoord  (j, x2, 0, z2); 
00156                                 output.Vertices.setTexCoord             (j, 0, u2, v1);
00157                                 ++j;
00158 
00159                                 output.Vertices.setVertexCoord  (j, x1, 0, z2); 
00160                                 output.Vertices.setTexCoord             (j, 0, u1, v1);
00161                                 ++j;
00162                                 
00163                                 if (z2 > output.StringHeight) 
00164                                         output.StringHeight = z2;
00165                         }
00166                         penx += pLI->AdvX;
00167                 }
00168 
00169                 // Building Material
00170                 output.Material = pMatFont;
00171         }
00172         output.Vertices.setNumVertices (j);
00173 
00174         output.StringWidth = penx * FontRatio;
00175 }
00176   */
00177 
00178 static void NL3DcomputeStringChar (CFontManager *fm, const std::basic_string<char> &s,
00179                                 CFontGenerator *fontGen,
00180                                 const NLMISC::CRGBA &color,
00181                                 uint32 fontSize,
00182                                 IDriver *driver,
00183                                 CComputedString &output,
00184                                 bool    keep800x600Ratio)
00185 {
00186 
00187         float FontRatio = 1.0;
00188         uint32 width, height;
00189 
00190         output.Color = color;
00191         driver->getWindowSize (width, height);
00192         if (height > 0)
00193                 FontRatio = FontRatio / height;
00194         
00195         // resize fontSize if window not of 800x600.
00196         if (keep800x600Ratio)
00197         {
00198                 // keep the 800*600 ratio
00199                 fontSize = (uint32)floor(fontSize*height/600.f);
00200                 fontSize = max(fontSize, (uint32)2);
00201         }
00202         
00203         // Setting vertices format
00204         output.Vertices.setNumVertices (4 * s.size());
00205         
00206         // 1 character <-> 1 primitive block
00207         sint32 penx = 0, dx;
00208         sint32 penz = 0, dz;
00209         float x1, z1, x2, z2;
00210         float u1, v1, u2, v2;
00211         CMaterial               *pMatFont = fm->getFontMaterial();
00212         CTextureFont    *pTexFont = (CTextureFont*)(pMatFont->getTexture (0));
00213         float hlfW = 0.5f / pTexFont->getWidth();
00214         float hlfH = 0.5f / pTexFont->getHeight();
00215         float hlfPix = 0.5f;
00216         if (height > 0)
00217                 hlfPix = hlfPix / height;
00218         CTextureFont::SLetterKey k;
00219 
00220         output.StringHeight = 0;
00221         uint j = 0;
00222         for (uint i = 0; i < s.size(); i++)
00223         {
00224                 // Creating font
00225                 k.Char = s[i];
00226                 k.FontGenerator = fontGen;
00227                 k.Size = fontSize;
00228                 CTextureFont::SLetterInfo *pLI = pTexFont->getLetterInfo (k);
00229                 if(pLI != NULL)
00230                 {
00231                         sint32 width = pLI->CharWidth - 1;
00232                         sint32 height = pLI->CharHeight - 1;
00233                         if ((pLI->CharWidth > 0) && (pLI->CharHeight > 0))
00234                         {
00235                                 // Creating vertices
00236                                 dx = pLI->Left;
00237                                 dz = -(height-(sint32)(pLI->Top));
00238                                 u1 = pLI->U - hlfW;
00239                                 v1 = pLI->V - hlfH;
00240                                 u2 = pLI->U + ((float)width) / pTexFont->getWidth() + hlfW;
00241                                 v2 = pLI->V + ((float)height) / pTexFont->getHeight() + hlfH;
00242 
00243                                 x1 = (penx + dx) * FontRatio - hlfPix;
00244                                 z1 = (penz + dz) * FontRatio - hlfPix;
00245                                 x2 = (penx + dx + width)  * FontRatio + hlfPix;
00246                                 z2 = (penz + dz + height) * FontRatio + hlfPix;
00247 
00248                                 output.Vertices.setVertexCoord  (j, x1, 0, z1);
00249                                 output.Vertices.setTexCoord             (j, 0, u1, v2);
00250                                 ++j;
00251 
00252                                 output.Vertices.setVertexCoord  (j, x2, 0, z1);
00253                                 output.Vertices.setTexCoord             (j, 0, u2, v2);
00254                                 ++j;
00255 
00256                                 output.Vertices.setVertexCoord  (j, x2, 0, z2); 
00257                                 output.Vertices.setTexCoord             (j, 0, u2, v1);
00258                                 ++j;
00259 
00260                                 output.Vertices.setVertexCoord  (j, x1, 0, z2); 
00261                                 output.Vertices.setTexCoord             (j, 0, u1, v1);
00262                                 ++j;
00263                                 
00264                                 if (fabsf(z1-z2) > output.StringHeight) 
00265                                         output.StringHeight = fabsf(z1-z2);
00266                         }
00267                         penx += pLI->AdvX;
00268                 }
00269 
00270                 // Building Material
00271                 output.Material = pMatFont;
00272         }
00273         output.Vertices.setNumVertices (j);
00274 
00275         output.StringWidth = penx * FontRatio;
00276 }
00277 // ---------------------------------------------------------------------------------------
00278 static void NL3DcomputeStringUC (CFontManager *fm, const std::basic_string<ucchar> &s,
00279                                 CFontGenerator *fontGen,
00280                                 const NLMISC::CRGBA &color,
00281                                 uint32 fontSize,
00282                                 IDriver *driver,
00283                                 CComputedString &output,
00284                                 bool    keep800x600Ratio)
00285 {
00286 
00287         float FontRatio = 1.0;
00288         uint32 width, height;
00289 
00290         output.Color = color;
00291         driver->getWindowSize (width, height);
00292         if (height > 0)
00293                 FontRatio = FontRatio / height;
00294         
00295         // resize fontSize if window not of 800x600.
00296         if (keep800x600Ratio)
00297         {
00298                 // keep the 800*600 ratio
00299                 fontSize = (uint32)floor(fontSize*height/600.f);
00300                 fontSize = max(fontSize, (uint32)2);
00301         }
00302         
00303         // Setting vertices format
00304         output.Vertices.setNumVertices (4 * s.size());
00305         
00306         // 1 character <-> 1 primitive block
00307         sint32 penx = 0, dx;
00308         sint32 penz = 0, dz;
00309         float x1, z1, x2, z2;
00310         float u1, v1, u2, v2;
00311         float maxZ=-1.0f, minZ=1.0f;
00312         CMaterial               *pMatFont = fm->getFontMaterial();
00313         CTextureFont    *pTexFont = (CTextureFont*)(pMatFont->getTexture (0));
00314         float hlfW = 0.5f / pTexFont->getWidth();
00315         float hlfH = 0.5f / pTexFont->getHeight();
00316         float hlfPix = 0.5f;
00317         if (height > 0)
00318                 hlfPix = hlfPix / height;
00319         CTextureFont::SLetterKey k;
00320 
00321         output.StringHeight = 0;
00322         uint j = 0;
00323         for (uint i = 0; i < s.size(); i++)
00324         {
00325                 // Creating font
00326                 k.Char = s[i];
00327                 k.FontGenerator = fontGen;
00328                 k.Size = fontSize;
00329                 CTextureFont::SLetterInfo *pLI = pTexFont->getLetterInfo (k);
00330                 if(pLI != NULL)
00331                 {
00332                         if ((pLI->CharWidth > 0) && (pLI->CharHeight > 0))
00333                         {
00334                                 // Creating vertices
00335                                 dx = pLI->Left;
00336                                 dz = -((sint32)pLI->CharHeight-(sint32)(pLI->Top));
00337                                 u1 = pLI->U - hlfW;
00338                                 v1 = pLI->V - hlfH;
00339                                 u2 = pLI->U + ((float)pLI->CharWidth) / pTexFont->getWidth() + hlfW;
00340                                 v2 = pLI->V + ((float)pLI->CharHeight) / pTexFont->getHeight() + hlfH;
00341 
00342                                 x1 = (penx + dx) * FontRatio - hlfPix;
00343                                 z1 = (penz + dz) * FontRatio - hlfPix;
00344                                 x2 = (penx + dx + (sint32)pLI->CharWidth)  * FontRatio + hlfPix;
00345                                 z2 = (penz + dz + (sint32)pLI->CharHeight) * FontRatio + hlfPix;
00346 
00347                                 output.Vertices.setVertexCoord  (j, x1, 0, z1);
00348                                 output.Vertices.setTexCoord             (j, 0, u1, v2);
00349                                 ++j;
00350 
00351                                 output.Vertices.setVertexCoord  (j, x2, 0, z1);
00352                                 output.Vertices.setTexCoord             (j, 0, u2, v2);
00353                                 ++j;
00354 
00355                                 output.Vertices.setVertexCoord  (j, x2, 0, z2); 
00356                                 output.Vertices.setTexCoord             (j, 0, u2, v1);
00357                                 ++j;
00358 
00359                                 output.Vertices.setVertexCoord  (j, x1, 0, z2); 
00360                                 output.Vertices.setTexCoord             (j, 0, u1, v1);
00361                                 ++j;
00362                                 
00363                                 if (z1 < minZ) minZ = z1;
00364                                 if (z2 > maxZ) maxZ = z2;
00365                         }
00366                         penx += pLI->AdvX;
00367                 }
00368 
00369                 // Building Material
00370                 output.Material = pMatFont;
00371         }
00372         output.Vertices.setNumVertices (j);
00373 
00374         output.StringWidth = penx * FontRatio;
00375         output.StringHeight = maxZ - minZ;
00376         output.StringLine = fabsf(minZ);
00377 }
00378 
00379 
00380 
00381 /*------------------------------------------------------------------*\
00382                                                         computeString()
00383 \*------------------------------------------------------------------*/
00384 void CFontManager::computeString (const std::string &s,
00385                                                                   CFontGenerator *fontGen,
00386                                                                   const NLMISC::CRGBA &color,
00387                                                                   uint32 fontSize,
00388                                                                   IDriver *driver,
00389                                                                   CComputedString &output,
00390                                                                   bool  keep800x600Ratio)
00391 {
00392         NL3DcomputeStringChar (this, s, fontGen, color, fontSize, driver, output,keep800x600Ratio);
00393 }
00394 
00395 
00396 /*------------------------------------------------------------------*\
00397                                                         computeString()
00398 \*------------------------------------------------------------------*/
00399 void CFontManager::computeString (const ucstring &s,
00400                                                                   CFontGenerator *fontGen,
00401                                                                   const NLMISC::CRGBA &color,
00402                                                                   uint32 fontSize,
00403                                                                   IDriver *driver,
00404                                                                   CComputedString &output,
00405                                                                   bool  keep800x600Ratio)
00406 {
00407         NL3DcomputeStringUC (this, s, fontGen, color, fontSize, driver, output,keep800x600Ratio);
00408 }
00409 
00410 
00411 string CFontManager::getCacheInformation() const
00412 {
00413         stringstream ss;
00414 
00415         ss << "MaxMemory: " << (uint) _MaxMemory << " MemSize: " << (uint) _MemSize << " NbChar: " << (uint) _NbChar;
00416 
00417         return ss.str();
00418 }
00419 
00420 
00421 
00422 
00423 
00424 } // NL3D