Skip to content

Commit

Permalink
Protect font initialization with mutex
Browse files Browse the repository at this point in the history
fixes #4532
  • Loading branch information
sfan5 committed Dec 18, 2021
1 parent b2409b1 commit 49f7d24
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 39 deletions.
48 changes: 10 additions & 38 deletions src/client/fontengine.cpp
Expand Up @@ -84,11 +84,13 @@ FontEngine::~FontEngine()
/******************************************************************************/
void FontEngine::cleanCache()
{
RecursiveMutexAutoLock l(m_font_mutex);

for (auto &font_cache_it : m_font_cache) {

for (auto &font_it : font_cache_it) {
font_it.second->drop();
font_it.second = NULL;
font_it.second = nullptr;
}
font_cache_it.clear();
}
Expand Down Expand Up @@ -122,6 +124,8 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
if (spec.size == FONT_SIZE_UNSPECIFIED)
spec.size = m_default_size[spec.mode];

RecursiveMutexAutoLock l(m_font_mutex);

const auto &cache = m_font_cache[spec.getHash()];
auto it = cache.find(spec.size);
if (it != cache.end())
Expand Down Expand Up @@ -149,42 +153,23 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
/******************************************************************************/
unsigned int FontEngine::getTextHeight(const FontSpec &spec)
{
irr::gui::IGUIFont *font = getFont(spec);

// use current skin font as fallback
if (font == NULL) {
font = m_env->getSkin()->getFont();
}
FATAL_ERROR_IF(font == NULL, "Could not get skin font");
gui::IGUIFont *font = getFont(spec);

return font->getDimension(L"Some unimportant example String").Height;
}

/******************************************************************************/
unsigned int FontEngine::getTextWidth(const std::wstring &text, const FontSpec &spec)
{
irr::gui::IGUIFont *font = getFont(spec);

// use current skin font as fallback
if (font == NULL) {
font = m_env->getSkin()->getFont();
}
FATAL_ERROR_IF(font == NULL, "Could not get font");
gui::IGUIFont *font = getFont(spec);

return font->getDimension(text.c_str()).Width;
}


/** get line height for a specific font (including empty room between lines) */
unsigned int FontEngine::getLineHeight(const FontSpec &spec)
{
irr::gui::IGUIFont *font = getFont(spec);

// use current skin font as fallback
if (font == NULL) {
font = m_env->getSkin()->getFont();
}
FATAL_ERROR_IF(font == NULL, "Could not get font");
gui::IGUIFont *font = getFont(spec);

return font->getDimension(L"Some unimportant example String").Height
+ font->getKerningHeight();
Expand Down Expand Up @@ -238,22 +223,9 @@ void FontEngine::readSettings()
void FontEngine::updateSkin()
{
gui::IGUIFont *font = getFont();
assert(font);

if (font)
m_env->getSkin()->setFont(font);
else
errorstream << "FontEngine: Default font file: " <<
"\n\t\"" << g_settings->get("font_path") << "\"" <<
"\n\trequired for current screen configuration was not found" <<
" or was invalid file format." <<
"\n\tUsing irrlicht default font." << std::endl;

// If we did fail to create a font our own make irrlicht find a default one
font = m_env->getSkin()->getFont();
FATAL_ERROR_IF(font == NULL, "Could not create/get font");

u32 text_height = font->getDimension(L"Hello, world!").Height;
infostream << "FontEngine: measured text_height=" << text_height << std::endl;
m_env->getSkin()->setFont(font);
}

/******************************************************************************/
Expand Down
5 changes: 4 additions & 1 deletion src/client/fontengine.h
Expand Up @@ -20,13 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once

#include <map>
#include <vector>
#include "util/basic_macros.h"
#include "irrlichttypes.h"
#include <IGUIFont.h>
#include <IGUISkin.h>
#include <IGUIEnvironment.h>
#include "settings.h"
#include "threading/mutex_auto_lock.h"

#define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF

Expand Down Expand Up @@ -152,6 +152,9 @@ class FontEngine
/** pointer to irrlicht gui environment */
gui::IGUIEnvironment* m_env = nullptr;

/** mutex used to protect font init and cache */
std::recursive_mutex m_font_mutex;

/** internal storage for caching fonts of different size */
std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode << 2];

Expand Down

0 comments on commit 49f7d24

Please sign in to comment.