diff --git a/src/common/config.cpp b/src/common/config.cpp index 498e84fca..34d1ca361 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -878,10 +878,6 @@ void load(const std::filesystem::path& path, bool is_game_specific) { return; } - if (!is_game_specific) { - system_font_overrides.clear(); - } - if (data.contains("General")) { const toml::value& general = data.at("General"); diff --git a/src/common/path_util.cpp b/src/common/path_util.cpp index 3cc54efe5..97d119b94 100644 --- a/src/common/path_util.cpp +++ b/src/common/path_util.cpp @@ -145,7 +145,7 @@ static auto UserPaths = [] { notice_file.close(); } - const auto instructions_path = user_dir / SYSFONTS_DIR / "Instructions.txt"; + const auto instructions_path = user_dir / FONTS_DIR / "Instructions.txt"; std::error_code ec; if (!std::filesystem::exists(instructions_path, ec)) { std::ofstream font_instructions(instructions_path); diff --git a/src/core/emulator_settings.cpp b/src/core/emulator_settings.cpp index 49d997c49..fbbdf5be6 100644 --- a/src/core/emulator_settings.cpp +++ b/src/core/emulator_settings.cpp @@ -65,7 +65,7 @@ void EmulatorSettings::SetInstance(std::shared_ptr instance) { std::filesystem::path EmulatorSettings::GetSysFontsDir() { if (m_general.sys_fonts_dir.value.empty()) { - return Common::FS::GetUserPath(Common::FS::PathType::FontDir); + return Common::FS::GetUserPath(Common::FS::PathType::FontsDir); } return m_general.sys_fonts_dir.value; } diff --git a/src/core/libraries/font/font.cpp b/src/core/libraries/font/font.cpp index 145331c59..02dbd4f1a 100644 --- a/src/core/libraries/font/font.cpp +++ b/src/core/libraries/font/font.cpp @@ -31,7 +31,6 @@ #include FT_TRUETYPE_TABLES_H #include "common/config.h" #include "common/logging/log.h" -#include "common/singleton.h" #include "core/file_sys/fs.h" #include "core/libraries/error_codes.h" #include "core/libraries/font/font.h" @@ -549,10 +548,10 @@ static const SystemFontDefinition* FindSystemFontDefinition(u32 font_set_type) { } static std::filesystem::path GetSysFontBaseDir() { - std::filesystem::path base = Config::getSysFontPath(); + std::filesystem::path base = Config::getFontsPath(); std::error_code ec; if (base.empty()) { - LOG_ERROR(Lib_Font, "SystemFonts: SysFontPath not set"); + LOG_ERROR(Lib_Font, "SystemFonts: FontsPath not set"); return {}; } if (std::filesystem::is_directory(base, ec)) { @@ -561,7 +560,7 @@ static std::filesystem::path GetSysFontBaseDir() { if (std::filesystem::is_regular_file(base, ec)) { return base.parent_path(); } - LOG_ERROR(Lib_Font, "SystemFonts: SysFontPath '{}' is not a valid directory or file", + LOG_ERROR(Lib_Font, "SystemFonts: FontsPath '{}' is not a valid directory or file", base.string()); return {}; } @@ -604,75 +603,12 @@ static std::filesystem::path ResolveSystemFontPathCandidate(const std::filesyste return direct; } -static std::string MacroToCamel(const char* macro_key) { - if (!macro_key) { - return {}; - } - std::string s(macro_key); - const std::string prefix = "FONTSET_"; - if (s.rfind(prefix, 0) != 0) { - return {}; - } - std::string out = "FontSet"; - size_t pos = prefix.size(); - while (pos < s.size()) { - size_t next = s.find('_', pos); - const size_t len = (next == std::string::npos) ? (s.size() - pos) : (next - pos); - std::string token = s.substr(pos, len); - for (auto& c : token) { - c = static_cast(std::tolower(static_cast(c))); - } - if (!token.empty()) { - token[0] = static_cast(std::toupper(static_cast(token[0]))); - } - out += token; - if (next == std::string::npos) { - break; - } - pos = next + 1; - } - return out; -} - static std::filesystem::path ResolveSystemFontPath(u32 font_set_type) { if (const auto* def = FindSystemFontDefinition(font_set_type); def) { const auto base_dir = GetSysFontBaseDir(); if (base_dir.empty()) { return {}; } - if (auto override_path = Config::getSystemFontOverride(def->config_key)) { - if (!override_path->empty() && !override_path->is_absolute() && - !override_path->has_parent_path()) { - return ResolveSystemFontPathCandidate(base_dir, *override_path); - } - LOG_ERROR(Lib_Font, - "SystemFonts: override for '{}' must be a filename only (no path): '{}'", - def->config_key, override_path->string()); - } - const auto camel_key = MacroToCamel(def->config_key); - if (!camel_key.empty()) { - if (auto override_path2 = Config::getSystemFontOverride(camel_key)) { - if (!override_path2->empty() && !override_path2->is_absolute() && - !override_path2->has_parent_path()) { - return ResolveSystemFontPathCandidate(base_dir, *override_path2); - } - LOG_ERROR(Lib_Font, - "SystemFonts: override for '{}' must be a filename only (no path): '{}'", - camel_key, override_path2->string()); - } - std::string lower_camel = camel_key; - lower_camel[0] = - static_cast(std::tolower(static_cast(lower_camel[0]))); - if (auto override_path3 = Config::getSystemFontOverride(lower_camel)) { - if (!override_path3->empty() && !override_path3->is_absolute() && - !override_path3->has_parent_path()) { - return ResolveSystemFontPathCandidate(base_dir, *override_path3); - } - LOG_ERROR(Lib_Font, - "SystemFonts: override for '{}' must be a filename only (no path): '{}'", - lower_camel, override_path3->string()); - } - } if (def->default_file && *def->default_file) { return ResolveSystemFontPathCandidate(base_dir, def->default_file); } @@ -4318,11 +4254,7 @@ s32 PS4_SYSV_ABI sceFontOpenFontSet(OrbisFontLib library, u32 fontSetType, u32 o return release_library_and_clear_out(ORBIS_FONT_ERROR_NO_SUPPORT_FUNCTION); } - std::filesystem::path primary_path = - Internal::ResolveSystemFontPathFromConfigOnly(fontSetType); - if (primary_path.empty()) { - primary_path = Internal::ResolveSystemFontPath(fontSetType); - } + std::filesystem::path primary_path = Internal::ResolveSystemFontPath(fontSetType); if (primary_path.empty()) { LOG_ERROR(Lib_Font, "NO_SUPPORT_FONTSET"); return release_library_and_clear_out(ORBIS_FONT_ERROR_NO_SUPPORT_FONTSET); @@ -4331,8 +4263,8 @@ s32 PS4_SYSV_ABI sceFontOpenFontSet(OrbisFontLib library, u32 fontSetType, u32 o std::vector primary_bytes; if (!Internal::LoadFontFile(primary_path, primary_bytes)) { - LOG_ERROR(Lib_Font, "FONT_OPEN_FAILED path='{}' sysFontPath='{}'", - primary_path.string(), Config::getSysFontPath().string()); + LOG_ERROR(Lib_Font, "FONT_OPEN_FAILED path='{}' fontsPath='{}'", primary_path.string(), + Config::getFontsPath().string()); return release_library_and_clear_out(ORBIS_FONT_ERROR_FONT_OPEN_FAILED); } LOG_INFO(Lib_Font, "OpenFontSet: stage=loaded_primary_bytes"); @@ -4561,23 +4493,6 @@ s32 PS4_SYSV_ABI sceFontOpenFontSet(OrbisFontLib library, u32 fontSetType, u32 o return std::nullopt; }; - auto resolve_override = - [&](const std::string& key) -> std::optional { - if (auto override_path = Config::getSystemFontOverride(key)) { - if (!override_path->empty() && override_path->is_absolute()) { - return *override_path; - } - if (!override_path->empty() && !override_path->has_parent_path()) { - return base_dir / *override_path; - } - LOG_ERROR(Lib_Font, - "SystemFonts: override for '{}' must be a filename only or absolute " - "path: '{}'", - key, override_path->string()); - } - return std::nullopt; - }; - auto lower_ascii = [](std::string s) { for (auto& c : s) { c = static_cast(std::tolower(static_cast(c))); @@ -4870,82 +4785,6 @@ s32 PS4_SYSV_ABI sceFontOpenFontSet(OrbisFontLib library, u32 fontSetType, u32 o : "SCEPS4Yoongd-Medium.otf"); } } - - for (int i = 0; i < 8; ++i) { - const std::string key_a = - fmt::format("fontset_0x{:08X}_fallback{}", fontSetType, i); - const std::string key_b = - fmt::format("fontSet_0x{:08X}_fallback{}", fontSetType, i); - std::optional p = resolve_override(key_a); - if (!p) { - p = resolve_override(key_b); - } - if (!p || p->empty()) { - continue; - } - - std::optional p_resolved; - if (p->is_absolute()) { - std::error_code ec; - if (std::filesystem::exists(*p, ec)) { - p_resolved = *p; - } - } else { - p_resolved = resolve_sysfont_path(*p); - } - if (!p_resolved) { - continue; - } - - std::vector fb_bytes; - if (!Internal::LoadFontFile(*p_resolved, fb_bytes)) { - continue; - } - - Internal::FontState::SystemFallbackFace fb{}; - fb.font_id = 0xffffffffu; - fb.scale_factor = 1.0f; - fb.shift_value = 0; - fb.path = *p_resolved; - fb.bytes = std::make_shared>(std::move(fb_bytes)); - fb.ft_face = Internal::CreateFreeTypeFaceFromBytes( - fb.bytes->data(), fb.bytes->size(), sub_font_index); - fb.ready = (fb.ft_face != nullptr); - if (fb.ready) { - fb.scale_factor = compute_sysfont_scale_factor( - fb.ft_face, fb.ft_face ? static_cast(fb.ft_face->units_per_EM) : 0); - fb.shift_value = compute_sysfont_shift_value(fb.ft_face); - LOG_DEBUG( - Lib_Font, - "SystemFonts: fallback='{}' unitsPerEm={} scaleFactor={} shiftValue={}", - fb.path.filename().string(), - fb.ft_face ? static_cast(fb.ft_face->units_per_EM) : 0, - fb.scale_factor, fb.shift_value); - st.system_fallback_faces.push_back(std::move(fb)); - } else { - Internal::DestroyFreeTypeFace(fb.ft_face); - } - } - - { - const std::string global_fallback_name = Config::getSystemFontFallbackName(); - if (!global_fallback_name.empty()) { - const auto existing_name = primary_path.filename().string(); - if (existing_name != global_fallback_name) { - std::filesystem::path fb_path = global_fallback_name; - if (!fb_path.is_absolute()) { - fb_path = base_dir / global_fallback_name; - } - if (const auto resolved_path = resolve_sysfont_path(fb_path)) { - const std::string fb_lower = - lower_ascii(resolved_path->filename().string()); - if (!has_fallback_name_lower(fb_lower)) { - add_fallback_face(*resolved_path); - } - } - } - } - } } { @@ -6928,16 +6767,6 @@ s32 PS4_SYSV_ABI sceFontSupportSystemFonts(OrbisFontLib library) { ls.owned_sysfonts_ctx = ctx; ls.owned_sysfonts_ctx_size = kSysCtxSize; - if (!Internal::g_mnt) { - Internal::g_mnt = Common::Singleton::Instance(); - } - if (Internal::g_mnt) { - const auto sysfont_base = GetSysFontBaseDir(); - if (!sysfont_base.empty() && !Internal::g_mnt->GetMount("/:dev_font:")) { - Internal::g_mnt->Mount(sysfont_base, "/:dev_font:", true); - } - } - ReleaseLibraryLock(lib, prev_lock_word); return ORBIS_OK; } diff --git a/src/core/libraries/font/font_internal.cpp b/src/core/libraries/font/font_internal.cpp index 962181e50..b58e1269f 100644 --- a/src/core/libraries/font/font_internal.cpp +++ b/src/core/libraries/font/font_internal.cpp @@ -1528,94 +1528,31 @@ static bool DirectoryContainsAnyFontFiles(const std::filesystem::path& dir) { return false; } -static std::optional FindChildDirContainingFile( - const std::filesystem::path& base_dir, const std::string& filename) { - if (filename.empty()) { - return std::nullopt; - } - - std::error_code ec; - if (!std::filesystem::is_directory(base_dir, ec)) { - return std::nullopt; - } - - std::optional match; - for (const auto& entry : std::filesystem::directory_iterator(base_dir, ec)) { - if (ec) { - return std::nullopt; - } - if (!entry.is_directory(ec) || ec) { - continue; - } - const auto candidate = entry.path() / filename; - if (std::filesystem::is_regular_file(candidate, ec) && !ec) { - if (match) { - return std::nullopt; - } - match = entry.path(); - } - } - return match; -} - std::filesystem::path GetSysFontBaseDir() { - std::filesystem::path base = Config::getSysFontPath(); + std::filesystem::path base = Config::getFontsPath(); std::error_code ec; if (base.empty()) { - LOG_ERROR(Lib_Font, "SystemFonts: SysFontPath not set"); + LOG_ERROR(Lib_Font, "SystemFonts: FontsPath not set"); return {}; } if (std::filesystem::is_directory(base, ec)) { - if (DirectoryContainsAnyFontFiles(base)) { + const auto font_dir = base / "font"; + const auto font2_dir = base / "font2"; + if (DirectoryContainsAnyFontFiles(base) || DirectoryContainsAnyFontFiles(font_dir) || + DirectoryContainsAnyFontFiles(font2_dir)) { return base; } - - { - const auto font_dir = base / "font"; - const auto font2_dir = base / "font2"; - if (DirectoryContainsAnyFontFiles(font_dir) || - DirectoryContainsAnyFontFiles(font2_dir)) { - return base; - } - } - - const std::string fallback = Config::getSystemFontFallbackName(); - if (auto child = FindChildDirContainingFile(base, fallback)) { - return *child; - } - - std::optional sole_font_dir; - for (const auto& entry : std::filesystem::directory_iterator(base, ec)) { - if (ec) { - break; - } - if (!entry.is_directory(ec) || ec) { - continue; - } - if (DirectoryContainsAnyFontFiles(entry.path())) { - if (sole_font_dir) { - sole_font_dir.reset(); - break; - } - sole_font_dir = entry.path(); - } - } - if (sole_font_dir) { - return *sole_font_dir; - } - LOG_ERROR( Lib_Font, - "SystemFonts: SysFontPath '{}' contains no font files; set it to the directory that " - "contains the .otf/.ttf files (or ensure [SystemFonts].fallback is present in exactly " - "one child directory)", + "SystemFonts: FontsPath '{}' contains no font files; expected files directly in this " + "directory or under 'font'/'font2'", base.string()); return {}; } if (std::filesystem::is_regular_file(base, ec)) { return base.parent_path(); } - LOG_ERROR(Lib_Font, "SystemFonts: SysFontPath '{}' is not a valid directory or file", + LOG_ERROR(Lib_Font, "SystemFonts: FontsPath '{}' is not a valid directory or file", base.string()); return {}; } @@ -1658,75 +1595,12 @@ static std::filesystem::path ResolveSystemFontPathCandidate(const std::filesyste return direct; } -std::string MacroToCamel(const char* macro_key) { - if (!macro_key) { - return {}; - } - std::string s(macro_key); - const std::string prefix = "FONTSET_"; - if (s.rfind(prefix, 0) != 0) { - return {}; - } - std::string out = "FontSet"; - size_t pos = prefix.size(); - while (pos < s.size()) { - size_t next = s.find('_', pos); - const size_t len = (next == std::string::npos) ? (s.size() - pos) : (next - pos); - std::string token = s.substr(pos, len); - for (auto& c : token) { - c = static_cast(std::tolower(static_cast(c))); - } - if (!token.empty()) { - token[0] = static_cast(std::toupper(static_cast(token[0]))); - } - out += token; - if (next == std::string::npos) { - break; - } - pos = next + 1; - } - return out; -} - std::filesystem::path ResolveSystemFontPath(u32 font_set_type) { if (const auto* def = FindSystemFontDefinition(font_set_type); def) { const auto base_dir = GetSysFontBaseDir(); if (base_dir.empty()) { return {}; } - if (auto override_path = Config::getSystemFontOverride(def->config_key)) { - if (!override_path->empty() && !override_path->is_absolute() && - !override_path->has_parent_path()) { - return ResolveSystemFontPathCandidate(base_dir, *override_path); - } - LOG_ERROR(Lib_Font, - "SystemFonts: override for '{}' must be a filename only (no path): '{}'", - def->config_key, override_path->string()); - } - const auto camel_key = MacroToCamel(def->config_key); - if (!camel_key.empty()) { - if (auto override_path2 = Config::getSystemFontOverride(camel_key)) { - if (!override_path2->empty() && !override_path2->is_absolute() && - !override_path2->has_parent_path()) { - return ResolveSystemFontPathCandidate(base_dir, *override_path2); - } - LOG_ERROR(Lib_Font, - "SystemFonts: override for '{}' must be a filename only (no path): '{}'", - camel_key, override_path2->string()); - } - std::string lower_camel = camel_key; - lower_camel[0] = - static_cast(std::tolower(static_cast(lower_camel[0]))); - if (auto override_path3 = Config::getSystemFontOverride(lower_camel)) { - if (!override_path3->empty() && !override_path3->is_absolute() && - !override_path3->has_parent_path()) { - return ResolveSystemFontPathCandidate(base_dir, *override_path3); - } - LOG_ERROR(Lib_Font, - "SystemFonts: override for '{}' must be a filename only (no path): '{}'", - lower_camel, override_path3->string()); - } - } if (def->default_file && *def->default_file) { return ResolveSystemFontPathCandidate(base_dir, def->default_file); } @@ -1735,45 +1609,6 @@ std::filesystem::path ResolveSystemFontPath(u32 font_set_type) { return {}; } -std::filesystem::path ResolveSystemFontPathFromConfigOnly(u32 font_set_type) { - const auto base_dir = GetSysFontBaseDir(); - if (base_dir.empty()) { - return {}; - } - - const std::string key_a = fmt::format("fontset_0x{:08X}", font_set_type); - const std::string key_b = fmt::format("fontSet_0x{:08X}", font_set_type); - - auto try_key = [&](const std::string& key) -> std::optional { - if (auto override_path = Config::getSystemFontOverride(key)) { - if (!override_path->empty() && override_path->is_absolute()) { - return *override_path; - } - if (!override_path->empty() && !override_path->has_parent_path()) { - return base_dir / *override_path; - } - LOG_ERROR( - Lib_Font, - "SystemFonts: override for '{}' must be a filename only or absolute path: '{}'", - key, override_path->string()); - } - return std::nullopt; - }; - - if (auto p = try_key(key_a)) { - return *p; - } - if (auto p = try_key(key_b)) { - return *p; - } - - const std::string fallback = Config::getSystemFontFallbackName(); - if (!fallback.empty()) { - return base_dir / fallback; - } - return {}; -} - const FontSetCache* EnsureFontSetCache(u32 font_set_type) { if (font_set_type == 0) { return nullptr; @@ -1872,10 +1707,7 @@ bool AttachSystemFont(FontState& st, Libraries::Font::OrbisFontHandle handle) { return false; } - std::filesystem::path primary_path = ResolveSystemFontPathFromConfigOnly(st.font_set_type); - if (primary_path.empty()) { - primary_path = ResolveSystemFontPath(st.font_set_type); - } + std::filesystem::path primary_path = ResolveSystemFontPath(st.font_set_type); std::vector primary_bytes; if (primary_path.empty() || !LoadFontFile(primary_path, primary_bytes)) { return false; @@ -1901,80 +1733,6 @@ bool AttachSystemFont(FontState& st, Libraries::Font::OrbisFontHandle handle) { st.system_font_path = primary_path; st.system_requested = true; - const auto base_dir = GetSysFontBaseDir(); - if (!base_dir.empty()) { - auto resolve_override = - [&](const std::string& key) -> std::optional { - if (auto override_path = Config::getSystemFontOverride(key)) { - if (!override_path->empty() && override_path->is_absolute()) { - return *override_path; - } - if (!override_path->empty() && !override_path->has_parent_path()) { - return base_dir / *override_path; - } - } - return std::nullopt; - }; - - for (int i = 0; i < 8; ++i) { - const std::string key_a = - fmt::format("fontset_0x{:08X}_fallback{}", st.font_set_type, i); - const std::string key_b = - fmt::format("fontSet_0x{:08X}_fallback{}", st.font_set_type, i); - std::optional p = resolve_override(key_a); - if (!p) { - p = resolve_override(key_b); - } - if (!p || p->empty()) { - continue; - } - - std::vector fb_bytes; - if (!LoadFontFile(*p, fb_bytes)) { - continue; - } - FontState::SystemFallbackFace fb{}; - fb.font_id = static_cast(i + 1); - fb.scale_factor = 1.0f; - fb.shift_value = 0; - fb.path = *p; - fb.bytes = std::make_shared>(std::move(fb_bytes)); - fb.ft_face = - CreateFreeTypeFaceFromBytes(fb.bytes->data(), fb.bytes->size(), subfont_index); - fb.ready = (fb.ft_face != nullptr); - if (fb.ready) { - st.system_fallback_faces.push_back(std::move(fb)); - } else { - DestroyFreeTypeFace(fb.ft_face); - } - } - - const std::string global_fallback_name = Config::getSystemFontFallbackName(); - if (!global_fallback_name.empty()) { - const auto existing_name = primary_path.filename().string(); - if (existing_name != global_fallback_name) { - const std::filesystem::path fb_path = base_dir / global_fallback_name; - std::vector fb_bytes; - if (LoadFontFile(fb_path, fb_bytes)) { - FontState::SystemFallbackFace fb{}; - fb.font_id = 0xFFFFFFFFu; - fb.scale_factor = 1.0f; - fb.shift_value = 0; - fb.path = fb_path; - fb.bytes = std::make_shared>(std::move(fb_bytes)); - fb.ft_face = CreateFreeTypeFaceFromBytes(fb.bytes->data(), fb.bytes->size(), - subfont_index); - fb.ready = (fb.ft_face != nullptr); - if (fb.ready) { - st.system_fallback_faces.push_back(std::move(fb)); - } else { - DestroyFreeTypeFace(fb.ft_face); - } - } - } - } - } - LOG_INFO(Lib_Font, "system font attached"); LOG_DEBUG(Lib_Font, "system font attach params:\n" @@ -1994,8 +1752,8 @@ std::string ReportSystemFaceRequest(FontState& st, Libraries::Font::OrbisFontHan } if (!st.system_requested) { st.system_requested = true; - const auto configured = Config::getSysFontPath(); - return fmt::format("SystemFace: handle={} requested internal font but sysFontPath ('{}') " + const auto configured = Config::getFontsPath(); + return fmt::format("SystemFace: handle={} requested internal font but fontsPath ('{}') " "could not be loaded", static_cast(handle), configured.string()); } diff --git a/src/core/libraries/font/font_internal.h b/src/core/libraries/font/font_internal.h index 39850c3f7..fe1ea225c 100644 --- a/src/core/libraries/font/font_internal.h +++ b/src/core/libraries/font/font_internal.h @@ -748,9 +748,7 @@ const GlyphEntry* GetGlyphEntry(FontState& st, Libraries::Font::OrbisFontHandle FT_Face& face_out, float& scale_out); const SystemFontDefinition* FindSystemFontDefinition(u32 font_set_type); std::filesystem::path GetSysFontBaseDir(); -std::string MacroToCamel(const char* macro_key); std::filesystem::path ResolveSystemFontPath(u32 font_set_type); -std::filesystem::path ResolveSystemFontPathFromConfigOnly(u32 font_set_type); const struct FontSetCache* EnsureFontSetCache(u32 font_set_type); bool HasSfntTables(const std::vector& bytes); bool LoadFontFile(const std::filesystem::path& path, std::vector& out_bytes);