Clean up old font code

This commit is contained in:
Benau 2016-07-18 23:00:40 +08:00
parent 05419cd555
commit 6a319cbed2
28 changed files with 376 additions and 1616 deletions

View File

@ -23,8 +23,19 @@
class BoldFace : public FontWithFace
{
private:
virtual std::vector<std::string> getFacesList() const OVERRIDE;
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 1024; }
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const OVERRIDE { return 0.2f; }
// ------------------------------------------------------------------------
virtual unsigned int getScalingFactorTwo() const OVERRIDE { return 120; }
public:
LEAK_CHECK();
LEAK_CHECK()
// ------------------------------------------------------------------------
BoldFace();
// ------------------------------------------------------------------------
@ -33,18 +44,8 @@ public:
virtual void init() OVERRIDE;
// ------------------------------------------------------------------------
virtual void reset() OVERRIDE;
// ------------------------------------------------------------------------
virtual std::vector<std::string> getFacesList() const;
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const { return true; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const { return 1024; }
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const { return 0.2f; }
// ------------------------------------------------------------------------
virtual unsigned int getScalingFactorTwo() const { return 120; }
}; // FontWithFace
}; // BoldFace
#endif
/* EOF */

58
src/font/digit_face.cpp Normal file
View File

@ -0,0 +1,58 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2016 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "font/digit_face.hpp"
#include "config/stk_config.hpp"
// ----------------------------------------------------------------------------
DigitFace::DigitFace() : FontWithFace("DigitFace")
{
} // DigitFace
// ----------------------------------------------------------------------------
void DigitFace::init()
{
FontWithFace::init();
m_font_max_height = m_glyph_max_height + 10;
} // init
// ----------------------------------------------------------------------------
void DigitFace::reset()
{
FontWithFace::reset();
core::stringw preload_chars;
for (int i = 32; i < 64; i++)
{
// No lazy loading for digit font, include the least characters
preload_chars.append((wchar_t)i);
}
// Used when displaying multiple items, e.g. 6x
preload_chars.append((wchar_t)120);
insertCharacters(preload_chars.c_str(), true/*first_load*/);
updateCharactersList();
} // reset
// ----------------------------------------------------------------------------
std::vector<std::string> DigitFace::getFacesList() const
{
return stk_config->m_digit_faces;
} // getFacesList

53
src/font/digit_face.hpp Normal file
View File

@ -0,0 +1,53 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2016 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_DIGIT_FACE_HPP
#define HEADER_DIGIT_FACE_HPP
#include "font/font_with_face.hpp"
class DigitFace : public FontWithFace
{
private:
virtual std::vector<std::string> getFacesList() const OVERRIDE;
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const OVERRIDE { return false; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 256; }
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; }
// ------------------------------------------------------------------------
virtual unsigned int getScalingFactorTwo() const OVERRIDE { return 40; }
// ------------------------------------------------------------------------
virtual unsigned int getVerticalDrawOffset() const OVERRIDE { return 20; }
public:
LEAK_CHECK()
// ------------------------------------------------------------------------
DigitFace();
// ------------------------------------------------------------------------
virtual ~DigitFace() {}
// ------------------------------------------------------------------------
virtual void init() OVERRIDE;
// ------------------------------------------------------------------------
virtual void reset() OVERRIDE;
}; // DigitFace
#endif
/* EOF */

View File

@ -19,8 +19,8 @@
#include "font/font_manager.hpp"
#include "font/bold_face.hpp"
#include "font/digit_face.hpp"
#include "font/regular_face.hpp"
#include "graphics/irr_driver.hpp"
#include "utils/leak_check.hpp"
FontManager *font_manager = NULL;
@ -28,13 +28,14 @@ FontManager *font_manager = NULL;
FontManager::FontManager()
{
checkFTError(FT_Init_FreeType(&m_ft_library), "loading freetype library");
} // FontManager
// ----------------------------------------------------------------------------
FontManager::~FontManager()
{
m_fonts.clearAndDeleteAll();
checkFTError(FT_Done_FreeType(m_ft_library), "removing freetype library");
m_ft_library = NULL;
} // ~FontManager
// ----------------------------------------------------------------------------
@ -46,6 +47,9 @@ void FontManager::loadFonts()
BoldFace* bold = new BoldFace();
bold->init();
m_fonts.push_back(bold);
DigitFace* digit = new DigitFace();
digit->init();
m_fonts.push_back(digit);
} // loadFonts
// ----------------------------------------------------------------------------

View File

@ -34,11 +34,12 @@ class FontWithFace;
class FontManager : public NoCopy
{
private:
FT_Library m_ft_library;
PtrVector<FontWithFace> m_fonts;
FT_Library m_ft_library;
public:
LEAK_CHECK();
LEAK_CHECK()
// ------------------------------------------------------------------------
FontManager();
// ------------------------------------------------------------------------

View File

@ -38,7 +38,7 @@ private:
video::SColor m_shadow_color;
public:
LEAK_CHECK();
LEAK_CHECK()
// ------------------------------------------------------------------------
FontSettings(bool black_border = false, bool rtl = false,
float scale = 1.0f, bool shadow = false,

View File

@ -20,6 +20,7 @@
#include "font/bold_face.hpp"
#include "graphics/2dutils.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/skin.hpp"
#include "utils/string_utils.hpp"
@ -45,6 +46,11 @@ FontWithFace::~FontWithFace()
m_spritebank->drop();
m_spritebank = NULL;
for (unsigned int i = 0; i < m_faces.size(); i++)
{
font_manager->checkFTError(FT_Done_Face(m_faces[i]), "removing face");
}
} // ~FontWithFace
// ----------------------------------------------------------------------------
@ -504,7 +510,7 @@ void FontWithFace::render(const core::stringw& text,
else
{
// Prevent overwriting texture used by billboard text when
// using lazying loading characters
// using lazy loading characters
if (supportLazyLoadChar() && fallback[i])
{
const int cur_texno = m_fallback_font->getSpriteBank()
@ -515,7 +521,7 @@ void FontWithFace::render(const core::stringw& text,
m_fallback_font->createNewGlyphPage();
}
}
else
else if (supportLazyLoadChar())
{
const int cur_texno = m_spritebank
->getSprites()[area.spriteno].Frames[0].textureNumber;

View File

@ -21,9 +21,7 @@
#include "font/font_manager.hpp"
#include "font/font_settings.hpp"
#include "graphics/irr_driver.hpp"
#include "utils/cpp2011.hpp"
#include "utils/leak_check.hpp"
#include <algorithm>
#include <map>
@ -46,11 +44,42 @@ public:
protected:
std::vector<FT_Face> m_faces;
int m_font_max_height;
int m_font_max_height;
int m_glyph_max_height;
int m_glyph_max_height;
unsigned int getDPI() const;
// ------------------------------------------------------------------------
void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
{
if (!supportLazyLoadChar() && !first_load) return;
for (const wchar_t* p = in_ptr; *p; ++p)
{
if (*p == L'\r' || *p == L'\n' || *p < (wchar_t)32)
continue;
if (!loadedChar(*p))
{
loadGlyphInfo(*p);
if (supportChar(*p))
addLazyLoadChar(*p);
else if (m_fallback_font != NULL)
{
if (!m_fallback_font->loadedChar(*p))
{
m_fallback_font->loadGlyphInfo(*p);
if (m_fallback_font->supportChar(*p))
m_fallback_font->addLazyLoadChar(*p);
}
}
}
}
}
// ------------------------------------------------------------------------
void updateCharactersList();
// ------------------------------------------------------------------------
void setFallbackFont(FontWithFace* face) { m_fallback_font = face; }
// ------------------------------------------------------------------------
void setFallbackFontScale(float scale) { m_fallback_font_scale = scale; }
private:
struct FontArea
@ -75,24 +104,23 @@ private:
}
};
FontWithFace* m_fallback_font;
float m_fallback_font_scale;
FontWithFace* m_fallback_font;
float m_fallback_font_scale;
/** A temporary holder stored new char to be inserted.
*/
std::set<wchar_t> m_new_char_holder;
std::set<wchar_t> m_new_char_holder;
gui::IGUISpriteBank* m_spritebank;
gui::IGUISpriteBank* m_spritebank;
/** A full glyph page for this font.
*/
video::IImage* m_page;
video::IImage* m_page;
unsigned int m_temp_height;
unsigned int m_used_width;
unsigned int m_used_height;
unsigned int m_temp_height;
unsigned int m_used_width;
unsigned int m_used_height;
//std::vector<FontArea> m_areas;
std::map<wchar_t, FontArea> m_character_area_map;
std::map<wchar_t, GlyphInfo> m_character_glyph_info_map;
@ -104,33 +132,6 @@ private:
else
return (int)(area.advance_x * scale);
}
public:
LEAK_CHECK();
// ------------------------------------------------------------------------
FontWithFace(const std::string& name);
// ------------------------------------------------------------------------
virtual ~FontWithFace();
// ------------------------------------------------------------------------
virtual void init();
// ------------------------------------------------------------------------
virtual void reset();
// ------------------------------------------------------------------------
void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
// ------------------------------------------------------------------------
void updateCharactersList();
// ------------------------------------------------------------------------
void insertGlyph(wchar_t c, const GlyphInfo& gi);
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const = 0;
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const = 0;
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const = 0;
// ------------------------------------------------------------------------
virtual unsigned int getScalingFactorTwo() const = 0;
// ------------------------------------------------------------------------
virtual std::vector<std::string> getFacesList() const = 0;
// ------------------------------------------------------------------------
bool loadedChar(wchar_t c) const
{
@ -174,35 +175,43 @@ public:
m_character_glyph_info_map[c] = GlyphInfo(font_number, glyph_index);
}
// ------------------------------------------------------------------------
void insertCharacters(const wchar_t* in_ptr)
{
if (!supportLazyLoadChar()) return;
for (const wchar_t* p = in_ptr; *p; ++p)
{
if (*p == L'\r' || *p == L'\n' || *p < (wchar_t)32)
continue;
if (!loadedChar(*p))
{
loadGlyphInfo(*p);
if (supportChar(*p))
addLazyLoadChar(*p);
else if (m_fallback_font != NULL)
{
if (!m_fallback_font->loadedChar(*p))
{
m_fallback_font->loadGlyphInfo(*p);
if (m_fallback_font->supportChar(*p))
m_fallback_font->addLazyLoadChar(*p);
}
}
}
}
}
void createNewGlyphPage();
// ------------------------------------------------------------------------
unsigned int getDPI() const;
// ------------------------------------------------------------------------
gui::IGUISpriteBank* getSpriteBank() const { return m_spritebank; }
// ------------------------------------------------------------------------
void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
// ------------------------------------------------------------------------
void insertGlyph(wchar_t c, const GlyphInfo& gi);
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const = 0;
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const = 0;
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const = 0;
// ------------------------------------------------------------------------
virtual unsigned int getScalingFactorTwo() const = 0;
// ------------------------------------------------------------------------
virtual std::vector<std::string> getFacesList() const = 0;
// ------------------------------------------------------------------------
virtual unsigned int getVerticalDrawOffset() const { return 0; }
// ------------------------------------------------------------------------
const FontArea& getAreaFromCharacter(const wchar_t c,
bool* fallback_font) const;
// ------------------------------------------------------------------------
public:
LEAK_CHECK();
// ------------------------------------------------------------------------
FontWithFace(const std::string& name);
// ------------------------------------------------------------------------
virtual ~FontWithFace();
// ------------------------------------------------------------------------
virtual void init();
// ------------------------------------------------------------------------
virtual void reset();
// ------------------------------------------------------------------------
core::dimension2d<u32> getDimension(const wchar_t* text,
FontSettings* font_settings = NULL);
// ------------------------------------------------------------------------
@ -215,17 +224,9 @@ public:
FontSettings* font_settings = NULL,
FontCharCollector* char_collector = NULL);
// ------------------------------------------------------------------------
gui::IGUISpriteBank* getSpriteBank() const { return m_spritebank; }
// ------------------------------------------------------------------------
void createNewGlyphPage();
// ------------------------------------------------------------------------
void setFallbackFont(FontWithFace* face) { m_fallback_font = face; }
// ------------------------------------------------------------------------
void setFallbackFontScale(float scale) { m_fallback_font_scale = scale; }
// ------------------------------------------------------------------------
/** Write the current glyph page in png inside current running directory.
* Mainly for debug use.
* \param fn The file name.
* \param name The file name.
*/
void dumpGlyphPage(const std::string& name);
// ------------------------------------------------------------------------

