From 3037f190be35e25688390823c62ab99c4d62f4b3 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 23 Aug 2022 09:35:13 +0400 Subject: [PATCH] Implement per-font resolution --- apps/launcher/advancedpage.cpp | 5 -- apps/openmw/mwgui/windowmanagerimp.cpp | 1 - components/fontloader/fontloader.cpp | 77 ++++++++++++++----- components/fontloader/fontloader.hpp | 3 +- components/myguiplatform/scalinglayer.cpp | 14 ++-- components/myguiplatform/scalinglayer.hpp | 3 +- docs/source/reference/modding/font.rst | 7 +- .../source/reference/modding/settings/GUI.rst | 12 --- files/data/fonts/DejaVuLGCSansMono.omwfont | 1 + files/data/fonts/DemonicLetters.omwfont | 1 + files/data/fonts/MysticCards.omwfont | 1 + files/settings-default.cfg | 3 - files/ui/advancedpage.ui | 27 ------- 13 files changed, 75 insertions(+), 80 deletions(-) diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index fa29b848b7..73aec4cdae 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -205,7 +205,6 @@ bool Launcher::AdvancedPage::loadSettings() loadSettingBool(graphicHerbalismCheckBox, "graphic herbalism", "Game"); scalingSpinBox->setValue(Settings::Manager::getFloat("scaling factor", "GUI")); fontSizeSpinBox->setValue(Settings::Manager::getInt("font size", "GUI")); - ttfResolutionSpinBox->setValue(Settings::Manager::getInt("ttf resolution", "GUI")); } // Bug fixes @@ -373,10 +372,6 @@ void Launcher::AdvancedPage::saveSettings() int fontSize = fontSizeSpinBox->value(); if (fontSize != Settings::Manager::getInt("font size", "GUI")) Settings::Manager::setInt("font size", "GUI", fontSize); - - int ttfResolution = ttfResolutionSpinBox->value(); - if (ttfResolution != Settings::Manager::getInt("ttf resolution", "GUI")) - Settings::Manager::setInt("ttf resolution", "GUI", ttfResolution); } // Bug fixes diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 0c4d36a185..22833c4796 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -209,7 +209,6 @@ namespace MWGui // Load fonts mFontLoader = std::make_unique(encoding, resourceSystem->getVFS(), mScalingFactor); - mFontLoader->loadFonts(); //Register own widgets with MyGUI MyGUI::FactoryManager::getInstance().registerFactory("Widget"); diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index dbf42e810b..cafc97ba6b 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -25,11 +25,52 @@ #include #include +#include #include namespace { + MyGUI::xml::ElementPtr getProperty(MyGUI::xml::ElementPtr resourceNode, const std::string propertyName) + { + MyGUI::xml::ElementPtr propertyNode = nullptr; + MyGUI::xml::ElementEnumerator propertyIterator = resourceNode->getElementEnumerator(); + while (propertyIterator.next("Property")) + { + std::string key = propertyIterator->findAttribute("key"); + + if (key == propertyName) + { + propertyNode = propertyIterator.current(); + break; + } + } + + return propertyNode; + } + + MyGUI::IntSize getBookSize(MyGUI::IDataStream* layersStream) + { + MyGUI::xml::Document xmlDocument; + xmlDocument.open(layersStream); + MyGUI::xml::ElementPtr root = xmlDocument.getRoot(); + MyGUI::xml::ElementEnumerator layersIterator = root->getElementEnumerator(); + while (layersIterator.next("Layer")) + { + std::string name = layersIterator->findAttribute("name"); + + if (name == "JournalBooks") + { + MyGUI::xml::ElementPtr sizeProperty = getProperty(layersIterator.current(), "Size"); + const std::string& sizeValue = sizeProperty != nullptr ? sizeProperty->findAttribute("value") : std::string(); + if (!sizeValue.empty()) + return MyGUI::IntSize::parse(sizeValue); + } + } + + return MyGUI::RenderManager::getInstance().getViewSize(); + } + unsigned long utf8ToUnicode(std::string_view utf8) { if (utf8.empty()) @@ -165,6 +206,8 @@ namespace Gui MyGUI::ResourceManager::getInstance().unregisterLoadXmlDelegate("Resource"); MyGUI::ResourceManager::getInstance().registerLoadXmlDelegate("Resource") = MyGUI::newDelegate(this, &FontLoader::overrideLineHeight); + + loadFonts(); } void FontLoader::loadFonts() @@ -203,6 +246,11 @@ namespace Gui return; } + // TODO: it may be worth to take in account resolution change, but it is not safe to replace used assets + std::unique_ptr layersStream(dataManager->getData("openmw_layers.xml")); + MyGUI::IntSize bookSize = getBookSize(layersStream.get()); + float bookScale = osgMyGUI::ScalingLayer::getScaleFactor(bookSize); + std::string oldDataPath = dataManager->getDataPath(""); dataManager->setResourcePath("fonts"); std::unique_ptr dataStream(dataManager->getData(fileName)); @@ -226,15 +274,17 @@ namespace Gui return; } - // For TrueType fonts we should override Size and Resolution properties - // to allow to configure font size via config file, without need to edit XML files. - // Also we should take UI scaling factor in account. - int resolution = Settings::Manager::getInt("ttf resolution", "GUI"); - resolution = std::clamp(resolution, 50, 125) * mScalingFactor; + int resolution = 70; + MyGUI::xml::ElementPtr resolutionNode = getProperty(resourceNode.current(), "Resolution"); + if (resolutionNode == nullptr) + { + resolutionNode = resourceNode->createChild("Property"); + resolutionNode->addAttribute("key", "Resolution"); + } + else + resolution = MyGUI::utility::parseInt(resolutionNode->findAttribute("value")); - MyGUI::xml::ElementPtr resolutionNode = resourceNode->createChild("Property"); - resolutionNode->addAttribute("key", "Resolution"); - resolutionNode->addAttribute("value", std::to_string(resolution)); + resolutionNode->setAttribute("value", MyGUI::utility::toString(resolution * std::ceil(mScalingFactor))); MyGUI::xml::ElementPtr sizeNode = resourceNode->createChild("Property"); sizeNode->addAttribute("key", "Size"); @@ -246,16 +296,7 @@ namespace Gui font->setResourceName(fontId); MyGUI::ResourceManager::getInstance().addResource(font); - float currentX = Settings::Manager::getInt("resolution x", "Video"); - float currentY = Settings::Manager::getInt("resolution y", "Video"); - // TODO: read size from openmw_layout.xml somehow - // TODO: it may be worth to take in account resolution change, but it is not safe to replace used assets - float heightScale = (currentY / 520); - float widthScale = (currentX / 600); - float uiScale = std::min(widthScale, heightScale); - resolution = Settings::Manager::getInt("ttf resolution", "GUI"); - resolution = std::clamp(resolution, 50, 125) * uiScale; - resolutionNode->setAttribute("value", std::to_string(resolution)); + resolutionNode->setAttribute("value", MyGUI::utility::toString(static_cast(resolution * bookScale * mScalingFactor))); MyGUI::ResourceTrueTypeFont* bookFont = static_cast( MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceTrueTypeFont")); diff --git a/components/fontloader/fontloader.hpp b/components/fontloader/fontloader.hpp index 3a2151787b..abc0b22bc6 100644 --- a/components/fontloader/fontloader.hpp +++ b/components/fontloader/fontloader.hpp @@ -27,8 +27,6 @@ namespace Gui public: FontLoader (ToUTF8::FromType encoding, const VFS::Manager* vfs, float scalingFactor); - void loadFonts(); - void overrideLineHeight(MyGUI::xml::ElementPtr _node, const std::string& _file, MyGUI::Version _version); int getFontHeight(); @@ -41,6 +39,7 @@ namespace Gui int mFontHeight; float mScalingFactor; + void loadFonts(); void loadFont(const std::string& fontName, const std::string& fontId); void loadBitmapFont (const std::string& fileName, const std::string& fontId); diff --git a/components/myguiplatform/scalinglayer.cpp b/components/myguiplatform/scalinglayer.cpp index 75a149c810..e0ab25819c 100644 --- a/components/myguiplatform/scalinglayer.cpp +++ b/components/myguiplatform/scalinglayer.cpp @@ -63,7 +63,7 @@ namespace osgMyGUI void ScalingLayer::screenToLayerCoords(int& _left, int& _top) const { - float scale = getScaleFactor(); + float scale = getScaleFactor(mViewSize); if (scale <= 0.f) return; @@ -79,14 +79,14 @@ namespace osgMyGUI _top += mViewSize.height/2; } - float ScalingLayer::getScaleFactor() const + float ScalingLayer::getScaleFactor(const MyGUI::IntSize& _layerViewSize) { MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); float w = static_cast(viewSize.width); float h = static_cast(viewSize.height); - float heightScale = (h / mViewSize.height); - float widthScale = (w / mViewSize.width); + float heightScale = (h / _layerViewSize.height); + float widthScale = (w / _layerViewSize.width); return std::min(widthScale, heightScale); } @@ -100,12 +100,12 @@ namespace osgMyGUI { MyGUI::IntSize globalViewSize = MyGUI::RenderManager::getInstance().getViewSize(); MyGUI::IntSize viewSize = globalViewSize; - float scale = getScaleFactor(); + float scale = getScaleFactor(mViewSize); viewSize.width = static_cast(viewSize.width / scale); viewSize.height = static_cast(viewSize.height / scale); - float hoffset = (globalViewSize.width - mViewSize.width*getScaleFactor())/2.f / static_cast(globalViewSize.width); - float voffset = (globalViewSize.height - mViewSize.height*getScaleFactor())/2.f / static_cast(globalViewSize.height); + float hoffset = (globalViewSize.width - mViewSize.width*getScaleFactor(mViewSize))/2.f / static_cast(globalViewSize.width); + float voffset = (globalViewSize.height - mViewSize.height*getScaleFactor(mViewSize))/2.f / static_cast(globalViewSize.height); ProxyRenderTarget proxy(_target, viewSize, hoffset, voffset); diff --git a/components/myguiplatform/scalinglayer.hpp b/components/myguiplatform/scalinglayer.hpp index f9fd92a784..805edb0d01 100644 --- a/components/myguiplatform/scalinglayer.hpp +++ b/components/myguiplatform/scalinglayer.hpp @@ -21,9 +21,10 @@ namespace osgMyGUI void resizeView(const MyGUI::IntSize& _viewSize) override; + static float getScaleFactor(const MyGUI::IntSize& _layerViewSize); + private: void screenToLayerCoords(int& _left, int& _top) const; - float getScaleFactor() const; }; } diff --git a/docs/source/reference/modding/font.rst b/docs/source/reference/modding/font.rst index 0b8c3273f5..ae2a457e44 100644 --- a/docs/source/reference/modding/font.rst +++ b/docs/source/reference/modding/font.rst @@ -39,14 +39,13 @@ TrueType fonts are configured via ``openmw.cfg`` too: In this example, OpenMW will scan ``Fonts`` folder in data directories for ``.omwfont`` files. These files are XML files with schema provided by MyGUI. OpenMW uses ``.omwfont`` files which name (without extension) matches ``openmw.cfg`` entries. -It is also possible to adjust the font size and resolution via ``settings.cfg`` file:: +It is also possible to adjust the font size via ``settings.cfg`` file:: [GUI] font size = 16 - ttf resolution = 75 -The ``font size`` setting accepts clamped values in range from 12 to 18 while ``ttf resolution`` setting accepts values from 50 to 125. +The ``font size`` setting accepts clamped values in range from 12 to 18. -Any Resolution or Size properties in the ``.omwfont`` file have no effect because the engine settings override them. +Any Size property in the ``.omwfont`` file has no effect because the engine overrides it. The engine automatically takes UI scaling factor into account, so don't account for it when tweaking the settings. diff --git a/docs/source/reference/modding/settings/GUI.rst b/docs/source/reference/modding/settings/GUI.rst index 5f2b6b1ca0..d9ab6af197 100644 --- a/docs/source/reference/modding/settings/GUI.rst +++ b/docs/source/reference/modding/settings/GUI.rst @@ -26,18 +26,6 @@ TrueType fonts do not have this issue. This setting can be configured in the Interface section of Advanced tab of the launcher. -ttf resolution --------------- - -:Type: integer -:Range: 50 to 125 -:Default: 75 - -Allows to specify resolution for in-game TrueType fonts. -Note: actual resolution depends on "scaling factor" setting value, this value is for 1.0 scaling factor. - -This setting can be configured in the Interface section of Advanced tab of the launcher. - menu transparency ----------------- diff --git a/files/data/fonts/DejaVuLGCSansMono.omwfont b/files/data/fonts/DejaVuLGCSansMono.omwfont index 5e6726c2fb..0d5a115c18 100644 --- a/files/data/fonts/DejaVuLGCSansMono.omwfont +++ b/files/data/fonts/DejaVuLGCSansMono.omwfont @@ -4,6 +4,7 @@ + diff --git a/files/data/fonts/DemonicLetters.omwfont b/files/data/fonts/DemonicLetters.omwfont index bbe15dac5d..adbf7bd7b5 100644 --- a/files/data/fonts/DemonicLetters.omwfont +++ b/files/data/fonts/DemonicLetters.omwfont @@ -5,6 +5,7 @@ + diff --git a/files/data/fonts/MysticCards.omwfont b/files/data/fonts/MysticCards.omwfont index 2749d6d1c3..1297c981df 100644 --- a/files/data/fonts/MysticCards.omwfont +++ b/files/data/fonts/MysticCards.omwfont @@ -5,6 +5,7 @@ + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 644858c4ff..8a6fc40fd7 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -192,9 +192,6 @@ scaling factor = 1.0 # Size of in-game fonts font size = 16 -# Resolution of TrueType fonts glyphs -ttf resolution = 75 - # Transparency of GUI windows (0.0 to 1.0, transparent to opaque). menu transparency = 0.84 diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 0f895ad65b..6a50fc8a9b 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -1063,33 +1063,6 @@ - - - - Resolution of TrueType fonts glyphs. Automatically takes in account UI scaling factor. -Lower values make text more blurry, higher ones - more pixelated. - - - TTF texture resolution - - - - - - - 50 - - - 125 - - - 5 - - - 75 - - -