Added support for displaying the same fonts in different sizes. Use smaller font for in-game messages

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@4951 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria
2010-03-07 02:03:39 +00:00
parent 11c147c8e9
commit 4340cccd9f
6 changed files with 79 additions and 30 deletions

View File

@@ -26,6 +26,7 @@ ScalableFont::ScalableFont(IGUIEnvironment *env, const io::path& filename)
m_fallback_font = NULL;
m_fallback_font_scale = 1.0f;
m_fallback_kerning_width = 0;
m_is_hollow_copy = false;
m_black_border = false;
@@ -52,18 +53,20 @@ ScalableFont::ScalableFont(IGUIEnvironment *env, const io::path& filename)
setInvisibleCharacters ( L" " );
load( file_manager->createXMLReader(filename.c_str()) );
assert(Areas.size() > 0);
}
//! destructor
ScalableFont::~ScalableFont()
{
if (Driver)
Driver->drop();
if (SpriteBank)
SpriteBank->drop();
if (!m_is_hollow_copy)
{
if (Driver) Driver->drop();
if (SpriteBank) SpriteBank->drop();
}
}
void ScalableFont::setShadow(irr::video::SColor col)
{
m_shadow = true;
@@ -193,7 +196,7 @@ bool ScalableFont::load(io::IXMLReader* xml)
}
rectangle.LowerRightCorner.Y = val;
CharacterMap.insert(ch,Areas.size());
CharacterMap[ch] = Areas.size();
//std::cout << "Inserting character '" << ch << "' with area " << Areas.size() << std::endl;
// make frame
@@ -382,7 +385,7 @@ void ScalableFont::readPositions(video::IImage* image, s32& lowerRightPositions)
Areas.push_back(a);
// map letter to character
wchar_t ch = (wchar_t)(lowerRightPositions + 32);
CharacterMap.set(ch, lowerRightPositions);
CharacterMap[ch] = lowerRightPositions;
++lowerRightPositions;
}
@@ -443,11 +446,11 @@ u32 ScalableFont::getSpriteNoFromChar(const wchar_t *c) const
s32 ScalableFont::getAreaFromCharacter(const wchar_t c, bool* fallback_font) const
{
core::map<wchar_t, s32>::Node* n = CharacterMap.find(c);
if (n)
std::map<wchar_t, s32>::const_iterator n = CharacterMap.find(c);
if (n != CharacterMap.end())
{
if (fallback_font != NULL) *fallback_font = false;
return n->getValue();
return (*n).second;
}
else if (m_fallback_font != NULL && fallback_font != NULL)
{
@@ -472,6 +475,8 @@ void ScalableFont::setInvisibleCharacters( const wchar_t *s )
//! returns the dimension of text
core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
{
assert(Areas.size() > 0);
core::dimension2d<u32> dim(0, 0);
core::dimension2d<u32> thisLine(0, (int)(MaxHeight*m_scale));
@@ -499,6 +504,7 @@ core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
bool fallback = false;
const int areaID = getAreaFromCharacter(*p, &fallback);
assert(areaID < (int)Areas.size());
const SFontArea &area = (fallback ? m_fallback_font->Areas[areaID] : Areas[areaID]);

View File

@@ -52,6 +52,8 @@ class ScalableFont : public IGUIFontBitmap
std::map<int /* texture file ID */, TextureInfo> m_texture_files;
void lazyLoadTexture(int texID);
bool m_is_hollow_copy;
public:
bool m_black_border;
@@ -63,6 +65,21 @@ public:
//! constructor
ScalableFont(IGUIEnvironment* env, const io::path& filename);
/** Creates a hollow copy of this font; i.e. the underlying font data is the *same* for
* both fonts. The advantage of doing this is that you can change "view" parameters
* in the copy, for example kerning or scale.
* The object returned by this method is 'new'ed and must be deleted. Deleting it will
* not delete the data of the original. Do *not* delete the original as long as this
* hollow copy is still used, since they share their data (and the original is the one
* that "owns" it).
*/
ScalableFont* getHollowCopy() const
{
ScalableFont* out = new ScalableFont(*this);
out->m_is_hollow_copy = true;
return out;
}
//! destructor
virtual ~ScalableFont();
@@ -132,7 +149,7 @@ private:
void setMaxHeight();
core::array<SFontArea> Areas;
core::map<wchar_t, s32> CharacterMap;
std::map<wchar_t, s32> CharacterMap;
video::IVideoDriver* Driver;
IGUISpriteBank* SpriteBank;
IGUIEnvironment* Environment;

View File

@@ -43,12 +43,16 @@ namespace GUIEngine
Skin* g_skin = NULL;
IGUIFont* g_font;
IGUIFont* g_title_font;
IGUIFont* g_small_font;
IrrlichtDevice* g_device;
IVideoDriver* g_driver;
Screen* g_current_screen = NULL;
AbstractStateManager* g_state_manager = NULL;
Widget* g_focus_for_player[MAX_PLAYER_COUNT];
int font_height;
int small_font_height;
}
using namespace Private;
@@ -91,10 +95,14 @@ namespace GUIEngine
int getFontHeight()
{
// FIXME: this needs to be reset when changing resolution
static int fh = g_font->getDimension( L"X" ).Height;
return fh;
return Private::font_height;
}
int getSmallFontHeight()
{
return Private::small_font_height;
}
// -----------------------------------------------------------------------------
void clear()
{
@@ -176,6 +184,8 @@ void cleanUp()
g_font = NULL;
delete g_title_font;
g_title_font = NULL;
delete g_small_font;
g_small_font = NULL;
// nothing else to delete for now AFAIK, irrlicht will automatically kill everything along the device
}
@@ -218,6 +228,16 @@ void init(IrrlichtDevice* device_a, IVideoDriver* driver_a, AbstractStateManager
sfont->setKerningHeight(-5);
g_font = sfont;
Private::font_height = g_font->getDimension( L"X" ).Height;
//ScalableFont* sfont_smaller = new ScalableFont(g_env, file_manager->getFontFile("StkFont.xml").c_str() );
ScalableFont* sfont_smaller = sfont->getHollowCopy();
sfont_smaller->setScale(normal_text_scale*0.8f);
sfont_smaller->setKerningHeight(-5);
g_small_font = sfont_smaller;
Private::small_font_height = g_small_font->getDimension( L"X" ).Height;
ScalableFont* sfont2 = new ScalableFont(g_env, file_manager->getFontFile("title_font.xml").c_str() );
sfont2->m_fallback_font = sfont;
sfont2->m_fallback_font_scale = 4.0f; // because the fallback font is much smaller than the title font

View File

@@ -258,6 +258,7 @@ namespace GUIEngine
{
extern irr::gui::IGUIEnvironment* g_env;
extern Skin* g_skin;
extern irr::gui::IGUIFont* g_small_font;
extern irr::gui::IGUIFont* g_font;
extern irr::gui::IGUIFont* g_title_font;
@@ -271,6 +272,7 @@ namespace GUIEngine
inline IrrlichtDevice* getDevice() { return Private::g_device; }
inline irr::gui::IGUIEnvironment* getGUIEnv() { return Private::g_env; }
inline irr::video::IVideoDriver* getDriver() { return Private::g_driver; }
inline irr::gui::IGUIFont* getSmallFont() { return Private::g_small_font; }
inline irr::gui::IGUIFont* getFont() { return Private::g_font; }
inline irr::gui::IGUIFont* getTitleFont() { return Private::g_title_font; }
inline Screen* getCurrentScreen() { return Private::g_current_screen; }
@@ -280,6 +282,8 @@ namespace GUIEngine
/** Returns the height of the font in pixels */
int getFontHeight();
int getSmallFontHeight();
float getLatestDt();
/** Add a cutscene to the list of screens known by the gui engine */

View File

@@ -47,17 +47,18 @@ using namespace irr;
*/
RaceGUI::RaceGUI()
{
m_marker_rendered_size = 32;
m_marker_ai_size = 14;
m_marker_player_size = 16;
m_map_rendered_width = 128;
m_map_rendered_height = 128;
m_map_width = 100;
m_map_height = 100;
m_map_left = 10;
m_map_bottom = 10;
m_max_font_height = GUIEngine::getFontHeight() + 10;
m_marker_rendered_size = 32;
m_marker_ai_size = 14;
m_marker_player_size = 16;
m_map_rendered_width = 128;
m_map_rendered_height = 128;
m_map_width = 100;
m_map_height = 100;
m_map_left = 10;
m_map_bottom = 10;
m_max_font_height = GUIEngine::getFontHeight() + 10;
m_small_font_max_height = GUIEngine::getSmallFontHeight() + 5;
// special case : when 3 players play, use available 4th space for such things
if (race_manager->getNumLocalPlayers() == 3)
{
@@ -653,7 +654,7 @@ void RaceGUI::drawAllMessages(const Kart* kart,
const core::recti &viewport,
const core::vector2df &scaling)
{
int y = viewport.LowerRightCorner.Y - m_max_font_height;
int y = viewport.LowerRightCorner.Y - m_small_font_max_height - 10;
const int x = (viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X)/2;
const int w = (viewport.LowerRightCorner.X + viewport.UpperLeftCorner.X)/2;
@@ -668,9 +669,9 @@ void RaceGUI::drawAllMessages(const Kart* kart,
if (msg.m_kart && msg.m_kart!=kart) continue;
core::rect<s32> pos(x - w/2, y, x + w/2, y + m_max_font_height);
GUIEngine::getFont()->draw(core::stringw(msg.m_message.c_str()).c_str(),
pos, msg.m_color, true /* hcenter */, true /* vcenter */);
y -= m_max_font_height;
GUIEngine::getSmallFont()->draw(core::stringw(msg.m_message.c_str()).c_str(),
pos, msg.m_color, true /* hcenter */, true /* vcenter */);
y -= m_small_font_max_height;
}
}

View File

@@ -143,6 +143,7 @@ private:
/** Used to display messages without overlapping */
int m_max_font_height;
int m_small_font_max_height;
void createMarkerTexture();
void createRegularPolygon(unsigned int n, float radius,