1
0
Fork 0
spectre/source/Graphics/Font.cpp

127 lines
2.2 KiB
C++

#include <Spectre/System/File.h>
#include <Spectre/System/Log.h>
#include <Spectre/Graphics/Font.h>
#include <Spectre/Graphics/Image.h>
#include <Spectre/Graphics/Texture.h>
#include <Spectre/Math/Math.h>
#include "Font/FreeTypeDriver.h"
Font::Font() :
m_size (22),
m_driver (new FreeTypeDriver())
{
}
Font::~Font()
{
delete m_driver;
}
bool Font::loadFromFile(const std::string& filename, unsigned int size)
{
if (!m_driver->loadFromFile(filename)) {
return false;
}
if (!m_driver->setCharacterSize(size)) {
return false;
}
m_size = size;
m_shelf = 0;
m_texpos = vec2u(0, 0);
createTexture();
return true;
}
bool Font::loadFromMemory(const void *data, unsigned int size)
{
return false;
}
Font::Glyph Font::getGlyph(unsigned int code) const
{
if (m_charset.find(code) == m_charset.end()) {
loadChar(code);
}
return m_charset[code];
}
void Font::loadChar(unsigned char code) const
{
Image img;
Font::Glyph glyph;
if (!m_driver) {
return;
}
glyph = m_driver->loadGlyph(code, img);
if (glyph.size > vec2b(0, 0)) {
Vector2u pos = findTextureRegion(img);
m_texture.enable();
m_texture.update(pos, img);
glyph.texture = &m_texture;
glyph.texture_origin = vec2u(pos.x, pos.y);
} else {
glyph.texture = NULL;
}
m_charset[code] = glyph;
}
void Font::createTexture()
{
m_texture.create(128, 32, PixelFormat::PF_Alpha);
m_texture.enable();
m_texture.setSmooth(true);
m_texture.disable();
}
void Font::resizeTexture() const
{
unsigned int nextSize = math::nextPowerOfTwo(m_texture.getSize().y + 1);
Image tmpImg = m_texture.copyToImage();
// recreate texture.
m_texture.create(m_texture.getSize().x, nextSize, tmpImg.getFormat());
m_texture.update(vec2u(0, 0), tmpImg);
}
Vector2u Font::findTextureRegion(const Image& img) const
{
Vector2u pos;
if (m_texpos.x + img.getWidth() + 1 > m_texture.getSize().x) {
m_texpos.y += m_shelf;
m_texpos.x = 0;
m_shelf = 0;
}
if (img.getHeight() + 1 > m_shelf) {
m_shelf = img.getHeight() + 1;
if (m_texpos.y + m_shelf > m_texture.getSize().y) {
resizeTexture();
}
}
pos = m_texpos;
m_texpos.x += img.getWidth() + 1;
return pos;
}
const Texture* Font::getTexture() const
{
return &m_texture;
}