summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsfan5 <sfan5@live.de>2021-12-17 23:49:47 +0100
committersfan5 <sfan5@live.de>2021-12-18 20:38:33 +0100
commit49f7d2494ce178162a96da57315ad41f6c2796c6 (patch)
treebd49cbfdfa65bf8f1a2c9cd11147fbe79ad281af /src
parentb2409b14d0682655363c1b3b3b6bafbaa7e7c1bf (diff)
downloadminetest-49f7d2494ce178162a96da57315ad41f6c2796c6.tar.gz
minetest-49f7d2494ce178162a96da57315ad41f6c2796c6.tar.bz2
minetest-49f7d2494ce178162a96da57315ad41f6c2796c6.zip
Protect font initialization with mutex
fixes #4532
Diffstat (limited to 'src')
-rw-r--r--src/client/fontengine.cpp48
-rw-r--r--src/client/fontengine.h5
2 files changed, 14 insertions, 39 deletions
diff --git a/src/client/fontengine.cpp b/src/client/fontengine.cpp
index f64315db4..35e908b0c 100644
--- a/src/client/fontengine.cpp
+++ b/src/client/fontengine.cpp
@@ -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();
}
@@ -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())
@@ -149,13 +153,7 @@ 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;
}
@@ -163,28 +161,15 @@ unsigned int FontEngine::getTextHeight(const FontSpec &spec)
/******************************************************************************/
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();
@@ -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);
}
/******************************************************************************/
diff --git a/src/client/fontengine.h b/src/client/fontengine.h
index 3d389ea48..403ac2e48 100644
--- a/src/client/fontengine.h
+++ b/src/client/fontengine.h
@@ -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
@@ -152,6 +152,9 @@ private:
/** 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];