From dd04bfccfb607487cc06175c28bf52fc6caaa54b Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 7 Jul 2022 19:34:18 +0400 Subject: [PATCH 01/17] Load fonts --- CMakeLists.txt | 4 - README.md | 4 +- apps/openmw/engine.cpp | 4 +- apps/openmw/mwgui/windowmanagerimp.cpp | 2 +- components/fontloader/fontloader.cpp | 16 +-- components/myguiplatform/myguidatamanager.cpp | 27 +++++ components/myguiplatform/myguidatamanager.hpp | 10 ++ components/myguiplatform/myguiplatform.cpp | 3 +- components/myguiplatform/myguiplatform.hpp | 4 +- components/resource/stats.cpp | 20 ++-- components/resource/stats.hpp | 9 +- files/data/CMakeLists.txt | 10 ++ files/data/fonts/DejaVuFontLicense.txt | 99 ++++++++++++++++++ .../fonts/DejaVuLGCSansMono.omwfont} | 2 +- .../fonts}/DejaVuLGCSansMono.ttf | Bin files/data/fonts/OMWAyembedt.omwfont | 12 +++ files/data/fonts/OMWAyembedt.ttf | Bin 0 -> 25550 bytes files/data/fonts/OMWAyembedtFontLicense.txt | 94 +++++++++++++++++ files/data/fonts/Pelagiad.omwfont | 43 ++++++++ files/data/fonts/Pelagiad.ttf | Bin 0 -> 29820 bytes files/data/fonts/PelagiadFontLicense.txt | 94 +++++++++++++++++ files/mygui/CMakeLists.txt | 2 - files/mygui/skins.xml | 1 - 23 files changed, 430 insertions(+), 30 deletions(-) create mode 100644 files/data/fonts/DejaVuFontLicense.txt rename files/{mygui/openmw_font.xml => data/fonts/DejaVuLGCSansMono.omwfont} (89%) rename files/{mygui => data/fonts}/DejaVuLGCSansMono.ttf (100%) create mode 100644 files/data/fonts/OMWAyembedt.omwfont create mode 100644 files/data/fonts/OMWAyembedt.ttf create mode 100644 files/data/fonts/OMWAyembedtFontLicense.txt create mode 100644 files/data/fonts/Pelagiad.omwfont create mode 100644 files/data/fonts/Pelagiad.ttf create mode 100644 files/data/fonts/PelagiadFontLicense.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index d1bcfa832e..96092a2f61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -921,7 +921,6 @@ elseif(NOT APPLE) INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/LICENSE" DESTINATION "." RENAME "LICENSE.txt") - INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/mygui/DejaVuFontLicense.txt" DESTINATION ".") INSTALL(FILES "${INSTALL_SOURCE}/defaults.bin" DESTINATION ".") INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION ".") @@ -1023,9 +1022,6 @@ elseif(NOT APPLE) INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-bulletobjecttool" DESTINATION "${BINDIR}" ) ENDIF(BUILD_BULLETOBJECTTOOL) - # Install licenses - INSTALL(FILES "files/mygui/DejaVuFontLicense.txt" DESTINATION "${LICDIR}" ) - # Install icon and desktop file INSTALL(FILES "${OpenMW_BINARY_DIR}/org.openmw.launcher.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "openmw") INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.png" DESTINATION "${ICONDIR}" COMPONENT "openmw") diff --git a/README.md b/README.md index 2f21f8211b..b1ea6cbde3 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,9 @@ OpenMW also comes with OpenMW-CS, a replacement for Bethesda's Construction Set. Font Licenses: -* DejaVuLGCSansMono.ttf: custom (see [files/mygui/DejaVuFontLicense.txt](https://gitlab.com/OpenMW/openmw/-/raw/master/files/mygui/DejaVuFontLicense.txt) for more information) +* DejaVuLGCSansMono.ttf: custom (see [files/data/fonts/DejaVuFontLicense.txt](https://gitlab.com/OpenMW/openmw/-/raw/master/files/data/fonts/DejaVuFontLicense.txt) for more information) +* OMWAyembedt.ttf: SIL Open Font License (see [files/data/fonts/OMWAyembedtFontLicense.txt](https://gitlab.com/OpenMW/openmw/-/raw/master/files/data/fonts/OMWAyembedtFontLicense.txt) for more information) +* Pelagiad.ttf: SIL Open Font License (see [files/data/fonts/PelagiadFontLicense.txt](https://gitlab.com/OpenMW/openmw/-/raw/master/files/data/fonts/PelagiadFontLicense.txt) for more information) Current Status -------------- diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 76c164c90e..4d10b47963 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -1037,13 +1037,13 @@ void OMW::Engine::go() } // Setup profiler - osg::ref_ptr statshandler = new Resource::Profiler(stats.is_open()); + osg::ref_ptr statshandler = new Resource::Profiler(stats.is_open(), mVFS.get()); initStatsHandler(*statshandler); mViewer->addEventHandler(statshandler); - osg::ref_ptr resourceshandler = new Resource::StatsHandler(stats.is_open()); + osg::ref_ptr resourceshandler = new Resource::StatsHandler(stats.is_open(), mVFS.get()); mViewer->addEventHandler(resourceshandler); if (stats.is_open()) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5442b22df2..382f489e20 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -195,7 +195,7 @@ namespace MWGui { mScalingFactor = std::clamp(Settings::Manager::getFloat("scaling factor", "GUI"), 0.5f, 8.f); mGuiPlatform = new osgMyGUI::Platform(viewer, guiRoot, resourceSystem->getImageManager(), mScalingFactor); - mGuiPlatform->initialise(resourcePath, (std::filesystem::path(logpath) / "MyGUI.log").generic_string()); + mGuiPlatform->initialise(resourceSystem->getVFS(), resourcePath, (std::filesystem::path(logpath) / "MyGUI.log").generic_string()); mGui = new MyGUI::Gui; mGui->initialise(""); diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index 4e370a729a..ab4ca24eee 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -214,17 +214,17 @@ namespace Gui return; } - const std::string cfg = dataManager->getDataPath(""); - const std::string fontFile = mUserDataPath + "/" + "Fonts" + "/" + "openmw_font.xml"; - if (!std::filesystem::exists(fontFile)) - return; + dataManager->setUseVfs(true); - dataManager->setResourcePath(mUserDataPath + "/" + "Fonts"); - MyGUI::ResourceManager::getInstance().load("openmw_font.xml"); - dataManager->setResourcePath(cfg); + for (const auto& name : mVFS->getRecursiveDirectoryIterator("Fonts/")) + { + if (Misc::getFileExtension(name) == "omwfont") + MyGUI::ResourceManager::getInstance().load(name); + } + + dataManager->setUseVfs(false); } - typedef struct { float x; diff --git a/components/myguiplatform/myguidatamanager.cpp b/components/myguiplatform/myguidatamanager.cpp index b01c5bbcf6..d3edb82ae5 100644 --- a/components/myguiplatform/myguidatamanager.cpp +++ b/components/myguiplatform/myguidatamanager.cpp @@ -18,8 +18,25 @@ void DataManager::setResourcePath(const std::string &path) mResourcePath = path; } +void DataManager::setUseVfs(bool useVfs) +{ + mUseVfs = useVfs; +} + MyGUI::IDataStream *DataManager::getData(const std::string &name) const { + if (mUseVfs) + { + // Note: MyGUI is supposed to read/free input steam itself, + // so copy data from VFS stream to the string stream and pass it to MyGUI. + Files::IStreamPtr streamPtr = mVfs->get(name); + std::istream* fileStream = streamPtr.get(); + std::unique_ptr dataStream; + dataStream.reset(new std::stringstream); + *dataStream << fileStream->rdbuf(); + return new MyGUI::DataStream(dataStream.release()); + } + std::string fullpath = getDataPath(name); auto stream = std::make_unique(); stream->open(fullpath, std::ios::binary); @@ -38,10 +55,17 @@ void DataManager::freeData(MyGUI::IDataStream *data) bool DataManager::isDataExist(const std::string &name) const { + if (mUseVfs) return mVfs->exists(name); + std::string fullpath = mResourcePath + "/" + name; return std::filesystem::exists(fullpath); } +void DataManager::setVfs(const VFS::Manager* vfs) +{ + mVfs = vfs; +} + const MyGUI::VectorString &DataManager::getDataListNames(const std::string &pattern) const { // TODO: pattern matching (unused?) @@ -53,6 +77,9 @@ const MyGUI::VectorString &DataManager::getDataListNames(const std::string &patt const std::string &DataManager::getDataPath(const std::string &name) const { + // FIXME: in theory, we should use the VFS here too, but it does not provide the real path to data files. + // In some cases there is no real path at all (when the requested MyGUI file is in BSA archive, for example). + // Currently it should not matter since we use this virtual function only to setup fonts for profilers. static std::string result; result.clear(); if (!isDataExist(name)) diff --git a/components/myguiplatform/myguidatamanager.hpp b/components/myguiplatform/myguidatamanager.hpp index e0c4e6c436..a859ce99c1 100644 --- a/components/myguiplatform/myguidatamanager.hpp +++ b/components/myguiplatform/myguidatamanager.hpp @@ -5,6 +5,8 @@ #include +#include + namespace osgMyGUI { @@ -16,6 +18,10 @@ public: void setResourcePath(const std::string& path); + void setUseVfs(bool useVfs); + + void setVfs(const VFS::Manager* vfs); + /** Get data stream from specified resource name. @param _name Resource name (usually file name). */ @@ -44,6 +50,10 @@ public: private: std::string mResourcePath; + + const VFS::Manager* mVfs; + + bool mUseVfs{false}; }; } diff --git a/components/myguiplatform/myguiplatform.cpp b/components/myguiplatform/myguiplatform.cpp index dfb2e6539d..b19bc722a2 100644 --- a/components/myguiplatform/myguiplatform.cpp +++ b/components/myguiplatform/myguiplatform.cpp @@ -30,7 +30,7 @@ Platform::~Platform() mLogFacility = nullptr; } -void Platform::initialise(const std::string &resourcePath, const std::string &_logName) +void Platform::initialise(const VFS::Manager* vfs, const std::string &resourcePath, const std::string &_logName) { if (!_logName.empty() && !mLogFacility) { @@ -39,6 +39,7 @@ void Platform::initialise(const std::string &resourcePath, const std::string &_l } mDataManager->setResourcePath(resourcePath); + mDataManager->setVfs(vfs); mRenderManager->initialise(); mDataManager->initialise(); diff --git a/components/myguiplatform/myguiplatform.hpp b/components/myguiplatform/myguiplatform.hpp index 5ffbe0be70..a46fedcd75 100644 --- a/components/myguiplatform/myguiplatform.hpp +++ b/components/myguiplatform/myguiplatform.hpp @@ -3,6 +3,8 @@ #include +#include + namespace osgViewer { class Viewer; @@ -34,7 +36,7 @@ namespace osgMyGUI ~Platform(); - void initialise(const std::string& resourcePath, const std::string& _logName = "MyGUI.log"); + void initialise(const VFS::Manager* vfs, const std::string& resourcePath, const std::string& _logName = "MyGUI.log"); void shutdown(); diff --git a/components/resource/stats.cpp b/components/resource/stats.cpp index 0ab523ab59..d578259033 100644 --- a/components/resource/stats.cpp +++ b/components/resource/stats.cpp @@ -15,6 +15,8 @@ #include +#include + namespace Resource { @@ -28,6 +30,8 @@ static bool collectStatFrameRate = false; static bool collectStatUpdate = false; static bool collectStatEngine = false; +inline static std::string sFontName = "Fonts\\DejaVuLGCSansMono.ttf"; + static void setupStatCollection() { const char* envList = getenv("OPENMW_OSG_STATS_LIST"); @@ -79,7 +83,7 @@ static void setupStatCollection() } } -StatsHandler::StatsHandler(bool offlineCollect): +StatsHandler::StatsHandler(bool offlineCollect, VFS::Manager* vfs): _key(osgGA::GUIEventAdapter::KEY_F4), _initialized(false), _statsType(false), @@ -96,15 +100,19 @@ StatsHandler::StatsHandler(bool offlineCollect): _resourceStatsChildNum = 0; - if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf")) - _font = osgMyGUI::DataManager::getInstance().getDataPath("DejaVuLGCSansMono.ttf"); + if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs->exists(sFontName)) + { + _font = vfs->getAbsoluteFileName(sFontName); + } } -Profiler::Profiler(bool offlineCollect): +Profiler::Profiler(bool offlineCollect, VFS::Manager* vfs): _offlineCollect(offlineCollect) { - if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf")) - _font = osgMyGUI::DataManager::getInstance().getDataPath("DejaVuLGCSansMono.ttf"); + if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs->exists(sFontName)) + { + _font = vfs->getAbsoluteFileName(sFontName); + } else _font.clear(); diff --git a/components/resource/stats.hpp b/components/resource/stats.hpp index 560275d701..b61280ceb1 100644 --- a/components/resource/stats.hpp +++ b/components/resource/stats.hpp @@ -13,12 +13,17 @@ namespace osg class Switch; } +namespace VFS +{ + class Manager; +} + namespace Resource { class Profiler : public osgViewer::StatsHandler { public: - Profiler(bool offlineCollect); + Profiler(bool offlineCollect, VFS::Manager* vfs); bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override; private: @@ -28,7 +33,7 @@ namespace Resource class StatsHandler : public osgGA::GUIEventHandler { public: - StatsHandler(bool offlineCollect); + StatsHandler(bool offlineCollect, VFS::Manager* vfs); void setKey(int key) { _key = key; } int getKey() const { return _key; } diff --git a/files/data/CMakeLists.txt b/files/data/CMakeLists.txt index f476498494..1fa40b3f54 100644 --- a/files/data/CMakeLists.txt +++ b/files/data/CMakeLists.txt @@ -10,6 +10,16 @@ set(BUILTIN_DATA_FILES textures/omw_menu_scroll_center_h.dds textures/omw_menu_scroll_center_v.dds + fonts/DejaVuFontLicense.txt + fonts/DejaVuLGCSansMono.ttf + fonts/DejaVuLGCSansMono.omwfont + fonts/OMWAyembedt.ttf + fonts/OMWAyembedt.omwfont + fonts/OMWAyembedtFontLicense.txt + fonts/Pelagiad.ttf + fonts/Pelagiad.omwfont + fonts/PelagiadFontLicense.txt + l10n/Calendar/en.yaml l10n/Calendar/ru.yaml l10n/DebugMenu/en.yaml diff --git a/files/data/fonts/DejaVuFontLicense.txt b/files/data/fonts/DejaVuFontLicense.txt new file mode 100644 index 0000000000..254e2cc42a --- /dev/null +++ b/files/data/fonts/DejaVuFontLicense.txt @@ -0,0 +1,99 @@ +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +------------------------------ + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and +associated documentation files (the "Font Software"), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Tavmjong Bah" or the word "Arev". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Tavmjong Bah Arev" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. + +$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $ diff --git a/files/mygui/openmw_font.xml b/files/data/fonts/DejaVuLGCSansMono.omwfont similarity index 89% rename from files/mygui/openmw_font.xml rename to files/data/fonts/DejaVuLGCSansMono.omwfont index 6ffe3017e5..6511877656 100644 --- a/files/mygui/openmw_font.xml +++ b/files/data/fonts/DejaVuLGCSansMono.omwfont @@ -1,7 +1,7 @@ - + diff --git a/files/mygui/DejaVuLGCSansMono.ttf b/files/data/fonts/DejaVuLGCSansMono.ttf similarity index 100% rename from files/mygui/DejaVuLGCSansMono.ttf rename to files/data/fonts/DejaVuLGCSansMono.ttf diff --git a/files/data/fonts/OMWAyembedt.omwfont b/files/data/fonts/OMWAyembedt.omwfont new file mode 100644 index 0000000000..c8ac1c2ecb --- /dev/null +++ b/files/data/fonts/OMWAyembedt.omwfont @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/files/data/fonts/OMWAyembedt.ttf b/files/data/fonts/OMWAyembedt.ttf new file mode 100644 index 0000000000000000000000000000000000000000..fb889b17fcc290758f65252f0e5a458bf8ca7157 GIT binary patch literal 25550 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/data/fonts/Pelagiad.ttf b/files/data/fonts/Pelagiad.ttf new file mode 100644 index 0000000000000000000000000000000000000000..07653b0530b0468ccc2d92d2d81e8f2796edb549 GIT binary patch literal 29820 zcmdSCcbr^R-9LWLo!;A>-uuk%?Ck8+-PxMWwrn=ZX0xfJXVWWbkN_bGp@d!}(#6n0 zP(cupFCzMgB9=!{5m6CEeUPF&BIuXQeBbBHYzRp}p5OD=Z})ZQ-Z}TqJ?DHrpY!RT zdkH0k=*fN}AJFi}%zzny%Oo(hD!O_{D zCFFOHFLEz4bi7OaQv8gN|1{706WhP=_Mewk|4=PUek>WoS0xcxEB^31$?WQEvRLvy z&fhKhF>5*TkJ?xZK9>?18OO$cN%>VhBn=2ih*VJ0t8s=1Hww?=>{Ycr{R_!a6caspip3cPwAViJWzd~Ge z4hafv#7zH0RKnv#CLAIL@&ytk$B2(@bd1>O(?rDe3AzAnf5+ZLy!1QRUjl5pNuK_S zBn3(u=vUG9Q<9}`lO%lu+xJP9RIqoEM*1SL@P4qTQ;17=kvN3gh)>vw?FNz%4q$&2 zdkMC0k%VL%ecpp@4iSZGaqcoAN|s^&Jhs2!nv2o?F7^*&e=geYB?jRe*ss8K-$2_L z`0Z0fE$qjbe@dJfvy1$k80i!EjTgB4F)?6#KKc$|fpO4ZV0#c-3%38j_6|{#w~3l6 zt8ZX#B6$z@{44sf;CIj9{CoJ_udqLeel}sh4Sl?g{hhexLR`aOhhzE*_RENZT#c2o z6xaR&m|<=5YK4}uZzTynmVS(#!Q(WWw#0hYy2MeLD^t2A`8R2AdN$ z1{?ZUqT(=Ma5!lb9zxqq*cePs*vRXE-RpqO>!6?4tFIl02ZPDU8-vG*8-oXf&uyR+ z^vCedV1IlM8leA;?*{@A6(YKfN2bj9Z`=C*Vf8bzpFL@txy@{k49RL?fMhgrd zwSDy;j4l{%*xcDz7(FnY@cr*j_|9O;#&R?844S0>#BbK)JK8~uKA{uaB>WgXezQi8 zj7}M>B~92fnq;)hXfclC|H1}36z<3M*W-E|OZMUWChR{;tilM6FCsqPhWl|GJcquo z!?qdQ)7SueA&32y*d}3lGmc*)8v1{+{}S-X;Qkxz8BMY|Jb_~d=S65|bofndkE8u3 z*j~W#chIkcSSk9Z>v23A`%BS3!!x5vw%tgY=?$bwIFn4}`~WV4IFtM^pz zuHIF>vwBDMbJd%x*H!mbw^lb-C#uVr&OW7TONJo~}dK6w01BQX&(v4DSB ziH+EagE+B{+`x?&e9;eB1|b*1BtoJjM&jT_NzyH z+DMtSlMd2Jx=1%LJB9RuLi$KQ86bmXh)g5HWI7okGssLbi;R-lWQ@##%$rN*k@;i+ zSx6Ro`RLbNgAxHV=={`1+9b^O9NzNp@$ywxVvWuKU&c%g$ z$pLZ@!kfwF)BSP12(X|09|pW0rx|(?{R91nAPQMwn{bQp9pN{^UnNFKhh#!>ljH@^ z^{Dg`>9=J{S%+*$HZI#MyIb}{xm>Xm{8oQct<%?dB5@lRav!0^@Qqu^*Z%e z)GujLnk||av?=X&?L*pEbRpdu-4}GP>&^O%ex81x{ucd1`gaTw!#u;4h94W%#+k-L z#)plsn?j~8(oEuXQxD%!+hai4fZ{EqmR_`X$bHCr>* zKI=^DV(SL$ZtFqomDZbVHrp24xwcDfM{GxJU$Q-Ad(QTA+pD&}+A4On-DVHjx7qjE zFSp-dztjG({T+M7p>{YNF-O+X<@l209Y@8fcG{dFXU5s(9C0piu5s>k9&}#myv2F1 z^ItBx%k1*G8eBzJuj_ud)NOVL+!wiD^prjOJTG~(-rIdrU&wd1?@r&Bd{6ol{(b&8 z0zHB61kJ%fFde)%B!t$5ZVTNXdMxzq&`(0Y2}i;Q!!Lwi3I91V5SbadDDr&dh3L%a z(dhj#b<7-F5L+Hw7uyzlEcR6FJFy?eK8P=lPsDGFznn-Ub|$`(cqUOvjwEkLRvP3D zJq`OBo@n@c!v~Fv8*ga5z3~f;ucnNt@zh1BD^pLVzMXo$$=u{>+Szn&)00hqO_$S` zr=Li_-yCWlZN9wuJIz0A{&VwRoBx%OW;~f#CY@=`^kjxI;~7TT0@LYe7V<@cwV(bn zCCwcVE2QMj?3d-TmpdMo2sk8Pmat|SYkpWEryq1YOj&!*6g0(irf`TF-+KOe;r?Uu zLIM_%KwQ;dk*9dXQm+8zjx2sXMa%H zKcy6IZ^Mwlql0uWEeVeqQ4oqa1A&}7a^rsyjZfA;$5_qwP#8; zyUi+B{#w=re4fCAp&ZpQiCrD4vnvR~CgWS6b9Bp|(NOdTN%p*GOeYUS7;Rzrc0OE8kWgy z5sPS#738ISF=zKtQ63J(V{x0+2B=x_EnlkdVud`LU9pg+g?x#9%h^j7fI+UXWi9cr zg3UZ17Zt@7gOa{mqGlmAVKG^nMT_*RBS`~I#B}r)YdG91^e?=L2F*f@N?jU3BI*?q z(JTns1I-TiHblVptwp`Vh(ixo&sZ}dF?6Q?nw;>xIy~;E) zV|UtamODz)V|TqK7xr!!=!{=V+KvdXBvKnPEx?(K$f_?3cMAt0Nt~dy6r=z!S14L) zh!Q1&A{OC0maK5gq$28;3 z-UF-0`U{KC&~Vs?7-d22Xo;<^Q`&0d*`P6 z$_Y=IUO2F7*6j9Vt1WcFN{d`=u!{x_Rfvn5qKox{RE#7BS){T-T%bj=8J_q=A6qi7+{%&d@EPl zQXNzKyF+fD@!F%0d|qQ&vFVP>H!;DCer?djO2Pzm12#6^BU_bWz_1QN_7&U#D>N2o zceWSrYiKeg)Vh#J1-;v8k6WlzZ8c~e#*oh8km_SSMqy%(!e&$(dYM`#k=!oTJ4Ctk8kqreN>pzke}*RE0zGFrF#ryjK@lt{ zAJvH7g1VT<{l}yyKJ$%#j8|O(V(a9MOJg1^Ju>%+NwQs#Ilzu;=+0-XPCID*(=me8FUG&)3*$Q=OYq;;r6B z-i589XMBdOHbA&&W?b^!Y17mWqf)E6SnV)ah4WOEqm|noTBFkE6fW;D7;Wf7z&!s& z?-%w$AH+<}a)oHeh#3CE79fie5T^q9gCcc#GhT1H!(C15whQo*Q-l~QB>9k>-?CV;@Oy^8ak)ulSWhkE zMnU#Ko{o8xUPZGE66mLDw;+qD`wYh()=7;4cE5b}ZTc=`PK1ysD3dSFSV++&Fpk1# zl%az)1NFsHk$z898T`V7XPuk=+@kWVoZ9U)8P7g)=GMf_m*j@SDV_EKjc)XX%g36^ z;U!Mp!rPb6n0lnR3N(hklGT^#H(-NB0n<>dlLi^isy^N*8BF(HY>iU=yJr1 zzSf_T#a&Hvnkv_Md<|~Z$co-6^uW;2yfgdlv9Zh6FJ6?J>-Iwv;qd-D{UYeh4!e%n znZ^bT0}jPP4axXsluIx!ARi<8P51h!&OFf2Zg7 z^jz4y>W&L8soZ@#ee$A%YaE(c=mt7ovidgp0o?{2&kU%)4IR%+C1`J~UPb;zcN$~F zXnxPAz*!0TZ(L!izC)j(=K(qd?Ar$+9L~p~)DTANvFF}(Y_ z$|!7I{20AV*tYnR8w909>v-e8uD6wCvbfWzx#0I+ z1*VE6sHwnX%n%r)@~-A9iWhlZbf|T|t=y5J>0p{(luPy+W0|Nw5O6lBqh344>8k#k zhCve^PWyS>gXt9v51{uP7djw9xz!%FfgBiZ42}8n<912JU^0d*4VevYPhcL6Z>b3d znsK{SsjkJM$82#>SNYs*D5Q`2yDz8-3n_6_e`{9}d3vC2Y> zkH$d_L@wGH>#tELlL<^0;?j?CZaavVONeYqPpu-o^{Ho{x_kd)`wa~pcBwiu60*!V zFs)ME&=8BJ_s-1emG&M-W3XdQ2d(4zdOm2718jIL`KR0OIg(LS@)}5`(`<#HAulk;_AAV>FbZl^~xIzL6 z0}?KoOKC{~Bg8Rdm|@Xu75Vfq_^^V36_g%lE8CtG!_PkzU%z;REua>{(*)@{tFCKg z`tnGixje9;q|;jT&AC-7ol((Rn08vA!&fFyAz+0Rj$VHTftPuvqkv)Bqzy3>YdP&yda* zqAAU^i~7Q>qlYX1zygG0Z!klPvphqM{<0%_ZBde27L}NDInfMFMiAP(N|i>HEP9fC zgQM#UEi%^(i?e^0FtyNBxwY6_YFZq1Io0;Y1*zU+H%4VftInvFDCo~L9-YzXp1yJ* zKgT4|h69b+iN+Ste4=_6{0i5?<3nT&aIpeoR-7e6HGtw=1GNHUW~9p12Vg?jDv|2d z3aL<>c&hLG^E$2?Pih@u(R99Ne<&21zIpYSINodR$3;}C9J7T?*`+_dZ&TipQrm*w z#G3FhO|9IqXYstQ7VRV)9}*S{S7A+KBvHOjtR|3ZsVHX(K#f~+$T1}2L=AA@?((f& zp}{RfZh!0xXUw^vXm@e3*rr*_g zMMrq#iCZ3?GmY5}3=VsRt6}pRU_X#3=t#4ug=7tyow?%^{g`p)0iaqz;l%wW))lJZfFM5;B@vFP1)+FR(L zM+;-NzO5B?$dCkl?%kAY&FFia`3DoqODc~_q&k5q4@`%9i@pZks13e0#y#cCxCHxT zbY;rgm`Di$NQ}Y&Fo`0bW2?8;05HL<S@RdO1sxW(%0k{;nO{G5blAjxf34$XWqUy@lxs1kf|up!c{&=B%TDqq>T`(L_zxzO0z)9Fauv({p!GpWh!YgB!!f2xqK z_{?fetI5!&?)Zu2HND!AR4Eh?QC9kz#~##Zi#Ys(Ik(;3A{UElHE2St{)1iz*!r2K zQ!+7GTIY;eD0QO31ZdkCQ810iO+~vzer4H_D77RC!;+A?!P*+rDCx$1TM{vQ=Mq|? zrCIbxPMP5FYgDR;SDMit`=>^)b{g~nkD#EhR$6S7Rt3-_gU>qJ2s_jb4Ffs^fWUfZ z@(Zid#I;E#T^2ZsM(NZujLzQaL(Wz0kxsWF)*NUS!WNU@@u)4~;IX4K4+eZ*lZ^2I zX5aor*aw>eT;I%TncWZT%u6T9g{?M3L%4aN2nnDVF9kxxaGX&)n`*%XR-heB_N!g} z-nqXP^-7h{c1f!tvTcD`qt)(idMu=LHKtss8;-R7m?LM&JZIRi?p zjuA!;i1nJB_l(6fTA3m_rSe>KV=`vz>F6nC;^~n&{-FV(sp7|Kb_A)}9C~r5(ijHZ zE%Xl_nXCwusA*m<<1l(nG6gW20f?FNp+b?#Lfk)$wPS|hX4J_U1H*hSn~%j|GfLzF zRu=RCrUcYTB5!8KO@Z-I_G`19zP@50Khn@(Rw^~_G)aF@GkbftQ4b5bJ~Yi97#7RudDX z1!`gokD-~X@Fr#!g5kkn0x=MKZ5;~Zi>Oj*4jDzEa^=|A!`}Y1$C#ojhf5nb55y8W z1x@!x^>$&OBB@d;jvaA2e3a75DwpczVjM$t3Q`OGZ?#+*mxzt_%F|u+klGFxE91d$ z3*SQKf(B6(5-~D{0H+JsEkx6#jwOs8-Zp*1?FSRyB~N|#se7O?ZK3%Guh@LuE!L4Q z(kb_S```ojvU`cuH{qwc9FZD0OeuIc?gNfZxK02PX3MF@%vlG(BKT%q{)DYQNsZgn zi9~AF*y2@{Jz9f)ra@t%gI>L*WwgZ?3iq$NswXsmr-A^UX}EQj9bh ztZFI&6zn>z81uuwRm7n1udsxeQO&GN+Ey^D)z0kf*&}A35rC6ZsZ>e(y+%{EH|q=O zN|BY@i)o!L+C>cwmm7_qZR_dWWQsOUZ*S}^X$@whii%dP-DKIjw>5i)#-DOT^^RSu zON$-WKw+^U)!1WpTl#C7mjp@bu432W9zGXe^{B8E`b7(qhOk(;4+ahsZVEup;%F9` zYYS}jxS&*UI}zLko`PbjPIL#4&PmSqr|#W7GWeA8mjLI_X^+Rx)9S|YrK`gn(-G7e<^p6l(ob4s4GaAnTiWNaE;9}(qBqjpB6+!pZpGr?$v zIZc_I`<1W)Iw_O_3s=|8Op)Sz69i`!A%8e|0U%;~+`9N2w`QbEt?3Q@BH$Qk&1SWB zpIg{sG(A@NeZl?YO%7!s;IsMKj@^C3xqJ3{N)DD2BvyYZ`3Cx6vZUseW%rFC&LOYu z>I7o8LlLUEXv~tc#7_S=y}s3L{_NSd__xHQrWg@tZ+7&zn~hfAym8MV!7TLn>|XRG zP~rNS_f(z{gm5XURvJx@R9?-0^Om-3I{n4? zC8%MwB?r}lF(U=w4_F8(cPZErb&N$fHw81<#FGQ(F0#uutFgJ&f2*l@z@3pkvmen+=WG`2b-371wT6KrjERk`mR znN*iq*1KrREnPaB-e6mPaco^S6$*NSExGAK8Ou#ASt`iPKAo1D19h6)D69nkV~$mZF*tOu+=O)(Q)h?N0U}b=^i>)tFc-5Z;jP&kgwOq zVgc$c5?_Y0CV z%W{A{KsV9b1QFf|jDz7Y2d@LB#*qrDgEW6J76=%ksrG1(R~z-X1XYW~LeCLIv&$i7 z0=+(^*=AEZ6=weu+)oLAhZZsvQA#_81Vw<0OC~ErN~1#6Fn-{|)|jA(tb0?TNh_#S zA~dU&=pDZ`&}+yykt+t@yM;*)xXKKW+s4#I!j!d#^^|+Jv87DB>INj z1-g9F*)z0krn_6Alro=)%aygp^{&R33}VP~OG94HC{8mUyJidUX4T{h9Uf8$cRG<58} z{S9jeu0SZ3!NXU5lkTS%A|HfA8I{!?6nx3mXH+xJ&@bKZvt$P6uHLY$XO>qbI<$eT zOB53g?Y_9qvZBM7IRDX!q|W@c>aU_Lf8Vm2fpAUl=~85p>U9L zA(*un>Wm!WEH*oa&VZI=L7pn`NOP;RW7R9Ib6RB*W-C?#uRYGKeJij{{#y~z+0~1>TRAyj~Qo0){<7MjrdFr z%8b?7pr$r!SqD=jwR=v>ApJQt8I4WS#on0`YHHF*6u&TgTzNXKq7s|OasFjZHl(&n z0Ov9KWqKI6Odx-Ul*D$*?hT}3(WhxG_?)#v@ei}+Pzh#22<~?~$eKCSE}OTexqat? zXJ^_%{R`)9OJD77)671hI`pg#9c>LB>O>Y`QQ_VU$4CEwN|^8yAZNU>LN?UM$)yYUK)} z%DFx0DW&_%`iw@r(KY<-VWUz}dDmwZpd`rjp@2|%(e2!|d1`|vsPE&rR#)F5uLup$ z&ta8X*dnbNi3sP)!xAQ0fmss-=mJ+ZVMNlyrt_n;rL`Dzxy|%Gzi~{hcGv>`%2Cq@ zZF8xO2BT3@c~tGT5uy4j#%@m01YH%O z14{>B!ky5MOJR;Kp&h11jnN~i^bU6W0|qUEd<<@4^)K}I@PC44;MfiWUOYyG(SuJh zrJJkV40CCyAc|Yckp`O2248K~na^+}F>MH&K- znU45|@H^xzBL~pTtbewq`1T=E!$tTLIcLH|z@u<1=lKv!i!uxZ+x4ZsdG@ZEX=luk z(TWc^tb$4FiNqU9CcWKmN;DMgRyxC-aC=H^ZQjO<#+p0ZDaxBJTXwanAo zsqe|2@&mgAV2*4|Zwpe43DJ+*n7U{d4uU$3g==JJg%INd7z}pm{jEzojI8q;?Y5Sp zB`IXGqDZH^8@wK$t9#%x=uzK4{^)@J>(M#)pXEg_HQw?ry%TFp#iTU+mE0W6B5=W( z8KY}DFn^(Y%ZO>|_!lnPuzXeaf zF`(gaVg;}Yb{LpoPPKM0<+ue*iW5LS_RKo7{L;P|8k4QftRHF^mBh^rgRQMI#xrTh zuqSAg7}o~G(mIJwDiiGjb!f~=`URy~?^WtMnyj>=JH6qc-biC^*EQ|w?JFkdHJiRh zKZ|*J8LfjWWEq#X6qrchs|u?Y>=~@SnG%nncr{ zq}<{xDU8!X?x?ek%6=g>(xlm{FnF|0Dnroa>kgpsfZ^O%{X4vA2e^FzNZDcMaZZcz za?Zk(jGAwegO{;STB{|t zH){)ceGaovt@enKk%<}Hx9LQ@Z!!G}=QfOI)_53;CUfRCnI>`1EPG5DJahJ3stN3L z^$wXWH1kxe!DehL2YwGD#yzh~;)ovifBlvI3i<~8&y?S9QpaG)6_Z|hEGTC0)Lo@4 zSpnbaypql=6B2rhIoM$ccP(_4CBZYAjH16WpP-5mJs{aLB`@k-KDAbDvw6HempOKI zY_lAepRW7NMb6mpmSKz1jLZ_ghW<#eM{Y1QC3{)|(=W?(aID@!ZI$WeLF4y1r=2n1x^%TPY%&ElK32nxq54N*H|_=7!Vbt_{c~-Lxunwq!w*;Q z5h($tAQIUnAgwpk(TKURp)1^KO#5xqoe@J!XyjW6I`qI$<;z404TehS+S&xFspQ zQ=DQo8q`LQO5eJ5eoQoW9vUeJ8oa^$)CCPDr9vw)tF$F|YqPx967txP41+uZ4)0OG z`%1`b#sO;mb47$f3%y$ad$3mw4U10W_PH%Kr(16fMh6`6hG=Hq>>gX#RA}g!YP1cS z#h7SL=@pDOk{Tuzm>EkYf=U2E!cc-8S4HS{ zjBnev7Xw-v)zDiThIZYtEisZySp6Ai?ooP1*s8sJze%oN>X%ylkDjBntDAGvIZvZR zQT-w9gMS$P$NJm4&1Tw@p)?0Fm05V%f&;UU(Wh35ha5EEPo)yoyri_3B*%lzdY zUza{Y$isV?zVI~Ks>kS2L|m-KwTOamrH`byWeyt$ky-f)eV85BepkywLQI~mXZZ4< z1sjD$uytT5nd_pe2%f^J>br@gDw`N8uA0@ebeO)Mk!#!;ZFlF~<~Apz&AOcgmz;%Z zX<^{-#>9n9&W4n*BH+Dleg{3=T~kho0V<4oDz8Nc*Bj=|uf?8C^|;|rjz<#TlTZ6{gK%;*+IBod zctPb$RE`kgRu(;+b*oZ|pfoK~`hI~26+M$dM#q-<((i!|C~`B(@H=12Jdm|@`AHF8 zOjsUf(O@t~&J?jwSlkt>Sx#px`}m+Qos0}OX=b$sd;Br!G`ZaM@$uh3NTdcHBUTt) zZF34CW6Lz7k1`tJF94 z)OWm{$I>K>7W+tqrg})*VVr|LhB172ZY{Zh+IvVlqtg%1Jp%e>bZX^v`eFNZk~r_D z7vY@A>v?QL(vJ3(uOPN@Ir2tgY(y07im4Y&1i=OXORNz9C?Up^ zEQT~OcXS1Ttjec;}vf+7%7X(ZbDM{mFX*l&8Qxtk7-O}k(Xo1+gt zo-avebKE>iM|()&Ma&0rlaHKROGP>e*nIn>a|0YUH`DA%?H068kf%uHcsut!avZEB z-=?u1Qf6?*O2N8OReuBj%U+h5U_;Ix_W-lh4hAL((_#Q76PKDyMAxKeNiR z^}1Ejgy0`<&xmx#ioqqBTvTjLPM?t2y5OS2>Si}EvhUaO=@n36? zLxx^ft)Jm|e2?BF6oIea4??G0@8|ecpU|%4zLQ0um%a~%@_*-&_>1*Em|x|;(Dxd$ zw$R(YgG=zqa|Gx9BJ?sk`%^lh=9E-Fhx$5pu7UOSCoB4z{0+Cyg)UBiGs(AFp5eb5 ztJ5EBYT*nvj^%l9VYbre9G`3L9McyLl18jgw$^c$&zGI!^Odpre)Kmjye}_#EMM#E z#NUM2_~z**f5UxeZ@{kqJUp#QW-CPG5crJm!9uCkY{0|8xFRECn-!HPoE?CA>(M!O zmfkr&uczoSDG^SPSz9(N&o-$Qb{aFt)Tx(~zL?2jb9>|AP|6($#Kk>_!d`>IYE`2U zqi5qvzfSF^KD|$E$TgnZU~9;=xPzgala5#^A8SIkHJ>l+L}3}m-nWEtu!YBA#M)PY zx2;8mC0nUDbNu=qT;FR-opODE!C;f-gmyy}_K48U@AE|UH#oC|->24YW7n@m-3@ES zABz>Q7B1!adZ0{}uSc2qU`eh39`iRMWXw~O0LfZv9>RquC|o?vPo z!vSRwsT3BIy!?@5z1ELtSvN17nW(4r=^XVuKAWXaD#%1#)Dmnq$WBPy`>0N((|wrV zC#}uLS6vT1{#^L|d*BhPaV0wzJNKV*4#)H8PviRst+1IR+hTI+F&+mvAkinsmh9b2 zM{P;zNx=Zo>T;N-C_|x2CTzovzyB(bT$tUGBYpBUVDA%Ct#(xPgO zYP~(t_Egjm2we0D;SPF>V{rfjR;J98d`teUz#5v{K$(vgbk1A#C8+q6jG4(H;NVO=SGid;#=afBAcaTKsG;n%6f zN5e+)X(BrGJyz9J`R2z4c7*k{f~QLI-$Zz@SgYp>U#RD7nwU;_O4ep1T3e4brw$Y~ z&@r>%n92r!^`w1Aj~=(Wj^}UQa_lq0*=eUKqYN6uiHO!{JT;y3q(shR`$mEhW74FN z%0+!FlJZzos*@8tYrf;1JTBG3G7L+f5Rqcq5%&Rp$WaQ&C$5L7Mn5h-1$8LaA+0f$ zLeyd$n8LN8v?`cCO|XjEA}und0W3u-<18f^(a~Y10h#6Cf3TNpw$=#Nl^+%YbVZ7U z0Om6}nP`vO!JjH=)}1?-VyWqzjBIK#|^BUy`Zg+^_QF zzY8(~M=aKc_!oS822d2J{ltjZD<4L>rk@hsV!w4EpK%BB8IgAx;YM8vi2X=5V+k@m z0}Y6oKHyluJoA<^9SFfpZX(JRR;oBP!?A-32|*JSx{-QX%XG9kTmxmPL{{kM$&SY3 z$&NB>|4!{3iT=D)%pE9TM`cni^@_(4+$mUhk&qpAiz)!KxPpb|{d9?47B5S02I+;{?{o?~}wUz8t z+CE&$8$U4y$N17w$&ZCApygyRTIe&i%!N2uJkQBw_9hqpOp#&4T9QlHF2?+J+<=4U zu24(!j~!3wgm932F74=@JzCD4!SXnl_Y^zIyOSu7P{?%#vqd(j5EObXt$fxbp}nbc zxwHN2^Rtx)jPgw3e&z?c{b1ZPuM=*$q?e_AW(x4x1%g^_e%`#Ka-wn#ciRbJ=BH~d zRgOFAo`q}Vx?9Ah51j=)0diH?PtOFu%`k0-%?$t0FKdYzY-&tJJJF!VWRC|TizO~4 zV!{?dVbzDGO-m;~bJp@X?S56;L zl;{)MkR(^$@%b|fCBIIu@flq$@oX}$l6UX1g?rBu-yRCu9AFm`o;!AjWC-hE4zma9 zlHp|jDcEYUz5i|U=DO1{*SY_jj85V9Q>7@UQ|27uQcs6o%B~yT> znr?PFStMchD+|EY%Fq6767T#|$KLYq^Lm9FPtjkFE&dL|k3?Gi-}6D2}@e z!$!#`MA)f<85E7D#My;E*X@X*)5qI6?bm$EEI#yg@*dU%WFBv4ev}39bF7*3QU3~Z zLTffQ`5is0hqN#c73hTj2C>!pI{G}BUH3&Vt)FARV{rmAc~JOa?KfP9_#yp?Fpjyx zyGS@^N3IIz>Bs>Ae^*R~X7M1DT5#6D>TIyM=y0tjG{K^@t*tKx^tCYUV1JAG%&S?T z)@awUNUcD4b?DP9Ufa`SQs`K~)~plv-G-2@TXed3(3aWGY>cCzA_E<5T6v-g^o&ZvHpfvNc_d!G0RXj-t$uS+lkpSU*1C{l=+dUjB(8@Xwz@ z>I*(DC=U9l*-&ZFzy$dUb%F+dSf>qM>xx)yl5WGQX(xCKqtH2$Q)WBk!nJ(Y+} zLt{gopIP5IBBEx*qW2C`lR}7>^g69Rd2y)klI||8-uE{Ro>AvDjoKpSP~-qrTZLt# zvzBl2yB%UceaXU?>`JL<(<$s2I$s0478Y~CGY&xCPULg{Q&@vztmTp&i3N=PSW$A3mjNEpIU>1F^mL_f3~DSvh0P7cZ>-|tc=;P$5CYE_U+D4<;_(>6 zOZ~d$9nGS6)>Y0LF9|rJP1E=8_DyRkNn~=PL8VOubd4Kh-C378kX5MWJ&~tJhV2`AH=z!lkFt@G2djqHu-Jhu2YJKFu5tV)b$1L97c_ zQ&*>VcorENY8o37OhHV*N6oh2(K&d?czRS$SXoRN_4>_9)3c>?dPcHsbbMt}r;{nI zR)>Qxjy)=2k;|r3yDPntfLg9a)~klz<@5jbH-qEZSjg$z&sRrp9oDb0`bCTlqrq6~ zwYK;Ui-)fpUT25zx%${&mpJiUP0Yj+M9`4Yj*&+ftZdLwX$tv5lotm=1FdT~F_wg1 z_&UAAb+w^6RP1v#*6MI8zh1lc@r@fAW410)(EvaFb`j|TI(g-+F*6?S5n=_njT zm9SpxNNV&UJf_AwJ8#MR-e zup@&P4iowZv5F?MK|Eh=d+4jz#qf9CS06%Up%rz7 z!VJHzQuV}8g2-X{7OOb|tU5TXeAS1ABbW~)N0d9Sn7lTDM{}~|CVc@54(yUuVKDa- z{T6Ln*=!uuO4Z=kZ}(o>AuV5=R?7;H=v7anrpvBDN!PK8R;HOAwzipvj-#yP?6Zij5n!E_`2KU@7_xobv6q4y-I)##wlXRKily>|7OBds>bq`PiK z#aXTIwLXaLbQ9n>m9G3Fu)u#a+TWUQ^1X6n|PmEG`4<17lRMq(;ta zSo%9tHK28Yn&bJnkFw+o`sbmaNEMebpzz*DHf zQ(;dX-F?XCa6Z@BWa(-w0&ISbJKG9P1qh7W-!&Pe$eSA`8${&GW`9Juq6f zGHdLWC&%Zq$R?)K3axbgHjmMGd4qv=MQyrtar??hNf+{=rr2ck_EV))O67)`dZW)g zGJAH`sa7`(^ftCnZ=|V4EqzJzwKUj{T_Y717Xntt;?n9}4t>;-@@vk>w(i|)G1;}q zlvNqc2Eo{KxT|XqBMu%AlaOSDEW2xd9LwxBn=Fb>f z(L7l&_So!z!GWX+I=pL8;B{jIE6!Xze2A5e35yI0kLXkDy?wd(($Zy{^ZPfh{lBwT z9((3+ZtcJk^vQfg@6lbTvBDGKSq&?4fRG7QTbzI)n71V4rHoy(EMU04FrF+j8A3bf zt-g4Ux1nHk?Q3f_cUmk;^@LF!n@OXyR6eTBW;+^vaGmSzfl@zRTI!M*jAB?P-Z>?$ zQ`3$H7)!Oh|5?cUN54^CI#9O4KS;lYbHElsCME^)YZt?WvF=)N!e!Etxb82nw+jOqt+Maxt@8u6JCLcI#Ft-Aa9Z{C}t0PzM6*$ig95X9kmoK^>-m8#4$n0cQ2C zR6G2snafv3Bf<80bJKfl8kyKJ-_zbvw5qy7G^R^hWDa{VVvnFAHrYMcVzM@h9f4L) z-eGpAH4Pk&yv71>Tv*pfnXiZC4x8ZPe7Dxl;rnNLF`j=8vB;jdgQt!_a|Vdh;H1p% zVwEe!93sd-GhOAI;!<1t3ywjLxxEd~#hK!nf+xi-oNmH{16L{sJZkIq`9_Uq%^Htx zy{VDzGlZYeEg6}t_tI3~pwH5Mthy69W=t2TCE9W$l|P}d&KKqT!dbPbZPc|}+B1t* zO3I0_BV#X$qQPUAJ1)-8>Csot%MM)T3v@1T+f;}1>-5+35RcQt(6-rmMM0_9iCHl+ zf!1iVhQTRVl^M5*Ys5mIlUV7Mc>a}KF4;yMGp(A)XQ)a#Zaq^Ym+8wkvx*){R=%h7 z*hJJ9>3^VgLP+@%vW>eT?_k>$cDrJmZ|Mc>OHCBM!y;eoMH8p2zgN zQ)=TtPpFFnKg6m%K4pGfAI@N~T(65Oxjh#7nAL1i1`TDawdAw}+^Fe6QCzuR6xWnq zp1;UK$6Bv-Yf`sO@%!$Z8}s?^Lq*&wRuRX>#`Cu5l^7e#*y8n}LI-Nj60otDw-0et zR$9pE8x(<~7z*5BJ+Oh+xEs)9FDO_!7|aONgXJI=tvCi8=}fge5bjtuWhfc9PLJ>M z9Zq)Z)%N1hl;s@}pIY7%&X_z4bvpO`4!2IX&;#9hds3rL(LF8eFVGv$@y7)r5;{jC z*Ilr_We-gmWy!V`XEwKA<8rggwB|Ec)ZokOcQA*=9KOEl1N1@60aha0>GgKZx}yF;Lgar{b|7l}<==?U829JflnyJUY=}(#gZDWXh>`eeH*mad4^4Cj5etT3vpXeh35mf%w`|+5ir^FOL`ODHvxJM!aK+B4+XD)4Z3iBC~PV7 z2pzpl<4&MRw`cPVnQ>*rs>-&98dY+`I-}O4(OjOe>F3VN$&~?Jb8xh=xi2PF>18h6f58BsbQqiEMXWqWxyCB*YjSc z_tNX}<^#6+q2PhWb9J+U(R7I`cwBJKO*&{IHM9BrsVmB3OXz~YfX|T+c4%lsXNd(P z&juC_gl13e{r-Dy|CEdq>&J@c$Nr1n%4?08B4XjiViNX%4%vrYK+P%@Ej60N;->$k z)S-8~`Df*-^!~o(?X#DPzF1(u@5qPH-K~}Ll^&&$9#DA{MrEzrzTWpDDt+bi?m!Q^ zuIqT~FfaBz?&G#bO{qJvx80|?|MjQ6C1^~n{*g`xJ^`r`NQ&9NV8_hlZdx|5d(KU}9ldnf{DrQ~ zBc`ZAt5s?RI)P**g;scWV&bgq+CyWV>bkNtiT{7#X%iO$N6fFzW`t*6LJuvlnK1>` z#8yv%pMbf~9`H$35l4eoX|_x?A0D4`@tU+DBy~p>hNiAO4e67#&0{qd3bpexzcRCRGPUmXmDu;xC~&qM1Jt7Yd8)1>d%8Fc#0CC{5e}86i|R9D2nt>^Gs-V zj}vRR@V%M5NFShi;{Y)!Ds$KMFkaY1enD@eIo@_`?9Cp=kEW8J3)j#r=KGOnPYc&X z&s+7it7BJvZGyHOfA%!)QGebz>a{fF%hK%A?7ow2{CWNSd+j;?1|p{mq?!6PwKh4j zW7%&KRsIZX%(*6m)6iueA_sV^>s7*RWQ00!UB3D{JT1JPK7)4xuvpmZwetWDLGAfN zm__Yx3OQ6i#xp+1i}hmxe*M4Ik0m5P+0zx+pOh%+min=bnCQ**V>#Ntfz?W-DqM9C zTkV*l3hq1gV*&mCu6`^bJ>;MDV=3MfwYYvPBO%H%GT43OXnzo}-imjX?7`bg)+1`Z z4)6L1Kr7#YH<@h2(Fpe2QC+bWpIZ>wV=e3Pc9GTiwgaCNXxWA12^??7@lM=fHTH9G zj}h!=;oj`p0IDjsV$bgW(K{eoICbl`J=@o>UAHqZZO4j@fsqy4S8m*Ex6+3Tb(efdFXFDK)9ZRC2;(%8T7&W3J@}H_4Xa>w{8ir zdu8(39GX7ihK!%`zv{J&o1Xed;d%l!;Sox}|No!guyY5wl1lJiohy+4{UG@sc^0c} zC1~<$;Qjjm>vzd>q$vfR82MH7vxpc%xd}DbquIk_%b!}x9nKRAK+UP@h~wPwd0LWPU@m=yvOfP)I;&~ z6zZn|8pKms!!$ypaKOazl#L{9pm3+qCPc5BX$EhB%F-N^i~@=xOSF}?;o1D{w1XlF zMZ0Mas#JUFRJ?DhpAO({QA2bZ9flMfp)=@AI*X3d*?1Pq96U;CE}ci`<6Tk<=_0(B zYB60xm(pc)IeC~o!rlyoH(5Q3w^gkq4=8qRS)a*d`fB?reTpet*KXaidZS`RZ7=Uz zwPO3$E%FJzQ}ox*uCAZ$ubo|8+s$0DYS+%y@-4O9%v$4?+HS12+g{tvsa>+8wi~ZC z?&Le!-0kbPtd;FzpYlbu3-S?pBrJ$}eXp3k(@_AQzEe)4;^{ykUU z=j;1IeP68aOZ9zgecx8!PpR*F>-(woeGOvymj3$pf!aP>?>}4bKU?oVTkk(x?>}4b zKU?n~kIZ10$Y<;QXY2iE>-}fz{b%d_XY2iE>-}fz{pafa=j#3E>iy^H{pafa=j#3E z>iy^H{r|tF?j{9c7zo2Kb?Ksak@-AO!T1BB&{}%SUZq#?oAE`u3W0 - From 4ddba5142ef360b4d8e08649d6cd36c0360f2b97 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 7 Jul 2022 23:20:22 +0400 Subject: [PATCH 02/17] Introduce font mappings --- apps/openmw/mwgui/formatting.cpp | 5 ++- apps/openmw/mwgui/formatting.hpp | 2 +- components/fontloader/fontloader.cpp | 45 ++++++++++++++++------ components/fontloader/fontloader.hpp | 4 ++ files/data/fonts/DejaVuLGCSansMono.omwfont | 2 +- files/data/fonts/OMWAyembedt.omwfont | 2 +- files/data/fonts/Pelagiad.omwfont | 2 +- files/mygui/openmw_book.layout | 4 +- files/mygui/openmw_journal.layout | 4 +- files/mygui/openmw_journal.skin.xml | 4 +- files/mygui/openmw_settings.xml | 2 +- files/settings-default.cfg | 9 +++++ 12 files changed, 62 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwgui/formatting.cpp b/apps/openmw/mwgui/formatting.cpp index c9a9da6066..64e3847887 100644 --- a/apps/openmw/mwgui/formatting.cpp +++ b/apps/openmw/mwgui/formatting.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -367,7 +368,9 @@ namespace MWGui::Formatting if (attr.find("face") != attr.end()) { std::string face = attr.at("face"); - mTextStyle.mFont = "Journalbook "+face; + std::string name = Gui::FontLoader::getFontForFace(face); + + mTextStyle.mFont = "Journalbook "+name; } if (attr.find("size") != attr.end()) { diff --git a/apps/openmw/mwgui/formatting.hpp b/apps/openmw/mwgui/formatting.hpp index 12a3d46caa..387acd58c8 100644 --- a/apps/openmw/mwgui/formatting.hpp +++ b/apps/openmw/mwgui/formatting.hpp @@ -14,7 +14,7 @@ namespace MWGui { TextStyle() : mColour(0,0,0) - , mFont("Journalbook Magic Cards") + , mFont("Journalbook DefaultFont") , mTextSize(16) { } diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index ab4ca24eee..d7d16f0aa1 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -304,13 +304,7 @@ namespace Gui fail(*bitmapFile, bitmapFilename, "File too small to be a valid bitmap"); bitmapFile.reset(); - std::string resourceName; - if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic")) - resourceName = "Magic Cards"; - else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century")) - resourceName = "Century Gothic"; - else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric")) - resourceName = "Daedric"; + std::string resourceName = name; if (exportToFile) { @@ -346,7 +340,9 @@ namespace Gui // We need to emulate loading from XML because the data members are private as of mygui 3.2.0 MyGUI::xml::Document xmlDocument; MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont"); - root->addAttribute("name", resourceName); + + const std::string baseName = Misc::StringUtils::lowerCase(std::filesystem::path(mVFS->getAbsoluteFileName(fileName)).stem().string()); + root->addAttribute("name", getInternalFontName(baseName)); MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property"); defaultHeight->addAttribute("key", "DefaultHeight"); @@ -506,12 +502,11 @@ namespace Gui font->deserialization(root, MyGUI::Version(3,2,0)); - // Setup "book" version of font as fallback if we will not use TrueType fonts MyGUI::ResourceManualFont* bookFont = static_cast( MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont")); mFonts.push_back(bookFont); bookFont->deserialization(root, MyGUI::Version(3,2,0)); - bookFont->setResourceName("Journalbook " + resourceName); + bookFont->setResourceName("Journalbook " + getInternalFontName(baseName)); // Remove automatically registered fonts for (std::vector::iterator it = mFonts.begin(); it != mFonts.end();) @@ -564,6 +559,8 @@ namespace Gui MyGUI::xml::ElementPtr sizeNode = resourceNode->createChild("Property"); sizeNode->addAttribute("key", "Size"); sizeNode->addAttribute("value", std::to_string(mFontHeight)); + + resourceNode->setAttribute("name", getInternalFontName(name)); } else if (Misc::StringUtils::ciEqual(type, "ResourceSkin") || Misc::StringUtils::ciEqual(type, "AutoSizedResourceSkin")) @@ -611,7 +608,7 @@ namespace Gui resolutionNode->addAttribute("key", "Resolution"); resolutionNode->addAttribute("value", std::to_string(resolution)); - copyFont->setAttribute("name", "Journalbook " + name); + copyFont->setAttribute("name", "Journalbook " + getInternalFontName(name)); } } @@ -623,4 +620,30 @@ namespace Gui { return mFontHeight; } + + std::string FontLoader::getInternalFontName(const std::string& name) + { + if (name == Settings::Manager::getString("default font", "GUI")) + return "DefaultFont"; + if (name == Settings::Manager::getString("scroll font", "GUI")) + return "ScrollFont"; + if (name == Settings::Manager::getString("mono font", "GUI")) + return "MonoFont"; + + return name; + } + + std::string FontLoader::getFontForFace(const std::string& face) + { + const std::string lowerFace = Misc::StringUtils::lowerCase(face); + + if (lowerFace == "magic cards") + return "DefaultFont"; + if (lowerFace == "daedric") + return "ScrollFont"; + if (lowerFace == "century gothic") + return "MonoFont"; + + return face; + } } diff --git a/components/fontloader/fontloader.hpp b/components/fontloader/fontloader.hpp index ee54e077a5..652f9bdf43 100644 --- a/components/fontloader/fontloader.hpp +++ b/components/fontloader/fontloader.hpp @@ -36,6 +36,8 @@ namespace Gui int getFontHeight(); + static std::string getFontForFace(const std::string& face); + private: ToUTF8::FromType mEncoding; const VFS::Manager* mVFS; @@ -46,6 +48,8 @@ namespace Gui std::vector mTextures; std::vector mFonts; + std::string getInternalFontName(const std::string& name); + /// @param exportToFile export the converted font (Image and XML with glyph metrics) to files? void loadBitmapFont (const std::string& fileName, bool exportToFile); diff --git a/files/data/fonts/DejaVuLGCSansMono.omwfont b/files/data/fonts/DejaVuLGCSansMono.omwfont index 6511877656..184c8a0d8f 100644 --- a/files/data/fonts/DejaVuLGCSansMono.omwfont +++ b/files/data/fonts/DejaVuLGCSansMono.omwfont @@ -1,6 +1,6 @@ - + diff --git a/files/data/fonts/OMWAyembedt.omwfont b/files/data/fonts/OMWAyembedt.omwfont index c8ac1c2ecb..9af8f655d8 100644 --- a/files/data/fonts/OMWAyembedt.omwfont +++ b/files/data/fonts/OMWAyembedt.omwfont @@ -1,6 +1,6 @@ - + diff --git a/files/data/fonts/Pelagiad.omwfont b/files/data/fonts/Pelagiad.omwfont index 38dc29e09d..4b01a9f308 100644 --- a/files/data/fonts/Pelagiad.omwfont +++ b/files/data/fonts/Pelagiad.omwfont @@ -1,6 +1,6 @@ - + diff --git a/files/mygui/openmw_book.layout b/files/mygui/openmw_book.layout index e6f0f858c0..c0b19783c4 100644 --- a/files/mygui/openmw_book.layout +++ b/files/mygui/openmw_book.layout @@ -32,13 +32,13 @@ - + - + diff --git a/files/mygui/openmw_journal.layout b/files/mygui/openmw_journal.layout index 3752897f97..c93fbb3329 100644 --- a/files/mygui/openmw_journal.layout +++ b/files/mygui/openmw_journal.layout @@ -25,12 +25,12 @@ - + - + diff --git a/files/mygui/openmw_journal.skin.xml b/files/mygui/openmw_journal.skin.xml index 0702d8c5eb..ddf9497f28 100644 --- a/files/mygui/openmw_journal.skin.xml +++ b/files/mygui/openmw_journal.skin.xml @@ -2,7 +2,7 @@ - + @@ -19,7 +19,7 @@ - + diff --git a/files/mygui/openmw_settings.xml b/files/mygui/openmw_settings.xml index 37d2359683..1bd0e25437 100644 --- a/files/mygui/openmw_settings.xml +++ b/files/mygui/openmw_settings.xml @@ -1,7 +1,7 @@ - + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 2675004907..d42c093f0a 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -234,6 +234,15 @@ color topic specific = 0.45 0.5 0.8 1 # Default to grey color topic exhausted = 0.3 0.3 0.3 1 +# Font used by UI and books +default font = pelagiad + +# Font used by magic scrolls +scroll font = ayembedt + +# Font used by console and debug log +mono font = dejavusansmono + [HUD] # Displays the crosshair or reticle when not in GUI mode. From 2630bc21ddfab2e9ce170f4133b1a848707bd29f Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 9 Jul 2022 19:58:40 +0400 Subject: [PATCH 03/17] Allow to override MyGUI layout --- apps/openmw/engine.cpp | 3 +- apps/openmw/mwgui/windowmanagerimp.cpp | 4 +- apps/openmw/mwgui/windowmanagerimp.hpp | 2 +- components/fontloader/fontloader.cpp | 7 +-- components/fontloader/fontloader.hpp | 3 +- components/myguiplatform/myguidatamanager.cpp | 57 ++++--------------- components/myguiplatform/myguidatamanager.hpp | 4 -- 7 files changed, 18 insertions(+), 62 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 4d10b47963..2b9206354a 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -521,6 +521,7 @@ void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs) { mDataDirs = dataDirs; mDataDirs.insert(mDataDirs.begin(), (mResDir / "vfs")); + mDataDirs.insert(mDataDirs.begin(), (mResDir / "mygui")); mFileCollections = Files::Collections (mDataDirs, !mFSStrict); } @@ -825,7 +826,7 @@ void OMW::Engine::prepareEngine() mWindowManager = std::make_unique(mWindow, mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(), mCfgMgr.getLogPath().string() + std::string("/"), myguiResources, mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, - Version::getOpenmwVersionDescription(mResDir.string()), mCfgMgr.getUserConfigPath().string(), shadersSupported); + Version::getOpenmwVersionDescription(mResDir.string()), shadersSupported); mEnvironment.setWindowManager(*mWindowManager); mInputManager = std::make_unique(mWindow, mViewer, mScreenCaptureHandler, diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 382f489e20..5141736204 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -129,7 +129,7 @@ namespace MWGui WindowManager::WindowManager( SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& logpath, const std::string& resourcePath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, - ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, const std::string& userDataPath, bool useShaders) + ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, bool useShaders) : mOldUpdateMask(0) , mOldCullMask(0) , mStore(nullptr) @@ -205,7 +205,7 @@ namespace MWGui MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag); // Load fonts - mFontLoader = std::make_unique(encoding, resourceSystem->getVFS(), userDataPath, mScalingFactor); + mFontLoader = std::make_unique(encoding, resourceSystem->getVFS(), mScalingFactor); mFontLoader->loadBitmapFonts(exportFonts); //Register own widgets with MyGUI diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 2367470223..083ecc6992 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -136,7 +136,7 @@ namespace MWGui WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, - ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, const std::string& localPath, bool useShaders); + ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, bool useShaders); virtual ~WindowManager(); /// Set the ESMStore to use for retrieving of GUI-related strings. diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index d7d16f0aa1..fca8346e19 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -151,9 +151,8 @@ namespace namespace Gui { - FontLoader::FontLoader(ToUTF8::FromType encoding, const VFS::Manager* vfs, const std::string& userDataPath, float scalingFactor) + FontLoader::FontLoader(ToUTF8::FromType encoding, const VFS::Manager* vfs, float scalingFactor) : mVFS(vfs) - , mUserDataPath(userDataPath) , mFontHeight(std::clamp(Settings::Manager::getInt("font size", "GUI"), 12, 20)) , mScalingFactor(scalingFactor) { @@ -214,15 +213,11 @@ namespace Gui return; } - dataManager->setUseVfs(true); - for (const auto& name : mVFS->getRecursiveDirectoryIterator("Fonts/")) { if (Misc::getFileExtension(name) == "omwfont") MyGUI::ResourceManager::getInstance().load(name); } - - dataManager->setUseVfs(false); } typedef struct diff --git a/components/fontloader/fontloader.hpp b/components/fontloader/fontloader.hpp index 652f9bdf43..eb705fdd4a 100644 --- a/components/fontloader/fontloader.hpp +++ b/components/fontloader/fontloader.hpp @@ -25,7 +25,7 @@ namespace Gui class FontLoader { public: - FontLoader (ToUTF8::FromType encoding, const VFS::Manager* vfs, const std::string& userDataPath, float scalingFactor); + FontLoader (ToUTF8::FromType encoding, const VFS::Manager* vfs, float scalingFactor); ~FontLoader(); /// @param exportToFile export the converted fonts (Images and XML with glyph metrics) to files? @@ -41,7 +41,6 @@ namespace Gui private: ToUTF8::FromType mEncoding; const VFS::Manager* mVFS; - std::string mUserDataPath; int mFontHeight; float mScalingFactor; diff --git a/components/myguiplatform/myguidatamanager.cpp b/components/myguiplatform/myguidatamanager.cpp index d3edb82ae5..c06532a9f4 100644 --- a/components/myguiplatform/myguidatamanager.cpp +++ b/components/myguiplatform/myguidatamanager.cpp @@ -18,34 +18,16 @@ void DataManager::setResourcePath(const std::string &path) mResourcePath = path; } -void DataManager::setUseVfs(bool useVfs) -{ - mUseVfs = useVfs; -} - MyGUI::IDataStream *DataManager::getData(const std::string &name) const { - if (mUseVfs) - { - // Note: MyGUI is supposed to read/free input steam itself, - // so copy data from VFS stream to the string stream and pass it to MyGUI. - Files::IStreamPtr streamPtr = mVfs->get(name); - std::istream* fileStream = streamPtr.get(); - std::unique_ptr dataStream; - dataStream.reset(new std::stringstream); - *dataStream << fileStream->rdbuf(); - return new MyGUI::DataStream(dataStream.release()); - } - - std::string fullpath = getDataPath(name); - auto stream = std::make_unique(); - stream->open(fullpath, std::ios::binary); - if (stream->fail()) - { - Log(Debug::Error) << "DataManager::getData: Failed to open '" << name << "'"; - return nullptr; - } - return new MyGUI::DataFileStream(stream.release()); + // Note: MyGUI is supposed to read/free input steam itself, + // so copy data from VFS stream to the string stream and pass it to MyGUI. + Files::IStreamPtr streamPtr = mVfs->get(name); + std::istream* fileStream = streamPtr.get(); + std::unique_ptr dataStream; + dataStream.reset(new std::stringstream); + *dataStream << fileStream->rdbuf(); + return new MyGUI::DataStream(dataStream.release()); } void DataManager::freeData(MyGUI::IDataStream *data) @@ -55,10 +37,7 @@ void DataManager::freeData(MyGUI::IDataStream *data) bool DataManager::isDataExist(const std::string &name) const { - if (mUseVfs) return mVfs->exists(name); - - std::string fullpath = mResourcePath + "/" + name; - return std::filesystem::exists(fullpath); + return mVfs->exists(name); } void DataManager::setVfs(const VFS::Manager* vfs) @@ -68,26 +47,12 @@ void DataManager::setVfs(const VFS::Manager* vfs) const MyGUI::VectorString &DataManager::getDataListNames(const std::string &pattern) const { - // TODO: pattern matching (unused?) - static MyGUI::VectorString strings; - strings.clear(); - strings.push_back(getDataPath(pattern)); - return strings; + throw std::runtime_error("DataManager::getDataListNames is not implemented - VFS is used"); } const std::string &DataManager::getDataPath(const std::string &name) const { - // FIXME: in theory, we should use the VFS here too, but it does not provide the real path to data files. - // In some cases there is no real path at all (when the requested MyGUI file is in BSA archive, for example). - // Currently it should not matter since we use this virtual function only to setup fonts for profilers. - static std::string result; - result.clear(); - if (!isDataExist(name)) - { - return result; - } - result = mResourcePath + "/" + name; - return result; + throw std::runtime_error("DataManager::getDataPath is not implemented - VFS is used"); } } diff --git a/components/myguiplatform/myguidatamanager.hpp b/components/myguiplatform/myguidatamanager.hpp index a859ce99c1..47203e1634 100644 --- a/components/myguiplatform/myguidatamanager.hpp +++ b/components/myguiplatform/myguidatamanager.hpp @@ -18,8 +18,6 @@ public: void setResourcePath(const std::string& path); - void setUseVfs(bool useVfs); - void setVfs(const VFS::Manager* vfs); /** Get data stream from specified resource name. @@ -52,8 +50,6 @@ private: std::string mResourcePath; const VFS::Manager* mVfs; - - bool mUseVfs{false}; }; } From c47a48e25dc026b0643d265af0b04eff02891b87 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 9 Jul 2022 20:42:18 +0400 Subject: [PATCH 04/17] Inject layout files to VFS --- apps/openmw/engine.cpp | 6 +- apps/openmw/mwgui/windowmanagerimp.cpp | 4 +- apps/openmw/mwgui/windowmanagerimp.hpp | 2 +- components/fontloader/fontloader.cpp | 9 +- components/myguiplatform/myguidatamanager.cpp | 16 ++- files/CMakeLists.txt | 1 - files/data/CMakeLists.txt | 90 ++++++++++++++++ files/data/fonts/DejaVuLGCSansMono.omwfont | 2 +- files/data/fonts/OMWAyembedt.omwfont | 2 +- files/data/fonts/Pelagiad.omwfont | 2 +- .../{ => data}/mygui/OpenMWResourcePlugin.xml | 0 files/{ => data}/mygui/core.skin | 0 files/{ => data}/mygui/core.xml | 0 files/{ => data}/mygui/core_layouteditor.xml | 0 .../mygui/openmw_alchemy_window.layout | 0 files/{ => data}/mygui/openmw_book.layout | 0 files/{ => data}/mygui/openmw_box.skin.xml | 0 files/{ => data}/mygui/openmw_button.skin.xml | 0 .../mygui/openmw_chargen_birth.layout | 0 .../mygui/openmw_chargen_class.layout | 0 .../openmw_chargen_class_description.layout | 0 .../mygui/openmw_chargen_create_class.layout | 0 ...penmw_chargen_generate_class_result.layout | 0 .../mygui/openmw_chargen_race.layout | 0 .../mygui/openmw_chargen_review.layout | 0 .../openmw_chargen_select_attribute.layout | 0 .../mygui/openmw_chargen_select_skill.layout | 0 ...penmw_chargen_select_specialization.layout | 0 .../mygui/openmw_companion_window.layout | 0 .../mygui/openmw_confirmation_dialog.layout | 0 files/{ => data}/mygui/openmw_console.layout | 0 .../{ => data}/mygui/openmw_console.skin.xml | 0 .../mygui/openmw_container_window.layout | 0 .../mygui/openmw_count_window.layout | 0 .../mygui/openmw_debug_window.layout | 0 .../mygui/openmw_debug_window.skin.xml | 0 .../mygui/openmw_dialogue_window.layout | 0 .../mygui/openmw_dialogue_window.skin.xml | 0 files/{ => data}/mygui/openmw_edit.skin.xml | 0 .../mygui/openmw_edit_effect.layout | 0 .../{ => data}/mygui/openmw_edit_note.layout | 0 .../mygui/openmw_enchanting_dialog.layout | 0 files/{ => data}/mygui/openmw_hud.layout | 0 .../{ => data}/mygui/openmw_hud_box.skin.xml | 0 .../mygui/openmw_hud_energybar.skin.xml | 0 files/{ => data}/mygui/openmw_infobox.layout | 0 .../openmw_interactive_messagebox.layout | 0 ...nmw_interactive_messagebox_notransp.layout | 0 .../mygui/openmw_inventory_window.layout | 0 .../mygui/openmw_itemselection_dialog.layout | 0 .../mygui/openmw_jail_screen.layout | 0 files/{ => data}/mygui/openmw_journal.layout | 0 .../{ => data}/mygui/openmw_journal.skin.xml | 0 files/{ => data}/mygui/openmw_layers.xml | 0 .../mygui/openmw_levelup_dialog.layout | 0 files/{ => data}/mygui/openmw_list.skin.xml | 0 .../mygui/openmw_loading_screen.layout | 0 files/{ => data}/mygui/openmw_lua.xml | 0 .../mygui/openmw_magicselection_dialog.layout | 0 files/{ => data}/mygui/openmw_mainmenu.layout | 0 .../{ => data}/mygui/openmw_mainmenu.skin.xml | 0 .../{ => data}/mygui/openmw_map_window.layout | 0 .../mygui/openmw_map_window.skin.xml | 0 .../mygui/openmw_merchantrepair.layout | 0 .../{ => data}/mygui/openmw_messagebox.layout | 0 .../mygui/openmw_persuasion_dialog.layout | 0 files/{ => data}/mygui/openmw_pointer.xml | 0 .../mygui/openmw_postprocessor_hud.layout | 0 .../mygui/openmw_postprocessor_hud.skin.xml | 0 .../{ => data}/mygui/openmw_progress.skin.xml | 0 .../mygui/openmw_quickkeys_menu.layout | 0 .../mygui/openmw_quickkeys_menu_assign.layout | 0 .../mygui/openmw_recharge_dialog.layout | 0 files/{ => data}/mygui/openmw_repair.layout | 0 files/{ => data}/mygui/openmw_resources.xml | 0 .../mygui/openmw_savegame_dialog.layout | 0 .../mygui/openmw_screen_fader.layout | 0 .../mygui/openmw_screen_fader_hit.layout | 0 files/{ => data}/mygui/openmw_scroll.layout | 0 files/{ => data}/mygui/openmw_scroll.skin.xml | 0 files/{ => data}/mygui/openmw_settings.xml | 0 .../mygui/openmw_settings_window.layout | 0 .../mygui/openmw_spell_buying_window.layout | 0 .../mygui/openmw_spell_window.layout | 0 .../mygui/openmw_spellcreation_dialog.layout | 0 .../mygui/openmw_stats_window.layout | 0 files/{ => data}/mygui/openmw_text.skin.xml | 0 .../{ => data}/mygui/openmw_text_input.layout | 0 files/{ => data}/mygui/openmw_tooltips.layout | 0 .../mygui/openmw_trade_window.layout | 0 .../mygui/openmw_trainingwindow.layout | 0 .../mygui/openmw_travel_window.layout | 0 .../mygui/openmw_wait_dialog.layout | 0 .../openmw_wait_dialog_progressbar.layout | 0 .../{ => data}/mygui/openmw_windows.skin.xml | 0 files/{ => data}/mygui/skins.xml | 0 files/mygui/CMakeLists.txt | 101 ------------------ files/mygui/DejaVuFontLicense.txt | 99 ----------------- 98 files changed, 119 insertions(+), 215 deletions(-) rename files/{ => data}/mygui/OpenMWResourcePlugin.xml (100%) rename files/{ => data}/mygui/core.skin (100%) rename files/{ => data}/mygui/core.xml (100%) rename files/{ => data}/mygui/core_layouteditor.xml (100%) rename files/{ => data}/mygui/openmw_alchemy_window.layout (100%) rename files/{ => data}/mygui/openmw_book.layout (100%) rename files/{ => data}/mygui/openmw_box.skin.xml (100%) rename files/{ => data}/mygui/openmw_button.skin.xml (100%) rename files/{ => data}/mygui/openmw_chargen_birth.layout (100%) rename files/{ => data}/mygui/openmw_chargen_class.layout (100%) rename files/{ => data}/mygui/openmw_chargen_class_description.layout (100%) rename files/{ => data}/mygui/openmw_chargen_create_class.layout (100%) rename files/{ => data}/mygui/openmw_chargen_generate_class_result.layout (100%) rename files/{ => data}/mygui/openmw_chargen_race.layout (100%) rename files/{ => data}/mygui/openmw_chargen_review.layout (100%) rename files/{ => data}/mygui/openmw_chargen_select_attribute.layout (100%) rename files/{ => data}/mygui/openmw_chargen_select_skill.layout (100%) rename files/{ => data}/mygui/openmw_chargen_select_specialization.layout (100%) rename files/{ => data}/mygui/openmw_companion_window.layout (100%) rename files/{ => data}/mygui/openmw_confirmation_dialog.layout (100%) rename files/{ => data}/mygui/openmw_console.layout (100%) rename files/{ => data}/mygui/openmw_console.skin.xml (100%) rename files/{ => data}/mygui/openmw_container_window.layout (100%) rename files/{ => data}/mygui/openmw_count_window.layout (100%) rename files/{ => data}/mygui/openmw_debug_window.layout (100%) rename files/{ => data}/mygui/openmw_debug_window.skin.xml (100%) rename files/{ => data}/mygui/openmw_dialogue_window.layout (100%) rename files/{ => data}/mygui/openmw_dialogue_window.skin.xml (100%) rename files/{ => data}/mygui/openmw_edit.skin.xml (100%) rename files/{ => data}/mygui/openmw_edit_effect.layout (100%) rename files/{ => data}/mygui/openmw_edit_note.layout (100%) rename files/{ => data}/mygui/openmw_enchanting_dialog.layout (100%) rename files/{ => data}/mygui/openmw_hud.layout (100%) rename files/{ => data}/mygui/openmw_hud_box.skin.xml (100%) rename files/{ => data}/mygui/openmw_hud_energybar.skin.xml (100%) rename files/{ => data}/mygui/openmw_infobox.layout (100%) rename files/{ => data}/mygui/openmw_interactive_messagebox.layout (100%) rename files/{ => data}/mygui/openmw_interactive_messagebox_notransp.layout (100%) rename files/{ => data}/mygui/openmw_inventory_window.layout (100%) rename files/{ => data}/mygui/openmw_itemselection_dialog.layout (100%) rename files/{ => data}/mygui/openmw_jail_screen.layout (100%) rename files/{ => data}/mygui/openmw_journal.layout (100%) rename files/{ => data}/mygui/openmw_journal.skin.xml (100%) rename files/{ => data}/mygui/openmw_layers.xml (100%) rename files/{ => data}/mygui/openmw_levelup_dialog.layout (100%) rename files/{ => data}/mygui/openmw_list.skin.xml (100%) rename files/{ => data}/mygui/openmw_loading_screen.layout (100%) rename files/{ => data}/mygui/openmw_lua.xml (100%) rename files/{ => data}/mygui/openmw_magicselection_dialog.layout (100%) rename files/{ => data}/mygui/openmw_mainmenu.layout (100%) rename files/{ => data}/mygui/openmw_mainmenu.skin.xml (100%) rename files/{ => data}/mygui/openmw_map_window.layout (100%) rename files/{ => data}/mygui/openmw_map_window.skin.xml (100%) rename files/{ => data}/mygui/openmw_merchantrepair.layout (100%) rename files/{ => data}/mygui/openmw_messagebox.layout (100%) rename files/{ => data}/mygui/openmw_persuasion_dialog.layout (100%) rename files/{ => data}/mygui/openmw_pointer.xml (100%) rename files/{ => data}/mygui/openmw_postprocessor_hud.layout (100%) rename files/{ => data}/mygui/openmw_postprocessor_hud.skin.xml (100%) rename files/{ => data}/mygui/openmw_progress.skin.xml (100%) rename files/{ => data}/mygui/openmw_quickkeys_menu.layout (100%) rename files/{ => data}/mygui/openmw_quickkeys_menu_assign.layout (100%) rename files/{ => data}/mygui/openmw_recharge_dialog.layout (100%) rename files/{ => data}/mygui/openmw_repair.layout (100%) rename files/{ => data}/mygui/openmw_resources.xml (100%) rename files/{ => data}/mygui/openmw_savegame_dialog.layout (100%) rename files/{ => data}/mygui/openmw_screen_fader.layout (100%) rename files/{ => data}/mygui/openmw_screen_fader_hit.layout (100%) rename files/{ => data}/mygui/openmw_scroll.layout (100%) rename files/{ => data}/mygui/openmw_scroll.skin.xml (100%) rename files/{ => data}/mygui/openmw_settings.xml (100%) rename files/{ => data}/mygui/openmw_settings_window.layout (100%) rename files/{ => data}/mygui/openmw_spell_buying_window.layout (100%) rename files/{ => data}/mygui/openmw_spell_window.layout (100%) rename files/{ => data}/mygui/openmw_spellcreation_dialog.layout (100%) rename files/{ => data}/mygui/openmw_stats_window.layout (100%) rename files/{ => data}/mygui/openmw_text.skin.xml (100%) rename files/{ => data}/mygui/openmw_text_input.layout (100%) rename files/{ => data}/mygui/openmw_tooltips.layout (100%) rename files/{ => data}/mygui/openmw_trade_window.layout (100%) rename files/{ => data}/mygui/openmw_trainingwindow.layout (100%) rename files/{ => data}/mygui/openmw_travel_window.layout (100%) rename files/{ => data}/mygui/openmw_wait_dialog.layout (100%) rename files/{ => data}/mygui/openmw_wait_dialog_progressbar.layout (100%) rename files/{ => data}/mygui/openmw_windows.skin.xml (100%) rename files/{ => data}/mygui/skins.xml (100%) delete mode 100644 files/mygui/CMakeLists.txt delete mode 100644 files/mygui/DejaVuFontLicense.txt diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 2b9206354a..467d61bf12 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -521,7 +521,6 @@ void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs) { mDataDirs = dataDirs; mDataDirs.insert(mDataDirs.begin(), (mResDir / "vfs")); - mDataDirs.insert(mDataDirs.begin(), (mResDir / "mygui")); mFileCollections = Files::Collections (mDataDirs, !mFSStrict); } @@ -701,7 +700,7 @@ void OMW::Engine::createWindow() void OMW::Engine::setWindowIcon() { std::ifstream windowIconStream; - std::string windowIcon = (mResDir / "mygui" / "openmw.png").string(); + std::string windowIcon = (mResDir / "openmw.png").string(); windowIconStream.open(windowIcon, std::ios_base::in | std::ios_base::binary); if (windowIconStream.fail()) Log(Debug::Error) << "Error: Failed to open " << windowIcon; @@ -816,7 +815,6 @@ void OMW::Engine::prepareEngine() exts->glRenderbufferStorageMultisampleCoverageNV = nullptr; #endif - std::string myguiResources = (mResDir / "mygui").string(); osg::ref_ptr guiRoot = new osg::Group; guiRoot->setName("GUI Root"); guiRoot->setNodeMask(MWRender::Mask_GUI); @@ -824,7 +822,7 @@ void OMW::Engine::prepareEngine() rootNode->addChild(guiRoot); mWindowManager = std::make_unique(mWindow, mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(), - mCfgMgr.getLogPath().string() + std::string("/"), myguiResources, + mCfgMgr.getLogPath().string() + std::string("/"), mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, Version::getOpenmwVersionDescription(mResDir.string()), shadersSupported); mEnvironment.setWindowManager(*mWindowManager); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5141736204..623c46fedc 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -128,7 +128,7 @@ namespace MWGui { WindowManager::WindowManager( SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, - const std::string& logpath, const std::string& resourcePath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, + const std::string& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, bool useShaders) : mOldUpdateMask(0) , mOldCullMask(0) @@ -195,7 +195,7 @@ namespace MWGui { mScalingFactor = std::clamp(Settings::Manager::getFloat("scaling factor", "GUI"), 0.5f, 8.f); mGuiPlatform = new osgMyGUI::Platform(viewer, guiRoot, resourceSystem->getImageManager(), mScalingFactor); - mGuiPlatform->initialise(resourceSystem->getVFS(), resourcePath, (std::filesystem::path(logpath) / "MyGUI.log").generic_string()); + mGuiPlatform->initialise(resourceSystem->getVFS(), "mygui", (std::filesystem::path(logpath) / "MyGUI.log").generic_string()); mGui = new MyGUI::Gui; mGui->initialise(""); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 083ecc6992..a48847de3f 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -135,7 +135,7 @@ namespace MWGui typedef std::vector FactionList; WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, - const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, + const std::string& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, bool useShaders); virtual ~WindowManager(); diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index fca8346e19..7d90002d95 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -213,11 +213,18 @@ namespace Gui return; } + std::string oldDataPath = dataManager->getDataPath(""); + dataManager->setResourcePath("fonts"); + for (const auto& name : mVFS->getRecursiveDirectoryIterator("Fonts/")) { + std::filesystem::path path = name; + std::cout << name << std::endl; if (Misc::getFileExtension(name) == "omwfont") - MyGUI::ResourceManager::getInstance().load(name); + MyGUI::ResourceManager::getInstance().load(path.filename()); } + + dataManager->setResourcePath(oldDataPath); } typedef struct diff --git a/components/myguiplatform/myguidatamanager.cpp b/components/myguiplatform/myguidatamanager.cpp index c06532a9f4..1eefa6b81d 100644 --- a/components/myguiplatform/myguidatamanager.cpp +++ b/components/myguiplatform/myguidatamanager.cpp @@ -22,7 +22,7 @@ MyGUI::IDataStream *DataManager::getData(const std::string &name) const { // Note: MyGUI is supposed to read/free input steam itself, // so copy data from VFS stream to the string stream and pass it to MyGUI. - Files::IStreamPtr streamPtr = mVfs->get(name); + Files::IStreamPtr streamPtr = mVfs->get(mResourcePath + "\\" + name); std::istream* fileStream = streamPtr.get(); std::unique_ptr dataStream; dataStream.reset(new std::stringstream); @@ -37,7 +37,7 @@ void DataManager::freeData(MyGUI::IDataStream *data) bool DataManager::isDataExist(const std::string &name) const { - return mVfs->exists(name); + return mVfs->exists(mResourcePath + "\\" + name); } void DataManager::setVfs(const VFS::Manager* vfs) @@ -52,7 +52,17 @@ const MyGUI::VectorString &DataManager::getDataListNames(const std::string &patt const std::string &DataManager::getDataPath(const std::string &name) const { - throw std::runtime_error("DataManager::getDataPath is not implemented - VFS is used"); + static std::string result; + result.clear(); + + if (name.empty()) + return mResourcePath; + + if (!isDataExist(name)) + return result; + + result = mResourcePath + "\\" + name; + return result; } } diff --git a/files/CMakeLists.txt b/files/CMakeLists.txt index a3d5c14e5c..b7b4b4cd23 100644 --- a/files/CMakeLists.txt +++ b/files/CMakeLists.txt @@ -1,4 +1,3 @@ -add_subdirectory(mygui) add_subdirectory(shaders) add_subdirectory(data) add_subdirectory(lua_api) diff --git a/files/data/CMakeLists.txt b/files/data/CMakeLists.txt index 1fa40b3f54..63df2f53b5 100644 --- a/files/data/CMakeLists.txt +++ b/files/data/CMakeLists.txt @@ -69,8 +69,98 @@ set(BUILTIN_DATA_FILES shaders/main.omwfx shaders/displaydepth.omwfx + + mygui/core.skin + mygui/core.xml + mygui/core_layouteditor.xml + mygui/openmw_alchemy_window.layout + mygui/openmw_book.layout + mygui/openmw_box.skin.xml + mygui/openmw_button.skin.xml + mygui/openmw_chargen_birth.layout + mygui/openmw_chargen_class_description.layout + mygui/openmw_chargen_class.layout + mygui/openmw_chargen_create_class.layout + mygui/openmw_chargen_generate_class_result.layout + mygui/openmw_chargen_race.layout + mygui/openmw_chargen_review.layout + mygui/openmw_chargen_select_attribute.layout + mygui/openmw_chargen_select_skill.layout + mygui/openmw_chargen_select_specialization.layout + mygui/openmw_confirmation_dialog.layout + mygui/openmw_console.layout + mygui/openmw_console.skin.xml + mygui/openmw_container_window.layout + mygui/openmw_count_window.layout + mygui/openmw_dialogue_window.layout + mygui/openmw_dialogue_window.skin.xml + mygui/openmw_edit.skin.xml + mygui/openmw_hud_box.skin.xml + mygui/openmw_hud_energybar.skin.xml + mygui/openmw_hud.layout + mygui/openmw_infobox.layout + mygui/openmw_interactive_messagebox.layout + mygui/openmw_interactive_messagebox_notransp.layout + mygui/openmw_inventory_window.layout + mygui/openmw_journal.layout + mygui/openmw_journal.skin.xml + mygui/openmw_layers.xml + mygui/openmw_lua.xml + mygui/openmw_list.skin.xml + mygui/openmw_mainmenu.layout + mygui/openmw_mainmenu.skin.xml + mygui/openmw_map_window.layout + mygui/openmw_map_window.skin.xml + mygui/openmw_messagebox.layout + mygui/openmw_pointer.xml + mygui/openmw_progress.skin.xml + mygui/openmw_resources.xml + mygui/openmw_scroll.layout + mygui/openmw_scroll.skin.xml + mygui/openmw_settings_window.layout + mygui/openmw_settings.xml + mygui/openmw_spell_window.layout + mygui/openmw_stats_window.layout + mygui/openmw_text_input.layout + mygui/openmw_text.skin.xml + mygui/openmw_tooltips.layout + mygui/openmw_trade_window.layout + mygui/openmw_spell_buying_window.layout + mygui/openmw_windows.skin.xml + mygui/openmw_quickkeys_menu.layout + mygui/openmw_quickkeys_menu_assign.layout + mygui/openmw_itemselection_dialog.layout + mygui/openmw_magicselection_dialog.layout + mygui/openmw_spell_buying_window.layout + mygui/openmw_loading_screen.layout + mygui/openmw_levelup_dialog.layout + mygui/openmw_wait_dialog.layout + mygui/openmw_wait_dialog_progressbar.layout + mygui/openmw_spellcreation_dialog.layout + mygui/openmw_edit_effect.layout + mygui/openmw_enchanting_dialog.layout + mygui/openmw_trainingwindow.layout + mygui/openmw_travel_window.layout + mygui/openmw_persuasion_dialog.layout + mygui/openmw_merchantrepair.layout + mygui/openmw_repair.layout + mygui/openmw_companion_window.layout + mygui/openmw_savegame_dialog.layout + mygui/openmw_recharge_dialog.layout + mygui/openmw_screen_fader.layout + mygui/openmw_screen_fader_hit.layout + mygui/openmw_edit_note.layout + mygui/openmw_debug_window.layout + mygui/openmw_debug_window.skin.xml + mygui/openmw_postprocessor_hud.layout + mygui/openmw_postprocessor_hud.skin.xml + mygui/openmw_jail_screen.layout + mygui/OpenMWResourcePlugin.xml + mygui/skins.xml ) foreach (f ${BUILTIN_DATA_FILES}) copy_resource_file("${CMAKE_CURRENT_SOURCE_DIR}/${f}" "${OPENMW_RESOURCES_ROOT}" "resources/vfs/${f}") endforeach (f) + +copy_resource_file("../launcher/images/openmw.png" "${OPENMW_RESOURCES_ROOT}" "resources/openmw.png") diff --git a/files/data/fonts/DejaVuLGCSansMono.omwfont b/files/data/fonts/DejaVuLGCSansMono.omwfont index 184c8a0d8f..8bd6f50174 100644 --- a/files/data/fonts/DejaVuLGCSansMono.omwfont +++ b/files/data/fonts/DejaVuLGCSansMono.omwfont @@ -1,7 +1,7 @@ - + diff --git a/files/data/fonts/OMWAyembedt.omwfont b/files/data/fonts/OMWAyembedt.omwfont index 9af8f655d8..25659da215 100644 --- a/files/data/fonts/OMWAyembedt.omwfont +++ b/files/data/fonts/OMWAyembedt.omwfont @@ -1,7 +1,7 @@ - + diff --git a/files/data/fonts/Pelagiad.omwfont b/files/data/fonts/Pelagiad.omwfont index 4b01a9f308..e06a233b3a 100644 --- a/files/data/fonts/Pelagiad.omwfont +++ b/files/data/fonts/Pelagiad.omwfont @@ -1,7 +1,7 @@ - + diff --git a/files/mygui/OpenMWResourcePlugin.xml b/files/data/mygui/OpenMWResourcePlugin.xml similarity index 100% rename from files/mygui/OpenMWResourcePlugin.xml rename to files/data/mygui/OpenMWResourcePlugin.xml diff --git a/files/mygui/core.skin b/files/data/mygui/core.skin similarity index 100% rename from files/mygui/core.skin rename to files/data/mygui/core.skin diff --git a/files/mygui/core.xml b/files/data/mygui/core.xml similarity index 100% rename from files/mygui/core.xml rename to files/data/mygui/core.xml diff --git a/files/mygui/core_layouteditor.xml b/files/data/mygui/core_layouteditor.xml similarity index 100% rename from files/mygui/core_layouteditor.xml rename to files/data/mygui/core_layouteditor.xml diff --git a/files/mygui/openmw_alchemy_window.layout b/files/data/mygui/openmw_alchemy_window.layout similarity index 100% rename from files/mygui/openmw_alchemy_window.layout rename to files/data/mygui/openmw_alchemy_window.layout diff --git a/files/mygui/openmw_book.layout b/files/data/mygui/openmw_book.layout similarity index 100% rename from files/mygui/openmw_book.layout rename to files/data/mygui/openmw_book.layout diff --git a/files/mygui/openmw_box.skin.xml b/files/data/mygui/openmw_box.skin.xml similarity index 100% rename from files/mygui/openmw_box.skin.xml rename to files/data/mygui/openmw_box.skin.xml diff --git a/files/mygui/openmw_button.skin.xml b/files/data/mygui/openmw_button.skin.xml similarity index 100% rename from files/mygui/openmw_button.skin.xml rename to files/data/mygui/openmw_button.skin.xml diff --git a/files/mygui/openmw_chargen_birth.layout b/files/data/mygui/openmw_chargen_birth.layout similarity index 100% rename from files/mygui/openmw_chargen_birth.layout rename to files/data/mygui/openmw_chargen_birth.layout diff --git a/files/mygui/openmw_chargen_class.layout b/files/data/mygui/openmw_chargen_class.layout similarity index 100% rename from files/mygui/openmw_chargen_class.layout rename to files/data/mygui/openmw_chargen_class.layout diff --git a/files/mygui/openmw_chargen_class_description.layout b/files/data/mygui/openmw_chargen_class_description.layout similarity index 100% rename from files/mygui/openmw_chargen_class_description.layout rename to files/data/mygui/openmw_chargen_class_description.layout diff --git a/files/mygui/openmw_chargen_create_class.layout b/files/data/mygui/openmw_chargen_create_class.layout similarity index 100% rename from files/mygui/openmw_chargen_create_class.layout rename to files/data/mygui/openmw_chargen_create_class.layout diff --git a/files/mygui/openmw_chargen_generate_class_result.layout b/files/data/mygui/openmw_chargen_generate_class_result.layout similarity index 100% rename from files/mygui/openmw_chargen_generate_class_result.layout rename to files/data/mygui/openmw_chargen_generate_class_result.layout diff --git a/files/mygui/openmw_chargen_race.layout b/files/data/mygui/openmw_chargen_race.layout similarity index 100% rename from files/mygui/openmw_chargen_race.layout rename to files/data/mygui/openmw_chargen_race.layout diff --git a/files/mygui/openmw_chargen_review.layout b/files/data/mygui/openmw_chargen_review.layout similarity index 100% rename from files/mygui/openmw_chargen_review.layout rename to files/data/mygui/openmw_chargen_review.layout diff --git a/files/mygui/openmw_chargen_select_attribute.layout b/files/data/mygui/openmw_chargen_select_attribute.layout similarity index 100% rename from files/mygui/openmw_chargen_select_attribute.layout rename to files/data/mygui/openmw_chargen_select_attribute.layout diff --git a/files/mygui/openmw_chargen_select_skill.layout b/files/data/mygui/openmw_chargen_select_skill.layout similarity index 100% rename from files/mygui/openmw_chargen_select_skill.layout rename to files/data/mygui/openmw_chargen_select_skill.layout diff --git a/files/mygui/openmw_chargen_select_specialization.layout b/files/data/mygui/openmw_chargen_select_specialization.layout similarity index 100% rename from files/mygui/openmw_chargen_select_specialization.layout rename to files/data/mygui/openmw_chargen_select_specialization.layout diff --git a/files/mygui/openmw_companion_window.layout b/files/data/mygui/openmw_companion_window.layout similarity index 100% rename from files/mygui/openmw_companion_window.layout rename to files/data/mygui/openmw_companion_window.layout diff --git a/files/mygui/openmw_confirmation_dialog.layout b/files/data/mygui/openmw_confirmation_dialog.layout similarity index 100% rename from files/mygui/openmw_confirmation_dialog.layout rename to files/data/mygui/openmw_confirmation_dialog.layout diff --git a/files/mygui/openmw_console.layout b/files/data/mygui/openmw_console.layout similarity index 100% rename from files/mygui/openmw_console.layout rename to files/data/mygui/openmw_console.layout diff --git a/files/mygui/openmw_console.skin.xml b/files/data/mygui/openmw_console.skin.xml similarity index 100% rename from files/mygui/openmw_console.skin.xml rename to files/data/mygui/openmw_console.skin.xml diff --git a/files/mygui/openmw_container_window.layout b/files/data/mygui/openmw_container_window.layout similarity index 100% rename from files/mygui/openmw_container_window.layout rename to files/data/mygui/openmw_container_window.layout diff --git a/files/mygui/openmw_count_window.layout b/files/data/mygui/openmw_count_window.layout similarity index 100% rename from files/mygui/openmw_count_window.layout rename to files/data/mygui/openmw_count_window.layout diff --git a/files/mygui/openmw_debug_window.layout b/files/data/mygui/openmw_debug_window.layout similarity index 100% rename from files/mygui/openmw_debug_window.layout rename to files/data/mygui/openmw_debug_window.layout diff --git a/files/mygui/openmw_debug_window.skin.xml b/files/data/mygui/openmw_debug_window.skin.xml similarity index 100% rename from files/mygui/openmw_debug_window.skin.xml rename to files/data/mygui/openmw_debug_window.skin.xml diff --git a/files/mygui/openmw_dialogue_window.layout b/files/data/mygui/openmw_dialogue_window.layout similarity index 100% rename from files/mygui/openmw_dialogue_window.layout rename to files/data/mygui/openmw_dialogue_window.layout diff --git a/files/mygui/openmw_dialogue_window.skin.xml b/files/data/mygui/openmw_dialogue_window.skin.xml similarity index 100% rename from files/mygui/openmw_dialogue_window.skin.xml rename to files/data/mygui/openmw_dialogue_window.skin.xml diff --git a/files/mygui/openmw_edit.skin.xml b/files/data/mygui/openmw_edit.skin.xml similarity index 100% rename from files/mygui/openmw_edit.skin.xml rename to files/data/mygui/openmw_edit.skin.xml diff --git a/files/mygui/openmw_edit_effect.layout b/files/data/mygui/openmw_edit_effect.layout similarity index 100% rename from files/mygui/openmw_edit_effect.layout rename to files/data/mygui/openmw_edit_effect.layout diff --git a/files/mygui/openmw_edit_note.layout b/files/data/mygui/openmw_edit_note.layout similarity index 100% rename from files/mygui/openmw_edit_note.layout rename to files/data/mygui/openmw_edit_note.layout diff --git a/files/mygui/openmw_enchanting_dialog.layout b/files/data/mygui/openmw_enchanting_dialog.layout similarity index 100% rename from files/mygui/openmw_enchanting_dialog.layout rename to files/data/mygui/openmw_enchanting_dialog.layout diff --git a/files/mygui/openmw_hud.layout b/files/data/mygui/openmw_hud.layout similarity index 100% rename from files/mygui/openmw_hud.layout rename to files/data/mygui/openmw_hud.layout diff --git a/files/mygui/openmw_hud_box.skin.xml b/files/data/mygui/openmw_hud_box.skin.xml similarity index 100% rename from files/mygui/openmw_hud_box.skin.xml rename to files/data/mygui/openmw_hud_box.skin.xml diff --git a/files/mygui/openmw_hud_energybar.skin.xml b/files/data/mygui/openmw_hud_energybar.skin.xml similarity index 100% rename from files/mygui/openmw_hud_energybar.skin.xml rename to files/data/mygui/openmw_hud_energybar.skin.xml diff --git a/files/mygui/openmw_infobox.layout b/files/data/mygui/openmw_infobox.layout similarity index 100% rename from files/mygui/openmw_infobox.layout rename to files/data/mygui/openmw_infobox.layout diff --git a/files/mygui/openmw_interactive_messagebox.layout b/files/data/mygui/openmw_interactive_messagebox.layout similarity index 100% rename from files/mygui/openmw_interactive_messagebox.layout rename to files/data/mygui/openmw_interactive_messagebox.layout diff --git a/files/mygui/openmw_interactive_messagebox_notransp.layout b/files/data/mygui/openmw_interactive_messagebox_notransp.layout similarity index 100% rename from files/mygui/openmw_interactive_messagebox_notransp.layout rename to files/data/mygui/openmw_interactive_messagebox_notransp.layout diff --git a/files/mygui/openmw_inventory_window.layout b/files/data/mygui/openmw_inventory_window.layout similarity index 100% rename from files/mygui/openmw_inventory_window.layout rename to files/data/mygui/openmw_inventory_window.layout diff --git a/files/mygui/openmw_itemselection_dialog.layout b/files/data/mygui/openmw_itemselection_dialog.layout similarity index 100% rename from files/mygui/openmw_itemselection_dialog.layout rename to files/data/mygui/openmw_itemselection_dialog.layout diff --git a/files/mygui/openmw_jail_screen.layout b/files/data/mygui/openmw_jail_screen.layout similarity index 100% rename from files/mygui/openmw_jail_screen.layout rename to files/data/mygui/openmw_jail_screen.layout diff --git a/files/mygui/openmw_journal.layout b/files/data/mygui/openmw_journal.layout similarity index 100% rename from files/mygui/openmw_journal.layout rename to files/data/mygui/openmw_journal.layout diff --git a/files/mygui/openmw_journal.skin.xml b/files/data/mygui/openmw_journal.skin.xml similarity index 100% rename from files/mygui/openmw_journal.skin.xml rename to files/data/mygui/openmw_journal.skin.xml diff --git a/files/mygui/openmw_layers.xml b/files/data/mygui/openmw_layers.xml similarity index 100% rename from files/mygui/openmw_layers.xml rename to files/data/mygui/openmw_layers.xml diff --git a/files/mygui/openmw_levelup_dialog.layout b/files/data/mygui/openmw_levelup_dialog.layout similarity index 100% rename from files/mygui/openmw_levelup_dialog.layout rename to files/data/mygui/openmw_levelup_dialog.layout diff --git a/files/mygui/openmw_list.skin.xml b/files/data/mygui/openmw_list.skin.xml similarity index 100% rename from files/mygui/openmw_list.skin.xml rename to files/data/mygui/openmw_list.skin.xml diff --git a/files/mygui/openmw_loading_screen.layout b/files/data/mygui/openmw_loading_screen.layout similarity index 100% rename from files/mygui/openmw_loading_screen.layout rename to files/data/mygui/openmw_loading_screen.layout diff --git a/files/mygui/openmw_lua.xml b/files/data/mygui/openmw_lua.xml similarity index 100% rename from files/mygui/openmw_lua.xml rename to files/data/mygui/openmw_lua.xml diff --git a/files/mygui/openmw_magicselection_dialog.layout b/files/data/mygui/openmw_magicselection_dialog.layout similarity index 100% rename from files/mygui/openmw_magicselection_dialog.layout rename to files/data/mygui/openmw_magicselection_dialog.layout diff --git a/files/mygui/openmw_mainmenu.layout b/files/data/mygui/openmw_mainmenu.layout similarity index 100% rename from files/mygui/openmw_mainmenu.layout rename to files/data/mygui/openmw_mainmenu.layout diff --git a/files/mygui/openmw_mainmenu.skin.xml b/files/data/mygui/openmw_mainmenu.skin.xml similarity index 100% rename from files/mygui/openmw_mainmenu.skin.xml rename to files/data/mygui/openmw_mainmenu.skin.xml diff --git a/files/mygui/openmw_map_window.layout b/files/data/mygui/openmw_map_window.layout similarity index 100% rename from files/mygui/openmw_map_window.layout rename to files/data/mygui/openmw_map_window.layout diff --git a/files/mygui/openmw_map_window.skin.xml b/files/data/mygui/openmw_map_window.skin.xml similarity index 100% rename from files/mygui/openmw_map_window.skin.xml rename to files/data/mygui/openmw_map_window.skin.xml diff --git a/files/mygui/openmw_merchantrepair.layout b/files/data/mygui/openmw_merchantrepair.layout similarity index 100% rename from files/mygui/openmw_merchantrepair.layout rename to files/data/mygui/openmw_merchantrepair.layout diff --git a/files/mygui/openmw_messagebox.layout b/files/data/mygui/openmw_messagebox.layout similarity index 100% rename from files/mygui/openmw_messagebox.layout rename to files/data/mygui/openmw_messagebox.layout diff --git a/files/mygui/openmw_persuasion_dialog.layout b/files/data/mygui/openmw_persuasion_dialog.layout similarity index 100% rename from files/mygui/openmw_persuasion_dialog.layout rename to files/data/mygui/openmw_persuasion_dialog.layout diff --git a/files/mygui/openmw_pointer.xml b/files/data/mygui/openmw_pointer.xml similarity index 100% rename from files/mygui/openmw_pointer.xml rename to files/data/mygui/openmw_pointer.xml diff --git a/files/mygui/openmw_postprocessor_hud.layout b/files/data/mygui/openmw_postprocessor_hud.layout similarity index 100% rename from files/mygui/openmw_postprocessor_hud.layout rename to files/data/mygui/openmw_postprocessor_hud.layout diff --git a/files/mygui/openmw_postprocessor_hud.skin.xml b/files/data/mygui/openmw_postprocessor_hud.skin.xml similarity index 100% rename from files/mygui/openmw_postprocessor_hud.skin.xml rename to files/data/mygui/openmw_postprocessor_hud.skin.xml diff --git a/files/mygui/openmw_progress.skin.xml b/files/data/mygui/openmw_progress.skin.xml similarity index 100% rename from files/mygui/openmw_progress.skin.xml rename to files/data/mygui/openmw_progress.skin.xml diff --git a/files/mygui/openmw_quickkeys_menu.layout b/files/data/mygui/openmw_quickkeys_menu.layout similarity index 100% rename from files/mygui/openmw_quickkeys_menu.layout rename to files/data/mygui/openmw_quickkeys_menu.layout diff --git a/files/mygui/openmw_quickkeys_menu_assign.layout b/files/data/mygui/openmw_quickkeys_menu_assign.layout similarity index 100% rename from files/mygui/openmw_quickkeys_menu_assign.layout rename to files/data/mygui/openmw_quickkeys_menu_assign.layout diff --git a/files/mygui/openmw_recharge_dialog.layout b/files/data/mygui/openmw_recharge_dialog.layout similarity index 100% rename from files/mygui/openmw_recharge_dialog.layout rename to files/data/mygui/openmw_recharge_dialog.layout diff --git a/files/mygui/openmw_repair.layout b/files/data/mygui/openmw_repair.layout similarity index 100% rename from files/mygui/openmw_repair.layout rename to files/data/mygui/openmw_repair.layout diff --git a/files/mygui/openmw_resources.xml b/files/data/mygui/openmw_resources.xml similarity index 100% rename from files/mygui/openmw_resources.xml rename to files/data/mygui/openmw_resources.xml diff --git a/files/mygui/openmw_savegame_dialog.layout b/files/data/mygui/openmw_savegame_dialog.layout similarity index 100% rename from files/mygui/openmw_savegame_dialog.layout rename to files/data/mygui/openmw_savegame_dialog.layout diff --git a/files/mygui/openmw_screen_fader.layout b/files/data/mygui/openmw_screen_fader.layout similarity index 100% rename from files/mygui/openmw_screen_fader.layout rename to files/data/mygui/openmw_screen_fader.layout diff --git a/files/mygui/openmw_screen_fader_hit.layout b/files/data/mygui/openmw_screen_fader_hit.layout similarity index 100% rename from files/mygui/openmw_screen_fader_hit.layout rename to files/data/mygui/openmw_screen_fader_hit.layout diff --git a/files/mygui/openmw_scroll.layout b/files/data/mygui/openmw_scroll.layout similarity index 100% rename from files/mygui/openmw_scroll.layout rename to files/data/mygui/openmw_scroll.layout diff --git a/files/mygui/openmw_scroll.skin.xml b/files/data/mygui/openmw_scroll.skin.xml similarity index 100% rename from files/mygui/openmw_scroll.skin.xml rename to files/data/mygui/openmw_scroll.skin.xml diff --git a/files/mygui/openmw_settings.xml b/files/data/mygui/openmw_settings.xml similarity index 100% rename from files/mygui/openmw_settings.xml rename to files/data/mygui/openmw_settings.xml diff --git a/files/mygui/openmw_settings_window.layout b/files/data/mygui/openmw_settings_window.layout similarity index 100% rename from files/mygui/openmw_settings_window.layout rename to files/data/mygui/openmw_settings_window.layout diff --git a/files/mygui/openmw_spell_buying_window.layout b/files/data/mygui/openmw_spell_buying_window.layout similarity index 100% rename from files/mygui/openmw_spell_buying_window.layout rename to files/data/mygui/openmw_spell_buying_window.layout diff --git a/files/mygui/openmw_spell_window.layout b/files/data/mygui/openmw_spell_window.layout similarity index 100% rename from files/mygui/openmw_spell_window.layout rename to files/data/mygui/openmw_spell_window.layout diff --git a/files/mygui/openmw_spellcreation_dialog.layout b/files/data/mygui/openmw_spellcreation_dialog.layout similarity index 100% rename from files/mygui/openmw_spellcreation_dialog.layout rename to files/data/mygui/openmw_spellcreation_dialog.layout diff --git a/files/mygui/openmw_stats_window.layout b/files/data/mygui/openmw_stats_window.layout similarity index 100% rename from files/mygui/openmw_stats_window.layout rename to files/data/mygui/openmw_stats_window.layout diff --git a/files/mygui/openmw_text.skin.xml b/files/data/mygui/openmw_text.skin.xml similarity index 100% rename from files/mygui/openmw_text.skin.xml rename to files/data/mygui/openmw_text.skin.xml diff --git a/files/mygui/openmw_text_input.layout b/files/data/mygui/openmw_text_input.layout similarity index 100% rename from files/mygui/openmw_text_input.layout rename to files/data/mygui/openmw_text_input.layout diff --git a/files/mygui/openmw_tooltips.layout b/files/data/mygui/openmw_tooltips.layout similarity index 100% rename from files/mygui/openmw_tooltips.layout rename to files/data/mygui/openmw_tooltips.layout diff --git a/files/mygui/openmw_trade_window.layout b/files/data/mygui/openmw_trade_window.layout similarity index 100% rename from files/mygui/openmw_trade_window.layout rename to files/data/mygui/openmw_trade_window.layout diff --git a/files/mygui/openmw_trainingwindow.layout b/files/data/mygui/openmw_trainingwindow.layout similarity index 100% rename from files/mygui/openmw_trainingwindow.layout rename to files/data/mygui/openmw_trainingwindow.layout diff --git a/files/mygui/openmw_travel_window.layout b/files/data/mygui/openmw_travel_window.layout similarity index 100% rename from files/mygui/openmw_travel_window.layout rename to files/data/mygui/openmw_travel_window.layout diff --git a/files/mygui/openmw_wait_dialog.layout b/files/data/mygui/openmw_wait_dialog.layout similarity index 100% rename from files/mygui/openmw_wait_dialog.layout rename to files/data/mygui/openmw_wait_dialog.layout diff --git a/files/mygui/openmw_wait_dialog_progressbar.layout b/files/data/mygui/openmw_wait_dialog_progressbar.layout similarity index 100% rename from files/mygui/openmw_wait_dialog_progressbar.layout rename to files/data/mygui/openmw_wait_dialog_progressbar.layout diff --git a/files/mygui/openmw_windows.skin.xml b/files/data/mygui/openmw_windows.skin.xml similarity index 100% rename from files/mygui/openmw_windows.skin.xml rename to files/data/mygui/openmw_windows.skin.xml diff --git a/files/mygui/skins.xml b/files/data/mygui/skins.xml similarity index 100% rename from files/mygui/skins.xml rename to files/data/mygui/skins.xml diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt deleted file mode 100644 index 4716a7712b..0000000000 --- a/files/mygui/CMakeLists.txt +++ /dev/null @@ -1,101 +0,0 @@ -if (NOT DEFINED OPENMW_RESOURCES_ROOT) - return() -endif() - -# Copy resource files into the build directory -set(SDIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(DDIRRELATIVE resources/mygui) - -set(MYGUI_FILES - core.skin - core.xml - core_layouteditor.xml - openmw_alchemy_window.layout - openmw_book.layout - openmw_box.skin.xml - openmw_button.skin.xml - openmw_chargen_birth.layout - openmw_chargen_class_description.layout - openmw_chargen_class.layout - openmw_chargen_create_class.layout - openmw_chargen_generate_class_result.layout - openmw_chargen_race.layout - openmw_chargen_review.layout - openmw_chargen_select_attribute.layout - openmw_chargen_select_skill.layout - openmw_chargen_select_specialization.layout - openmw_confirmation_dialog.layout - openmw_console.layout - openmw_console.skin.xml - openmw_container_window.layout - openmw_count_window.layout - openmw_dialogue_window.layout - openmw_dialogue_window.skin.xml - openmw_edit.skin.xml - openmw_hud_box.skin.xml - openmw_hud_energybar.skin.xml - openmw_hud.layout - openmw_infobox.layout - openmw_interactive_messagebox.layout - openmw_interactive_messagebox_notransp.layout - openmw_inventory_window.layout - openmw_journal.layout - openmw_journal.skin.xml - openmw_layers.xml - openmw_lua.xml - openmw_list.skin.xml - openmw_mainmenu.layout - openmw_mainmenu.skin.xml - openmw_map_window.layout - openmw_map_window.skin.xml - openmw_messagebox.layout - openmw_pointer.xml - openmw_progress.skin.xml - openmw_resources.xml - openmw_scroll.layout - openmw_scroll.skin.xml - openmw_settings_window.layout - openmw_settings.xml - openmw_spell_window.layout - openmw_stats_window.layout - openmw_text_input.layout - openmw_text.skin.xml - openmw_tooltips.layout - openmw_trade_window.layout - openmw_spell_buying_window.layout - openmw_windows.skin.xml - openmw_quickkeys_menu.layout - openmw_quickkeys_menu_assign.layout - openmw_itemselection_dialog.layout - openmw_magicselection_dialog.layout - openmw_spell_buying_window.layout - openmw_loading_screen.layout - openmw_levelup_dialog.layout - openmw_wait_dialog.layout - openmw_wait_dialog_progressbar.layout - openmw_spellcreation_dialog.layout - openmw_edit_effect.layout - openmw_enchanting_dialog.layout - openmw_trainingwindow.layout - openmw_travel_window.layout - openmw_persuasion_dialog.layout - openmw_merchantrepair.layout - openmw_repair.layout - openmw_companion_window.layout - openmw_savegame_dialog.layout - openmw_recharge_dialog.layout - openmw_screen_fader.layout - openmw_screen_fader_hit.layout - openmw_edit_note.layout - openmw_debug_window.layout - openmw_debug_window.skin.xml - openmw_postprocessor_hud.layout - openmw_postprocessor_hud.skin.xml - openmw_jail_screen.layout - ../launcher/images/openmw.png - OpenMWResourcePlugin.xml - skins.xml -) - - -copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_RESOURCES_ROOT} ${DDIRRELATIVE} "${MYGUI_FILES}") diff --git a/files/mygui/DejaVuFontLicense.txt b/files/mygui/DejaVuFontLicense.txt deleted file mode 100644 index 254e2cc42a..0000000000 --- a/files/mygui/DejaVuFontLicense.txt +++ /dev/null @@ -1,99 +0,0 @@ -Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. -Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) - -Bitstream Vera Fonts Copyright ------------------------------- - -Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is -a trademark of Bitstream, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of the fonts accompanying this license ("Fonts") and associated -documentation files (the "Font Software"), to reproduce and distribute the -Font Software, including without limitation the rights to use, copy, merge, -publish, distribute, and/or sell copies of the Font Software, and to permit -persons to whom the Font Software is furnished to do so, subject to the -following conditions: - -The above copyright and trademark notices and this permission notice shall -be included in all copies of one or more of the Font Software typefaces. - -The Font Software may be modified, altered, or added to, and in particular -the designs of glyphs or characters in the Fonts may be modified and -additional glyphs or characters may be added to the Fonts, only if the fonts -are renamed to names not containing either the words "Bitstream" or the word -"Vera". - -This License becomes null and void to the extent applicable to Fonts or Font -Software that has been modified and is distributed under the "Bitstream -Vera" names. - -The Font Software may be sold as part of a larger software package but no -copy of one or more of the Font Software typefaces may be sold by itself. - -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, -TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME -FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING -ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE -FONT SOFTWARE. - -Except as contained in this notice, the names of Gnome, the Gnome -Foundation, and Bitstream Inc., shall not be used in advertising or -otherwise to promote the sale, use or other dealings in this Font Software -without prior written authorization from the Gnome Foundation or Bitstream -Inc., respectively. For further information, contact: fonts at gnome dot -org. - -Arev Fonts Copyright ------------------------------- - -Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of the fonts accompanying this license ("Fonts") and -associated documentation files (the "Font Software"), to reproduce -and distribute the modifications to the Bitstream Vera Font Software, -including without limitation the rights to use, copy, merge, publish, -distribute, and/or sell copies of the Font Software, and to permit -persons to whom the Font Software is furnished to do so, subject to -the following conditions: - -The above copyright and trademark notices and this permission notice -shall be included in all copies of one or more of the Font Software -typefaces. - -The Font Software may be modified, altered, or added to, and in -particular the designs of glyphs or characters in the Fonts may be -modified and additional glyphs or characters may be added to the -Fonts, only if the fonts are renamed to names not containing either -the words "Tavmjong Bah" or the word "Arev". - -This License becomes null and void to the extent applicable to Fonts -or Font Software that has been modified and is distributed under the -"Tavmjong Bah Arev" names. - -The Font Software may be sold as part of a larger software package but -no copy of one or more of the Font Software typefaces may be sold by -itself. - -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL -TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. - -Except as contained in this notice, the name of Tavmjong Bah shall not -be used in advertising or otherwise to promote the sale, use or other -dealings in this Font Software without prior written authorization -from Tavmjong Bah. For further information, contact: tavmjong @ free -. fr. - -$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $ From 8fc3635c2c6924caaa0e32adfa6c8615df883e02 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 9 Jul 2022 22:09:37 +0400 Subject: [PATCH 05/17] Use case-insensitive font keys, remove debug code --- components/fontloader/fontloader.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index 7d90002d95..35d0e8d4fa 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -219,7 +219,6 @@ namespace Gui for (const auto& name : mVFS->getRecursiveDirectoryIterator("Fonts/")) { std::filesystem::path path = name; - std::cout << name << std::endl; if (Misc::getFileExtension(name) == "omwfont") MyGUI::ResourceManager::getInstance().load(path.filename()); } @@ -625,11 +624,13 @@ namespace Gui std::string FontLoader::getInternalFontName(const std::string& name) { - if (name == Settings::Manager::getString("default font", "GUI")) + const std::string lowerName = Misc::StringUtils::lowerCase(name); + + if (lowerName == Misc::StringUtils::lowerCase(Settings::Manager::getString("default font", "GUI"))) return "DefaultFont"; - if (name == Settings::Manager::getString("scroll font", "GUI")) + if (lowerName == Misc::StringUtils::lowerCase(Settings::Manager::getString("scroll font", "GUI"))) return "ScrollFont"; - if (name == Settings::Manager::getString("mono font", "GUI")) + if (lowerName == Misc::StringUtils::lowerCase(Settings::Manager::getString("mono font", "GUI"))) return "MonoFont"; return name; From 8513bc96203a5c2ababd79a162289a4b530e1cbb Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 9 Jul 2022 22:53:34 +0400 Subject: [PATCH 06/17] Fix build error on MSVC --- components/fontloader/fontloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index 35d0e8d4fa..40cf965f43 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -220,7 +220,7 @@ namespace Gui { std::filesystem::path path = name; if (Misc::getFileExtension(name) == "omwfont") - MyGUI::ResourceManager::getInstance().load(path.filename()); + MyGUI::ResourceManager::getInstance().load(path.filename().string()); } dataManager->setResourcePath(oldDataPath); From db686b25c29c246bfdabb1225f64627e26311b29 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 12 Jul 2022 17:27:59 +0400 Subject: [PATCH 07/17] Use fallback data from openmw.cfg to setup fonts --- components/fontloader/fontloader.cpp | 10 ++++++---- files/openmw.cfg | 6 +++--- files/openmw.cfg.local | 6 +++--- files/settings-default.cfg | 9 --------- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index 40cf965f43..ffd9d82555 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -17,6 +17,8 @@ #include +#include + #include #include @@ -626,12 +628,12 @@ namespace Gui { const std::string lowerName = Misc::StringUtils::lowerCase(name); - if (lowerName == Misc::StringUtils::lowerCase(Settings::Manager::getString("default font", "GUI"))) + if (lowerName == Misc::StringUtils::lowerCase(Fallback::Map::getString("Fonts_Font_0"))) return "DefaultFont"; - if (lowerName == Misc::StringUtils::lowerCase(Settings::Manager::getString("scroll font", "GUI"))) - return "ScrollFont"; - if (lowerName == Misc::StringUtils::lowerCase(Settings::Manager::getString("mono font", "GUI"))) + if (lowerName == Misc::StringUtils::lowerCase(Fallback::Map::getString("Fonts_Font_1"))) return "MonoFont"; + if (lowerName == Misc::StringUtils::lowerCase(Fallback::Map::getString("Fonts_Font_2"))) + return "ScrollFont"; return name; } diff --git a/files/openmw.cfg b/files/openmw.cfg index b56f2bbca1..00c1435212 100644 --- a/files/openmw.cfg +++ b/files/openmw.cfg @@ -71,9 +71,9 @@ fallback=Water_UnderwaterColor,012,030,037 fallback=Water_UnderwaterColorWeight,0.85 # fonts -fallback=Fonts_Font_0,magic_cards_regular -fallback=Fonts_Font_1,century_gothic_font_regular -fallback=Fonts_Font_2,daedric_font +fallback=Fonts_Font_0,pelagiad +fallback=Fonts_Font_1,dejavusansmono +fallback=Fonts_Font_2,ayembedt fallback=FontColor_color_normal,202,165,96 fallback=FontColor_color_normal_over,223,201,159 fallback=FontColor_color_normal_pressed,243,237,221 diff --git a/files/openmw.cfg.local b/files/openmw.cfg.local index 94f17d8aec..44525dc486 100644 --- a/files/openmw.cfg.local +++ b/files/openmw.cfg.local @@ -71,9 +71,9 @@ fallback=Water_UnderwaterColor,012,030,037 fallback=Water_UnderwaterColorWeight,0.85 # fonts -fallback=Fonts_Font_0,magic_cards_regular -fallback=Fonts_Font_1,century_gothic_font_regular -fallback=Fonts_Font_2,daedric_font +fallback=Fonts_Font_0,pelagiad +fallback=Fonts_Font_1,dejavusansmono +fallback=Fonts_Font_2,ayembedt fallback=FontColor_color_normal,202,165,96 fallback=FontColor_color_normal_over,223,201,159 fallback=FontColor_color_normal_pressed,243,237,221 diff --git a/files/settings-default.cfg b/files/settings-default.cfg index d42c093f0a..2675004907 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -234,15 +234,6 @@ color topic specific = 0.45 0.5 0.8 1 # Default to grey color topic exhausted = 0.3 0.3 0.3 1 -# Font used by UI and books -default font = pelagiad - -# Font used by magic scrolls -scroll font = ayembedt - -# Font used by console and debug log -mono font = dejavusansmono - [HUD] # Displays the crosshair or reticle when not in GUI mode. From 6f6b5ba04b8d814b84d853999830e381ab723e35 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 17 Jul 2022 17:54:06 +0400 Subject: [PATCH 08/17] Some refactoring --- components/fontloader/fontloader.cpp | 16 ++++++-------- components/misc/pathhelpers.hpp | 22 +++++++++++++++++++ components/myguiplatform/myguidatamanager.cpp | 9 ++++---- components/resource/stats.cpp | 2 +- files/CMakeLists.txt | 2 ++ files/data/CMakeLists.txt | 2 -- 6 files changed, 36 insertions(+), 17 deletions(-) diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index ffd9d82555..200309e091 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -1,6 +1,5 @@ #include "fontloader.hpp" -#include #include #include #include @@ -199,10 +198,10 @@ namespace Gui void FontLoader::loadBitmapFonts(bool exportToFile) { - for (const auto& name : mVFS->getRecursiveDirectoryIterator("Fonts/")) + for (const auto& path : mVFS->getRecursiveDirectoryIterator("Fonts/")) { - if (Misc::getFileExtension(name) == "fnt") - loadBitmapFont(name, exportToFile); + if (Misc::getFileExtension(path) == "fnt") + loadBitmapFont(path, exportToFile); } } @@ -218,11 +217,10 @@ namespace Gui std::string oldDataPath = dataManager->getDataPath(""); dataManager->setResourcePath("fonts"); - for (const auto& name : mVFS->getRecursiveDirectoryIterator("Fonts/")) + for (const auto& path : mVFS->getRecursiveDirectoryIterator("Fonts/")) { - std::filesystem::path path = name; - if (Misc::getFileExtension(name) == "omwfont") - MyGUI::ResourceManager::getInstance().load(path.filename().string()); + if (Misc::getFileExtension(path) == "omwfont") + MyGUI::ResourceManager::getInstance().load(std::string(Misc::getFileName(path))); } dataManager->setResourcePath(oldDataPath); @@ -344,7 +342,7 @@ namespace Gui MyGUI::xml::Document xmlDocument; MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont"); - const std::string baseName = Misc::StringUtils::lowerCase(std::filesystem::path(mVFS->getAbsoluteFileName(fileName)).stem().string()); + std::string baseName(Misc::stemFile(fileName)); root->addAttribute("name", getInternalFontName(baseName)); MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property"); diff --git a/components/misc/pathhelpers.hpp b/components/misc/pathhelpers.hpp index 88913a1f7b..ee6ba8e0d5 100644 --- a/components/misc/pathhelpers.hpp +++ b/components/misc/pathhelpers.hpp @@ -14,6 +14,28 @@ namespace Misc } return {}; } + + inline std::string_view getFileName(std::string_view path) + { + if (auto namePos = path.find_last_of("/\\"); namePos != std::string::npos) + { + path.remove_prefix(namePos + 1); + } + + return path; + } + + inline std::string_view stemFile(std::string_view path) + { + path = getFileName(path); + + if (auto extPos = path.find_last_of("."); extPos != std::string::npos) + { + path.remove_suffix(path.size() - extPos); + } + + return path; + } } #endif diff --git a/components/myguiplatform/myguidatamanager.cpp b/components/myguiplatform/myguidatamanager.cpp index 1eefa6b81d..87e20dbe85 100644 --- a/components/myguiplatform/myguidatamanager.cpp +++ b/components/myguiplatform/myguidatamanager.cpp @@ -22,10 +22,9 @@ MyGUI::IDataStream *DataManager::getData(const std::string &name) const { // Note: MyGUI is supposed to read/free input steam itself, // so copy data from VFS stream to the string stream and pass it to MyGUI. - Files::IStreamPtr streamPtr = mVfs->get(mResourcePath + "\\" + name); + Files::IStreamPtr streamPtr = mVfs->get(mResourcePath + "/" + name); std::istream* fileStream = streamPtr.get(); - std::unique_ptr dataStream; - dataStream.reset(new std::stringstream); + auto dataStream = std::make_unique(); *dataStream << fileStream->rdbuf(); return new MyGUI::DataStream(dataStream.release()); } @@ -37,7 +36,7 @@ void DataManager::freeData(MyGUI::IDataStream *data) bool DataManager::isDataExist(const std::string &name) const { - return mVfs->exists(mResourcePath + "\\" + name); + return mVfs->exists(mResourcePath + "/" + name); } void DataManager::setVfs(const VFS::Manager* vfs) @@ -61,7 +60,7 @@ const std::string &DataManager::getDataPath(const std::string &name) const if (!isDataExist(name)) return result; - result = mResourcePath + "\\" + name; + result = mResourcePath + "/" + name; return result; } diff --git a/components/resource/stats.cpp b/components/resource/stats.cpp index d578259033..84588d4ab9 100644 --- a/components/resource/stats.cpp +++ b/components/resource/stats.cpp @@ -30,7 +30,7 @@ static bool collectStatFrameRate = false; static bool collectStatUpdate = false; static bool collectStatEngine = false; -inline static std::string sFontName = "Fonts\\DejaVuLGCSansMono.ttf"; +static std::string sFontName = "Fonts/DejaVuLGCSansMono.ttf"; static void setupStatCollection() { diff --git a/files/CMakeLists.txt b/files/CMakeLists.txt index b7b4b4cd23..587c3fa1d3 100644 --- a/files/CMakeLists.txt +++ b/files/CMakeLists.txt @@ -1,3 +1,5 @@ add_subdirectory(shaders) add_subdirectory(data) add_subdirectory(lua_api) + +copy_resource_file("launcher/images/openmw.png" "${OPENMW_RESOURCES_ROOT}" "resources/openmw.png") diff --git a/files/data/CMakeLists.txt b/files/data/CMakeLists.txt index 63df2f53b5..1130524e45 100644 --- a/files/data/CMakeLists.txt +++ b/files/data/CMakeLists.txt @@ -162,5 +162,3 @@ set(BUILTIN_DATA_FILES foreach (f ${BUILTIN_DATA_FILES}) copy_resource_file("${CMAKE_CURRENT_SOURCE_DIR}/${f}" "${OPENMW_RESOURCES_ROOT}" "resources/vfs/${f}") endforeach (f) - -copy_resource_file("../launcher/images/openmw.png" "${OPENMW_RESOURCES_ROOT}" "resources/openmw.png") From 59c4ea014d1c8ce7c69ffffdf7e3466d30767e02 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 17 Jul 2022 18:16:18 +0400 Subject: [PATCH 09/17] Rework StatsHandler to support VFS --- components/resource/stats.cpp | 21 ++++++++++++--------- components/resource/stats.hpp | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/components/resource/stats.cpp b/components/resource/stats.cpp index 84588d4ab9..ba39b638b5 100644 --- a/components/resource/stats.cpp +++ b/components/resource/stats.cpp @@ -6,6 +6,7 @@ #include +#include #include #include @@ -90,8 +91,8 @@ StatsHandler::StatsHandler(bool offlineCollect, VFS::Manager* vfs): _offlineCollect(offlineCollect), _statsWidth(1280.0f), _statsHeight(1024.0f), - _font(""), - _characterSize(18.0f) + _characterSize(18.0f), + _VFS(vfs) { _camera = new osg::Camera; _camera->getOrCreateStateSet()->setGlobalDefaults(); @@ -99,11 +100,6 @@ StatsHandler::StatsHandler(bool offlineCollect, VFS::Manager* vfs): _camera->setProjectionResizePolicy(osg::Camera::FIXED); _resourceStatsChildNum = 0; - - if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs->exists(sFontName)) - { - _font = vfs->getAbsoluteFileName(sFontName); - } } Profiler::Profiler(bool offlineCollect, VFS::Manager* vfs): @@ -431,7 +427,6 @@ void StatsHandler::setUpScene(osgViewer::ViewerBase *viewer) osg::ref_ptr staticText = new osgText::Text; group->addChild( staticText.get() ); staticText->setColor(staticTextColor); - staticText->setFont(_font); staticText->setCharacterSize(_characterSize); staticText->setPosition(pos); @@ -457,11 +452,19 @@ void StatsHandler::setUpScene(osgViewer::ViewerBase *viewer) group->addChild( statsText.get() ); statsText->setColor(dynamicTextColor); - statsText->setFont(_font); statsText->setCharacterSize(_characterSize); statsText->setPosition(pos); statsText->setText(""); statsText->setDrawCallback(new ResourceStatsTextDrawCallback(viewer->getViewerStats(), statNames)); + + if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && _VFS->exists(sFontName)) + { + Files::IStreamPtr streamPtr = _VFS->get(sFontName); + osg::ref_ptr font = osgText::readRefFontStream(*streamPtr.get()); + + staticText->setFont(font); + statsText->setFont(font); + } } } diff --git a/components/resource/stats.hpp b/components/resource/stats.hpp index b61280ceb1..bb6cf09eda 100644 --- a/components/resource/stats.hpp +++ b/components/resource/stats.hpp @@ -61,11 +61,11 @@ namespace Resource float _statsWidth; float _statsHeight; - std::string _font; float _characterSize; int _resourceStatsChildNum; + VFS::Manager* _VFS; }; void CollectStatistics(osgViewer::ViewerBase* viewer); From d83382d2367eb3f7e5569f003f37ae2520d12383 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 17 Jul 2022 20:53:38 +0400 Subject: [PATCH 10/17] Rework Profiler to work with VFS --- components/resource/stats.cpp | 64 +++++++++++++++++++++++++++-------- components/resource/stats.hpp | 11 +++++- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/components/resource/stats.cpp b/components/resource/stats.cpp index ba39b638b5..690e41bbaf 100644 --- a/components/resource/stats.cpp +++ b/components/resource/stats.cpp @@ -84,6 +84,26 @@ static void setupStatCollection() } } +class SetFontVisitor : public osg::NodeVisitor +{ +public: + SetFontVisitor(osgText::Font* font) + : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + , mFont(font) + {} + + void apply(osg::Drawable& node) override + { + if (osgText::Text* text = dynamic_cast(&node)) + { + text->setFont(mFont); + } + } + +private: + osgText::Font* mFont; +}; + StatsHandler::StatsHandler(bool offlineCollect, VFS::Manager* vfs): _key(osgGA::GUIEventAdapter::KEY_F4), _initialized(false), @@ -91,8 +111,7 @@ StatsHandler::StatsHandler(bool offlineCollect, VFS::Manager* vfs): _offlineCollect(offlineCollect), _statsWidth(1280.0f), _statsHeight(1024.0f), - _characterSize(18.0f), - _VFS(vfs) + _characterSize(18.0f) { _camera = new osg::Camera; _camera->getOrCreateStateSet()->setGlobalDefaults(); @@ -100,29 +119,49 @@ StatsHandler::StatsHandler(bool offlineCollect, VFS::Manager* vfs): _camera->setProjectionResizePolicy(osg::Camera::FIXED); _resourceStatsChildNum = 0; + + if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs->exists(sFontName)) + { + Files::IStreamPtr streamPtr = vfs->get(sFontName); + _textFont = osgText::readRefFontStream(*streamPtr.get()); + } } Profiler::Profiler(bool offlineCollect, VFS::Manager* vfs): - _offlineCollect(offlineCollect) + _offlineCollect(offlineCollect), + _initFonts(false) { + _characterSize = 18; + _font.clear(); + if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs->exists(sFontName)) { - _font = vfs->getAbsoluteFileName(sFontName); + Files::IStreamPtr streamPtr = vfs->get(sFontName); + _textFont = osgText::readRefFontStream(*streamPtr.get()); } - else - _font.clear(); - - _characterSize = 18; setKeyEventTogglesOnScreenStats(osgGA::GUIEventAdapter::KEY_F3); setupStatCollection(); } +void Profiler::setUpFonts() +{ + if (_textFont != nullptr) + { + SetFontVisitor visitor(_textFont); + _switch->accept(visitor); + } + + _initFonts = true; +} + bool Profiler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa) { osgViewer::ViewerBase* viewer = nullptr; bool handled = StatsHandler::handle(ea, aa); + if (_initialized && !_initFonts) + setUpFonts(); auto* view = dynamic_cast(&aa); if (view) @@ -457,13 +496,10 @@ void StatsHandler::setUpScene(osgViewer::ViewerBase *viewer) statsText->setText(""); statsText->setDrawCallback(new ResourceStatsTextDrawCallback(viewer->getViewerStats(), statNames)); - if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && _VFS->exists(sFontName)) + if (_textFont) { - Files::IStreamPtr streamPtr = _VFS->get(sFontName); - osg::ref_ptr font = osgText::readRefFontStream(*streamPtr.get()); - - staticText->setFont(font); - statsText->setFont(font); + staticText->setFont(_textFont); + statsText->setFont(_textFont); } } } diff --git a/components/resource/stats.hpp b/components/resource/stats.hpp index bb6cf09eda..e51474c6cb 100644 --- a/components/resource/stats.hpp +++ b/components/resource/stats.hpp @@ -13,6 +13,11 @@ namespace osg class Switch; } +namespace osgText +{ + class Font; +} + namespace VFS { class Manager; @@ -27,7 +32,11 @@ namespace Resource bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override; private: + void setUpFonts(); + bool _offlineCollect; + bool _initFonts; + osg::ref_ptr _textFont; }; class StatsHandler : public osgGA::GUIEventHandler @@ -65,7 +74,7 @@ namespace Resource int _resourceStatsChildNum; - VFS::Manager* _VFS; + osg::ref_ptr _textFont; }; void CollectStatistics(osgViewer::ViewerBase* viewer); From facdc8fc0d49efdf774f45caa080f466df21df0f Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 17 Jul 2022 22:13:27 +0400 Subject: [PATCH 11/17] Use string_view --- components/resource/stats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/resource/stats.cpp b/components/resource/stats.cpp index 690e41bbaf..863429d600 100644 --- a/components/resource/stats.cpp +++ b/components/resource/stats.cpp @@ -31,7 +31,7 @@ static bool collectStatFrameRate = false; static bool collectStatUpdate = false; static bool collectStatEngine = false; -static std::string sFontName = "Fonts/DejaVuLGCSansMono.ttf"; +constexpr std::string_view sFontName = "Fonts/DejaVuLGCSansMono.ttf"; static void setupStatCollection() { From dc0d6fe31d48e5d51c13ded97260a9f9c447ac2a Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 17 Jul 2022 23:59:35 +0400 Subject: [PATCH 12/17] Avoid code duplication --- components/resource/stats.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/components/resource/stats.cpp b/components/resource/stats.cpp index 863429d600..a204bf61f8 100644 --- a/components/resource/stats.cpp +++ b/components/resource/stats.cpp @@ -104,6 +104,17 @@ private: osgText::Font* mFont; }; +osg::ref_ptr getMonoFont(VFS::Manager* vfs) +{ + if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs->exists(sFontName)) + { + Files::IStreamPtr streamPtr = vfs->get(sFontName); + return osgText::readRefFontStream(*streamPtr.get()); + } + + return nullptr; +} + StatsHandler::StatsHandler(bool offlineCollect, VFS::Manager* vfs): _key(osgGA::GUIEventAdapter::KEY_F4), _initialized(false), @@ -120,11 +131,7 @@ StatsHandler::StatsHandler(bool offlineCollect, VFS::Manager* vfs): _resourceStatsChildNum = 0; - if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs->exists(sFontName)) - { - Files::IStreamPtr streamPtr = vfs->get(sFontName); - _textFont = osgText::readRefFontStream(*streamPtr.get()); - } + _textFont = getMonoFont(vfs); } Profiler::Profiler(bool offlineCollect, VFS::Manager* vfs): @@ -134,11 +141,7 @@ Profiler::Profiler(bool offlineCollect, VFS::Manager* vfs): _characterSize = 18; _font.clear(); - if (osgDB::Registry::instance()->getReaderWriterForExtension("ttf") && vfs->exists(sFontName)) - { - Files::IStreamPtr streamPtr = vfs->get(sFontName); - _textFont = osgText::readRefFontStream(*streamPtr.get()); - } + _textFont = getMonoFont(vfs); setKeyEventTogglesOnScreenStats(osgGA::GUIEventAdapter::KEY_F3); setupStatCollection(); From 1f864e31277bd4aecc000ad11388518efcc29478 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 18 Jul 2022 00:04:43 +0400 Subject: [PATCH 13/17] Do not override monospace font --- components/fontloader/fontloader.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index 200309e091..00c029216f 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -628,8 +628,8 @@ namespace Gui if (lowerName == Misc::StringUtils::lowerCase(Fallback::Map::getString("Fonts_Font_0"))) return "DefaultFont"; - if (lowerName == Misc::StringUtils::lowerCase(Fallback::Map::getString("Fonts_Font_1"))) - return "MonoFont"; + if (lowerName == "dejavusansmono") + return "MonoFont"; // We need to use a TrueType monospace font to display debug texts properly. if (lowerName == Misc::StringUtils::lowerCase(Fallback::Map::getString("Fonts_Font_2"))) return "ScrollFont"; @@ -644,8 +644,6 @@ namespace Gui return "DefaultFont"; if (lowerFace == "daedric") return "ScrollFont"; - if (lowerFace == "century gothic") - return "MonoFont"; return face; } From 5bc5c1bb0c8100422251e7596c58388c61a3f28b Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 18 Jul 2022 09:57:20 +0400 Subject: [PATCH 14/17] Use our fonts as a fallback --- apps/openmw/mwgui/windowmanagerimp.cpp | 9 ++------- apps/openmw/mwgui/windowmanagerimp.hpp | 1 - components/fontloader/fontloader.cpp | 8 +++++++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 623c46fedc..5c780d764e 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -234,7 +234,7 @@ namespace MWGui MyGUI::FactoryManager::getInstance().registerFactory("Resource", "ResourceImageSetPointer"); MyGUI::FactoryManager::getInstance().registerFactory("Resource", "AutoSizedResourceSkin"); MyGUI::ResourceManager::getInstance().load("core.xml"); - WindowManager::loadUserFonts(); + mFontLoader->loadTrueTypeFonts(); bool keyboardNav = Settings::Manager::getBool("keyboard navigation", "GUI"); mKeyboardNavigation = std::make_unique(); @@ -290,11 +290,6 @@ namespace MWGui mStatsWatcher = std::make_unique(); } - void WindowManager::loadUserFonts() - { - mFontLoader->loadTrueTypeFonts(); - } - void WindowManager::initUI() { // Get size info from the Gui object @@ -1179,7 +1174,7 @@ namespace MWGui window->onResChange(x, y); // We should reload TrueType fonts to fit new resolution - loadUserFonts(); + mFontLoader->loadTrueTypeFonts(); // TODO: check if any windows are now off-screen and move them back if so } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index a48847de3f..090a2b52f9 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -143,7 +143,6 @@ namespace MWGui void setStore (const MWWorld::ESMStore& store); void initUI(); - void loadUserFonts(); Loading::Listener* getLoadingScreen() override; diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index 00c029216f..b906554cc5 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -628,9 +628,15 @@ namespace Gui if (lowerName == Misc::StringUtils::lowerCase(Fallback::Map::getString("Fonts_Font_0"))) return "DefaultFont"; + if (lowerName == Misc::StringUtils::lowerCase(Fallback::Map::getString("Fonts_Font_2"))) + return "ScrollFont"; if (lowerName == "dejavusansmono") return "MonoFont"; // We need to use a TrueType monospace font to display debug texts properly. - if (lowerName == Misc::StringUtils::lowerCase(Fallback::Map::getString("Fonts_Font_2"))) + + // Use our TrueType fonts as a fallback. + if (!MyGUI::ResourceManager::getInstance().isExist("DefaultFont") && name == "pelagiad") + return "DefaultFont"; + if (!MyGUI::ResourceManager::getInstance().isExist("ScrollFont") && name == "ayembedt") return "ScrollFont"; return name; From b60d14d43438b3a270921a82fa8508d6f7046fee Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 18 Jul 2022 10:38:55 +0400 Subject: [PATCH 15/17] Updated documentation --- docs/source/reference/modding/font.rst | 48 +++++++++++++++----------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/docs/source/reference/modding/font.rst b/docs/source/reference/modding/font.rst index 3778ac5ed2..d43f37340c 100644 --- a/docs/source/reference/modding/font.rst +++ b/docs/source/reference/modding/font.rst @@ -1,30 +1,44 @@ Fonts ##### +Default UI font and font used in magic scrolls are defined in ``openmw.cfg``: + + fallback=Fonts_Font_0,pelagiad + fallback=Fonts_Font_2,ayembedt + +By default, built-in TrueType fonts are used. Font used by console and another debug windows is not configurable (so ``Fonts_Font_1`` is unused). + Morrowind .fnt fonts -------------------- Morrowind uses a custom ``.fnt`` file format. It is not compatible with the Windows Font File ``.fnt`` format. -To our knowledge, the format is undocumented. +To our knowledge, the format is undocumented. OpenMW can load this format and convert it on the fly into something usable +(see font loader `source code `_). -OpenMW can load this format and convert it on the fly into something usable -(see font loader `source code `_). -You can use --export-fonts command line option to write the converted font -(a PNG image and an XML file describing the position of each glyph in the image) to the current directory. +They can be used instead of TrueType fonts if needed by specifying their ``.fnt`` files names in the ``openmw.cfg``. For example: + + fallback=Fonts_Font_0,magic_cards_regular + fallback=Fonts_Font_2,daedric_font + +In this example OpenMW will search for ``magic_cards_regular.fnt`` and ``daedric_font.fnt`` in the ``Fonts`` folder in data directories. +If they are not found, built-in TrueType fonts will be used as a fallback. +Note that an import wizard copies values from ``Morrowind.ini``, so bitmap fonts will be used after import. +If such behaviour is undesirable, ``Fonts_Font*`` entries should be removed from ``openmw.cfg``. TrueType fonts -------------- -Unlike vanilla Morrowind, OpenMW directly supports TrueType (``.ttf``) fonts. +Unlike vanilla Morrowind, OpenMW directly supports TrueType (``.ttf``) fonts. This is the recommended fonts format. +OpenMW has build-in TrueType fonts: Pelagiad, OMWAyembedt and DejaVuLGCSansMono, which are used by default. +TrueType fonts are configured via ``openmw.cfg`` too: -This is the recommended way to install replacement fonts. + fallback=Fonts_Font_0,pelagiad + fallback=Fonts_Font_2,ayembedt - 1. Download `TrueType fonts for OpenMW `_ - 2. Place the ``Fonts`` folder from archive to the configuration folder. Use :doc:`paths` article to find the folder. +In this example, OpenMW will scan ``Fonts`` folder in data directories for ``.omwfont`` files. +These files are XML files wich schema used by MyGUI. OpenMW uses files which ``name`` tag matches ``openmw.cfg`` entries: -Now Fonts folder should include ``openmw_font.xml`` file and three ``.ttf`` files. - -If desired, you can now delete the ``Data Files/Fonts`` directory. + It is also possible to adjust the font size and resolution via ``settings.cfg`` file:: @@ -34,14 +48,6 @@ It is also possible to adjust the font size and resolution via ``settings.cfg`` The ``font size`` setting accepts clamped values in range from 12 to 20 while ``ttf resolution`` setting accepts values from 48 to 960. -Any Resolution or Size properties in the XML file have no effect because the engine settings override them. +Any Resolution or Size properties in the ``.omwfont`` file have no effect because the engine settings override them. The engine automatically takes UI scaling factor into account, so don't account for it when tweaking the settings. - -Bitmap fonts ------------- - -Morrowind ``.fnt`` files are essentially a bitmap font, but using them is discouraged because they don't have Unicode support. -MyGUI has its own format for bitmap fonts. An example can be seen by using the --export-fonts command line option (see above), -which converts Morrowind ``.fnt`` to a MyGUI bitmap font. -This is the recommended format to use if you wish to edit Morrowind's bitmap font or create a new bitmap font. From 845a812ebf34d97756f74f15656ac767b04b0c8a Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 18 Jul 2022 10:40:03 +0400 Subject: [PATCH 16/17] Drop fonts export - users are supposed to use TrueType fonts or mods with legacy format --- apps/openmw/engine.cpp | 8 +------- apps/openmw/engine.hpp | 3 --- apps/openmw/main.cpp | 1 - apps/openmw/mwgui/windowmanagerimp.cpp | 4 ++-- apps/openmw/mwgui/windowmanagerimp.hpp | 2 +- components/fontloader/fontloader.cpp | 24 +++--------------------- components/fontloader/fontloader.hpp | 6 ++---- 7 files changed, 9 insertions(+), 39 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 467d61bf12..c3ace78ac8 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -453,7 +453,6 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) , mScriptConsoleMode (false) , mActivationDistanceOverride(-1) , mGrab(true) - , mExportFonts(false) , mRandomSeed(0) , mFSStrict (false) , mScriptBlacklistUse (true) @@ -823,7 +822,7 @@ void OMW::Engine::prepareEngine() mWindowManager = std::make_unique(mWindow, mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(), mCfgMgr.getLogPath().string() + std::string("/"), - mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, + mScriptConsoleMode, mTranslationDataStorage, mEncoding, Version::getOpenmwVersionDescription(mResDir.string()), shadersSupported); mEnvironment.setWindowManager(*mWindowManager); @@ -1186,11 +1185,6 @@ void OMW::Engine::setScriptBlacklistUse (bool use) mScriptBlacklistUse = use; } -void OMW::Engine::enableFontExport(bool exportFonts) -{ - mExportFonts = exportFonts; -} - void OMW::Engine::setSaveGameFile(const std::string &savegame) { mSaveGameFile = savegame; diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index ba39132b04..329993a93e 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -160,7 +160,6 @@ namespace OMW // Grab mouse? bool mGrab; - bool mExportFonts; unsigned int mRandomSeed; Compiler::Extensions mExtensions; @@ -254,8 +253,6 @@ namespace OMW void setScriptBlacklistUse (bool use); - void enableFontExport(bool exportFonts); - /// Set the save game file to load after initialising the engine. void setSaveGameFile(const std::string& savegame); diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 3274451243..f13d1b39b5 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -156,7 +156,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat Fallback::Map::init(variables["fallback"].as().mMap); engine.setSoundUsage(!variables["no-sound"].as()); engine.setActivationDistanceOverride (variables["activate-dist"].as()); - engine.enableFontExport(variables["export-fonts"].as()); engine.setRandomSeed(variables["random-seed"].as()); return true; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5c780d764e..3915f3b9c4 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -129,7 +129,7 @@ namespace MWGui WindowManager::WindowManager( SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, - ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, bool useShaders) + ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders) : mOldUpdateMask(0) , mOldCullMask(0) , mStore(nullptr) @@ -206,7 +206,7 @@ namespace MWGui // Load fonts mFontLoader = std::make_unique(encoding, resourceSystem->getVFS(), mScalingFactor); - mFontLoader->loadBitmapFonts(exportFonts); + mFontLoader->loadBitmapFonts(); //Register own widgets with MyGUI MyGUI::FactoryManager::getInstance().registerFactory("Widget"); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 090a2b52f9..6ff99665c2 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -136,7 +136,7 @@ namespace MWGui WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, - ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, bool useShaders); + ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders); virtual ~WindowManager(); /// Set the ESMStore to use for retrieving of GUI-related strings. diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index b906554cc5..ffa1593318 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -196,12 +196,12 @@ namespace Gui mFonts.clear(); } - void FontLoader::loadBitmapFonts(bool exportToFile) + void FontLoader::loadBitmapFonts() { for (const auto& path : mVFS->getRecursiveDirectoryIterator("Fonts/")) { if (Misc::getFileExtension(path) == "fnt") - loadBitmapFont(path, exportToFile); + loadBitmapFont(path); } } @@ -246,7 +246,7 @@ namespace Gui float ascent; } GlyphInfo; - void FontLoader::loadBitmapFont(const std::string &fileName, bool exportToFile) + void FontLoader::loadBitmapFont(const std::string &fileName) { Files::IStreamPtr file = mVFS->get(fileName); @@ -307,17 +307,6 @@ namespace Gui std::string resourceName = name; - if (exportToFile) - { - osg::ref_ptr image = new osg::Image; - image->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE); - assert (image->isDataContiguous()); - memcpy(image->data(), &textureData[0], textureData.size()); - - Log(Debug::Info) << "Writing " << resourceName + ".png"; - osgDB::writeImageFile(*image, resourceName + ".png"); - } - // Register the font with MyGUI MyGUI::ResourceManualFont* font = static_cast( MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont")); @@ -494,13 +483,6 @@ namespace Gui cursorCode->addAttribute("size", "0 0"); } - if (exportToFile) - { - Log(Debug::Info) << "Writing " << resourceName + ".xml"; - xmlDocument.createDeclaration(); - xmlDocument.save(resourceName + ".xml"); - } - font->deserialization(root, MyGUI::Version(3,2,0)); MyGUI::ResourceManualFont* bookFont = static_cast( diff --git a/components/fontloader/fontloader.hpp b/components/fontloader/fontloader.hpp index eb705fdd4a..1f1137614e 100644 --- a/components/fontloader/fontloader.hpp +++ b/components/fontloader/fontloader.hpp @@ -28,8 +28,7 @@ namespace Gui FontLoader (ToUTF8::FromType encoding, const VFS::Manager* vfs, float scalingFactor); ~FontLoader(); - /// @param exportToFile export the converted fonts (Images and XML with glyph metrics) to files? - void loadBitmapFonts (bool exportToFile); + void loadBitmapFonts (); void loadTrueTypeFonts (); void loadFontFromXml(MyGUI::xml::ElementPtr _node, const std::string& _file, MyGUI::Version _version); @@ -49,8 +48,7 @@ namespace Gui std::string getInternalFontName(const std::string& name); - /// @param exportToFile export the converted font (Image and XML with glyph metrics) to files? - void loadBitmapFont (const std::string& fileName, bool exportToFile); + void loadBitmapFont (const std::string& fileName); FontLoader(const FontLoader&); void operator=(const FontLoader&); From dc97b1d1b4824300f00d7b63a3f089749553a38f Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 18 Jul 2022 10:59:52 +0400 Subject: [PATCH 17/17] Add changelog entries --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b121947f3..97198823ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -145,6 +145,8 @@ Feature #4297: Implement APPLIED_ONCE flag for magic effects Feature #4414: Handle duration of EXTRA SPELL magic effect Feature #4595: Unique object identifier + Feature #4974: Overridable MyGUI layout + Feature #4975: Built-in TrueType fonts Feature #5198: Implement "Magic effect expired" event Feature #5454: Clear active spells from actor when he disappears from scene Feature #5489: MCP: Telekinesis fix for activators