From: sapier Date: Sun, 17 Aug 2014 01:33:34 +0000 (+0200) Subject: Implement proper font handling X-Git-Url: http://81.2.79.47:8989/gitweb/?a=commitdiff_plain;h=b7a96e817a3aeb501fac3b685eb39ffb6fd40e49;p=zefram%2Fminetest%2Fminetest_engine.git Implement proper font handling Remove autoadjustment of screen dpi --- diff --git a/builtin/mainmenu/tab_server.lua b/builtin/mainmenu/tab_server.lua index 154a54cc..a6186ee8 100644 --- a/builtin/mainmenu/tab_server.lua +++ b/builtin/mainmenu/tab_server.lua @@ -35,9 +35,9 @@ local function get_formspec(tabview, name, tabdata) dump(core.setting_getbool("enable_damage")) .. "]".. "checkbox[0.5,1.15;cb_server_announce;".. fgettext("Public") .. ";" .. dump(core.setting_getbool("server_announce")) .. "]".. - "field[0.8,3.2;3.5,0.5;te_playername;".. fgettext("Name") .. ";" .. + "field[0.8,3.0;3.5,0.5;te_playername;".. fgettext("Name") .. ";" .. core.setting_get("name") .. "]" .. - "pwdfield[0.8,4.2;3.5,0.5;te_passwd;".. fgettext("Password") .. "]" + "pwdfield[0.8,4.1;3.5,0.5;te_passwd;".. fgettext("Password") .. "]" local bind_addr = core.setting_get("bind_address") if bind_addr ~= nil and bind_addr ~= "" then diff --git a/fonts/fontdejavusansmono.png b/fonts/fontdejavusansmono.png deleted file mode 100644 index 02ad4135..00000000 Binary files a/fonts/fontdejavusansmono.png and /dev/null differ diff --git a/fonts/fontlucida.png b/fonts/fontlucida.png deleted file mode 100644 index ab7bb70b..00000000 Binary files a/fonts/fontlucida.png and /dev/null differ diff --git a/fonts/lucida_sans_10.xml b/fonts/lucida_sans_10.xml new file mode 100755 index 00000000..d54e9f6a Binary files /dev/null and b/fonts/lucida_sans_10.xml differ diff --git a/fonts/lucida_sans_100.png b/fonts/lucida_sans_100.png new file mode 100755 index 00000000..29658356 Binary files /dev/null and b/fonts/lucida_sans_100.png differ diff --git a/fonts/lucida_sans_11.xml b/fonts/lucida_sans_11.xml new file mode 100755 index 00000000..33d06c37 Binary files /dev/null and b/fonts/lucida_sans_11.xml differ diff --git a/fonts/lucida_sans_110.png b/fonts/lucida_sans_110.png new file mode 100755 index 00000000..db053037 Binary files /dev/null and b/fonts/lucida_sans_110.png differ diff --git a/fonts/lucida_sans_12.xml b/fonts/lucida_sans_12.xml new file mode 100755 index 00000000..382981dc Binary files /dev/null and b/fonts/lucida_sans_12.xml differ diff --git a/fonts/lucida_sans_120.png b/fonts/lucida_sans_120.png new file mode 100755 index 00000000..fd67f87c Binary files /dev/null and b/fonts/lucida_sans_120.png differ diff --git a/fonts/lucida_sans_14.xml b/fonts/lucida_sans_14.xml new file mode 100755 index 00000000..99398d79 Binary files /dev/null and b/fonts/lucida_sans_14.xml differ diff --git a/fonts/lucida_sans_140.png b/fonts/lucida_sans_140.png new file mode 100755 index 00000000..d6b27d46 Binary files /dev/null and b/fonts/lucida_sans_140.png differ diff --git a/fonts/lucida_sans_16.xml b/fonts/lucida_sans_16.xml new file mode 100755 index 00000000..b07c1119 Binary files /dev/null and b/fonts/lucida_sans_16.xml differ diff --git a/fonts/lucida_sans_160.png b/fonts/lucida_sans_160.png new file mode 100755 index 00000000..b365ba60 Binary files /dev/null and b/fonts/lucida_sans_160.png differ diff --git a/fonts/lucida_sans_18.xml b/fonts/lucida_sans_18.xml new file mode 100755 index 00000000..881aff18 Binary files /dev/null and b/fonts/lucida_sans_18.xml differ diff --git a/fonts/lucida_sans_180.png b/fonts/lucida_sans_180.png new file mode 100755 index 00000000..4d383050 Binary files /dev/null and b/fonts/lucida_sans_180.png differ diff --git a/fonts/lucida_sans_20.xml b/fonts/lucida_sans_20.xml new file mode 100755 index 00000000..329c226c Binary files /dev/null and b/fonts/lucida_sans_20.xml differ diff --git a/fonts/lucida_sans_200.png b/fonts/lucida_sans_200.png new file mode 100755 index 00000000..41cc997f Binary files /dev/null and b/fonts/lucida_sans_200.png differ diff --git a/fonts/lucida_sans_22.xml b/fonts/lucida_sans_22.xml new file mode 100755 index 00000000..14d0cc2b Binary files /dev/null and b/fonts/lucida_sans_22.xml differ diff --git a/fonts/lucida_sans_220.png b/fonts/lucida_sans_220.png new file mode 100755 index 00000000..ec72bf16 Binary files /dev/null and b/fonts/lucida_sans_220.png differ diff --git a/fonts/lucida_sans_24.xml b/fonts/lucida_sans_24.xml new file mode 100755 index 00000000..5956f46e Binary files /dev/null and b/fonts/lucida_sans_24.xml differ diff --git a/fonts/lucida_sans_240.png b/fonts/lucida_sans_240.png new file mode 100755 index 00000000..0ec3cede Binary files /dev/null and b/fonts/lucida_sans_240.png differ diff --git a/fonts/lucida_sans_26.xml b/fonts/lucida_sans_26.xml new file mode 100755 index 00000000..ae10ff8d Binary files /dev/null and b/fonts/lucida_sans_26.xml differ diff --git a/fonts/lucida_sans_260.png b/fonts/lucida_sans_260.png new file mode 100755 index 00000000..ce7ec143 Binary files /dev/null and b/fonts/lucida_sans_260.png differ diff --git a/fonts/lucida_sans_28.xml b/fonts/lucida_sans_28.xml new file mode 100755 index 00000000..c1b3361d Binary files /dev/null and b/fonts/lucida_sans_28.xml differ diff --git a/fonts/lucida_sans_280.png b/fonts/lucida_sans_280.png new file mode 100755 index 00000000..f46a7846 Binary files /dev/null and b/fonts/lucida_sans_280.png differ diff --git a/fonts/lucida_sans_36.xml b/fonts/lucida_sans_36.xml new file mode 100755 index 00000000..ca300d6d Binary files /dev/null and b/fonts/lucida_sans_36.xml differ diff --git a/fonts/lucida_sans_360.png b/fonts/lucida_sans_360.png new file mode 100755 index 00000000..99bdbf6e Binary files /dev/null and b/fonts/lucida_sans_360.png differ diff --git a/fonts/lucida_sans_4.xml b/fonts/lucida_sans_4.xml new file mode 100755 index 00000000..edc5af95 Binary files /dev/null and b/fonts/lucida_sans_4.xml differ diff --git a/fonts/lucida_sans_40.png b/fonts/lucida_sans_40.png new file mode 100755 index 00000000..24f59aa0 Binary files /dev/null and b/fonts/lucida_sans_40.png differ diff --git a/fonts/lucida_sans_6.xml b/fonts/lucida_sans_6.xml new file mode 100755 index 00000000..069c9aa8 Binary files /dev/null and b/fonts/lucida_sans_6.xml differ diff --git a/fonts/lucida_sans_60.png b/fonts/lucida_sans_60.png new file mode 100755 index 00000000..ef608243 Binary files /dev/null and b/fonts/lucida_sans_60.png differ diff --git a/fonts/lucida_sans_8.xml b/fonts/lucida_sans_8.xml new file mode 100755 index 00000000..44f0e6a7 Binary files /dev/null and b/fonts/lucida_sans_8.xml differ diff --git a/fonts/lucida_sans_80.png b/fonts/lucida_sans_80.png new file mode 100755 index 00000000..9118b791 Binary files /dev/null and b/fonts/lucida_sans_80.png differ diff --git a/fonts/lucida_sans_9.xml b/fonts/lucida_sans_9.xml new file mode 100755 index 00000000..99aa6447 Binary files /dev/null and b/fonts/lucida_sans_9.xml differ diff --git a/fonts/lucida_sans_90.png b/fonts/lucida_sans_90.png new file mode 100755 index 00000000..92fe3b79 Binary files /dev/null and b/fonts/lucida_sans_90.png differ diff --git a/fonts/mono_dejavu_sans_10.xml b/fonts/mono_dejavu_sans_10.xml new file mode 100755 index 00000000..0276cedb Binary files /dev/null and b/fonts/mono_dejavu_sans_10.xml differ diff --git a/fonts/mono_dejavu_sans_100.png b/fonts/mono_dejavu_sans_100.png new file mode 100755 index 00000000..3f8d1fe3 Binary files /dev/null and b/fonts/mono_dejavu_sans_100.png differ diff --git a/fonts/mono_dejavu_sans_11.xml b/fonts/mono_dejavu_sans_11.xml new file mode 100755 index 00000000..f727ed2b Binary files /dev/null and b/fonts/mono_dejavu_sans_11.xml differ diff --git a/fonts/mono_dejavu_sans_110.png b/fonts/mono_dejavu_sans_110.png new file mode 100755 index 00000000..ad1cd079 Binary files /dev/null and b/fonts/mono_dejavu_sans_110.png differ diff --git a/fonts/mono_dejavu_sans_12.xml b/fonts/mono_dejavu_sans_12.xml new file mode 100755 index 00000000..38f6427b Binary files /dev/null and b/fonts/mono_dejavu_sans_12.xml differ diff --git a/fonts/mono_dejavu_sans_120.png b/fonts/mono_dejavu_sans_120.png new file mode 100755 index 00000000..f9c9544b Binary files /dev/null and b/fonts/mono_dejavu_sans_120.png differ diff --git a/fonts/mono_dejavu_sans_14.xml b/fonts/mono_dejavu_sans_14.xml new file mode 100755 index 00000000..b90a3496 Binary files /dev/null and b/fonts/mono_dejavu_sans_14.xml differ diff --git a/fonts/mono_dejavu_sans_140.png b/fonts/mono_dejavu_sans_140.png new file mode 100755 index 00000000..c817dd85 Binary files /dev/null and b/fonts/mono_dejavu_sans_140.png differ diff --git a/fonts/mono_dejavu_sans_16.xml b/fonts/mono_dejavu_sans_16.xml new file mode 100755 index 00000000..3f7d2c2a Binary files /dev/null and b/fonts/mono_dejavu_sans_16.xml differ diff --git a/fonts/mono_dejavu_sans_160.png b/fonts/mono_dejavu_sans_160.png new file mode 100755 index 00000000..9886e36a Binary files /dev/null and b/fonts/mono_dejavu_sans_160.png differ diff --git a/fonts/mono_dejavu_sans_18.xml b/fonts/mono_dejavu_sans_18.xml new file mode 100755 index 00000000..92865cbf Binary files /dev/null and b/fonts/mono_dejavu_sans_18.xml differ diff --git a/fonts/mono_dejavu_sans_180.png b/fonts/mono_dejavu_sans_180.png new file mode 100755 index 00000000..ae08915a Binary files /dev/null and b/fonts/mono_dejavu_sans_180.png differ diff --git a/fonts/mono_dejavu_sans_20.xml b/fonts/mono_dejavu_sans_20.xml new file mode 100755 index 00000000..acd8c77d Binary files /dev/null and b/fonts/mono_dejavu_sans_20.xml differ diff --git a/fonts/mono_dejavu_sans_200.png b/fonts/mono_dejavu_sans_200.png new file mode 100755 index 00000000..a4ca2155 Binary files /dev/null and b/fonts/mono_dejavu_sans_200.png differ diff --git a/fonts/mono_dejavu_sans_22.xml b/fonts/mono_dejavu_sans_22.xml new file mode 100755 index 00000000..eafb4def Binary files /dev/null and b/fonts/mono_dejavu_sans_22.xml differ diff --git a/fonts/mono_dejavu_sans_220.png b/fonts/mono_dejavu_sans_220.png new file mode 100755 index 00000000..a9ab2e25 Binary files /dev/null and b/fonts/mono_dejavu_sans_220.png differ diff --git a/fonts/mono_dejavu_sans_24.xml b/fonts/mono_dejavu_sans_24.xml new file mode 100755 index 00000000..fc8b6232 Binary files /dev/null and b/fonts/mono_dejavu_sans_24.xml differ diff --git a/fonts/mono_dejavu_sans_240.png b/fonts/mono_dejavu_sans_240.png new file mode 100755 index 00000000..0b565cd9 Binary files /dev/null and b/fonts/mono_dejavu_sans_240.png differ diff --git a/fonts/mono_dejavu_sans_26.xml b/fonts/mono_dejavu_sans_26.xml new file mode 100755 index 00000000..829f0994 Binary files /dev/null and b/fonts/mono_dejavu_sans_26.xml differ diff --git a/fonts/mono_dejavu_sans_260.png b/fonts/mono_dejavu_sans_260.png new file mode 100755 index 00000000..51417d3e Binary files /dev/null and b/fonts/mono_dejavu_sans_260.png differ diff --git a/fonts/mono_dejavu_sans_28.xml b/fonts/mono_dejavu_sans_28.xml new file mode 100755 index 00000000..b5b25bd0 Binary files /dev/null and b/fonts/mono_dejavu_sans_28.xml differ diff --git a/fonts/mono_dejavu_sans_280.png b/fonts/mono_dejavu_sans_280.png new file mode 100755 index 00000000..15f81040 Binary files /dev/null and b/fonts/mono_dejavu_sans_280.png differ diff --git a/fonts/mono_dejavu_sans_4.xml b/fonts/mono_dejavu_sans_4.xml new file mode 100755 index 00000000..cfebb39b Binary files /dev/null and b/fonts/mono_dejavu_sans_4.xml differ diff --git a/fonts/mono_dejavu_sans_40.png b/fonts/mono_dejavu_sans_40.png new file mode 100755 index 00000000..680b05be Binary files /dev/null and b/fonts/mono_dejavu_sans_40.png differ diff --git a/fonts/mono_dejavu_sans_6.xml b/fonts/mono_dejavu_sans_6.xml new file mode 100755 index 00000000..d0e1de21 Binary files /dev/null and b/fonts/mono_dejavu_sans_6.xml differ diff --git a/fonts/mono_dejavu_sans_60.png b/fonts/mono_dejavu_sans_60.png new file mode 100755 index 00000000..3de61cb5 Binary files /dev/null and b/fonts/mono_dejavu_sans_60.png differ diff --git a/fonts/mono_dejavu_sans_8.xml b/fonts/mono_dejavu_sans_8.xml new file mode 100755 index 00000000..c48bf7cc Binary files /dev/null and b/fonts/mono_dejavu_sans_8.xml differ diff --git a/fonts/mono_dejavu_sans_80.png b/fonts/mono_dejavu_sans_80.png new file mode 100755 index 00000000..e94cbbec Binary files /dev/null and b/fonts/mono_dejavu_sans_80.png differ diff --git a/fonts/mono_dejavu_sans_9.xml b/fonts/mono_dejavu_sans_9.xml new file mode 100755 index 00000000..74e84103 Binary files /dev/null and b/fonts/mono_dejavu_sans_9.xml differ diff --git a/fonts/mono_dejavu_sans_90.png b/fonts/mono_dejavu_sans_90.png new file mode 100755 index 00000000..61b8d858 Binary files /dev/null and b/fonts/mono_dejavu_sans_90.png differ diff --git a/minetest.conf.example b/minetest.conf.example index 24724ce2..ff50fca2 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -202,6 +202,8 @@ #directional_colored_fog = true #tooltip_show_delay = 400 # Delay showing tooltips, in miliseconds +#screen_dpi = 72 +# adjust dpi configuration to your screen (PC/MAC only) e.g. for 4k screens # Default timeout for cURL, in milliseconds # Only has an effect if compiled with cURL diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index de1ea2c2..e594ac67 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -453,6 +453,7 @@ set(minetest_SRCS client.cpp clientmedia.cpp filecache.cpp + fontengine.cpp tile.cpp shader.cpp game.cpp diff --git a/src/constants.h b/src/constants.h index 526e4415..d5dce65f 100644 --- a/src/constants.h +++ b/src/constants.h @@ -98,7 +98,8 @@ with this program; if not, write to the Free Software Foundation, Inc., * GUI related things */ #define LEGACY_SCALING (2./3.) -#define DEFAULT_FONT_SIZE (13.0 / LEGACY_SCALING) +#define TTF_DEFAULT_FONT_SIZE (13.0 / LEGACY_SCALING) +#define DEFAULT_FONT_SIZE (14) #define DEFAULT_IMGSIZE (48.0) #define DEFAULT_XSPACING ((15.0 + (1.0 / 3.0))) #define DEFAULT_YSPACING (9.0) diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 9cd17ac9..4142458d 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -176,10 +176,23 @@ void set_default_settings(Settings *settings) settings->setDefault("fallback_font_shadow", "1"); settings->setDefault("fallback_font_shadow_alpha", "128"); + + std::stringstream fontsize; + fontsize << TTF_DEFAULT_FONT_SIZE; + + settings->setDefault("font_size", fontsize.str()); + settings->setDefault("mono_font_size", fontsize.str()); + settings->setDefault("fallback_font_size", fontsize.str()); #else settings->setDefault("freetype", "false"); settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "fontlucida.png")); settings->setDefault("mono_font_path", porting::getDataPath("fonts" DIR_DELIM "fontdejavusansmono.png")); + + std::stringstream fontsize; + fontsize << DEFAULT_FONT_SIZE; + + settings->setDefault("font_size", fontsize.str()); + settings->setDefault("mono_font_size", fontsize.str()); #endif // Server stuff @@ -308,22 +321,8 @@ void set_default_settings(Settings *settings) settings->setDefault("gui_scaling", "0.7"); } settings->setDefault("curl_verify_cert","false"); -#endif -} - -void late_init_default_settings(Settings* settings) -{ -#ifndef SERVER - std::stringstream fontsize; - fontsize << floor( - DEFAULT_FONT_SIZE * - porting::getDisplayDensity() * - settings->getFloat("gui_scaling") - ); - - settings->setDefault("font_size", fontsize.str()); - settings->setDefault("mono_font_size", fontsize.str()); - settings->setDefault("fallback_font_size", fontsize.str()); +#else + settings->setDefault("screen_dpi", "72"); #endif } diff --git a/src/defaultsettings.h b/src/defaultsettings.h index 8c7f88a7..20274a00 100644 --- a/src/defaultsettings.h +++ b/src/defaultsettings.h @@ -28,12 +28,6 @@ class Settings; */ void set_default_settings(Settings *settings); -/** - * initialize default values which require knowledge about gui - * @param settings pointer to settings - */ -void late_init_default_settings(Settings* settings); - /** * override a default settings by settings from another settings element * @param settings target settings pointer diff --git a/src/fontengine.cpp b/src/fontengine.cpp new file mode 100644 index 00000000..ea9bc4d3 --- /dev/null +++ b/src/fontengine.cpp @@ -0,0 +1,419 @@ +/* +Minetest +Copyright (C) 2010-2014 sapier + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "fontengine.h" +#include "log.h" +#include "main.h" +#include "config.h" +#include "porting.h" +#include "constants.h" +#if USE_FREETYPE +#include "gettext.h" +#include "filesys.h" +#include "xCGUITTFont.h" +#endif + + +/** minimum font size supported */ +#define MIN_FONT_SIZE 4 + +/** maximum size distance for getting a "similar" font size */ +#define MAX_FONT_SIZE_OFFSET 10 + +/** reference to access font engine, has to be initialized by main */ +FontEngine* fe = NULL; + +/** callback to be used on change of font size setting */ +static void font_setting_changed() { + fe->readSettings(); +} + +/******************************************************************************/ +FontEngine::FontEngine(Settings* main_settings, gui::IGUIEnvironment* env) : + m_settings(NULL), + m_env(NULL), + m_font_cache(), + m_default_size(), + m_currentMode(Standard), + m_lastMode(), + m_lastSize(0), + m_lastFont(NULL) +{ + + for ( unsigned int i = 0; i < MaxMode; i++) { + m_default_size[i] = (FontMode) FONT_SIZE_UNSPECIFIED; + } + + m_settings = main_settings; + m_env = env; + + assert(m_settings != NULL); + assert(m_env != NULL); + assert(m_env->getSkin() != NULL); + + m_currentMode = Simple; + +#if USE_FREETYPE + if (g_settings->getBool("freetype")) { + m_default_size[Standard] = m_settings->getU16("font_size"); + m_default_size[Fallback] = m_settings->getU16("fallback_font_size"); + m_default_size[Mono] = m_settings->getU16("mono_font_size"); + + if (is_yes(gettext("needs_fallback_font"))) { + m_currentMode = Fallback; + } + else { + m_currentMode = Standard; + } + } + + // having freetype but not using it is quite a strange case so we need to do + // special handling for it + if (m_currentMode == Simple) { + std::stringstream fontsize; + fontsize << DEFAULT_FONT_SIZE; + m_settings->setDefault("font_size", fontsize.str()); + m_settings->setDefault("mono_font_size", fontsize.str()); + } +#endif + + m_default_size[Simple] = m_settings->getU16("font_size"); + m_default_size[SimpleMono] = m_settings->getU16("mono_font_size"); + + updateSkin(); + + if (m_currentMode == Standard) { + m_settings->registerChangedCallback("font_size", font_setting_changed); + m_settings->registerChangedCallback("font_path", font_setting_changed); + m_settings->registerChangedCallback("font_shadow", font_setting_changed); + m_settings->registerChangedCallback("font_shadow_alpha", font_setting_changed); + } + else if (m_currentMode == Fallback) { + m_settings->registerChangedCallback("fallback_font_size", font_setting_changed); + m_settings->registerChangedCallback("fallback_font_path", font_setting_changed); + m_settings->registerChangedCallback("fallback_font_shadow", font_setting_changed); + m_settings->registerChangedCallback("fallback_font_shadow_alpha", font_setting_changed); + } + + m_settings->registerChangedCallback("mono_font_path", font_setting_changed); + m_settings->registerChangedCallback("mono_font_size", font_setting_changed); + m_settings->registerChangedCallback("screen_dpi", font_setting_changed); + m_settings->registerChangedCallback("gui_scaling", font_setting_changed); +} + +/******************************************************************************/ +FontEngine::~FontEngine() +{ + cleanCache(); +} + +/******************************************************************************/ +void FontEngine::cleanCache() +{ + for ( unsigned int i = 0; i < MaxMode; i++) { + + for (std::map::iterator iter + = m_font_cache[i].begin(); + iter != m_font_cache[i].end(); iter++) { + iter->second->drop(); + iter->second = NULL; + } + m_font_cache[i].clear(); + } +} + +/******************************************************************************/ +irr::gui::IGUIFont* FontEngine::getFont(unsigned int font_size, FontMode mode) +{ + if (mode == Unspecified) { + mode = m_currentMode; + } + else if ((mode == Mono) && (m_currentMode == Simple)) { + mode = SimpleMono; + } + + if (font_size == FONT_SIZE_UNSPECIFIED) { + font_size = m_default_size[mode]; + } + + if ((font_size == m_lastSize) && (mode == m_lastMode)) { + return m_lastFont; + } + + if (m_font_cache[mode].find(font_size) == m_font_cache[mode].end()) { + initFont(font_size, mode); + } + + if (m_font_cache[mode].find(font_size) == m_font_cache[mode].end()) { + return NULL; + } + + m_lastSize = font_size; + m_lastMode = mode; + m_lastFont = m_font_cache[mode][font_size]; + + return m_font_cache[mode][font_size]; +} + +/******************************************************************************/ +unsigned int FontEngine::getTextHeight(unsigned int font_size, FontMode mode) +{ + irr::gui::IGUIFont* font = getFont(font_size,mode); + + if (font == NULL) return MIN_FONT_SIZE; + + return font->getDimension(L"Some unimportant example String").Height; +} + +/******************************************************************************/ +unsigned int FontEngine::getDefaultFontSize() +{ + return m_default_size[m_currentMode]; +} + +/******************************************************************************/ +void FontEngine::readSettings() +{ +#if USE_FREETYPE + if (g_settings->getBool("freetype")) { + m_default_size[Standard] = m_settings->getU16("font_size"); + m_default_size[Fallback] = m_settings->getU16("fallback_font_size"); + m_default_size[Mono] = m_settings->getU16("mono_font_size"); + + if (is_yes(gettext("needs_fallback_font"))) { + m_currentMode = Fallback; + } + else { + m_currentMode = Standard; + } + } +#endif + m_default_size[Simple] = m_settings->getU16("font_size"); + m_default_size[SimpleMono] = m_settings->getU16("mono_font_size"); + + cleanCache(); + updateFontCache(); + updateSkin(); +} + +/******************************************************************************/ +void FontEngine::updateSkin() +{ + gui::IGUIFont *font = getFont(); + + if (font) + m_env->getSkin()->setFont(font); + else + errorstream << "WARNING: Font file was not found." + << " Using 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(); + assert(font); + + u32 text_height = font->getDimension(L"Hello, world!").Height; + infostream << "text_height=" << text_height << std::endl; +} + +/******************************************************************************/ +void FontEngine::updateFontCache() +{ + for (unsigned int i = 0; i < MaxMode; i++) { + /* only font to be initialized is default one, + * all others are re-initialized on demand */ + initFont(m_default_size[i], (FontMode) i); + } + + /* reset font quick access */ + m_lastMode = Unspecified; + m_lastSize = 0; + m_lastFont = NULL; +} + +/******************************************************************************/ +void FontEngine::initFont(unsigned int basesize, FontMode mode) +{ + + std::string font_config_prefix; + + if (mode == Unspecified) { + mode = m_currentMode; + } + + switch (mode) { + + case Standard: + font_config_prefix = ""; + break; + + case Fallback: + font_config_prefix = "fallback_"; + break; + + case Mono: + font_config_prefix = "mono_"; + if (m_currentMode == Simple) + mode = SimpleMono; + break; + + case Simple: /* Fallthrough */ + case SimpleMono: /* Fallthrough */ + default: + font_config_prefix = ""; + + } + + if (m_font_cache[mode].find(basesize) != m_font_cache[mode].end()) + return; + + if ((mode == Simple) || (mode == SimpleMono)) { + initSimpleFont(basesize, mode); + return; + } +#if USE_FREETYPE + else { + if (! is_yes(m_settings->get("freetype"))) { + return; + } + unsigned int size = floor( + porting::getDisplayDensity() * + m_settings->getFloat("gui_scaling") * + basesize); + u32 font_shadow = 0; + u32 font_shadow_alpha = 0; + + try { + g_settings->getU16(font_config_prefix + "font_shadow"); + } catch (SettingNotFoundException&) {} + try { + g_settings->getU16(font_config_prefix + "font_shadow_alpha"); + } catch (SettingNotFoundException&) {} + + std::string font_path = g_settings->get(font_config_prefix + "font_path"); + + irr::gui::IGUIFont* font = gui::CGUITTFont::createTTFont(m_env, + font_path.c_str(), size, true, true, font_shadow, + font_shadow_alpha); + + if (font != NULL) { + font->grab(); + m_font_cache[mode][basesize] = font; + } + else { + errorstream << "FontEngine: failed to load freetype font: " + << font_path << std::endl; + } + } +#endif +} + +/** initialize a font without freetype */ +void FontEngine::initSimpleFont(unsigned int basesize, FontMode mode) +{ + assert((mode == Simple) || (mode == SimpleMono)); + + std::string font_path = ""; + if (mode == Simple) { + font_path = m_settings->get("font_path"); + } else { + font_path = m_settings->get("mono_font_path"); + } + std::string basename = font_path; + std::string ending = font_path.substr(font_path.length() -4); + + if ((ending == ".xml") || ( ending == ".png") || ( ending == ".ttf")) { + basename = font_path.substr(0,font_path.length()-4); + } + + if (basesize == FONT_SIZE_UNSPECIFIED) + basesize = DEFAULT_FONT_SIZE; + + unsigned int size = floor( + porting::getDisplayDensity() * + m_settings->getFloat("gui_scaling") * + basesize); + + irr::gui::IGUIFont* font = NULL; + + for(unsigned int offset = 0; offset < MAX_FONT_SIZE_OFFSET; offset++) { + + // try opening positive offset + std::stringstream fontsize_plus_png; + fontsize_plus_png << basename << "_" << (size + offset) << ".png"; + + if (fs::PathExists(fontsize_plus_png.str())) { + font = m_env->getFont(fontsize_plus_png.str().c_str()); + + if (font) { + verbosestream << "FontEngine: found font: " << fontsize_plus_png.str() << std::endl; + break; + } + } + + std::stringstream fontsize_plus_xml; + fontsize_plus_xml << basename << "_" << (size + offset) << ".xml"; + + if (fs::PathExists(fontsize_plus_xml.str())) { + font = m_env->getFont(fontsize_plus_xml.str().c_str()); + + if (font) { + verbosestream << "FontEngine: found font: " << fontsize_plus_xml.str() << std::endl; + break; + } + } + + // try negative offset + std::stringstream fontsize_minus_png; + fontsize_minus_png << basename << "_" << (size - offset) << ".png"; + + if (fs::PathExists(fontsize_minus_png.str())) { + font = m_env->getFont(fontsize_minus_png.str().c_str()); + + if (font) { + verbosestream << "FontEngine: found font: " << fontsize_minus_png.str() << std::endl; + break; + } + } + + std::stringstream fontsize_minus_xml; + fontsize_minus_xml << basename << "_" << (size - offset) << ".xml"; + + if (fs::PathExists(fontsize_minus_xml.str())) { + font = m_env->getFont(fontsize_minus_xml.str().c_str()); + + if (font) { + verbosestream << "FontEngine: found font: " << fontsize_minus_xml.str() << std::endl; + break; + } + } + } + + // try name direct + if (font == NULL) { + if (fs::PathExists(font_path)) { + font = m_env->getFont(font_path.c_str()); + if (font) + verbosestream << "FontEngine: found font: " << font_path << std::endl; + } + } + + if (font != NULL) { + font->grab(); + m_font_cache[mode][basesize] = font; + } +} diff --git a/src/fontengine.h b/src/fontengine.h new file mode 100644 index 00000000..f8e2716c --- /dev/null +++ b/src/fontengine.h @@ -0,0 +1,123 @@ +/* +Minetest +Copyright (C) 2010-2014 sapier + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#ifndef __FONTENGINE_H__ +#define __FONTENGINE_H__ + +#include +#include +#include "IGUIFont.h" +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "settings.h" + +#define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF + +enum FontMode { + Standard = 0, + Mono, + Fallback, + Simple, + SimpleMono, + MaxMode, + Unspecified +}; + +class FontEngine +{ +public: + + FontEngine(Settings* main_settings, gui::IGUIEnvironment* env); + + ~FontEngine(); + + /** get Font */ + irr::gui::IGUIFont* getFont(unsigned int font_size=FONT_SIZE_UNSPECIFIED, + FontMode mode=Unspecified); + + /** get text height for a specific font */ + unsigned int getTextHeight(unsigned int font_size=FONT_SIZE_UNSPECIFIED, + FontMode mode=Unspecified); + + /** get default font size */ + unsigned int getDefaultFontSize(); + + /** initialize font engine */ + void initialize(Settings* main_settings, gui::IGUIEnvironment* env); + + /** update internal parameters from settings */ + void readSettings(); + +private: + /** disable copy constructor */ + FontEngine() : + m_settings(NULL), + m_env(NULL), + m_font_cache(), + m_default_size(), + m_currentMode(Standard), + m_lastMode(), + m_lastSize(0), + m_lastFont(NULL) + {}; + + /** update content of font cache in case of a setting change made it invalid */ + void updateFontCache(); + + /** initialize a new font */ + void initFont(unsigned int basesize, FontMode mode=Unspecified); + + /** initialize a font without freetype */ + void initSimpleFont(unsigned int basesize, FontMode mode); + + /** update current minetest skin with font changes */ + void updateSkin(); + + /** clean cache */ + void cleanCache(); + + /** pointer to settings for registering callbacks or reading config */ + Settings* m_settings; + + /** pointer to irrlicht gui environment */ + gui::IGUIEnvironment* m_env; + + /** internal storage for caching fonts of different size */ + std::map m_font_cache[MaxMode]; + + /** default font size to use */ + unsigned int m_default_size[MaxMode]; + + /** current font engine mode */ + FontMode m_currentMode; + + /** font mode of last request */ + FontMode m_lastMode; + + /** size of last request */ + unsigned int m_lastSize; + + /** last font returned */ + irr::gui::IGUIFont* m_lastFont; + +}; + +/** interface to access main font engine*/ +extern FontEngine* fe; + +#endif diff --git a/src/game.cpp b/src/game.cpp index 76819314..874dae89 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -69,6 +69,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/pointedthing.h" #include "drawscene.h" #include "content_cao.h" +#include "fontengine.h" #ifdef HAVE_TOUCHSCREENGUI #include "touchscreengui.h" @@ -1067,7 +1068,7 @@ static void show_pause_menu(GUIFormSpecMenu** cur_formspec, /******************************************************************************/ void the_game(bool &kill, bool random_input, InputHandler *input, - IrrlichtDevice *device, gui::IGUIFont* font, std::string map_dir, + IrrlichtDevice *device, std::string map_dir, std::string playername, std::string password, std::string address /* If "", local server is used */, u16 port, std::wstring &error_message, ChatBackend &chat_backend, @@ -1078,16 +1079,13 @@ void the_game(bool &kill, bool random_input, InputHandler *input, video::IVideoDriver* driver = device->getVideoDriver(); scene::ISceneManager* smgr = device->getSceneManager(); - // Calculate text height using the font - u32 text_height = font->getDimension(L"Random test string").Height; - /* Draw "Loading" screen */ { wchar_t* text = wgettext("Loading..."); - draw_load_screen(text, device, guienv, font, 0, 0); + draw_load_screen(text, device, guienv, fe->getFont(), 0, 0); delete[] text; } @@ -1147,7 +1145,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, if(address == ""){ wchar_t* text = wgettext("Creating server...."); - draw_load_screen(text, device, guienv, font, 0, 25); + draw_load_screen(text, device, guienv, fe->getFont(), 0, 25); delete[] text; infostream<<"Creating server"<getFont(), 0, 50); delete[] text; } infostream<<"Creating client"<getFont(), 0, 75); delete[] text; } Address connect_address(0,0,0,0, port); @@ -1298,7 +1296,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, // Display status { wchar_t* text = wgettext("Connecting to server..."); - draw_load_screen(text, device, guienv, font, dtime, 100); + draw_load_screen(text, device, guienv, fe->getFont(), dtime, 100); delete[] text; } @@ -1401,14 +1399,14 @@ void the_game(bool &kill, bool random_input, InputHandler *input, { wchar_t* text = wgettext("Item definitions..."); progress = 0; - draw_load_screen(text, device, guienv, font, dtime, progress); + draw_load_screen(text, device, guienv, fe->getFont(), dtime, progress); delete[] text; } else if (!client.nodedefReceived()) { wchar_t* text = wgettext("Node definitions..."); progress = 25; - draw_load_screen(text, device, guienv, font, dtime, progress); + draw_load_screen(text, device, guienv, fe->getFont(), dtime, progress); delete[] text; } else @@ -1431,7 +1429,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, } progress = 50+client.mediaReceiveProgress()*50+0.5; draw_load_screen(narrow_to_wide(message.str().c_str()), device, - guienv, font, dtime, progress); + guienv, fe->getFont(), dtime, progress); } // On some computers framerate doesn't seem to be @@ -1475,7 +1473,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, After all content has been received: Update cached textures, meshes and materials */ - client.afterContentReceived(device,font); + client.afterContentReceived(device, fe->getFont()); /* Create the camera node @@ -1539,7 +1537,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, // Object infos are shown in this gui::IGUIStaticText *guitext_info = guienv->addStaticText( L"", - core::rect(0,0,400,text_height*5+5) + v2s32(100,200), + core::rect(0,0,400, (fe->getTextHeight() * 5) + 5) + v2s32(100,200), false, true); // Status text (displays info when showing and hiding GUI stuff, etc.) @@ -1657,7 +1655,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, /* HUD object */ - Hud hud(driver, smgr, guienv, font, text_height, + Hud hud(driver, smgr, guienv, fe->getFont(), fe->getTextHeight(), gamedef, player, &local_inventory); core::stringw str = L"Minetest ["; @@ -1864,8 +1862,8 @@ void the_game(bool &kill, bool random_input, InputHandler *input, g_profiler->print(infostream); } - update_profiler_gui(guitext_profiler, font, text_height, - show_profiler, show_profiler_max); + update_profiler_gui(guitext_profiler, fe->getFont(), + fe->getTextHeight(), show_profiler, show_profiler_max); g_profiler->clear(); } @@ -2112,8 +2110,8 @@ void the_game(bool &kill, bool random_input, InputHandler *input, show_profiler = (show_profiler + 1) % (show_profiler_max + 1); // FIXME: This updates the profiler with incomplete values - update_profiler_gui(guitext_profiler, font, text_height, - show_profiler, show_profiler_max); + update_profiler_gui(guitext_profiler, fe->getFont(), + fe->getTextHeight(), show_profiler, show_profiler_max); if(show_profiler != 0) { @@ -3233,7 +3231,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, 5, 5, screensize.X, - 5 + text_height + 5 + fe->getTextHeight() ); guitext->setRelativePosition(rect); } @@ -3253,9 +3251,9 @@ void the_game(bool &kill, bool random_input, InputHandler *input, core::rect rect( 5, - 5 + text_height, + 5 + fe->getTextHeight(), screensize.X, - 5 + (text_height * 2) + 5 + (fe->getTextHeight() * 2) ); guitext2->setRelativePosition(rect); } @@ -3335,9 +3333,9 @@ void the_game(bool &kill, bool random_input, InputHandler *input, guitext_chat->setText(recent_chat.c_str()); // Update gui element size and position - s32 chat_y = 5+(text_height+5); + s32 chat_y = 5+(fe->getTextHeight() + 5); if(show_debug) - chat_y += (text_height+5); + chat_y += (fe->getTextHeight() + 5); core::rect rect( 10, chat_y, @@ -3409,7 +3407,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, */ if(show_profiler_graph) { - graph.draw(10, screensize.Y - 10, driver, font); + graph.draw(10, screensize.Y - 10, driver, fe->getFont()); } /* @@ -3482,7 +3480,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, */ { wchar_t* text = wgettext("Shutting down stuff..."); - draw_load_screen(text, device, guienv, font, 0, -1, false); + draw_load_screen(text, device, guienv, fe->getFont(), 0, -1, false); delete[] text; } diff --git a/src/game.h b/src/game.h index 1c831c53..c29c852e 100644 --- a/src/game.h +++ b/src/game.h @@ -130,7 +130,6 @@ void the_game( bool random_input, InputHandler *input, IrrlichtDevice *device, - gui::IGUIFont* font, std::string map_dir, std::string playername, std::string password, diff --git a/src/guiChatConsole.cpp b/src/guiChatConsole.cpp index d8881dbd..9253e2a7 100644 --- a/src/guiChatConsole.cpp +++ b/src/guiChatConsole.cpp @@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "main.h" // for g_settings #include "porting.h" #include "tile.h" -#include "IGUIFont.h" +#include "fontengine.h" #include #include "gettext.h" @@ -92,23 +92,10 @@ GUIChatConsole::GUIChatConsole( m_background_color.setBlue(255); } - // load the font - // FIXME should a custom texture_path be searched too? - std::string font_name = g_settings->get("mono_font_path"); - #if USE_FREETYPE - m_use_freetype = g_settings->getBool("freetype"); - if (m_use_freetype) { - u16 font_size = g_settings->getU16("mono_font_size"); - m_font = gui::CGUITTFont::createTTFont(env, font_name.c_str(), font_size); - } else { - m_font = env->getFont(font_name.c_str()); - } - #else - m_font = env->getFont(font_name.c_str()); - #endif + m_font = fe->getFont(FONT_SIZE_UNSPECIFIED, Mono); if (m_font == NULL) { - dstream << "Unable to load font: " << font_name << std::endl; + errorstream << "GUIChatConsole: Unable to load mono font "; } else { @@ -125,10 +112,6 @@ GUIChatConsole::GUIChatConsole( GUIChatConsole::~GUIChatConsole() { -#if USE_FREETYPE - if (m_use_freetype) - m_font->drop(); -#endif } void GUIChatConsole::openConsole(f32 height) diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index d6ca12b7..dce6cd69 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -87,7 +87,6 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev, m_form_src(fsrc), m_text_dst(tdst), m_ext_ptr(ext_ptr), - m_font(dev->getGUIEnvironment()->getSkin()->getFont()), m_formspec_version(0) #ifdef __ANDROID__ ,m_JavaDialogFieldName(L"") @@ -105,9 +104,6 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev, m_doubleclickdetect[1].pos = v2s32(0, 0); m_tooltip_show_delay = (u32)g_settings->getS32("tooltip_show_delay"); - - m_btn_height = g_settings->getS32("font_size") +2; - assert(m_btn_height > 0); } GUIFormSpecMenu::~GUIFormSpecMenu() @@ -440,9 +436,14 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) std::wstring wlabel = narrow_to_wide(label.c_str()); + gui::IGUIFont *font = NULL; + gui::IGUISkin* skin = Environment->getSkin(); + if (skin) + font = skin->getFont(); + core::rect rect = core::rect( pos.X, pos.Y + ((imgsize.Y/2) - m_btn_height), - pos.X + m_font->getDimension(wlabel.c_str()).Width + 25, // text size + size of checkbox + pos.X + font->getDimension(wlabel.c_str()).Width + 25, // text size + size of checkbox pos.Y + ((imgsize.Y/2) + m_btn_height)); FieldSpec spec( @@ -1251,9 +1252,14 @@ void GUIFormSpecMenu::parseLabel(parserData* data,std::string element) std::wstring wlabel = narrow_to_wide(text.c_str()); + gui::IGUIFont *font = NULL; + gui::IGUISkin* skin = Environment->getSkin(); + if (skin) + font = skin->getFont(); + core::rect rect = core::rect( pos.X, pos.Y+((imgsize.Y/2) - m_btn_height), - pos.X + m_font->getDimension(wlabel.c_str()).Width, + pos.X + font->getDimension(wlabel.c_str()).Width, pos.Y+((imgsize.Y/2) + m_btn_height)); FieldSpec spec( @@ -1285,12 +1291,18 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element) pos.X += stof(v_pos[0]) * (float)spacing.X; pos.Y += stof(v_pos[1]) * (float)spacing.Y; + gui::IGUIFont *font = NULL; + gui::IGUISkin* skin = Environment->getSkin(); + if (skin) + font = skin->getFont(); + core::rect rect = core::rect( pos.X, pos.Y+((imgsize.Y/2)- m_btn_height), pos.X+15, pos.Y + - (m_font->getKerningHeight() + - m_font->getDimension(text.c_str()).Height) - * (text.length()+1)); + (font->getKerningHeight() + + font->getDimension(text.c_str()).Height) + * (text.length()+1) + +((imgsize.Y/2)- m_btn_height)); //actually text.length() would be correct but adding +1 avoids to break all mods if(data->bp_set != 2) @@ -1840,6 +1852,14 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) return; } + gui::IGUIFont *font = NULL; + gui::IGUISkin* skin = Environment->getSkin(); + if (skin) + font = skin->getFont(); + + m_btn_height = font->getDimension(L"Some unimportant test String").Height; + assert(m_btn_height > 0); + parserData mydata; //preserve tables @@ -2051,7 +2071,6 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase) { video::IVideoDriver* driver = Environment->getVideoDriver(); - // Get font gui::IGUIFont *font = NULL; gui::IGUISkin* skin = Environment->getSkin(); if (skin) @@ -2197,9 +2216,6 @@ void GUIFormSpecMenu::drawMenu() updateSelectedItem(); - gui::IGUISkin* skin = Environment->getSkin(); - if (!skin) - return; video::IVideoDriver* driver = Environment->getVideoDriver(); v2u32 screenSize = driver->getScreenSize(); diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index 15bc628d..b3a597ee 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -345,7 +345,6 @@ private: IFormSource *m_form_src; TextDest *m_text_dst; GUIFormSpecMenu **m_ext_ptr; - gui::IGUIFont *m_font; unsigned int m_formspec_version; typedef struct { diff --git a/src/main.cpp b/src/main.cpp index bb2ac5fa..96dc936e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,9 +69,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "profiler.h" #include "log.h" #include "mods.h" -#if USE_FREETYPE -#include "xCGUITTFont.h" -#endif #include "util/string.h" #include "subgame.h" #include "quicktune.h" @@ -79,6 +76,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "httpfetch.h" #include "guiEngine.h" #include "mapsector.h" +#include "fontengine.h" #include "database-sqlite3.h" #ifdef USE_LEVELDB @@ -1495,7 +1493,6 @@ int main(int argc, char *argv[]) irr_logger->setLogLevel(irr_log_level[loglevel]); porting::initIrrlicht(device); - late_init_default_settings(g_settings); /* Continue initialization @@ -1542,37 +1539,9 @@ int main(int argc, char *argv[]) guienv = device->getGUIEnvironment(); gui::IGUISkin* skin = guienv->getSkin(); - std::string font_path = g_settings->get("font_path"); - gui::IGUIFont *font; - #if USE_FREETYPE - bool use_freetype = g_settings->getBool("freetype"); - if (use_freetype) { - std::string fallback; - if (is_yes(gettext("needs_fallback_font"))) - fallback = "fallback_"; - u16 font_size = g_settings->getU16(fallback + "font_size"); - font_path = g_settings->get(fallback + "font_path"); - u32 font_shadow = g_settings->getU16(fallback + "font_shadow"); - u32 font_shadow_alpha = g_settings->getU16(fallback + "font_shadow_alpha"); - font = gui::CGUITTFont::createTTFont(guienv, font_path.c_str(), font_size, - true, true, font_shadow, font_shadow_alpha); - } else { - font = guienv->getFont(font_path.c_str()); - } - #else - font = guienv->getFont(font_path.c_str()); - #endif - if (font) - skin->setFont(font); - else - errorstream << "WARNING: Font file was not found." - << " Using default font." << std::endl; - // If font was not found, this will get us one - font = skin->getFont(); - assert(font); - u32 text_height = font->getDimension(L"Hello, world!").Height; - infostream << "text_height=" << text_height << std::endl; + fe = new FontEngine(g_settings, guienv); + assert(fe != NULL); skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255)); skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 0, 0, 0)); @@ -1855,7 +1824,6 @@ int main(int argc, char *argv[]) random_input, input, device, - font, worldspec.path, current_playername, current_password, @@ -1906,16 +1874,13 @@ int main(int argc, char *argv[]) g_menucloudsmgr->drop(); delete input; + delete fe; /* In the end, delete the Irrlicht device. */ device->drop(); -#if USE_FREETYPE - if (use_freetype) - font->drop(); -#endif delete receiver; #endif // !SERVER diff --git a/src/porting.cpp b/src/porting.cpp index ad942b0b..c44f3649 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -555,16 +555,7 @@ v2u32 getWindowSize() { #ifndef __ANDROID__ float getDisplayDensity() { - float gui_scaling = g_settings->getFloat("gui_scaling"); - // using Y here feels like a bug, this needs to be discussed later! - if (getWindowSize().Y <= 800) { - return (2.0/3.0) * gui_scaling; - } - if (getWindowSize().Y <= 1280) { - return 1.0 * gui_scaling; - } - - return (4.0/3.0) * gui_scaling; + return g_settings->getFloat("screen_dpi")/96.0; } v2u32 getDisplaySize() { diff --git a/src/settings.h b/src/settings.h index 13c8e1e6..40ec0b64 100644 --- a/src/settings.h +++ b/src/settings.h @@ -56,6 +56,9 @@ struct ValueSpec const char *help; }; +/** function type to register a changed callback */ +typedef void (*setting_changed_callback)(); + class Settings { public: @@ -423,16 +426,22 @@ public: void set(std::string name, std::string value) { - JMutexAutoLock lock(m_mutex); + { + JMutexAutoLock lock(m_mutex); - m_settings[name] = value; + m_settings[name] = value; + } + doCallbacks(name); } void set(std::string name, const char *value) { - JMutexAutoLock lock(m_mutex); + { + JMutexAutoLock lock(m_mutex); - m_settings[name] = value; + m_settings[name] = value; + } + doCallbacks(name); } @@ -848,9 +857,34 @@ public: return *this; } + void registerChangedCallback(std::string name, setting_changed_callback cbf) + { + m_callbacks[name].push_back(cbf); + } + private: + + void doCallbacks(std::string name) + { + std::vector tempvector; + { + JMutexAutoLock lock(m_mutex); + if (m_callbacks.find(name) != m_callbacks.end()) { + + tempvector = m_callbacks[name]; + } + } + + for (std::vector::iterator iter = tempvector.begin(); + iter != tempvector.end(); iter ++) + { + (*iter)(); + } + } + std::map m_settings; std::map m_defaults; + std::map > m_callbacks; // All methods that access m_settings/m_defaults directly should lock this. JMutex m_mutex; };