Add font configuration to skin
This commit is contained in:
parent
1d74efcd08
commit
25aca4328b
@ -18,12 +18,13 @@
|
|||||||
|
|
||||||
#include "font/font_manager.hpp"
|
#include "font/font_manager.hpp"
|
||||||
|
|
||||||
#include "config/stk_config.hpp"
|
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "font/bold_face.hpp"
|
#include "font/bold_face.hpp"
|
||||||
#include "font/digit_face.hpp"
|
#include "font/digit_face.hpp"
|
||||||
#include "font/face_ttf.hpp"
|
#include "font/face_ttf.hpp"
|
||||||
#include "font/regular_face.hpp"
|
#include "font/regular_face.hpp"
|
||||||
|
#include "guiengine/engine.hpp"
|
||||||
|
#include "guiengine/skin.hpp"
|
||||||
#include "modes/profile_world.hpp"
|
#include "modes/profile_world.hpp"
|
||||||
#include "states_screens/state_manager.hpp"
|
#include "states_screens/state_manager.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
@ -89,10 +90,8 @@ std::vector<FT_Face>
|
|||||||
for (const std::string& font : ttf_list)
|
for (const std::string& font : ttf_list)
|
||||||
{
|
{
|
||||||
FT_Face face = NULL;
|
FT_Face face = NULL;
|
||||||
const std::string loc = file_manager
|
|
||||||
->getAssetChecked(FileManager::TTF, font.c_str(), true);
|
|
||||||
font_manager->checkFTError(FT_New_Face(
|
font_manager->checkFTError(FT_New_Face(
|
||||||
m_ft_library, loc.c_str(), 0, &face), loc + " is loaded");
|
m_ft_library, font.c_str(), 0, &face), font + " is loaded");
|
||||||
ret.push_back(face);
|
ret.push_back(face);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -563,12 +562,11 @@ void FontManager::initGlyphLayouts(const core::stringw& text,
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
FT_Face FontManager::loadColorEmoji()
|
FT_Face FontManager::loadColorEmoji()
|
||||||
{
|
{
|
||||||
if (stk_config->m_color_emoji_ttf.empty())
|
if (GUIEngine::getSkin()->getColorEmojiTTF().empty())
|
||||||
return NULL;
|
return NULL;
|
||||||
FT_Face face = NULL;
|
FT_Face face = NULL;
|
||||||
const std::string loc = file_manager->getAssetChecked(FileManager::TTF,
|
FT_Error err = FT_New_Face(m_ft_library,
|
||||||
stk_config->m_color_emoji_ttf.c_str(), true);
|
GUIEngine::getSkin()->getColorEmojiTTF().c_str(), 0, &face);
|
||||||
FT_Error err = FT_New_Face(m_ft_library, loc.c_str(), 0, &face);
|
|
||||||
if (err > 0)
|
if (err > 0)
|
||||||
{
|
{
|
||||||
Log::error("FontManager", "Something wrong when loading color emoji! "
|
Log::error("FontManager", "Something wrong when loading color emoji! "
|
||||||
@ -579,7 +577,7 @@ FT_Face FontManager::loadColorEmoji()
|
|||||||
if (!FT_HAS_COLOR(face) || face->num_fixed_sizes == 0)
|
if (!FT_HAS_COLOR(face) || face->num_fixed_sizes == 0)
|
||||||
{
|
{
|
||||||
Log::error("FontManager", "Bad %s color emoji, ignored.",
|
Log::error("FontManager", "Bad %s color emoji, ignored.",
|
||||||
stk_config->m_color_emoji_ttf.c_str());
|
GUIEngine::getSkin()->getColorEmojiTTF().c_str());
|
||||||
checkFTError(FT_Done_Face(face), "removing faces for emoji");
|
checkFTError(FT_Done_Face(face), "removing faces for emoji");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -601,7 +599,8 @@ void FontManager::loadFonts()
|
|||||||
{
|
{
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
// First load the TTF files required by each font
|
// First load the TTF files required by each font
|
||||||
std::vector<FT_Face> normal_ttf = loadTTF(stk_config->m_normal_ttf);
|
std::vector<FT_Face> normal_ttf = loadTTF(
|
||||||
|
GUIEngine::getSkin()->getNormalTTF());
|
||||||
std::vector<FT_Face> bold_ttf = normal_ttf;
|
std::vector<FT_Face> bold_ttf = normal_ttf;
|
||||||
if (!ProfileWorld::isNoGraphics())
|
if (!ProfileWorld::isNoGraphics())
|
||||||
{
|
{
|
||||||
@ -622,7 +621,8 @@ void FontManager::loadFonts()
|
|||||||
m_ft_faces_to_index[normal_ttf[i]] = i;
|
m_ft_faces_to_index[normal_ttf[i]] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<FT_Face> digit_ttf = loadTTF(stk_config->m_digit_ttf);
|
std::vector<FT_Face> digit_ttf =
|
||||||
|
loadTTF(GUIEngine::getSkin()->getDigitTTF());
|
||||||
if (!digit_ttf.empty())
|
if (!digit_ttf.empty())
|
||||||
m_digit_face = digit_ttf.front();
|
m_digit_face = digit_ttf.front();
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,6 +75,9 @@ private:
|
|||||||
std::vector<irr::gui::GlyphLayout> > m_cached_gls;
|
std::vector<irr::gui::GlyphLayout> > m_cached_gls;
|
||||||
|
|
||||||
bool m_has_color_emoji;
|
bool m_has_color_emoji;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
std::vector<FT_Face> loadTTF(const std::vector<std::string>& ttf_list);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Map type for each \ref FontWithFace with a index, save getting time in
|
/** Map type for each \ref FontWithFace with a index, save getting time in
|
||||||
@ -120,8 +123,6 @@ public:
|
|||||||
/** Return the \ref m_ft_library. */
|
/** Return the \ref m_ft_library. */
|
||||||
FT_Library getFTLibrary() const { return m_ft_library; }
|
FT_Library getFTLibrary() const { return m_ft_library; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
std::vector<FT_Face> loadTTF(const std::vector<std::string>& ttf_list);
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
FT_Face loadColorEmoji();
|
FT_Face loadColorEmoji();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
unsigned getShapingDPI() const { return m_shaping_dpi; }
|
unsigned getShapingDPI() const { return m_shaping_dpi; }
|
||||||
|
@ -177,6 +177,7 @@ namespace GUIEngine
|
|||||||
*/
|
*/
|
||||||
inline Skin* getSkin() { return Private::g_skin; }
|
inline Skin* getSkin() { return Private::g_skin; }
|
||||||
|
|
||||||
|
inline void setSkin(Skin* skin) { Private::g_skin = skin; }
|
||||||
Screen* getScreenNamed(const char* name);
|
Screen* getScreenNamed(const char* name);
|
||||||
|
|
||||||
/** \return the height of the title font in pixels */
|
/** \return the height of the title font in pixels */
|
||||||
|
@ -54,7 +54,11 @@ namespace SkinConfig
|
|||||||
static std::map<std::string, BoxRenderParams> m_render_params;
|
static std::map<std::string, BoxRenderParams> m_render_params;
|
||||||
static std::map<std::string, SColor> m_colors;
|
static std::map<std::string, SColor> m_colors;
|
||||||
static std::string m_data_path;
|
static std::string m_data_path;
|
||||||
|
static std::vector<std::string> m_normal_ttf;
|
||||||
|
static std::vector<std::string> m_digit_ttf;
|
||||||
|
static std::string m_color_emoji_ttf;
|
||||||
static bool m_icon_theme;
|
static bool m_icon_theme;
|
||||||
|
static bool m_font;
|
||||||
|
|
||||||
static void parseElement(const XMLNode* node)
|
static void parseElement(const XMLNode* node)
|
||||||
{
|
{
|
||||||
@ -156,13 +160,26 @@ namespace SkinConfig
|
|||||||
* \brief loads skin information from a STK skin file
|
* \brief loads skin information from a STK skin file
|
||||||
* \throw std::runtime_error if file cannot be read
|
* \throw std::runtime_error if file cannot be read
|
||||||
*/
|
*/
|
||||||
static void loadFromFile(std::string file)
|
static void loadFromFile(std::string file, bool load_advanced_only)
|
||||||
{
|
{
|
||||||
// Clear global variables for android
|
// Clear global variables for android
|
||||||
m_render_params.clear();
|
m_render_params.clear();
|
||||||
m_colors.clear();
|
m_colors.clear();
|
||||||
m_data_path.clear();
|
m_data_path.clear();
|
||||||
|
m_normal_ttf.clear();
|
||||||
|
for (auto& p : stk_config->m_normal_ttf)
|
||||||
|
m_normal_ttf.push_back(file_manager->getAssetChecked(FileManager::TTF, p, true));
|
||||||
|
m_digit_ttf.clear();
|
||||||
|
for (auto& p : stk_config->m_digit_ttf)
|
||||||
|
m_digit_ttf.push_back(file_manager->getAssetChecked(FileManager::TTF, p, true));
|
||||||
|
m_color_emoji_ttf.clear();
|
||||||
|
if (!stk_config->m_color_emoji_ttf.empty())
|
||||||
|
{
|
||||||
|
m_color_emoji_ttf = file_manager->getAssetChecked(FileManager::TTF,
|
||||||
|
stk_config->m_color_emoji_ttf, true);
|
||||||
|
}
|
||||||
m_icon_theme = false;
|
m_icon_theme = false;
|
||||||
|
m_font = false;
|
||||||
|
|
||||||
XMLNode* root = file_manager->createXMLTree(file);
|
XMLNode* root = file_manager->createXMLTree(file);
|
||||||
if(!root)
|
if(!root)
|
||||||
@ -179,11 +196,11 @@ namespace SkinConfig
|
|||||||
{
|
{
|
||||||
const XMLNode* node = root->getNode(i);
|
const XMLNode* node = root->getNode(i);
|
||||||
|
|
||||||
if (node->getName() == "element")
|
if (node->getName() == "element" && !load_advanced_only)
|
||||||
{
|
{
|
||||||
parseElement(node);
|
parseElement(node);
|
||||||
}
|
}
|
||||||
else if (node->getName() == "color")
|
else if (node->getName() == "color" && !load_advanced_only)
|
||||||
{
|
{
|
||||||
parseColor(node);
|
parseColor(node);
|
||||||
}
|
}
|
||||||
@ -195,8 +212,54 @@ namespace SkinConfig
|
|||||||
if (file_manager->fileExists(m_data_path + "data/gui/icons/"))
|
if (file_manager->fileExists(m_data_path + "data/gui/icons/"))
|
||||||
m_icon_theme = true;
|
m_icon_theme = true;
|
||||||
}
|
}
|
||||||
|
std::string color_ttf;
|
||||||
|
if (node->get("color_emoji_ttf", &color_ttf))
|
||||||
|
{
|
||||||
|
std::string test_path = m_data_path + "data/ttf/" + color_ttf;
|
||||||
|
if (file_manager->fileExists(test_path))
|
||||||
|
{
|
||||||
|
m_color_emoji_ttf = test_path;
|
||||||
|
m_font = true;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
std::vector<std::string> list_ttf;
|
||||||
|
std::vector<std::string> list_ttf_path;
|
||||||
|
if (node->get("normal_ttf", &list_ttf))
|
||||||
|
{
|
||||||
|
for (auto& t : list_ttf)
|
||||||
|
{
|
||||||
|
std::string test_path = m_data_path + "data/ttf/" + t;
|
||||||
|
if (file_manager->fileExists(test_path))
|
||||||
|
{
|
||||||
|
list_ttf_path.push_back(test_path);
|
||||||
|
m_font = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We append at the begining of default ttf, so if some
|
||||||
|
// character missing from skin font we will fallback to
|
||||||
|
// bundled font later
|
||||||
|
m_normal_ttf.insert(m_normal_ttf.begin(),
|
||||||
|
list_ttf_path.begin(), list_ttf_path.end());
|
||||||
|
}
|
||||||
|
list_ttf.clear();
|
||||||
|
list_ttf_path.clear();
|
||||||
|
if (node->get("digit_ttf", &list_ttf))
|
||||||
|
{
|
||||||
|
m_digit_ttf.clear();
|
||||||
|
for (auto& t : list_ttf)
|
||||||
|
{
|
||||||
|
std::string test_path = m_data_path + "data/ttf/" + t;
|
||||||
|
if (file_manager->fileExists(test_path))
|
||||||
|
{
|
||||||
|
list_ttf_path.push_back(test_path);
|
||||||
|
m_font = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_digit_ttf.insert(m_digit_ttf.begin(),
|
||||||
|
list_ttf_path.begin(), list_ttf_path.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!load_advanced_only)
|
||||||
{
|
{
|
||||||
Log::error("skin", "Unknown node in XML file '%s'.",
|
Log::error("skin", "Unknown node in XML file '%s'.",
|
||||||
node->getName().c_str());
|
node->getName().c_str());
|
||||||
@ -321,6 +384,7 @@ X##_yflip.LowerRightCorner.Y = y1;}
|
|||||||
|
|
||||||
Skin::Skin(IGUISkin* fallback_skin)
|
Skin::Skin(IGUISkin* fallback_skin)
|
||||||
{
|
{
|
||||||
|
// fallback_skin will be null if load only basic theming data
|
||||||
std::string skin_id = UserConfigParams::m_skin_file;
|
std::string skin_id = UserConfigParams::m_skin_file;
|
||||||
std::string skin_name = skin_id.find("addon_") != std::string::npos ?
|
std::string skin_name = skin_id.find("addon_") != std::string::npos ?
|
||||||
file_manager->getAddonsFile(
|
file_manager->getAddonsFile(
|
||||||
@ -329,7 +393,7 @@ Skin::Skin(IGUISkin* fallback_skin)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SkinConfig::loadFromFile( skin_name );
|
SkinConfig::loadFromFile(skin_name, /*load_advanced_only*/fallback_skin == NULL);
|
||||||
}
|
}
|
||||||
catch (std::runtime_error& e)
|
catch (std::runtime_error& e)
|
||||||
{
|
{
|
||||||
@ -339,14 +403,18 @@ Skin::Skin(IGUISkin* fallback_skin)
|
|||||||
std::string default_skin_id = UserConfigParams::m_skin_file;
|
std::string default_skin_id = UserConfigParams::m_skin_file;
|
||||||
skin_name = file_manager->getAsset(FileManager::SKIN,
|
skin_name = file_manager->getAsset(FileManager::SKIN,
|
||||||
default_skin_id + "/stkskin.xml");
|
default_skin_id + "/stkskin.xml");
|
||||||
SkinConfig::loadFromFile( skin_name );
|
SkinConfig::loadFromFile(skin_name, /*load_advanced_only*/fallback_skin == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bg_image = NULL;
|
m_bg_image = NULL;
|
||||||
|
|
||||||
|
m_fallback_skin = NULL;
|
||||||
|
if (fallback_skin)
|
||||||
|
{
|
||||||
m_fallback_skin = fallback_skin;
|
m_fallback_skin = fallback_skin;
|
||||||
m_fallback_skin->grab();
|
m_fallback_skin->grab();
|
||||||
assert(fallback_skin != NULL);
|
assert(fallback_skin != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
m_dialog = false;
|
m_dialog = false;
|
||||||
m_dialog_size = 0.0f;
|
m_dialog_size = 0.0f;
|
||||||
@ -355,6 +423,7 @@ Skin::Skin(IGUISkin* fallback_skin)
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
Skin::~Skin()
|
Skin::~Skin()
|
||||||
{
|
{
|
||||||
|
if (m_fallback_skin)
|
||||||
m_fallback_skin->drop();
|
m_fallback_skin->drop();
|
||||||
} // ~Skin
|
} // ~Skin
|
||||||
|
|
||||||
@ -2642,12 +2711,37 @@ const std::string& Skin::getDataPath() const
|
|||||||
return SkinConfig::m_data_path;
|
return SkinConfig::m_data_path;
|
||||||
} // getDataPath
|
} // getDataPath
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
/* All TTF list here are in absolute path. */
|
||||||
|
const std::vector<std::string>& Skin::getNormalTTF() const
|
||||||
|
{
|
||||||
|
return SkinConfig::m_normal_ttf;
|
||||||
|
} // getNormalTTF
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
const std::vector<std::string>& Skin::getDigitTTF() const
|
||||||
|
{
|
||||||
|
return SkinConfig::m_digit_ttf;
|
||||||
|
} // getDigitTTF
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
const std::string& Skin::getColorEmojiTTF() const
|
||||||
|
{
|
||||||
|
return SkinConfig::m_color_emoji_ttf;
|
||||||
|
} // getColorEmojiTTF
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
bool Skin::hasIconTheme() const
|
bool Skin::hasIconTheme() const
|
||||||
{
|
{
|
||||||
return SkinConfig::m_icon_theme;
|
return SkinConfig::m_icon_theme;
|
||||||
} // hasIconTheme
|
} // hasIconTheme
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
bool Skin::hasFont() const
|
||||||
|
{
|
||||||
|
return SkinConfig::m_font;
|
||||||
|
} // hasFont
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
/* Return a themed icon from its relative path, if not found return the bundled
|
/* Return a themed icon from its relative path, if not found return the bundled
|
||||||
* icon. */
|
* icon. */
|
||||||
|
@ -424,6 +424,14 @@ namespace GUIEngine
|
|||||||
|
|
||||||
bool hasIconTheme() const;
|
bool hasIconTheme() const;
|
||||||
|
|
||||||
|
bool hasFont() const;
|
||||||
|
|
||||||
|
const std::vector<std::string>& getNormalTTF() const;
|
||||||
|
|
||||||
|
const std::vector<std::string>& getDigitTTF() const;
|
||||||
|
|
||||||
|
const std::string& getColorEmojiTTF() const;
|
||||||
|
|
||||||
std::string getThemedIcon(const std::string& relative_path) const;
|
std::string getThemedIcon(const std::string& relative_path) const;
|
||||||
}; // Skin
|
}; // Skin
|
||||||
} // guiengine
|
} // guiengine
|
||||||
|
@ -1729,8 +1729,14 @@ void initRest()
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need a temporary skin to load the font list from skin (if any)
|
||||||
|
GUIEngine::Skin* tmp_skin = new GUIEngine::Skin(NULL);
|
||||||
|
GUIEngine::setSkin(tmp_skin);
|
||||||
font_manager = new FontManager();
|
font_manager = new FontManager();
|
||||||
font_manager->loadFonts();
|
font_manager->loadFonts();
|
||||||
|
delete tmp_skin;
|
||||||
|
GUIEngine::setSkin(NULL);
|
||||||
|
|
||||||
GUIEngine::init(device, driver, StateManager::get());
|
GUIEngine::init(device, driver, StateManager::get());
|
||||||
input_manager = new InputManager();
|
input_manager = new InputManager();
|
||||||
// Get into menu mode initially.
|
// Get into menu mode initially.
|
||||||
|
@ -306,10 +306,28 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
|
|||||||
UserConfigParams::m_skin_file = m_skins[selectedSkin];
|
UserConfigParams::m_skin_file = m_skins[selectedSkin];
|
||||||
irr_driver->unsetMaxTextureSize();
|
irr_driver->unsetMaxTextureSize();
|
||||||
bool prev_icon_theme = GUIEngine::getSkin()->hasIconTheme();
|
bool prev_icon_theme = GUIEngine::getSkin()->hasIconTheme();
|
||||||
|
bool prev_font = GUIEngine::getSkin()->hasFont();
|
||||||
GUIEngine::reloadSkin();
|
GUIEngine::reloadSkin();
|
||||||
if (GUIEngine::getSkin()->hasIconTheme() != prev_icon_theme)
|
if (GUIEngine::getSkin()->hasIconTheme() != prev_icon_theme ||
|
||||||
|
prev_font != GUIEngine::getSkin()->hasFont())
|
||||||
{
|
{
|
||||||
|
if (prev_font != GUIEngine::getSkin()->hasFont())
|
||||||
|
{
|
||||||
|
GUIEngine::clear();
|
||||||
|
GUIEngine::cleanUp();
|
||||||
|
}
|
||||||
|
|
||||||
GUIEngine::clearScreenCache();
|
GUIEngine::clearScreenCache();
|
||||||
|
|
||||||
|
if (prev_font != GUIEngine::getSkin()->hasFont())
|
||||||
|
{
|
||||||
|
delete font_manager;
|
||||||
|
font_manager = new FontManager();
|
||||||
|
font_manager->loadFonts();
|
||||||
|
GUIEngine::init(irr_driver->getDevice(), irr_driver->getVideoDriver(),
|
||||||
|
StateManager::get(), false/*loading*/);
|
||||||
|
}
|
||||||
|
|
||||||
Screen* screen_list[] =
|
Screen* screen_list[] =
|
||||||
{
|
{
|
||||||
MainMenuScreen::getInstance(),
|
MainMenuScreen::getInstance(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user