diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 71a34661c..7595e1e8f 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -42,6 +42,28 @@ if(NOT KYTY_CLANG_CL) endif() install(FILES "${openxr_SOURCE_DIR}/LICENSE" DESTINATION "licenses/openxr") +# Noto Sans v2.015 (SIL Open Font License 1.1) is libFont's fallback font. +set(KYTY_NOTO_SANS_REPOSITORY "https://raw.githubusercontent.com/notofonts/notofonts.github.io") +set(KYTY_NOTO_SANS_COMMIT 42af67ccd12bc0e31ed85384bf73e39248265374) +set(KYTY_NOTO_SANS_BASE_URL "${KYTY_NOTO_SANS_REPOSITORY}/${KYTY_NOTO_SANS_COMMIT}/fonts") +set(KYTY_NOTO_SANS_DIR "${FETCHCONTENT_BASE_DIR}/noto-sans") +function(kyty_fetch_noto_sans path sha256) + get_filename_component(name "${path}" NAME) + file(DOWNLOAD "${KYTY_NOTO_SANS_BASE_URL}/${path}" "${KYTY_NOTO_SANS_DIR}/${name}" + EXPECTED_HASH SHA256=${sha256}) +endfunction() +kyty_fetch_noto_sans(LICENSE f2095b08bed08b23a6fe26112fcd679a2bee3f002eef077eb05d215ed1051bd8) +kyty_fetch_noto_sans(NotoSans/hinted/ttf/NotoSans-Regular.ttf + 478c558ea716033cd60c03438f628dfa75694dcf6b5f6d505a2f05fd2b4f3823) +kyty_fetch_noto_sans(NotoSans/hinted/ttf/NotoSans-Bold.ttf + 1df075a380fc7cb898acf64c1f7b3b4dd780de3caa860178bf929de35817a913) +kyty_fetch_noto_sans(NotoSans/hinted/ttf/NotoSans-Italic.ttf + 467e3f89eeca4108bb8710a2b9e0cf2281ac56d5b0609211a83776d0505eecb5) +kyty_fetch_noto_sans(NotoSans/hinted/ttf/NotoSans-BoldItalic.ttf + 1b602a9d6353be42c91df097a4857b69fa2696f26703d7a33b54a15d87c2622c) +install(FILES "${KYTY_NOTO_SANS_DIR}/LICENSE" DESTINATION "licenses/noto-sans") +set(KYTY_NOTO_SANS_DIR "${KYTY_NOTO_SANS_DIR}" PARENT_SCOPE) + # The guest instruction patcher needs a decoder/encoder and a small # trampoline assembler. Pin the same revisions used by shadPS4's implementation. set(XBYAK_BUILD_TESTS OFF CACHE BOOL "" FORCE) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04a20abd9..e5d6f8655 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -815,6 +815,19 @@ add_custom_target(kyty_touch_cursors add_dependencies(kyty_emulator kyty_touch_cursors) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/assets/cursors" DESTINATION assets) +set(KYTY_NOTO_SANS_FONTS + "${KYTY_NOTO_SANS_DIR}/NotoSans-Regular.ttf" + "${KYTY_NOTO_SANS_DIR}/NotoSans-Bold.ttf" + "${KYTY_NOTO_SANS_DIR}/NotoSans-Italic.ttf" + "${KYTY_NOTO_SANS_DIR}/NotoSans-BoldItalic.ttf") +add_custom_target(kyty_noto_sans_fonts + COMMAND ${CMAKE_COMMAND} -E make_directory "$/assets/fonts" + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${KYTY_NOTO_SANS_FONTS} + "$/assets/fonts" + VERBATIM) +add_dependencies(kyty_emulator kyty_noto_sans_fonts) +install(FILES ${KYTY_NOTO_SANS_FONTS} DESTINATION assets/fonts) + target_link_libraries(kyty_emulator ${kyty_emulator_link_libraries}) if (WIN32) target_link_libraries(kyty_emulator opengl32) diff --git a/src/launcher/CMakeLists.txt b/src/launcher/CMakeLists.txt index fbb9b0b54..a5f98859d 100644 --- a/src/launcher/CMakeLists.txt +++ b/src/launcher/CMakeLists.txt @@ -125,6 +125,7 @@ if(APPLE) install(TARGETS kyty_emulator DESTINATION "KytyPS5.app/Contents/MacOS") install(TARGETS kyty_updater DESTINATION "KytyPS5.app/Contents/MacOS") install(FILES "${KYTY_TROPHY_UNLOCK_SOUND}" DESTINATION "KytyPS5.app/Contents/Resources/assets/sounds") + install(FILES ${KYTY_NOTO_SANS_FONTS} DESTINATION "KytyPS5.app/Contents/Resources/assets/fonts") install(DIRECTORY "${CMAKE_SOURCE_DIR}/assets/cursors" DESTINATION "KytyPS5.app/Contents/Resources/assets") # Deploy and ad-hoc sign the Qt frameworks and plugins in the bundle. find_program(KYTY_MACDEPLOYQT NAMES macdeployqt PATHS "${Qt6_DIR}/../../../bin" NO_DEFAULT_PATH) diff --git a/src/libs/libFont.cpp b/src/libs/libFont.cpp index 2d1365e02..fc7d5db21 100644 --- a/src/libs/libFont.cpp +++ b/src/libs/libFont.cpp @@ -2,10 +2,12 @@ #include "common/assert.h" #include "common/common.h" #include "common/logging/log.h" +#include "common/stringUtils.h" #include "libs/errno.h" #include "libs/libs.h" #include "loader/symbolDatabase.h" +#include #include #include #include @@ -675,19 +677,6 @@ static bool font_is_italic(const FontState* font) { font->render_effect_slant != 0.0f; } -static const char* fallback_font_file_name(bool bold, bool italic) { - if (bold && italic) { - return "Roboto-BoldItalic.ttf"; - } - if (bold) { - return "Roboto-Bold.ttf"; - } - if (italic) { - return "Roboto-Italic.ttf"; - } - return "Roboto-Regular.ttf"; -} - static std::vector read_file_bytes(const std::filesystem::path& path) { std::ifstream file(path, std::ios::binary | std::ios::ate); if (!file) { @@ -709,49 +698,34 @@ static std::vector read_file_bytes(const std::filesystem::path& path) { return data; } -static std::vector fallback_font_candidates(const char* file_name) { - const auto rel = - std::filesystem::path("3rdparty") / "tracy" / "profiler" / "src" / "font" / file_name; - std::vector paths; - - auto source_root = std::filesystem::path(__FILE__).parent_path().parent_path().parent_path(); - paths.push_back(source_root / rel); - - std::error_code ec; - auto cwd = std::filesystem::current_path(ec); - if (!ec) { - paths.push_back(cwd / rel); - paths.push_back(cwd / ".." / rel); - paths.push_back(cwd / ".." / ".." / rel); +static std::vector load_fallback_font_data(const char* file_name) { + const char* base_path = SDL_GetBasePath(); + if (base_path == nullptr) { + LOGF("Font: SDL_GetBasePath failed: %s\n", SDL_GetError()); + return {}; } - - return paths; -} - -static std::vector load_fallback_font_data(bool bold, bool italic) { - for (const auto& path: fallback_font_candidates(fallback_font_file_name(bold, italic))) { - auto data = read_file_bytes(path); - if (!data.empty()) { - return data; - } + // SDL returns UTF-8; path(const char*) would read it in the Windows ANSI code page. + const auto path = Common::PathFromUtf8(base_path) / "assets" / "fonts" / file_name; + auto data = read_file_bytes(path); + if (data.empty()) { + LOGF("Font: fallback font not found: %s\n", Common::PathToString(path).c_str()); } - - return {}; + return data; } static const std::vector& fallback_font_data(bool bold, bool italic) { - static const auto regular = load_fallback_font_data(false, false); - static const auto bold_data = load_fallback_font_data(true, false); - static const auto italic_data = load_fallback_font_data(false, true); - static const auto bold_italic = load_fallback_font_data(true, true); + static const auto regular = load_fallback_font_data("NotoSans-Regular.ttf"); + static const auto bold_data = load_fallback_font_data("NotoSans-Bold.ttf"); + static const auto italic_data = load_fallback_font_data("NotoSans-Italic.ttf"); + static const auto bold_italic = load_fallback_font_data("NotoSans-BoldItalic.ttf"); - if (bold && italic && !bold_italic.empty()) { + if (bold && italic) { return bold_italic; } - if (bold && !bold_data.empty()) { + if (bold) { return bold_data; } - if (italic && !italic_data.empty()) { + if (italic) { return italic_data; } return regular;