Added features to manually control size of each texture in a font (this is useful for our 'composite font', where chinese characters are larger than latin ones)

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@4553 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2010-01-29 00:19:17 +00:00
parent 2f9f6a4db4
commit b256e43ab2
3 changed files with 79 additions and 14 deletions

Binary file not shown.

View File

@ -86,6 +86,11 @@ bool ScalableFont::load(io::IXMLReader* xml)
core::stringc filename = xml->getAttributeValue(L"filename");
core::stringc fn = file_manager->getFontFile(filename.c_str()).c_str();
u32 i = (u32)xml->getAttributeValueAsInt(L"index");
float scale = xml->getAttributeValueAsFloat(L"scale");
if (scale < 0.01f) scale = 1.0f; // FIXME: how do you check if some property exists in a cleaner way?
//std::cout << "scale = " << scale << std::endl;
core::stringw alpha = xml->getAttributeValue(L"hasAlpha");
//std::cout << "---- Adding font texture " << fn.c_str() << "; alpha=" << alpha.c_str() << std::endl;
@ -100,6 +105,7 @@ bool ScalableFont::load(io::IXMLReader* xml)
TextureInfo info;
info.m_file_name = fn;
info.m_has_alpha = (alpha == core::stringw("false"));
info.m_scale = scale;
// disable mipmaps+filtering
//bool mipmap = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
@ -225,6 +231,7 @@ void ScalableFont::setScale(const float scale)
void ScalableFont::setMaxHeight()
{
// FIXME: should consider per-texture scaling
MaxHeight = 0;
s32 t;
@ -466,7 +473,7 @@ void ScalableFont::setInvisibleCharacters( const wchar_t *s )
core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
{
core::dimension2d<u32> dim(0, 0);
core::dimension2d<u32> thisLine(0, MaxHeight);
core::dimension2d<u32> thisLine(0, MaxHeight*m_scale);
for (const wchar_t* p = text; *p; ++p)
{
@ -494,11 +501,16 @@ core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
const int areaID = getAreaFromCharacter(*p, &fallback);
const SFontArea &area = (fallback ? m_fallback_font->Areas[areaID] : Areas[areaID]);
//const TextureInfo& info = (*(m_texture_files.find(area.spriteno))).second;
//const float char_scale = info.m_scale;
thisLine.Width += area.underhang;
thisLine.Width += getCharWidth(area, fallback);
if (fallback) thisLine.Width += (int)((area.width + area.overhang)*m_fallback_font_scale + m_fallback_kerning_width);
else thisLine.Width += area.width + area.overhang + GlobalKerningWidth;
//if (fallback) thisLine.Width += (area.width + area.overhang)*m_fallback_font_scale*char_scale*m_scale + m_fallback_kerning_width;
//else thisLine.Width += (area.width + area.overhang)*m_scale*char_scale + GlobalKerningWidth;
}
dim.Height += thisLine.Height;
@ -506,8 +518,8 @@ core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
// std::cout << "ScalableFont::getDimension returns : " << dim.Width << ", " << dim.Height << " --> ";
dim.Width = (int)(dim.Width * m_scale);
dim.Height = (int)(dim.Height * m_scale);
dim.Width = (int)(dim.Width + 0.9f); // round up
dim.Height = (int)(dim.Height + 0.9f);
//std::cout << dim.Width << ", " << dim.Height << std::endl;
@ -590,11 +602,14 @@ void ScalableFont::draw(const core::stringw& text, const core::rect<s32>& positi
continue;
}
bool fallback_font = false;
const int areaID = getAreaFromCharacter(c, &fallback_font);
//std::cout << "Char " << c << " has area " << areaID << std::endl;
SFontArea& area = (fallback_font ? m_fallback_font->Areas[areaID] : Areas[areaID]);
//float char_scale = m_texture_files[area.spriteno].m_scale;
offset.X += area.underhang;
if ( Invisible.findFirst ( c ) < 0 )
{
@ -603,9 +618,10 @@ void ScalableFont::draw(const core::stringw& text, const core::rect<s32>& positi
fallback[i] = fallback_font;
}
if (fallback[i]) offset.X += (int)(((area.width + area.overhang)*m_fallback_font_scale + m_fallback_kerning_width) * m_scale);
else offset.X += (int)((area.width + area.overhang + GlobalKerningWidth) * m_scale);
}
//std::cout << "Char " << (char)((c >> 24) & 0xFF) << ", " << (char)((c >> 16) & 0xFF) << ", " <<
// (char)((c >> 8) & 0xFF) << ", " << (char)(c & 0xFF) << std::endl;
offset.X += getCharWidth(area, fallback[i]);
}
//SpriteBank->draw2DSpriteBatch(indices, offsets, clip, color);
@ -637,12 +653,23 @@ void ScalableFont::draw(const core::stringw& text, const core::rect<s32>& positi
(*fallback_positions)[(*fallback_sprites)[spriteID].Frames[0].rectNumber] :
positions[sprites[spriteID].Frames[0].rectNumber]);
core::dimension2d<s32> size = source.getSize();
float scale = fallback[n] ? m_scale*m_fallback_font_scale : m_scale;
size.Width = (int)(size.Width * scale);
size.Height = (int)(size.Height * scale);
core::rect<s32> dest(offsets[n], size);
const TextureInfo& info = (fallback[n] ?
(*(m_fallback_font->m_texture_files.find(texID))).second :
(*(m_texture_files.find(texID))).second
);
float char_scale = info.m_scale;
core::dimension2d<s32> size = source.getSize();
float scale = (fallback[n] ? m_scale*m_fallback_font_scale : m_scale);
size.Width = (int)(size.Width * scale * char_scale);
size.Height = (int)(size.Height * scale * char_scale);
// align vertically if character is smaller
int y_shift = (size.Height < MaxHeight*m_scale ? (MaxHeight*m_scale - size.Height)/2: 0);
core::rect<s32> dest(offsets[n] + core::position2di(0, y_shift), size);
video::SColor colors[] = {color, color, color, color};
video::ITexture* texture = (fallback[n] ?
@ -729,6 +756,7 @@ void ScalableFont::lazyLoadTexture(int texID)
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
// load texture
assert(m_texture_files[texID].m_file_name.size() > 0);
SpriteBank->setTexture(texID, Driver->getTexture( m_texture_files[texID].m_file_name ));
// set previous mip-map+filter state
@ -743,6 +771,8 @@ void ScalableFont::lazyLoadTexture(int texID)
}
else
{
assert(m_texture_files[texID].m_file_name.size() > 0);
// colorkey texture rather than alpha channel?
if (! m_texture_files[texID].m_has_alpha)
{
@ -751,6 +781,31 @@ void ScalableFont::lazyLoadTexture(int texID)
}
}
int ScalableFont::getCharWidth(const SFontArea& area, const bool fallback) const
{
core::array< SGUISprite >& sprites = SpriteBank->getSprites();
core::array< SGUISprite >* fallback_sprites = (m_fallback_font != NULL ?
&m_fallback_font->SpriteBank->getSprites() :
NULL);
const int texID = (fallback ?
(*fallback_sprites)[area.spriteno].Frames[0].textureNumber :
sprites[area.spriteno].Frames[0].textureNumber);
const TextureInfo& info = (fallback ?
(*(m_fallback_font->m_texture_files.find(texID))).second :
(*(m_texture_files.find(texID))).second
);
assert(info.m_file_name.size() > 0);
const float char_scale = info.m_scale;
//std::cout << "area.spriteno=" << area.spriteno << ", char_scale=" << char_scale << std::endl;
if (fallback) return (int)(((area.width + area.overhang)*m_fallback_font_scale + m_fallback_kerning_width) * m_scale * char_scale);
else return (int)((area.width + area.overhang + GlobalKerningWidth) * m_scale * char_scale);
}
//! Calculates the index of the character in the text which is on a specific position.
s32 ScalableFont::getCharacterFromPos(const wchar_t* text, s32 pixel_x) const
{

View File

@ -14,6 +14,7 @@
#include "IReadFile.h"
#include "irrArray.h"
#include <map>
#include <iostream>
namespace irr
{
@ -39,6 +40,13 @@ class ScalableFont : public IGUIFontBitmap
{
irr::core::stringc m_file_name;
bool m_has_alpha;
float m_scale;
TextureInfo()
{
m_has_alpha = false;
m_scale = 1.0f;
}
};
std::map<int /* texture file ID */, TextureInfo> m_texture_files;
@ -112,6 +120,8 @@ private:
s32 width;
u32 spriteno;
};
int getCharWidth(const SFontArea& area, const bool fallback) const;
//! load & prepare font from ITexture
bool loadTexture(video::IImage * image, const io::path& name);