From 4dc686564e596c3e0425d9514d5760f17702dc27 Mon Sep 17 00:00:00 2001 From: trompetin17 Date: Tue, 3 Jun 2025 07:22:13 -0500 Subject: [PATCH] Fix FreeType font loading from zipped mods The FreeType font loader was directly passing filesystem-style paths (e.g., mod.zip/...) to FT_New_Face, which does not support paths inside ZIP archives. As a result, FreeType failed to open the font, triggering a crash when the engine attempted to use an invalid face object. This patch changes the font loading logic to: Use the VFS to read the .ttf font file into memory (shared_ptr and size). Load the font using FT_New_Memory_Face with the in-memory buffer, ensuring compatibility with zipped mods. --- source/graphics/Font.cpp | 28 +++++++++++++++++++++++----- source/graphics/Font.h | 1 + source/graphics/FontManager.cpp | 12 ++---------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/source/graphics/Font.cpp b/source/graphics/Font.cpp index 9f39bbfee1..1100029bc0 100644 --- a/source/graphics/Font.cpp +++ b/source/graphics/Font.cpp @@ -20,6 +20,7 @@ #include "graphics/TextureManager.h" #include "ps/CLogger.h" +#include "ps/Filesystem.h" #include "ps/Profile.h" #include @@ -167,18 +168,35 @@ bool CFont::AddFontFromPath(const OsPath& fontPath) { ENSURE(m_FontSize > 0); + if (!VfsFileExists(fontPath)) + { + LOGERROR("Font file does not exist: %s", fontPath.string8()); + return false; + } + + std::shared_ptr fontData; + size_t fontDataSize; + if (g_VFS->LoadFile(fontPath, fontData, fontDataSize) != 0) + { + LOGERROR("Failed to load font file: %s", fontPath.string8()); + return false; + } + FT_Face face; - if (FT_Error error{FT_New_Face(m_FreeType, fontPath.string8().c_str(), 0, &face)}; error == FT_Err_Unknown_File_Format) - { - LOGERROR("Font file format is not supported: %s", fontPath.string8()); - return false; - } + if (FT_Error error{FT_New_Memory_Face(m_FreeType, fontData.get(), static_cast(fontDataSize), 0, &face)}; error == FT_Err_Unknown_File_Format) + { + LOGERROR("Font file format is not supported: %s", fontPath.string8()); + return false; + } else if (error) { LOGERROR("Failed to load font %s: %d", fontPath.string8(), error); return false; } + // Keep the font data alive. + m_FontsData.push_back(fontData); + // Set the font size. if (FT_Error error{FT_Set_Char_Size(face, 0, FloatToF26Dot6(m_FontSize), 0 , 0)}) { diff --git a/source/graphics/Font.h b/source/graphics/Font.h index c2e5234441..77dc6335b5 100644 --- a/source/graphics/Font.h +++ b/source/graphics/Font.h @@ -159,6 +159,7 @@ private: std::shared_ptr> m_GammaCorrectionLUT{nullptr}; FT_Library m_FreeType; + std::vector> m_FontsData; std::vector m_Faces; UniqueFTStroker m_Stroker{nullptr, &ftStrokerDeleter}; diff --git a/source/graphics/FontManager.cpp b/source/graphics/FontManager.cpp index 3aa65c0bbe..fde04db38a 100644 --- a/source/graphics/FontManager.cpp +++ b/source/graphics/FontManager.cpp @@ -186,17 +186,9 @@ std::shared_ptr CFontManager::LoadFont(CStrIntern fontName) return nullptr; } - OsPath realPath; - g_VFS->GetOriginalPath(fntPath, realPath); - if (realPath.empty()) + if (!font->AddFontFromPath(fntPath)) { - LOGERROR("Font file %s not found", fontPath.c_str()); - return nullptr; - } - - if (!font->AddFontFromPath(realPath)) - { - LOGERROR("Failed to load font %s", realPath.string8()); + LOGERROR("Failed to load font %s", fntPath.string8()); return nullptr; } }