View File

@ -23,8 +23,19 @@
class RegularFace : public FontWithFace
{
private:
virtual std::vector<std::string> getFacesList() const OVERRIDE;
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 512; }
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; }
// ------------------------------------------------------------------------
virtual unsigned int getScalingFactorTwo() const OVERRIDE { return 27; }
public:
LEAK_CHECK();
LEAK_CHECK()
// ------------------------------------------------------------------------
RegularFace();
// ------------------------------------------------------------------------
@ -33,18 +44,8 @@ public:
virtual void init() OVERRIDE;
// ------------------------------------------------------------------------
virtual void reset() OVERRIDE;
// ------------------------------------------------------------------------
virtual std::vector<std::string> getFacesList() const;
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const { return true; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const { return 512; }
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const { return 0.7f; }
// ------------------------------------------------------------------------
virtual unsigned int getScalingFactorTwo() const { return 27; }
}; // FontWithFace
}; // RegularFace
#endif
/* EOF */

View File

@ -18,6 +18,7 @@
#include "graphics/irr_driver.hpp"
#include "config/user_config.hpp"
#include "font/font_manager.hpp"
#include "graphics/callbacks.hpp"
#include "graphics/camera.hpp"
#include "graphics/central_settings.hpp"
@ -847,6 +848,8 @@ void IrrDriver::applyResolutionSettings()
Referee::cleanup();
ParticleKindManager::get()->cleanup();
delete input_manager;
delete font_manager;
font_manager = NULL;
GUIEngine::clear();
GUIEngine::cleanUp();
@ -875,6 +878,8 @@ void IrrDriver::applyResolutionSettings()
}
initDevice();
font_manager = new FontManager();
font_manager->loadFonts();
// Re-init GUI engine
GUIEngine::init(m_device, m_video_driver, StateManager::get());

View File

@ -658,6 +658,7 @@ namespace GUIEngine
#include "config/user_config.hpp"
#include "font/bold_face.hpp"
#include "font/digit_face.hpp"
#include "font/regular_face.hpp"
#include "input/input_manager.hpp"
#include "io/file_manager.hpp"
@ -690,8 +691,6 @@ namespace GUIEngine
{
IGUIEnvironment* g_env;
Skin* g_skin = NULL;
FTEnvironment* g_ft_env = NULL;
GlyphPageCreator* g_gp_creator = NULL;
ScalableFont *g_font;
ScalableFont *g_outline_font;
ScalableFont *g_large_font;
@ -956,11 +955,6 @@ namespace GUIEngine
//if (g_skin != NULL) delete g_skin;
g_skin = NULL;
//delete g_ft_env;
//g_ft_env = NULL;
//delete g_gp_creator;
//g_gp_creator = NULL;
for (unsigned int i=0; i<g_loaded_screens.size(); i++)
{
g_loaded_screens[i].unload();
@ -991,12 +985,6 @@ namespace GUIEngine
// kill everything along the device
} // cleanUp
// -----------------------------------------------------------------------
void cleanHollowCopyFont()
{
} // cleanHollowCopyFont
// -----------------------------------------------------------------------
/**
@ -1024,9 +1012,6 @@ namespace GUIEngine
g_focus_for_player[n] = NULL;
}
//g_ft_env = new FTEnvironment();
//g_gp_creator = new GlyphPageCreator();
/*
To make the g_font a little bit nicer, we load an external g_font
and set it as the new default g_font in the g_skin.
@ -1062,8 +1047,9 @@ namespace GUIEngine
RegularFace* regular = font_manager->getFont<RegularFace>();
BoldFace* bold = font_manager->getFont<BoldFace>();
DigitFace* digit = font_manager->getFont<DigitFace>();
ScalableFont* digit_font = new ScalableFont(regular);
ScalableFont* digit_font = new ScalableFont(digit);
g_digit_font = digit_font;
ScalableFont* sfont = new ScalableFont(regular);
@ -1099,11 +1085,6 @@ namespace GUIEngine
g_device->getVideoDriver()->endScene();
} // init
// -----------------------------------------------------------------------
void reloadHollowCopyFont(irr::gui::ScalableFont* sfont)
{
} // reloadHollowCopyFont
// -----------------------------------------------------------------------
void reloadSkin()
{

View File

@ -39,9 +39,6 @@ namespace irr
#include "utils/constants.hpp"
#include "utils/ptr_vector.hpp"
#include "guiengine/ft_environment.hpp"
#include "guiengine/glyph_page_creator.hpp"
/**
* \ingroup guiengine
* \brief Contains all GUI engine related classes and functions
@ -84,8 +81,6 @@ namespace GUIEngine
{
extern irr::gui::IGUIEnvironment* g_env;
extern Skin* g_skin;
extern FTEnvironment* g_ft_env;
extern GlyphPageCreator* g_gp_creator;
extern irr::gui::ScalableFont* g_small_font;
extern irr::gui::ScalableFont* g_font;
extern irr::gui::ScalableFont* g_outline_font;
@ -177,18 +172,6 @@ namespace GUIEngine
*/
inline Skin* getSkin() { return Private::g_skin; }
/**
* \pre GUIEngine::init must have been called first
* \return the freetype and library with face
*/
inline FTEnvironment* getFreetype() { return Private::g_ft_env; }
/**
* \pre GUIEngine::init must have been called first
* \return the glyph page creator, useful to create a glyph page from individual char
*/
inline GlyphPageCreator* getGlyphPageCreator() { return Private::g_gp_creator; }
Screen* getScreenNamed(const char* name);
/** \return the height of the title font in pixels */
@ -265,11 +248,6 @@ namespace GUIEngine
*/
void reloadSkin();
/**
* \brief call when translation in user config was updated for freetype rendering STK
*/
void cleanHollowCopyFont();
void reloadHollowCopyFont(irr::gui::ScalableFont*);
}
#endif

View File

