Clean up old font code
This commit is contained in:
parent
05419cd555
commit
6a319cbed2
@ -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
58
src/font/digit_face.cpp
Normal 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
53
src/font/digit_face.hpp
Normal 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 */
|
@ -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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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();
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -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 */
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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(),
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user