bluecore/engine/FontManager.cpp

205 lignes
4.6 KiB
C++

#include "FontManager.h"
#include "RenderDevice.h"
// project includes
#include "Utilities/Buffer.h"
#include "Utilities/Log.h"
#include "Utilities/format.h"
// library includes
#include "physfs.h"
#include "FTGLTextureFont.h"
// system includes
#include <iostream>
using namespace std;
#include "FontManagerDefaultFont.h"
namespace BlueCore
{
//------------------------------------------------------------------------------
FontManager::FontManager(RenderDevice* device) :
_Device(device)
{
// create default font
FTFont *ftfont = new FTGLTextureFont (
DefaultFontBytes,
sizeof ( DefaultFontBytes ),
false );
ftfont->FaceSize( 16);
_DefaultFont = new Font( ftfont, 0, device );
if (_Device.valid())
_Device->DeviceShutdownSignal.connect(this,
&FontManager::DeviceShutdownSlot);
clog << ">>> FontManager constructed..."<< endline;
}
//------------------------------------------------------------------------------
FontManager::~FontManager()
{
destroy();
clog << ">>> FontManager destructed..."<< endline;
}
//------------------------------------------------------------------------------
void FontManager::DeviceShutdownSlot()
{
destroy();
}
//------------------------------------------------------------------------------
void FontManager::destroy()
{
FontMap::iterator i;
for (i = _fonts.begin(); i != _fonts.end(); i++)
{
if (i->second.valid())
i->second->destroy();
}
_DefaultFont = 0;
}
//------------------------------------------------------------------------------
Font *FontManager::loadFont(const std::string &filename, int size, bool hinting)
{
string key = format("%s-%d", filename.c_str(), size);
// check if this font is already loaded
FontMap::const_iterator result;
result = _fonts.find(key);
if (result != _fonts.end() && result->second.valid())
{
return result->second.pointer();
}
Font *font;
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
if (file)
{
unsigned int file_size = PHYSFS_fileLength(file);
unsigned char *buffer = new unsigned char[file_size];
PHYSFS_read(file, buffer, 1, file_size);
PHYSFS_close(file);
// create the font
FTFont *ftfont = new FTGLTextureFont ( buffer, file_size, hinting );
ftfont->FaceSize(size);
if (ftfont->Error() == 0)
{
font = new Font( ftfont, buffer, _Device );
clog << ">>> Font '"<< filename << "' ("<< size << ") loaded"
<< endline;
}
else
{
delete ftfont;
clog << "!!! Font '"<< filename << "' could not be loaded"
<< endline;
font = new Font();
}
}
else
{
clog << "!!! Font '"<< filename << "' not found"<< endline;
font = new Font();
}
_fonts[key] = font;
return font;
}
//------------------------------------------------------------------------------
Font *FontManager::getDefaultFont()
{
return _DefaultFont.pointer();
}
//------------------------------------------------------------------------------
Font::Font()
{
_Font = 0;
_Buffer = 0;
clog << ">>> Font constructed..."<< endline;
}
//------------------------------------------------------------------------------
Font::Font(FTFont *font, unsigned char *buffer, RenderDevice* device) :
_Font(font), _Buffer(buffer), _Device(device)
{
clog << ">>> Font constructed..."<< endline;
}
//------------------------------------------------------------------------------
Font::~Font()
{
destroy();
clog << ">>> Font destructed..."<< endline;
}
//------------------------------------------------------------------------------
void Font::destroy()
{
delete _Font;
delete [] _Buffer;
clog << ">>> Font destroyed..."<< endline;
}
//------------------------------------------------------------------------------
void Font::print(float x, float y, const std::string &text, int halign,
int valign) const
{
if (_Font == 0)
return;
if (_Device.valid() == false)
return;
_Device->begin2D();
if (x < 0.0)
x += _Device->getViewportWidth();
else if (x <= 1.0)
x *= _Device->getViewportWidth();
if (halign == 0)
x -= _Font->Advance(text.c_str() ) / 2;
else if (halign == -1)
x -= _Font->Advance(text.c_str() );
if (y < 0.0)
y += _Device->getViewportHeight();
else if (y <= 1.0)
y *= _Device->getViewportHeight();
y -= _Font->Descender();
if (valign == 0)
y -= _Font->LineHeight() / 2;
else if (valign == -1)
y -= _Font->LineHeight();
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glLoadIdentity();
glTranslatef(x, y, 0);
_Font->Render(text.c_str() );
glPopMatrix();
_Device->end2D();
}
} // namespace BlueCore