@ -1,147 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2015 Ben Au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "graphics/irr_driver.hpp"
#include "guiengine/ft_environment.hpp"
#include "io/file_manager.hpp"
#include "utils/log.hpp"
#include "config/stk_config.hpp"
#include <algorithm>
using namespace gui;
namespace GUIEngine
{
// ----------------------------------------------------------------------------
FTEnvironment::FTEnvironment()
{
Log::info("Freetype Environment", "Loading fonts...");
checkError(FT_Init_FreeType(&m_ft_lib), "loading freetype library");
loadFont();
}
// ----------------------------------------------------------------------------
FTEnvironment::~FTEnvironment()
{
for (int i = 0; i < F_COUNT; ++i)
checkError(FT_Done_Face(m_ft_face[i]), "removing freetype face");
checkError(FT_Done_FreeType(m_ft_lib), "removing freetype library");
}
// ----------------------------------------------------------------------------
FT_Face FTEnvironment::getFace(const FontUse font)
{
return m_ft_face[font];
}
// ----------------------------------------------------------------------------
void FTEnvironment::checkError(FT_Error err, const irr::core::stringc desc)
{
if (err)
{
Log::error("Freetype Environment", "Something wrong when %s!", desc.c_str());
}
}
// ----------------------------------------------------------------------------
void FTEnvironment::loadFont()
{
checkError(FT_New_Face(m_ft_lib, (file_manager->getAssetChecked
(FileManager::TTF, stk_config->m_font_default.c_str(), true)).c_str(),
0, &m_ft_face[F_DEFAULT]), "loading F_DEFAULT");
checkError(FT_New_Face(m_ft_lib, (file_manager->getAssetChecked
(FileManager::TTF, stk_config->m_font_default_fallback.c_str(), true)).c_str(),
0, &m_ft_face[F_DEFAULT_FALLBACK]), "loading F_DEFAULT_FALLBACK");
checkError(FT_New_Face(m_ft_lib, (file_manager->getAssetChecked
(FileManager::TTF, stk_config->m_font_cjk.c_str(), true)).c_str(),
0, &m_ft_face[F_CJK]), "loading F_CJK");
checkError(FT_New_Face(m_ft_lib, (file_manager->getAssetChecked
(FileManager::TTF, stk_config->m_font_ar.c_str(), true)).c_str(),
0, &m_ft_face[F_AR]), "loading F_AR");
checkError(FT_New_Face(m_ft_lib, (file_manager->getAssetChecked
(FileManager::TTF, stk_config->m_font_bold.c_str(), true)).c_str(),
0, &m_ft_face[F_BOLD]), "loading F_BOLD");
checkError(FT_New_Face(m_ft_lib, (file_manager->getAssetChecked
(FileManager::TTF, stk_config->m_font_bold_fallback.c_str(), true)).c_str(),
0, &m_ft_face[F_BOLD_FALLBACK]), "loading F_BOLD_FALLBACK");
checkError(FT_New_Face(m_ft_lib, (file_manager->getAssetChecked
(FileManager::TTF, stk_config->m_font_digit.c_str(),true)).c_str(),
0, &m_ft_face[F_DIGIT]), "loading F_DIGIT");
//Set charmap
for (int h = 0; h < F_COUNT; ++h)
{
for (int i = 0; i < m_ft_face[h]->num_charmaps; ++i)
{
FT_UShort pid = m_ft_face[h]->charmaps[i]->platform_id;
FT_UShort eid = m_ft_face[h]->charmaps[i]->encoding_id;
if (((pid == 0) && (eid == 3)) || ((pid == 3) && (eid == 1)))
checkError(FT_Set_Charmap(m_ft_face[h], m_ft_face[h]->charmaps[i]), "setting charmaps");
}
}
// Set face dpi
// font size is resolution-dependent.
// normal text will range from 0.8, in 640x* resolutions (won't scale
// below that) to 1.0, in 1024x* resolutions, and linearly up
// normal text will range from 0.2, in 640x* resolutions (won't scale
// below that) to 0.4, in 1024x* resolutions, and linearly up
const s32 screen_width = irr_driver->getFrameSize().Width;
const s32 screen_height = irr_driver->getFrameSize().Height;
float scale = std::max(0, screen_width - 640)/564.0f;
// attempt to compensate for small screens
if (screen_width < 1200) scale = std::max(0, screen_width - 640) / 750.0f;
if (screen_width < 900 || screen_height < 700) scale = std::min(scale, 0.05f);
const u32 normal_dpi = u32((0.7f + 0.2f*scale)*27);
const u32 title_dpi = u32((0.2f + 0.2f*scale)*120);
const u32 digit_dpi = u32((0.7f + 0.2f*scale)*40);
Log::info("Freetype Environment", "DPI for Normal Font is %d.", normal_dpi);
Log::info("Freetype Environment", "DPI for Title Font is %d.", title_dpi);
Log::info("Freetype Environment", "DPI for Digit Font is %d.", digit_dpi);
checkError(FT_Set_Pixel_Sizes(m_ft_face[F_DEFAULT], 0, normal_dpi), "setting F_DEFAULT size");
checkError(FT_Set_Pixel_Sizes(m_ft_face[F_DEFAULT_FALLBACK], 0, normal_dpi), "setting F_DEFAULT_FALLBACK size");
checkError(FT_Set_Pixel_Sizes(m_ft_face[F_CJK], 0, normal_dpi), "setting F_CJK size");
checkError(FT_Set_Pixel_Sizes(m_ft_face[F_AR], 0, normal_dpi), "setting F_AR size");
checkError(FT_Set_Pixel_Sizes(m_ft_face[F_BOLD], 0, title_dpi), "setting F_BOLD size");
checkError(FT_Set_Pixel_Sizes(m_ft_face[F_BOLD_FALLBACK], 0, title_dpi), "setting F_BOLD_FALLBACK size");
checkError(FT_Set_Pixel_Sizes(m_ft_face[F_DIGIT], 0, digit_dpi), "setting F_DIGIT size");
}
FT_Library FTEnvironment::m_ft_lib = NULL;
} // guiengine

View File

@ -1,81 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2015 Ben Au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_FT_ENVIRONMENT_HPP
#define HEADER_FT_ENVIRONMENT_HPP
#include <ft2build.h>
#include FT_FREETYPE_H
#include <irrlicht.h>
#include "utils/leak_check.hpp"
/**
* \ingroup guiengine
*/
namespace GUIEngine
{
enum FontUse
{
F_DEFAULT = 0,
F_DEFAULT_FALLBACK = 1,
F_CJK = 2,
F_AR = 3,
F_LAST_REGULAR_FONT = F_AR,
F_BOLD = 4,
F_BOLD_FALLBACK = 5,
F_DIGIT = 6,
F_COUNT = 7
};
enum TTFLoadingType {T_NORMAL, T_DIGIT, T_BOLD};
/**
* \brief Initialize a freetype environment with a single freetype library.
*/
class FTEnvironment
{
public:
LEAK_CHECK()
FTEnvironment();
~FTEnvironment();
/** Get a face with a suitable font type.
*/
FT_Face getFace(const FontUse font);
private:
/** Check for any error discovered in a freetype function that will return a FT_Error value.
* \param err The Freetype function.
* \param desc The description of what is the function doing.
*/
void checkError(FT_Error err, const irr::core::stringc desc);
/** Load font face into memory, but don't create glyph yet.
*/
void loadFont();
FT_Face m_ft_face[F_COUNT];
static FT_Library m_ft_lib;
};
} // guiengine
#endif // HEADER_FT_ENVIRONMENT_HPP

View File

