00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
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
00196 if (keep800x600Ratio)
00197 {
00198
00199 fontSize = (uint32)floor(fontSize*height/600.f);
00200 fontSize = max(fontSize, (uint32)2);
00201 }
00202
00203
00204 output.Vertices.setNumVertices (4 * s.size());
00205
00206
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
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
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
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
00296 if (keep800x600Ratio)
00297 {
00298
00299 fontSize = (uint32)floor(fontSize*height/600.f);
00300 fontSize = max(fontSize, (uint32)2);
00301 }
00302
00303
00304 output.Vertices.setNumVertices (4 * s.size());
00305
00306
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
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
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
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
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
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 }