When writing the X11 (linux) implementation there was a problem with X11 defining a "Display" type and we also have a Display class in the engine. So to fix that problem and minimize the risk for running into other name conflicts. We move everything from global namespace.
130 lines
No EOL
2.5 KiB
C++
130 lines
No EOL
2.5 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"
|
|
|
|
namespace sp {
|
|
|
|
Font::Font() :
|
|
m_driver (new FreeTypeDriver())
|
|
{
|
|
}
|
|
|
|
Font::~Font()
|
|
{
|
|
delete m_driver;
|
|
}
|
|
|
|
bool Font::loadFromFile(const std::string& filename)
|
|
{
|
|
if (!m_driver->loadFromFile(filename)) {
|
|
return false;
|
|
}
|
|
|
|
if (!m_driver->setCharacterSize(22)) {
|
|
return false;
|
|
}
|
|
|
|
m_cacheTextureA.shelf = 0;
|
|
m_cacheTextureA.texpos = vec2u(0, 0);
|
|
|
|
createTexture();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Font::loadFromMemory(const void *data)
|
|
{
|
|
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_cacheTextureA.texture.enable();
|
|
m_cacheTextureA.texture.update(pos, img);
|
|
|
|
glyph.texture = &m_cacheTextureA.texture;
|
|
glyph.texture_origin = vec2u(pos.x, pos.y);
|
|
} else {
|
|
glyph.texture = NULL;
|
|
}
|
|
|
|
m_charset[code] = glyph;
|
|
}
|
|
|
|
void Font::createTexture()
|
|
{
|
|
m_cacheTextureA.texture.create(128, 32, PixelFormat::PF_Alpha);
|
|
m_cacheTextureA.texture.enable();
|
|
m_cacheTextureA.texture.setSmooth(true);
|
|
m_cacheTextureA.texture.disable();
|
|
}
|
|
|
|
void Font::resizeTexture() const
|
|
{
|
|
Texture& tex = m_cacheTextureA.texture;
|
|
unsigned int nextSize = math::nextPowerOfTwo(tex.getSize().y + 1);
|
|
|
|
Image tmpImg = tex.copyToImage();
|
|
|
|
// recreate texture.
|
|
tex.create(tex.getSize().x, nextSize, tmpImg.getFormat());
|
|
tex.update(vec2u(0, 0), tmpImg);
|
|
}
|
|
|
|
Vector2u Font::findTextureRegion(const Image& img) const
|
|
{
|
|
Vector2u pos;
|
|
|
|
if (m_cacheTextureA.texpos.x + img.getWidth() + 1 > m_cacheTextureA.texture.getSize().x) {
|
|
m_cacheTextureA.texpos.y += m_cacheTextureA.shelf;
|
|
m_cacheTextureA.texpos.x = 0;
|
|
m_cacheTextureA.shelf = 0;
|
|
}
|
|
|
|
if (img.getHeight() + 1 > m_cacheTextureA.shelf) {
|
|
m_cacheTextureA.shelf = img.getHeight() + 1;
|
|
if (m_cacheTextureA.texpos.y + m_cacheTextureA.shelf > m_cacheTextureA.texture.getSize().y) {
|
|
resizeTexture();
|
|
}
|
|
}
|
|
|
|
pos = m_cacheTextureA.texpos;
|
|
|
|
m_cacheTextureA.texpos.x += img.getWidth() + 1;
|
|
|
|
return pos;
|
|
}
|
|
|
|
const Texture* Font::getTexture() const
|
|
{
|
|
return &m_cacheTextureA.texture;
|
|
}
|
|
|
|
} // namespace sp
|