@ -1,185 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2010 John Norman
// Copyright (C) 2015 Ben Au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// The image loading function is partially based on CGUITTFont.cpp by John Norman,
// original version is located here:
//
// http://irrlicht.suckerfreegames.com/
#include <irrlicht.h>
#include "guiengine/engine.hpp"
namespace GUIEngine
{
// ----------------------------------------------------------------------------
GlyphPageCreator::GlyphPageCreator()
{
m_page = GUIEngine::getDriver()->createImage(video::ECF_A8R8G8B8, core::dimension2du(512, 512));
m_image = 0;
}
// ----------------------------------------------------------------------------
GlyphPageCreator::~GlyphPageCreator()
{
clearGlyphPage();
clearNewCharHolder();
m_page->drop();
m_page = 0;
}
// ----------------------------------------------------------------------------
void GlyphPageCreator::dumpGlyphPage(const core::stringc fn)
{
GUIEngine::getDriver()->writeImageToFile(m_page, fn + ".png");
}
// ----------------------------------------------------------------------------
bool GlyphPageCreator::checkEnoughSpace(FT_Bitmap bits)
{
core::dimension2du d(bits.width + 1, bits.rows + 1);
core::dimension2du texture_size;
texture_size = d.getOptimalSize(!(GUIEngine::getDriver()->queryFeature(video::EVDF_TEXTURE_NPOT)),
!(GUIEngine::getDriver()->queryFeature(video::EVDF_TEXTURE_NSQUARE)), true, 0);
if ((m_used_width + texture_size.Width > 512 && m_used_height + m_temp_height + texture_size.Height > 512)
|| m_used_height + texture_size.Height > 512)
return false;
return true;
}
// ----------------------------------------------------------------------------
void GlyphPageCreator::clearNewCharHolder()
{
m_new_char_holder.clear();
}
// ----------------------------------------------------------------------------
void GlyphPageCreator::clearGlyphPage()
{
m_used_width = 0;
m_temp_height = 0;
m_used_height = 0;
}
// ----------------------------------------------------------------------------
void GlyphPageCreator::createNewGlyphPage()
{
//Clean the current glyph page by filling it with transparent content
m_page->fill(video::SColor(0, 255, 255, 255));
}
// ----------------------------------------------------------------------------
video::IImage* GlyphPageCreator::getPage()
{
return m_page;
}
// ----------------------------------------------------------------------------
core::stringw GlyphPageCreator::getNewChar()
{
core::stringw c;
for (std::set<wchar_t>::iterator it = m_new_char_holder.begin(); it != m_new_char_holder.end(); ++it)
c += *it;
return c;
}
// ----------------------------------------------------------------------------
void GlyphPageCreator::insertChar(const wchar_t c)
{
m_new_char_holder.insert(c);
}
// ----------------------------------------------------------------------------
bool GlyphPageCreator::insertGlyph(FT_Bitmap bits, core::rect<s32>& rect)
{
core::dimension2du d(bits.width + 1, bits.rows + 1);
core::dimension2du texture_size;
switch (bits.pixel_mode)
{
case FT_PIXEL_MODE_GRAY:
{
// Create our blank image.
texture_size = d.getOptimalSize(!(GUIEngine::getDriver()->queryFeature(video::EVDF_TEXTURE_NPOT)),
!(GUIEngine::getDriver()->queryFeature(video::EVDF_TEXTURE_NSQUARE)), true, 0);
m_image = GUIEngine::getDriver()->createImage(video::ECF_A8R8G8B8, texture_size);
m_image->fill(video::SColor(0, 255, 255, 255));
// Load the grayscale data in.
const float gray_count = static_cast<float>(bits.num_grays);
const u32 image_pitch = m_image->getPitch() / sizeof(u32);
u32* image_data = (u32*)m_image->lock();
u8* glyph_data = bits.buffer;
for (u32 y = 0; y < (unsigned)bits.rows; ++y)
{
u8* row = glyph_data;
for (u32 x = 0; x < (unsigned)bits.width; ++x)
{
image_data[y * image_pitch + x] |= static_cast<u32>(255.0f * (static_cast<float>(*row++) / gray_count)) << 24;
//data[y * image_pitch + x] |= ((u32)(*bitsdata++) << 24);
}
glyph_data += bits.pitch;
}
m_image->unlock();
break;
}
default:
return false;
}
if (!m_image)
return false;
//Done creating a single glyph, now copy to the glyph page...
//Determine the linebreak location
if (m_used_width + texture_size.Width > 512)
{
m_used_width = 0;
m_used_height += m_temp_height;
m_temp_height = 0;
}
//Copy now
m_image->copyTo(m_page, core::position2di(m_used_width, m_used_height));
//Store the rectangle of current glyph
rect = core::rect<s32> (m_used_width, m_used_height, m_used_width + bits.width, m_used_height + bits.rows);
m_image->drop();
m_image = 0;
//Store used area
m_used_width += texture_size.Width;
if (m_temp_height < texture_size.Height)
m_temp_height = texture_size.Height;
return true;
}
} // guiengine

View File

