From dc3264a3a5ed6bced089cedec90573d4a9b387be Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Sun, 2 Mar 2025 19:10:03 +0300 Subject: [PATCH] Restore --export-fonts option functionality --- apps/openmw/engine.cpp | 8 +++++++- apps/openmw/engine.hpp | 3 +++ apps/openmw/main.cpp | 1 + apps/openmw/mwgui/windowmanagerimp.cpp | 5 +++-- apps/openmw/mwgui/windowmanagerimp.hpp | 2 +- components/fontloader/fontloader.cpp | 26 ++++++++++++++++++++++++-- components/fontloader/fontloader.hpp | 4 +++- docs/source/reference/modding/font.rst | 2 ++ 8 files changed, 44 insertions(+), 7 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 2736f339e4..609b92a20a 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -373,6 +373,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) , mScriptConsoleMode(false) , mActivationDistanceOverride(-1) , mGrab(true) + , mExportFonts(false) , mRandomSeed(0) , mNewGame(false) , mCfgMgr(configurationManager) @@ -807,7 +808,7 @@ void OMW::Engine::prepareEngine() rootNode->addChild(guiRoot); mWindowManager = std::make_unique(mWindow, mViewer, guiRoot, mResourceSystem.get(), - mWorkQueue.get(), mCfgMgr.getLogPath(), mScriptConsoleMode, mTranslationDataStorage, mEncoding, + mWorkQueue.get(), mCfgMgr.getLogPath(), mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, Version::getOpenmwVersionDescription(), shadersSupported, mCfgMgr); mEnvironment.setWindowManager(*mWindowManager); @@ -1109,6 +1110,11 @@ void OMW::Engine::setWarningsMode(int mode) mWarningsMode = mode; } +void OMW::Engine::enableFontExport(bool exportFonts) +{ + mExportFonts = exportFonts; +} + void OMW::Engine::setSaveGameFile(const std::filesystem::path& savegame) { mSaveGameFile = savegame; diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 39056af560..1b4620bcf1 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -171,6 +171,7 @@ namespace OMW // Grab mouse? bool mGrab; + bool mExportFonts; unsigned int mRandomSeed; Compiler::Extensions mExtensions; @@ -251,6 +252,8 @@ namespace OMW void setWarningsMode(int mode); + void enableFontExport(bool exportFonts); + /// Set the save game file to load after initialising the engine. void setSaveGameFile(const std::filesystem::path& savegame); diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 5b89bca960..cbfc0d7d24 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -155,6 +155,7 @@ bool parseOptions(int argc, char** argv, OMW::Engine& engine, Files::Configurati 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 e51350d19f..6ccc1e02f0 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -146,7 +146,7 @@ namespace MWGui WindowManager::WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::filesystem::path& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, - const std::string& versionDescription, bool useShaders, Files::ConfigurationManager& cfgMgr) + bool exportFonts, const std::string& versionDescription, bool useShaders, Files::ConfigurationManager& cfgMgr) : mOldUpdateMask(0) , mOldCullMask(0) , mStore(nullptr) @@ -215,7 +215,8 @@ namespace MWGui MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag); // Load fonts - mFontLoader = std::make_unique(encoding, resourceSystem->getVFS(), mScalingFactor); + mFontLoader + = std::make_unique(encoding, resourceSystem->getVFS(), mScalingFactor, exportFonts); // 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 052a269188..409a31a514 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -128,7 +128,7 @@ namespace MWGui WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::filesystem::path& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, - ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders, + ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, bool useShaders, Files::ConfigurationManager& cfgMgr); virtual ~WindowManager(); diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index 877d38116b..5f5dd57c2b 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -227,9 +227,10 @@ namespace namespace Gui { - FontLoader::FontLoader(ToUTF8::FromType encoding, const VFS::Manager* vfs, float scalingFactor) + FontLoader::FontLoader(ToUTF8::FromType encoding, const VFS::Manager* vfs, float scalingFactor, bool exportFonts) : mVFS(vfs) , mScalingFactor(scalingFactor) + , mExportFonts(exportFonts) { if (encoding == ToUTF8::WINDOWS_1252) mEncoding = ToUTF8::CP437; @@ -407,7 +408,8 @@ namespace Gui file.reset(); // Create the font texture - std::string bitmapFilename = "fonts/" + std::string(name_) + ".tex"; + const std::string name(name_); + const std::string bitmapFilename = "fonts/" + name + ".tex"; Files::IStreamPtr bitmapFile = mVFS->get(bitmapFilename); @@ -428,6 +430,19 @@ namespace Gui fail(*bitmapFile, bitmapFilename, "File too small to be a valid bitmap"); bitmapFile.reset(); + if (mExportFonts) + { + osg::ref_ptr image = new osg::Image; + image->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE); + assert(image->isDataContiguous()); + memcpy(image->data(), textureData.data(), textureData.size()); + // Convert to OpenGL origin for sensible output + image->flipVertical(); + + Log(Debug::Info) << "Writing " << name + ".png"; + osgDB::writeImageFile(*image, name + ".png"); + } + MyGUI::ITexture* tex = MyGUI::RenderManager::getInstance().createTexture(bitmapFilename); tex->createManual(width, height, MyGUI::TextureUsage::Write, MyGUI::PixelFormat::R8G8B8A8); unsigned char* texData = reinterpret_cast(tex->lock(MyGUI::TextureUsage::Write)); @@ -647,6 +662,13 @@ namespace Gui cursorCode->addAttribute("size", "0 0"); } + if (mExportFonts) + { + Log(Debug::Info) << "Writing " << name + ".xml"; + xmlDocument.createDeclaration(); + xmlDocument.save(name + ".xml"); + } + // Register the font with MyGUI MyGUI::ResourceManualFont* font = static_cast( MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont")); diff --git a/components/fontloader/fontloader.hpp b/components/fontloader/fontloader.hpp index 7e9220d58d..a7269f1a56 100644 --- a/components/fontloader/fontloader.hpp +++ b/components/fontloader/fontloader.hpp @@ -25,7 +25,8 @@ namespace Gui class FontLoader { public: - FontLoader(ToUTF8::FromType encoding, const VFS::Manager* vfs, float scalingFactor); + /// @param exportFonts export the converted fonts (Images and XML with glyph metrics) to files? + FontLoader(ToUTF8::FromType encoding, const VFS::Manager* vfs, float scalingFactor, bool exportFonts); void overrideLineHeight(MyGUI::xml::ElementPtr _node, std::string_view _file, MyGUI::Version _version); @@ -35,6 +36,7 @@ namespace Gui ToUTF8::FromType mEncoding; const VFS::Manager* mVFS; float mScalingFactor; + bool mExportFonts; void loadFonts(); void loadFont(const std::string& fontName, const std::string& fontId); diff --git a/docs/source/reference/modding/font.rst b/docs/source/reference/modding/font.rst index ae2a457e44..2c67a940d1 100644 --- a/docs/source/reference/modding/font.rst +++ b/docs/source/reference/modding/font.rst @@ -15,6 +15,8 @@ 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. 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: