diff --git a/library/include/borealis/frame_context.hpp b/library/include/borealis/frame_context.hpp index 9a05437ef..41ca4e9db 100644 --- a/library/include/borealis/frame_context.hpp +++ b/library/include/borealis/frame_context.hpp @@ -31,6 +31,10 @@ class FontStash { public: int regular = 0; + int standard = 0; + int schinese = 0; + int extSchinese = 0; + int tchinese = 0; int korean = 0; int material = 0; diff --git a/library/include/borealis/i18n.hpp b/library/include/borealis/i18n.hpp index ecc8dca83..def69f309 100644 --- a/library/include/borealis/i18n.hpp +++ b/library/include/borealis/i18n.hpp @@ -64,6 +64,13 @@ void loadTranslations(); */ std::string getCurrentLocale(); +/** + * Returns the current system locale id + * this id only make sense for libnx + * NOT the one that's currently used in the app! + */ +int nxGetCurrentLocaleID(); + inline namespace literals { /** diff --git a/library/lib/application.cpp b/library/lib/application.cpp index 693ea6507..27ef16bdf 100644 --- a/library/lib/application.cpp +++ b/library/lib/application.cpp @@ -229,23 +229,126 @@ bool Application::init(std::string title, Style* style, LibraryViewsThemeVariant #ifdef __SWITCH__ { PlFontData font; + SetLanguage localeID = (SetLanguage)i18n::nxGetCurrentLocaleID(); // Standard font Result rc = plGetSharedFontByType(&font, PlSharedFontType_Standard); if (R_SUCCEEDED(rc)) { - Logger::info("Using Switch shared font"); - Application::fontStash.regular = Application::loadFontFromMemory("regular", font.address, font.size, false); + Logger::info("Adding Switch shared standard font"); + Application::fontStash.standard = Application::loadFontFromMemory("standard", font.address, font.size, false); } - // Korean font - rc = plGetSharedFontByType(&font, PlSharedFontType_KO); - if (R_SUCCEEDED(rc)) + // Load other fonts on demand + bool isFullFallback = false; + AppletType at = appletGetAppletType(); + if (at == AppletType_Application || at == AppletType_SystemApplication) // title takeover + { + isFullFallback = true; + Logger::info("Non applet mode, font full fallback is enabled!"); + } + + if (localeID == SetLanguage_ZHCN || localeID == SetLanguage_ZHHANS || isFullFallback) + { + // S.Chinese font + rc = plGetSharedFontByType(&font, PlSharedFontType_ChineseSimplified); + if (R_SUCCEEDED(rc)) + { + Logger::info("Adding Switch shared S.Chinese font"); + Application::fontStash.schinese = Application::loadFontFromMemory("schinese", font.address, font.size, false); + } + // Ext S.Chinese font + rc = plGetSharedFontByType(&font, PlSharedFontType_ExtChineseSimplified); + if (R_SUCCEEDED(rc)) + { + Logger::info("Adding Switch shared S.Chinese extended font"); + Application::fontStash.extSchinese = Application::loadFontFromMemory("extSchinese", font.address, font.size, false); + } + } + if (localeID == SetLanguage_ZHTW || localeID == SetLanguage_ZHHANT || isFullFallback) { - Logger::info("Adding Switch shared Korean font"); - Application::fontStash.korean = Application::loadFontFromMemory("korean", font.address, font.size, false); - nvgAddFallbackFontId(Application::vg, Application::fontStash.regular, Application::fontStash.korean); + // T.Chinese font + rc = plGetSharedFontByType(&font, PlSharedFontType_ChineseTraditional); + if (R_SUCCEEDED(rc)) + { + Logger::info("Adding Switch shared T.Chinese font"); + Application::fontStash.tchinese = Application::loadFontFromMemory("tchinese", font.address, font.size, false); + } } + if (localeID == SetLanguage_KO || isFullFallback) + { + // Korean font + rc = plGetSharedFontByType(&font, PlSharedFontType_KO); + if (R_SUCCEEDED(rc)) + { + Logger::info("Adding Switch shared Korean font"); + Application::fontStash.korean = Application::loadFontFromMemory("korean", font.address, font.size, false); + } + } + + // Sequentially fallback to other fonts and decide regular font, also on demand + switch (localeID) + { + case SetLanguage_ZHCN : + case SetLanguage_ZHHANS : + if (isFullFallback) + { + nvgAddFallbackFontId(Application::vg, Application::fontStash.schinese, Application::fontStash.extSchinese); + nvgAddFallbackFontId(Application::vg, Application::fontStash.schinese, Application::fontStash.tchinese); + nvgAddFallbackFontId(Application::vg, Application::fontStash.schinese, Application::fontStash.standard); + nvgAddFallbackFontId(Application::vg, Application::fontStash.schinese, Application::fontStash.korean); + } + else + { + nvgAddFallbackFontId(Application::vg, Application::fontStash.schinese, Application::fontStash.extSchinese); + nvgAddFallbackFontId(Application::vg, Application::fontStash.schinese, Application::fontStash.standard); + } + Logger::info("Using Switch shared S.Chinese font as regular"); + Application::fontStash.regular = Application::fontStash.schinese; + break; + case SetLanguage_ZHTW : + case SetLanguage_ZHHANT : + if (isFullFallback) + { + nvgAddFallbackFontId(Application::vg, Application::fontStash.tchinese, Application::fontStash.schinese); + nvgAddFallbackFontId(Application::vg, Application::fontStash.tchinese, Application::fontStash.extSchinese); + nvgAddFallbackFontId(Application::vg, Application::fontStash.tchinese, Application::fontStash.standard); + nvgAddFallbackFontId(Application::vg, Application::fontStash.tchinese, Application::fontStash.korean); + } + else + { + nvgAddFallbackFontId(Application::vg, Application::fontStash.tchinese, Application::fontStash.standard); + } + Logger::info("Using Switch shared T.Chinese font as regular"); + Application::fontStash.regular = Application::fontStash.tchinese; + break; + case SetLanguage_KO : + if (isFullFallback) + { + nvgAddFallbackFontId(Application::vg, Application::fontStash.korean, Application::fontStash.standard); + nvgAddFallbackFontId(Application::vg, Application::fontStash.korean, Application::fontStash.schinese); + nvgAddFallbackFontId(Application::vg, Application::fontStash.korean, Application::fontStash.extSchinese); + nvgAddFallbackFontId(Application::vg, Application::fontStash.korean, Application::fontStash.tchinese); + } + else + { + nvgAddFallbackFontId(Application::vg, Application::fontStash.korean, Application::fontStash.standard); + } + Logger::info("Using Switch shared Korean font as regular"); + Application::fontStash.regular = Application::fontStash.korean; + break; + default: + if (isFullFallback) + { + nvgAddFallbackFontId(Application::vg, Application::fontStash.standard, Application::fontStash.schinese); + nvgAddFallbackFontId(Application::vg, Application::fontStash.standard, Application::fontStash.extSchinese); + nvgAddFallbackFontId(Application::vg, Application::fontStash.standard, Application::fontStash.tchinese); + nvgAddFallbackFontId(Application::vg, Application::fontStash.standard, Application::fontStash.korean); + } + Logger::info("Using Switch shared standard font as regular"); + Application::fontStash.regular = Application::fontStash.standard; + break; + } // Extented font rc = plGetSharedFontByType(&font, PlSharedFontType_NintendoExt); diff --git a/library/lib/i18n.cpp b/library/lib/i18n.cpp index f6c795c85..c9fa509df 100644 --- a/library/lib/i18n.cpp +++ b/library/lib/i18n.cpp @@ -102,12 +102,40 @@ std::string getCurrentLocale() } else { - brls::Logger::error("Unable to get system language (error 0x{0:x}), using the default one: {1}", res, DEFAULT_LOCALE); + brls::Logger::error("Unable to get system language (error {0:#x}), using the default one: {1}", res, DEFAULT_LOCALE); } #endif return DEFAULT_LOCALE; } +int nxGetCurrentLocaleID() +{ +#ifdef __SWITCH__ + u64 languageCode = 0; + SetLanguage setlanguage = SetLanguage_ENUS; + + Result res = setGetSystemLanguage(&languageCode); + + if (R_SUCCEEDED(res)) + { + if (R_SUCCEEDED(res)) + { + res = setMakeLanguage(languageCode, &setlanguage); + return (int)setlanguage; + } + else + { + brls::Logger::error("Unable to convert system language ID (error {0:#x}), using the default one: {1}", res, DEFAULT_LOCALE); + } + } + else + { + brls::Logger::error("Unable to get system language (error {0:#x}), using the default one: {1}", res, DEFAULT_LOCALE); + } +#endif + return 1; // SetLanguage_ENUS +} + void loadTranslations() { loadLocale(DEFAULT_LOCALE, &defaultLocale);