@ -1,109 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2015 Ben Au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <IVideoDriver.h>
#include <irrlicht.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include <set>
#include "utils/leak_check.hpp"
using namespace irr;
/**
* \ingroup guiengine
*/
namespace GUIEngine
{
/**
* \brief Create glyph pages for different fonts.
*/
class GlyphPageCreator
{
public:
LEAK_CHECK()
GlyphPageCreator();
~GlyphPageCreator();
/** Write the current glyph page into png on current running directory.
* Mainly for debug use.
* \param fn The file name.
*/
void dumpGlyphPage(const core::stringc fn);
/** Check whether it is ok the fit the inputted glyph into the current glyph page.
* \param bits The Glyph bitmap inputted.
* \return True if there is enough space.
*/
bool checkEnoughSpace(FT_Bitmap bits);
/** Reset position of glyph on the current glyph page.
*/
void clearGlyphPage();
/** Reset characters holder for lazy loading char.
*/
void clearNewCharHolder();
/** Clear (fill it with transparent content) the current glyph page.
*/
void createNewGlyphPage();
/** Used to get a glyph page which is loaded later for texture
* \return Glyph page image.
*/
video::IImage* getPage();
/** Used to get the string of new characters inside set m_new_char_holder for lazy char loading.
* \return string of wild-character.
*/
core::stringw getNewChar();
/** Used to insert a single new character into glyph page used for lazy char loading.
* \param c A new character.
*/
void insertChar(const wchar_t c);
/** Used to insert a single glyph bitmap into the glyph page
* \param bits The Glyph bitmap inputted.
* \param rect Give the rectangle of the glyph on the page.
* \return True if a glyph is loaded.
*/
bool insertGlyph(FT_Bitmap bits, core::rect<s32>& rect);
private:
/** A temporary storage for a single glyph.
*/
video::IImage* m_image;
/** A temporary holder stored new char to be inserted.
*/
std::set<wchar_t> m_new_char_holder;
/** A full glyph page.
*/
video::IImage* m_page;
u32 m_temp_height;
u32 m_used_width;
u32 m_used_height;
};
} // guiengine

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// Copyright (C) 2015 SuperTuxKart-Team
// Copyright (C) 2016 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -20,821 +20,95 @@
#include "font/font_manager.hpp"
#include "font/font_with_face.hpp"
#include "font/regular_face.hpp"
#include "graphics/2dutils.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/skin.hpp"
#include "io/file_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include <clocale>
#include <cmath>
#include <cwctype>
using namespace GUIEngine;
namespace irr
{
namespace gui
{
// ----------------------------------------------------------------------------
ScalableFont::ScalableFont(FontWithFace* face): m_video_driver(0), m_spritebank(0),
m_max_height(0), m_global_kerning_width(0), m_global_kerning_height(0)
ScalableFont::ScalableFont(FontWithFace* face)
{
m_face = face;
m_font_settings = new FontSettings();
}
} // ScalableFont
// ----------------------------------------------------------------------------
ScalableFont::ScalableFont(IGUIEnvironment *env, TTFLoadingType type)
: m_video_driver(0), m_spritebank(0), m_gui_env(env),
m_max_height(0), m_global_kerning_width(0), m_global_kerning_height(0)
{
m_font_settings = new FontSettings();
#ifdef _DEBUG
setDebugName("ScalableFont");
#endif
m_fallback_font = NULL;
m_fallback_kerning_width = 0;
m_fallback_font_scale = 1.0f;
m_scale = 1.0f;
m_is_hollow_copy = false;
m_black_border = false;
m_type = type;
m_font_use = (FontUse)0;
m_shadow = false;
m_mono_space_digits = false;
m_rtl = translations->isRTLLanguage();
if (m_gui_env)
{
// don't grab environment, to avoid circular references
m_video_driver = m_gui_env->getVideoDriver();
m_spritebank = m_gui_env->addEmptySpriteBank(
(StringUtils::toString(type)).c_str());
if (m_spritebank)
m_spritebank->grab();
}
if (m_video_driver)
m_video_driver->grab();
setInvisibleCharacters(L" ");
if (!loadTTF())
{
Log::fatal("ScalableFont", "Loading TTF font failed");
}
assert(m_areas.size() > 0);
}
// ----------------------------------------------------------------------------
ScalableFont::~ScalableFont()
{
delete m_font_settings;
}
} // ~ScalableFont
// ----------------------------------------------------------------------------
bool ScalableFont::loadTTF()
{
if (!m_spritebank)
{
Log::error("ScalableFont::loadTTF", "SpriteBank is NULL!!");
return false;
}
switch(m_type)
{
case T_NORMAL:
m_font_use = F_DEFAULT;
break;
case T_DIGIT:
m_font_use = F_DIGIT;
break;
case T_BOLD:
m_font_use = F_BOLD;
break;
}
GUIEngine::GlyphPageCreator* gp_creator = GUIEngine::getGlyphPageCreator();
//Initialize glyph slot
FT_GlyphSlot slot;
FT_Error err;
std::vector <s32> offset;
std::vector <s32> bearingx;
std::vector <s32> advance;
std::vector <s32> height;
std::set<wchar_t>::iterator it;
s32 curr_maxheight = 0;
s32 t;
u32 texno = 0;
m_spritebank->addTexture(NULL);
gp_creator->clearGlyphPage();
gp_creator->createNewGlyphPage();
GUIEngine::FTEnvironment* ft_env = GUIEngine::getFreetype();
std::set<wchar_t> preload_char = getPreloadCharacters(m_type);
it = preload_char.begin();
while (it != preload_char.end())
{
SGUISpriteFrame f;
SGUISprite s;
core::rect<s32> rectangle;
int idx;
if (m_type == T_BOLD) //Lite-Fontconfig for stk, this one is specifically for bold title
{
int count = F_BOLD;
while (count < GUIEngine::F_COUNT)
{
m_font_use = (FontUse)count;
FT_Face curr_face = ft_env->getFace(m_font_use);
idx = FT_Get_Char_Index(curr_face, *it);
if (idx > 0) break;
count++;
}
}
else
{
FT_Face curr_face = ft_env->getFace(m_font_use);
idx = FT_Get_Char_Index(curr_face, *it);
}
FT_Face curr_face = ft_env->getFace(m_font_use);
slot = curr_face->glyph;
if (idx)
{
// Load glyph image into the slot (erase previous one)
err = FT_Load_Glyph(curr_face, idx,
FT_LOAD_DEFAULT | FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL);
if (err)
Log::error("ScalableFont::loadTTF", "Can't load a single glyph.");
// Store vertical offset on line.
s32 curr_offset = (curr_face->glyph->metrics.height >> 6) - (curr_face->glyph->metrics.horiBearingY >> 6);
offset.push_back(curr_offset);
// This is to be used later.
t = curr_face->glyph->metrics.height >> 6;
height.push_back(t);
if (t > curr_maxheight)
{
if (t > 20)
{
}
curr_maxheight = t;
}
// Store horizontal padding (bearingX).
s32 curr_bearingx = curr_face->glyph->metrics.horiBearingX >> 6;
bearingx.push_back(curr_bearingx);
// Store total width on horizontal line.
s32 curr_advance = curr_face->glyph->advance.x >> 6;
advance.push_back(curr_advance);
// Convert to an anti-aliased bitmap
FT_Bitmap bits = slot->bitmap;
m_character_map[*it] = m_spritebank->getSprites().size();
if (!gp_creator->checkEnoughSpace(bits))
// Glyph page is full, save current one and reset the current page
{
#ifdef FONT_DEBUG
gp_creator->dumpGlyphPage(((std::to_string(m_type)) + "_" + (std::to_string(texno))).c_str());
#endif
m_spritebank->setTexture(texno, m_video_driver->addTexture("Glyph_page", gp_creator->getPage()));
gp_creator->clearGlyphPage();
m_spritebank->addTexture(NULL);
gp_creator->createNewGlyphPage();
texno++;
}
// Inserting now
if (gp_creator->insertGlyph(bits, rectangle))
{
f.rectNumber = m_spritebank->getPositions().size();
f.textureNumber = texno;
// add frame to sprite
s.Frames.push_back(f);
s.frameTime = 0;
m_spritebank->getPositions().push_back(rectangle);
m_spritebank->getSprites().push_back(s);
}
else
return false;
}
// Check for glyph page which can fit all characters
if (it == --preload_char.end())
{
#ifdef FONT_DEBUG
gp_creator->dumpGlyphPage(((std::to_string(m_type)) + "_" + (std::to_string(texno))).c_str());
#endif
if (m_type == T_NORMAL)
{
m_last_normal_page = m_video_driver->addTexture("Glyph_page", gp_creator->getPage());
m_spritebank->setTexture(texno, m_last_normal_page);
}
else
m_spritebank->setTexture(texno, m_video_driver->addTexture("Glyph_page", gp_creator->getPage()));
}
if (*it == (wchar_t)32 && m_spritebank->getPositions().size() == 1)
continue; //Preventing getAreaIDFromCharacter of whitespace == 0, which make space disappear
else ++it;
}
//Fix unused glyphs....
if (m_type == T_NORMAL || T_BOLD)
{
m_character_map[(wchar_t)9] = getAreaIDFromCharacter((wchar_t)160, NULL); //Use non-breaking space glyph to tab.
m_character_map[(wchar_t)173] = 0; //Don't need a glyph for the soft hypen, as it only print when not having enough space.
//And then it will convert to a "-".
if (m_type == T_NORMAL)
{
m_character_map[(wchar_t)8204] = 0; //They are zero width chars found in Arabic.
m_character_map[(wchar_t)65279] = 0;
}
}
if (m_type == T_BOLD)
{
setlocale(LC_ALL, "en_US.UTF8");
for (it = preload_char.begin(); it != preload_char.end(); ++it)
{
if (iswupper((wchar_t)*it) && *it < 640)
m_character_map[towlower((wchar_t)*it)] = getAreaIDFromCharacter(*it, NULL);
}
}
for (unsigned int n = 0 ; n < m_spritebank->getSprites().size(); ++n)
{
//Storing now
SFontArea a;
a.spriteno = n;
a.offsety = curr_maxheight - height.at(n)
+ offset.at(n); //Compute the correct offset as ttf texture image is cropped against the glyph fully.
a.offsety_bt = -offset.at(n); //FIXME
//Specific offset for billboard text as billboard text seems to be drawn bottom-up,
//as the offset in calculated based on the fact that the characters are drawn all
//at the bottom line, so no addition is required, but if we can make draw2dimage draw
//characters close to the bottom line too, than only one offsety is needed.
if (!n) //Skip width-less characters
a.bearingx = 0;
else
a.bearingx = bearingx.at(n);
if (!n) //Skip width-less characters
a.width = 0;
else
a.width = advance.at(n);
// add character to font
m_areas.push_back(a);
}
//Reserve 10 for normal font new characters added, 40 for digit font to display separately
//Consider fallback font (bold) too
m_max_height = (int)((curr_maxheight + (m_type == T_DIGIT ? 40 : 10) +
(m_type == T_BOLD ? 20 : 0))*m_scale);
m_glyph_max_height = curr_maxheight;
for(wchar_t c = '0'; c <= '9'; c++)
{
SFontArea a = getAreaFromCharacter(c, NULL);
m_max_digit_area.width = a.width;
m_max_digit_area.offsety = a.offsety;
m_max_digit_area.bearingx = a.bearingx;
}
switch (m_type)
{
case T_NORMAL:
Log::info("ScalableFont::loadTTF", "Created %d glyphs "
"supporting %d characters for normal font %s using %d glyph page(s)."
, m_areas.size(), m_character_map.size(), ft_env->getFace(m_font_use)->family_name, m_spritebank->getTextureCount());
break;
case T_DIGIT:
Log::info("ScalableFont::loadTTF", "Created %d glyphs "
"supporting %d characters for high-res digits font %s using %d glyph page(s)."
, m_areas.size(), m_character_map.size(), ft_env->getFace(m_font_use)->family_name, m_spritebank->getTextureCount());
break;
case T_BOLD:
Log::info("ScalableFont::loadTTF", "Created %d glyphs "
"supporting %d characters for bold title font %s using %d glyph page(s)."
, m_areas.size(), m_character_map.size(), ft_env->getFace(m_font_use)->family_name, m_spritebank->getTextureCount());
break;
}
return true;
}
// ----------------------------------------------------------------------------
bool ScalableFont::lazyLoadChar()
{
//Mainly copy from loadTTF(), so removing unnecessary comments
if (m_type != T_NORMAL) return false; //Make sure only insert char inside normal font
FT_GlyphSlot slot;
FT_Error err;
GUIEngine::FTEnvironment* ft_env = GUIEngine::getFreetype();
GUIEngine::GlyphPageCreator* gp_creator = GUIEngine::getGlyphPageCreator();
s32 height;
s32 bearingx;
s32 curr_offset;
s32 width;
u32 texno = m_spritebank->getTextureCount() - 1;
core::stringw lazy_load = gp_creator->getNewChar();
for (u32 i = 0; i < lazy_load.size(); ++i)
{
SGUISpriteFrame f;
SGUISprite s;
core::rect<s32> rectangle;
//Lite-Fontconfig for stk
int idx;
int font = F_DEFAULT;
while (font <= F_LAST_REGULAR_FONT)
{
m_font_use = (FontUse)font;
idx = FT_Get_Char_Index(ft_env->getFace(m_font_use), lazy_load[i]);
if (idx > 0) break;
font++;
}
FT_Face curr_face = ft_env->getFace(m_font_use);
slot = curr_face->glyph;
if (idx)
{
err = FT_Load_Glyph(curr_face, idx,
FT_LOAD_DEFAULT | FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL);
if (err)
Log::error("ScalableFont::loadTTF", "Can't load a single glyph.");
curr_offset = (curr_face->glyph->metrics.height >> 6) - (curr_face->glyph->metrics.horiBearingY >> 6);
height = curr_face->glyph->metrics.height >> 6;
bearingx = curr_face->glyph->metrics.horiBearingX >> 6;
width = curr_face->glyph->advance.x >> 6;
FT_Bitmap bits = slot->bitmap;
m_character_map[lazy_load[i]] = m_spritebank->getSprites().size();
if (!gp_creator->checkEnoughSpace(bits))
{
#ifdef FONT_DEBUG
gp_creator->dumpGlyphPage(((std::to_string(m_type)) + "_" + (std::to_string(texno))).c_str());
#endif
m_spritebank->setTexture(texno, m_video_driver->addTexture("Glyph_page", gp_creator->getPage()));
gp_creator->clearGlyphPage();
m_spritebank->addTexture(NULL);
gp_creator->createNewGlyphPage();
texno++;
}
if (gp_creator->insertGlyph(bits, rectangle))
{
f.rectNumber = m_spritebank->getPositions().size();
f.textureNumber = texno;
s.Frames.push_back(f);
s.frameTime = 0;
m_spritebank->getPositions().push_back(rectangle);
m_spritebank->getSprites().push_back(s);
}
else
return false;
SFontArea a;
a.spriteno = m_spritebank->getSprites().size() - 1;
a.offsety = m_glyph_max_height - height + curr_offset;
a.offsety_bt = -curr_offset;
a.bearingx = bearingx;
a.width = width;
m_areas.push_back(a);
}
else
m_character_map[lazy_load[i]] = 1; //Set any wrong characters to 1 (space), preventing it from loading again
}
#ifdef FONT_DEBUG
gp_creator->dumpGlyphPage(((std::to_string(m_type)) + "_" + (std::to_string(texno))).c_str());
#endif
gp_creator->clearNewCharHolder(); //Clear the Newly characters in creator after they are loaded
m_video_driver->removeTexture(m_last_normal_page); //Remove old texture
m_last_normal_page = m_video_driver->addTexture("Glyph_page", gp_creator->getPage());
m_spritebank->setTexture(texno, m_last_normal_page);
if (!m_is_hollow_copy)
{
GUIEngine::cleanHollowCopyFont();
GUIEngine::reloadHollowCopyFont(GUIEngine::getFont());
}
Log::debug("ScalableFont::lazyLoadChar", "New characters drawn by %s inserted, there are %d glyphs "
"supporting %d characters for normal font using %d glyph page(s) now."
, ft_env->getFace(m_font_use)->family_name, m_areas.size(), m_character_map.size(), m_spritebank->getTextureCount());
return true;
}
// ----------------------------------------------------------------------------
void ScalableFont::forceNewPage()
{
GUIEngine::GlyphPageCreator* gp_creator = GUIEngine::getGlyphPageCreator();
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1, m_video_driver->addTexture("Glyph_page", gp_creator->getPage()));
gp_creator->clearGlyphPage();
m_spritebank->addTexture(NULL);
gp_creator->createNewGlyphPage();
}
// ----------------------------------------------------------------------------
std::set<wchar_t> ScalableFont::getPreloadCharacters(const GUIEngine::TTFLoadingType type)
{
std::set<wchar_t> preload_char;
switch (type)
{
case T_NORMAL:
for (u32 i = 32; i < 128; ++i)
preload_char.insert((wchar_t)i); //Include basic Latin
preload_char.insert((wchar_t)160); //Non-breaking space
preload_char.insert((wchar_t)215); //Used on resolution selection screen (X).
break;
case T_DIGIT:
preload_char.insert((wchar_t)32); //Space
for (u32 i = 47; i < 59; ++i)
preload_char.insert((wchar_t)i); //Include chars used by timer and laps count only
preload_char.insert((wchar_t)120); //Used when displaying multiple items, e.g. 6x
break;
case T_BOLD:
preload_char = translations->getCurrentAllChar(); //Loading unique characters
for (u32 i = 65; i < 256; ++i)
preload_char.insert((wchar_t)i); //Include basic Latin too, starting from A (char code 65)
setlocale(LC_ALL, "en_US.UTF8");
std::set<wchar_t> upper;
std::set<wchar_t>::iterator it = preload_char.begin();
while (it != preload_char.end())
{
//Only use all capital letter for bold char with latin (<640 of char code).
//Remove all characters (>char code 8191) not used by the title
if (((iswlower((wchar_t)*it) || !iswalpha((wchar_t)*it)) && *it < 640) || *it > 8191)
{
if (*it < 8192 && iswalpha((wchar_t)*it))
{
//Make sure we include all upper case letters,
//because the title font shows all characters as capital letters
upper.insert(towupper((wchar_t)*it));
}
it = preload_char.erase(it);
}
else
++it;
}
//Final hack to make stk display title properly
for (u32 i = 32; i < 65; ++i)
preload_char.insert((wchar_t)i); //Include basic symbol (from space (char code 32) to @(char code 64))
preload_char.insert(upper.begin(), upper.end());
preload_char.insert((wchar_t)160); //Non-breaking space
//Remove Ordinal indicator (char code 170 and 186)
preload_char.erase((wchar_t)170);
preload_char.erase((wchar_t)186);
preload_char.erase((wchar_t)304); //Remove Capital I-dotted (char code 304) with using "I" altogether.
break;
}
return preload_char;
}
// ----------------------------------------------------------------------------
void ScalableFont::recreateFromLanguage()
{
//Clean previous font data
m_spritebank->clear();
m_areas.clear();
m_character_map.clear();
m_max_height = 0;
m_global_kerning_width = 0;
m_global_kerning_height = 0;
//Set to default scale to reload font
m_scale = 1;
//Reload
if (!loadTTF())
{
Log::fatal("ScalableFont", "Recreation of TTF font failed");
}
}
// ----------------------------------------------------------------------------
void ScalableFont::updateRTL()
{
m_rtl = translations->isRTLLanguage();
}
m_font_settings->setRTL(translations->isRTLLanguage());
} // updateRTL
// ----------------------------------------------------------------------------
void ScalableFont::setShadow(const irr::video::SColor &col)
{
m_shadow = true;
m_shadow_color = col;
}
m_font_settings->setShadow(true);
m_font_settings->setShadowColor(col);
} // setShadow
// ----------------------------------------------------------------------------
void ScalableFont::setScale(const float scale)
void ScalableFont::disableShadow()
{
m_scale = scale;
}
m_font_settings->setShadow(false);
} // setShadow
// ----------------------------------------------------------------------------
void ScalableFont::setKerningWidth(s32 kerning)
void ScalableFont::setScale(float scale)
{
m_global_kerning_width = kerning;
}
m_font_settings->setScale(scale);
} // setScale
// ----------------------------------------------------------------------------
s32 ScalableFont::getKerningWidth(const wchar_t* thisLetter, const wchar_t* previousLetter) const
float ScalableFont::getScale() const
{
s32 ret = m_global_kerning_width;
return ret;
}
return m_font_settings->getScale();
} // getScale
// ----------------------------------------------------------------------------
void ScalableFont::setKerningHeight(s32 kerning)
{
m_global_kerning_height = kerning;
}
// ----------------------------------------------------------------------------
s32 ScalableFont::getKerningHeight () const
{
return m_global_kerning_height;
}
// ----------------------------------------------------------------------------
u32 ScalableFont::getSpriteNoFromChar(const wchar_t *c) const
{
return m_areas[getAreaIDFromCharacter(*c, NULL)].spriteno;
}
// ----------------------------------------------------------------------------
s32 ScalableFont::getAreaIDFromCharacter(const wchar_t c, bool* fallback_font) const
{
std::map<wchar_t, s32>::const_iterator n = m_character_map.find(c);
if (n != m_character_map.end())
{
if (fallback_font != NULL) *fallback_font = false;
//Log::info("ScalableFont", "Character %d found in font", (int)c);
return (*n).second;
}
else if (m_fallback_font != NULL && fallback_font != NULL)
{
//Log::warn("ScalableFont", "Font does not have this character: <%d>, try fallback font", (int)c);
*fallback_font = true;
return m_fallback_font->getAreaIDFromCharacter(c, NULL);
}
else
{
//Log::warn("ScalableFont", "The font does not have this character: <%d>", (int)c);
if (fallback_font != NULL) *fallback_font = false;
return 1; //The first preload character in all type of fonts is space, which is 1
}
}
// ----------------------------------------------------------------------------
const ScalableFont::SFontArea &ScalableFont::getAreaFromCharacter(const wchar_t c,
bool* fallback_font) const
{
const int area_id = getAreaIDFromCharacter(c, fallback_font);
if (m_mono_space_digits && ((c>=L'0' && c<=L'9') || c==L' '))
{
const SFontArea &area = (fallback_font && *fallback_font)
? m_fallback_font->m_areas[area_id]
: m_areas[area_id];
m_max_digit_area.spriteno = area.spriteno;
return m_max_digit_area;
}
const bool use_fallback_font = (fallback_font && *fallback_font);
if (use_fallback_font)
{
assert(area_id < (int)m_fallback_font->m_areas.size());
}
else
{
assert(area_id < (int)m_areas.size());
}
// Note: fallback_font can be NULL
return (use_fallback_font ? m_fallback_font->m_areas[area_id] : m_areas[area_id]);
} // getAreaFromCharacter
// ----------------------------------------------------------------------------
bool ScalableFont::hasThisChar(const wchar_t c) const
{
std::map<wchar_t, s32>::const_iterator n = m_character_map.find(c);
if (n != m_character_map.end())
return true;
return false;
}
// ----------------------------------------------------------------------------
void ScalableFont::setInvisibleCharacters( const wchar_t *s )
{
m_invisible = s;
}
// ----------------------------------------------------------------------------
core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
{
return m_face->getDimension(text, m_font_settings);
/* GUIEngine::GlyphPageCreator* gp_creator = GUIEngine::getGlyphPageCreator();
if (m_type == T_NORMAL || T_BOLD) //lazy load char
{
for (const wchar_t* p = text; *p; ++p)
{
if (*p == L'\r' || *p == L'\n' || *p == L' ' || *p < 32) continue;
if (!GUIEngine::getFont()->hasThisChar(*p))
gp_creator->insertChar(*p);
}
if (gp_creator->getNewChar().size() > 0 && !m_is_hollow_copy && m_scale == 1)
{
Log::debug("ScalableFont::getDimension",
"New character(s) %s discoverd, perform lazy loading",
StringUtils::wideToUtf8(gp_creator->getNewChar()).c_str());
if (!GUIEngine::getFont()->lazyLoadChar())
Log::error("ScalableFont::lazyLoadChar",
"Can't insert new char into glyph pages.");
}
}
assert(m_areas.size() > 0);
core::dimension2d<u32> dim(0, 0);
core::dimension2d<u32> thisLine(0, (int)(m_max_height*m_scale));
for (const wchar_t* p = text; *p; ++p)
{
if (*p == L'\r' || // Windows breaks
*p == L'\n' ) // Unix breaks
{
if (*p==L'\r' && p[1] == L'\n') // Windows breaks
++p;
dim.Height += thisLine.Height;
if (dim.Width < thisLine.Width)
dim.Width = thisLine.Width;
thisLine.Width = 0;
continue;
}
bool fallback = false;
const SFontArea &area = getAreaFromCharacter(*p, &fallback);
thisLine.Width += getCharWidth(area, fallback);
}
dim.Height += thisLine.Height;
if (dim.Width < thisLine.Width) dim.Width = thisLine.Width;
//Log::info("ScalableFont", "ScalableFont::getDimension returns: %d, %d", dim.Width, dim.Height);
dim.Width = (int)(dim.Width + 0.9f); // round up
dim.Height = (int)(dim.Height + 0.9f);
//Log::info("ScalableFont", "After: %d, %d", dim.Width, dim.Height);
return dim;*/
}
} // getDimension
// ----------------------------------------------------------------------------
void ScalableFont::draw(const core::stringw& text,
const core::rect<s32>& position, video::SColor color,
bool hcenter, bool vcenter,
const core::rect<s32>* clip)
{
doDraw(text, position, color, hcenter, vcenter, clip, NULL);
}
// ----------------------------------------------------------------------------
void ScalableFont::draw(const core::stringw& text,
const core::rect<s32>& position, video::SColor color,
bool hcenter, bool vcenter,
const core::rect<s32>* clip)
{
m_face->render(text, position, color, hcenter, vcenter, clip,
m_font_settings);
} // draw
// ----------------------------------------------------------------------------
void ScalableFont::draw(const core::stringw& text,
const core::rect<s32>& position,
const video::SColor& color, bool hcenter, bool vcenter,
const core::rect<s32>* clip, bool ignoreRTL)
{
bool previousRTL = m_rtl;
if (ignoreRTL) m_rtl = false;
bool previousRTL = m_font_settings->isRTL();
if (ignoreRTL)
m_font_settings->setRTL(false);
doDraw(text, position, color, hcenter, vcenter, clip, NULL);
m_face->render(text, position, color, hcenter, vcenter, clip,
m_font_settings);
if (ignoreRTL) m_rtl = previousRTL;
}
if (ignoreRTL)
m_font_settings->setRTL(previousRTL);
} // draw
// ----------------------------------------------------------------------------
void ScalableFont::doDraw(const core::stringw& text,
const core::rect<s32>& position, video::SColor color,
bool hcenter, bool vcenter,
const core::rect<s32>* clip,
FontCharCollector* charCollector)
{
m_face->render(text,position,color,hcenter,vcenter,clip,m_font_settings,NULL);
}
// ----------------------------------------------------------------------------
s32 ScalableFont::getCharWidth(const SFontArea& area, const bool fallback) const
{
if (fallback) return (int)((area.width*m_fallback_font_scale + m_fallback_kerning_width) * m_scale);
else return (int)((area.width + m_global_kerning_width) * m_scale);
}
// ----------------------------------------------------------------------------
s32 ScalableFont::getCharacterFromPos(const wchar_t* text, s32 pixel_x) const
{
s32 x = 0;
s32 idx = 0;
while (text[idx])
{
bool use_fallback_font = false;
const SFontArea &a = getAreaFromCharacter(text[idx], &use_fallback_font);
x += getCharWidth(a, use_fallback_font) + m_global_kerning_width;
if (x >= pixel_x)
return idx;
++idx;
}
return -1;
}
// ----------------------------------------------------------------------------
IGUISpriteBank* ScalableFont::getSpriteBank() const
{
return m_spritebank;
}
return m_face->getCharacterFromPos(text, pixel_x, m_font_settings);
} // getCharacterFromPos
} // end namespace gui
} // end namespace irr

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// Copyright (C) 2015 SuperTuxKart-Team
// Copyright (C) 2016 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -19,191 +19,91 @@
#ifndef HEADER_SCALABLE_FONT_HPP
#define HEADER_SCALABLE_FONT_HPP
#include "guiengine/ft_environment.hpp"
#include "utils/leak_check.hpp"
#include <map>
#include <string>
#include <set>
#include <IGUIFontBitmap.h>
class FontSettings;
class FontWithFace;
namespace irr
{
namespace video
{
class IVideoDriver;
class IImage;
class ITexture;
}
namespace gui
{
class IGUIEnvironment;
class FontCharCollector
{
public:
virtual void collectChar(video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const video::SColor* const colors) = 0;
};
class ScalableFont : public IGUIFontBitmap
{
float m_scale;
bool m_shadow;
/** True if digits should be mono spaced. */
private:
FontWithFace* m_face;
bool m_mono_space_digits;
irr::video::SColor m_shadow_color;
bool m_is_hollow_copy;
bool m_rtl;
FontSettings* m_font_settings;
public:
LEAK_CHECK()
bool m_black_border;
ScalableFont* m_fallback_font;
float m_fallback_font_scale;
int m_fallback_kerning_width;
// ------------------------------------------------------------------------
ScalableFont(FontWithFace* face);
FontWithFace* m_face;
FontSettings* m_font_settings;
FontSettings* getFontSettings() { return m_font_settings; }
const FontSettings* getFontSettings() const { return m_font_settings; }
ScalableFont(IGUIEnvironment* env, GUIEngine::TTFLoadingType type);
// ------------------------------------------------------------------------
virtual ~ScalableFont();
/** 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;
out->setReferenceCount(1);
return out;
}
/** loads a font from a TTF file */
bool loadTTF();
/** lazy load new characters discovered in normal font */
bool lazyLoadChar();
/** draws an text and clips it to the specified rectangle if wanted */
virtual void draw(const core::stringw& text, const core::rect<s32>& position,
video::SColor color, bool hcenter = false,
bool vcenter = false, const core::rect<s32>* clip = 0);
// ------------------------------------------------------------------------
FontSettings* getFontSettings() { return m_font_settings; }
// ------------------------------------------------------------------------
const FontSettings* getFontSettings() const { return m_font_settings; }
// ------------------------------------------------------------------------
void setScale(float scale);
// ------------------------------------------------------------------------
float getScale() const;
// ------------------------------------------------------------------------
void setShadow(const irr::video::SColor &col);
// ------------------------------------------------------------------------
void disableShadow();
// ------------------------------------------------------------------------
void updateRTL();
// ------------------------------------------------------------------------
void draw(const core::stringw& text, const core::rect<s32>& position,
video::SColor color, bool hcenter,
bool vcenter, const core::rect<s32>* clip, bool ignoreRTL);
void doDraw(const core::stringw& text, const core::rect<s32>& position,
video::SColor color, bool hcenter,
const video::SColor& color, bool hcenter,
bool vcenter, const core::rect<s32>* clip,
FontCharCollector* charCollector = NULL);
bool ignoreRTL);
// ------------------------------------------------------------------------
/** draws an text and clips it to the specified rectangle if wanted */
virtual void draw(const core::stringw& text,
const core::rect<s32>& position,
video::SColor color, bool hcenter = false,
bool vcenter = false, const core::rect<s32>* clip = 0);
// ------------------------------------------------------------------------
/** returns the dimension of a text */
virtual core::dimension2d<u32> getDimension(const wchar_t* text) const;
/** Calculates the index of the character in the text which is on a specific position. */
// ------------------------------------------------------------------------
/** Calculates the index of the character in the text which is on a
* specific position. */
virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const;
// ------------------------------------------------------------------------
/** Returns the type of this font */
virtual EGUI_FONT_TYPE getType() const { return EGFT_BITMAP; }
virtual EGUI_FONT_TYPE getType() const { return EGFT_BITMAP; }
// ------------------------------------------------------------------------
// Below is not used:
/** set an Pixel Offset on Drawing ( scale position on width ) */
virtual void setKerningWidth (s32 kerning);
virtual void setKerningHeight (s32 kerning);
virtual void setKerningWidth (s32 kerning) {}
// ------------------------------------------------------------------------
virtual void setKerningHeight (s32 kerning) {}
// ------------------------------------------------------------------------
/** set an Pixel Offset on Drawing ( scale position on width ) */
virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const;
virtual s32 getKerningHeight() const;
/** Sets if digits are to be mono-spaced. */
void setMonospaceDigits(bool mono) {m_mono_space_digits = mono; }
bool getMonospaceDigits() const { return m_mono_space_digits; }
void setShadow(const irr::video::SColor &col);
void disableShadow() {m_shadow = false;}
virtual s32 getKerningWidth(const wchar_t* thisLetter=0,
const wchar_t* previousLetter=0) const
{ return 0; }
// ------------------------------------------------------------------------
virtual s32 getKerningHeight() const { return 0; }
// ------------------------------------------------------------------------
/** gets the sprite bank */
virtual IGUISpriteBank* getSpriteBank() const;
virtual IGUISpriteBank* getSpriteBank() const { return NULL; }
// ------------------------------------------------------------------------
/** returns the sprite number from a given character */
virtual u32 getSpriteNoFromChar(const wchar_t *c) const;
virtual u32 getSpriteNoFromChar(const wchar_t *c) const { return 0; }
// ------------------------------------------------------------------------
virtual void setInvisibleCharacters( const wchar_t *s ) {}
virtual void setInvisibleCharacters( const wchar_t *s );
/** test whether current font has this character regardless of fallback font */
virtual bool hasThisChar(const wchar_t c) const;
void setScale(const float scale);
float getScale() const { return m_scale; }
void updateRTL();
/** re-create fonts when language is changed */
void recreateFromLanguage();
/** force create a new texture (glyph) page in a font */
void forceNewPage();
private:
struct SFontArea
{
SFontArea() : width(0), spriteno(0), offsety(0), offsety_bt(0), bearingx(0) {}
s32 width;
u32 spriteno;
s32 offsety;
s32 offsety_bt;
s32 bearingx;
};
s32 getCharWidth(const SFontArea& area, const bool fallback) const;
s32 getAreaIDFromCharacter(const wchar_t c, bool* fallback_font) const;
const SFontArea &getAreaFromCharacter(const wchar_t c, bool* fallback_font) const;
/** get characters to be pre-loaded base on font type */
std::set<wchar_t> getPreloadCharacters(const GUIEngine::TTFLoadingType);
GUIEngine::TTFLoadingType m_type;
GUIEngine::FontUse m_font_use;
video::IVideoDriver *m_video_driver;
IGUISpriteBank *m_spritebank;
IGUIEnvironment *m_gui_env;
video::ITexture *m_last_normal_page;
core::array<SFontArea> m_areas;
/** The maximum values of all digits, used in monospace_digits. */
mutable SFontArea m_max_digit_area;
std::map<wchar_t, s32> m_character_map;
s32 m_max_height;
s32 m_global_kerning_width;
s32 m_global_kerning_height;
s32 m_glyph_max_height;
core::stringw m_invisible;
};
} // end namespace gui
} // end namespace irr
#endif // HEADER_SCALABLE_FONT_HPP

