127 lines
2.2 KiB
C++
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;
|
|
}
|