View File

@ -390,8 +390,7 @@ void DynamicRibbonWidget::buildInternalStructure()
// calculate font size
if (m_col_amount > 0)
{
m_font->getFontSettings()->setScale(GUIEngine::getFont()
->getFontSettings()->getScale() *
m_font->setScale(GUIEngine::getFont()->getScale() *
getFontScale((ribbon->m_w / m_col_amount) - 30));
}

View File

@ -22,7 +22,6 @@
#include "challenges/unlock_manager.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/stk_text_billboard.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "modes/world.hpp"

View File

@ -19,7 +19,7 @@
#include "script_track.hpp"
#include "animations/three_d_animation.hpp"
#include "font/regular_face.hpp"
#include "font/digit_face.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/stk_text_billboard.hpp"
#include "guiengine/scalable_font.hpp"
@ -89,17 +89,14 @@ namespace Scripting
void createTextBillboard(std::string* text, SimpleVec3* location)
{
core::stringw wtext = StringUtils::utf8ToWide(*text);
//core::dimension2d<u32> textsize = GUIEngine::getHighresDigitFont()
//->getDimension(wtext.c_str());
RegularFace* regular_face = font_manager->getFont<RegularFace>();
core::dimension2d<u32> textsize = regular_face->getDimension(wtext.c_str());
//assert(GUIEngine::getHighresDigitFont() != NULL);
DigitFace* digit_face = font_manager->getFont<DigitFace>();
core::dimension2d<u32> textsize = digit_face->getDimension(wtext.c_str());
core::vector3df xyz(location->getX(), location->getY(), location->getZ());
if (CVS->isGLSL())
{
STKTextBillboard* tb = new STKTextBillboard(wtext.c_str(), regular_face,
STKTextBillboard* tb = new STKTextBillboard(wtext.c_str(), digit_face,
GUIEngine::getSkin()->getColor("font::bottom"),
GUIEngine::getSkin()->getColor("font::top"),
irr_driver->getSceneManager()->getRootSceneNode(),
@ -110,6 +107,7 @@ namespace Scripting
}
else
{
assert(GUIEngine::getHighresDigitFont() != NULL);
scene::ISceneManager* sm = irr_driver->getSceneManager();
scene::ISceneNode* sn =
sm->addBillboardTextSceneNode(GUIEngine::getHighresDigitFont(),

View File

@ -22,6 +22,8 @@
#include "audio/sfx_base.hpp"
#include "config/hardware_stats.hpp"
#include "config/user_config.hpp"
#include "font/bold_face.hpp"
#include "font/regular_face.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/widgets/button_widget.hpp"
@ -334,6 +336,8 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
// Reload fonts for new translation
GUIEngine::getStateManager()->hardResetAndGoToScreen<MainMenuScreen>();
font_manager->getFont<BoldFace>()->reset();
font_manager->getFont<RegularFace>()->reset();
GUIEngine::getFont()->updateRTL();
GUIEngine::getTitleFont()->updateRTL();
GUIEngine::getSmallFont()->updateRTL();

View File

@ -143,7 +143,7 @@ void RaceResultGUI::init()
void RaceResultGUI::tearDown()
{
Screen::tearDown();
m_font->setMonospaceDigits(m_was_monospace);
//m_font->setMonospaceDigits(m_was_monospace);
if (m_finish_sound != NULL &&
m_finish_sound->getStatus() == SFXBase::SFX_PLAYING)
@ -455,8 +455,8 @@ void RaceResultGUI::backToLobby()
m_font = GUIEngine::getFont();
assert(m_font);
m_was_monospace = m_font->getMonospaceDigits();
m_font->setMonospaceDigits(true);
//m_was_monospace = m_font->getMonospaceDigits();
//m_font->setMonospaceDigits(true);
WorldWithRank *rank_world = (WorldWithRank*)World::getWorld();
unsigned int first_position = 1;
@ -556,14 +556,14 @@ void RaceResultGUI::backToLobby()
// Determine width of new points column
m_font->setMonospaceDigits(true);
//m_font->setMonospaceDigits(true);
core::dimension2du r_new_p = m_font->getDimension(L"+99");
m_width_new_points = r_new_p.Width;
// Determine width of overall points column
core::dimension2du r_all_p = m_font->getDimension(L"999");
m_font->setMonospaceDigits(false);
//m_font->setMonospaceDigits(false);
m_width_all_points = r_all_p.Width;

View File

@ -160,7 +160,7 @@ private:
bool m_gp_position_was_changed;
/** The previous monospace state of the font. */
bool m_was_monospace;
//bool m_was_monospace;
/** Sound effect at end of race. */
SFXBase *m_finish_sound;

View File

@ -18,9 +18,10 @@
#include "tracks/graph_structure.hpp"
#include <IMesh.h>
#include <ICameraSceneNode.h>
#include <IMesh.h>
#include <IMeshSceneNode.h>
#include <ISceneManager.h>
#include "graphics/irr_driver.hpp"
#include "graphics/glwrap.hpp"

View File

@ -38,7 +38,6 @@
#include "graphics/particle_emitter.hpp"
#include "graphics/particle_kind.hpp"
#include "graphics/particle_kind_manager.hpp"
#include "graphics/stk_text_billboard.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp"

View File

@ -19,6 +19,9 @@
#include "debug.hpp"
#include "config/user_config.hpp"
#include "font/bold_face.hpp"
#include "font/digit_face.hpp"
#include "font/regular_face.hpp"
#include "graphics/camera_debug.hpp"
#include "graphics/camera_fps.hpp"
#include "graphics/irr_driver.hpp"
@ -78,6 +81,8 @@ enum DebugMenuCommand
DEBUG_GRAPHICS_BOUNDING_BOXES_VIZ,
DEBUG_PROFILER,
DEBUG_PROFILER_GENERATE_REPORT,
DEBUG_FONT_DUMP_GLYPH_PAGE,
DEBUG_FONT_RELOAD,
DEBUG_FPS,
DEBUG_SAVE_REPLAY,
DEBUG_SAVE_HISTORY,
@ -337,6 +342,15 @@ bool handleContextMenuAction(s32 cmd_id)
case DEBUG_THROTTLE_FPS:
main_loop->setThrottleFPS(false);
break;
case DEBUG_FONT_DUMP_GLYPH_PAGE:
font_manager->getFont<BoldFace>()->dumpGlyphPage("bold");
font_manager->getFont<DigitFace>()->dumpGlyphPage("digit");
font_manager->getFont<RegularFace>()->dumpGlyphPage("regular");
case DEBUG_FONT_RELOAD:
font_manager->getFont<BoldFace>()->reset();
font_manager->getFont<DigitFace>()->reset();
font_manager->getFont<RegularFace>()->reset();
break;
case DEBUG_FPS:
UserConfigParams::m_display_fps =
!UserConfigParams::m_display_fps;
@ -606,7 +620,7 @@ bool handleContextMenuAction(s32 cmd_id)
break;
}
case DEBUG_SCRIPT_CONSOLE:
ScriptingConsole* console = new ScriptingConsole();
new ScriptingConsole();
break;
} // switch
return false;
@ -696,6 +710,11 @@ bool onEvent(const SEvent &event)
sub->addItem(L"To kart seven", DEBUG_VIEW_KART_SEVEN);
sub->addItem(L"To kart eight", DEBUG_VIEW_KART_EIGHT);
mnu->addItem(L"Font >",-1,true, true);
sub = mnu->getSubMenu(5);
sub->addItem(L"Dump glyph pages of fonts", DEBUG_FONT_DUMP_GLYPH_PAGE);
sub->addItem(L"Reload all fonts", DEBUG_FONT_RELOAD);
mnu->addItem(L"Adjust values", DEBUG_VISUAL_VALUES);
mnu->addItem(L"Profiler", DEBUG_PROFILER);