From ff1cc86225c40273ef18953cc5829a2fe05fcc2b Mon Sep 17 00:00:00 2001 From: CaiMiao Date: Sat, 13 Aug 2022 06:33:04 +0900 Subject: [PATCH] switch/application : shared font workaround v2 - utilize the use of plGetSharedFont(), leaving possibility to utilize HOS native fallback order - adjusted fallback chain, now identical with HOS --- library/include/borealis/core/font.hpp | 12 +- library/lib/core/application.cpp | 95 ++++++++------ library/lib/platforms/switch/switch_font.cpp | 126 +++++++++++-------- 3 files changed, 132 insertions(+), 101 deletions(-) diff --git a/library/include/borealis/core/font.hpp b/library/include/borealis/core/font.hpp index b6aaefc5c..b9027fcc7 100644 --- a/library/include/borealis/core/font.hpp +++ b/library/include/borealis/core/font.hpp @@ -25,13 +25,13 @@ namespace brls static constexpr const int FONT_INVALID = -1; static const std::string FONT_REGULAR = "regular"; // regular font (Borealis default font) -static const std::string FONT_STANDARD_REGULAR = "standard"; // regular Standard (Latin/Japanese) font -static const std::string FONT_SCHINESE_REGULAR = "schinese"; // regular S.Chinese font -static const std::string FONT_SCHINESE_EXTEND = "extschinese"; // extended S.Chinese font -static const std::string FONT_TCHINESE_REGULAR = "tchinese"; // regular T.Chinese font -static const std::string FONT_KOREAN_REGULAR = "korean"; // regular Korean font +static const std::string FONT_HOS_STANDARD = "switch_standard"; // Switch Standard (Latin/Japanese) shared font +static const std::string FONT_HOS_SCHINESE = "switch_schinese"; // Switch S.Chinese shared font +static const std::string FONT_HOS_SCHINESE_EXTEND = "switch_extschinese"; // Switch extended S.Chinese shared font +static const std::string FONT_HOS_TCHINESE = "switch_tchinese"; // Switch T.Chinese shared font +static const std::string FONT_HOS_KOREAN = "switch_korean"; // Switch Korean shared font static const std::string FONT_MATERIAL_ICONS = "material"; // Material icons font -static const std::string FONT_SWITCH_ICONS = "switch"; // Switch icons font (see the HOS shared symbols font for an example) +static const std::string FONT_SWITCH_ICONS = "switch_icons"; // Switch icons font (see the HOS shared symbols font for an example) typedef std::unordered_map FontStash; diff --git a/library/lib/core/application.cpp b/library/lib/core/application.cpp index 87b76245f..58e32db1b 100644 --- a/library/lib/core/application.cpp +++ b/library/lib/core/application.cpp @@ -124,61 +124,76 @@ void Application::createWindow(std::string windowTitle) // when defined font stash exists, determine regular font and try to build fallback chain, all fallback failures won't be logged if (regular == FONT_INVALID) { - Logger::info("No regular font loaded, checking the rest of font stash"); - std::string regularRedir = ""; - int standard = Application::getFont(FONT_STANDARD_REGULAR); - int schinese = Application::getFont(FONT_SCHINESE_REGULAR); - int tchinese = Application::getFont(FONT_TCHINESE_REGULAR); - int korean = Application::getFont(FONT_KOREAN_REGULAR); - - if (standard != FONT_INVALID) + Logger::info("No borealis regular font loaded, checking the rest of font stash"); + int switchIcons = Application::getFont(FONT_SWITCH_ICONS); + if (!switchIcons) + Logger::warning("Switch icons font was not loaded, icons will not be displayed"); + + std::string fallbackBase = ""; + int standard = Application::getFont(FONT_HOS_STANDARD); + int extschinese = Application::getFont(FONT_HOS_SCHINESE_EXTEND); + int schinese = Application::getFont(FONT_HOS_SCHINESE_EXTEND); + int tchinese = Application::getFont(FONT_HOS_TCHINESE); + int korean = Application::getFont(FONT_HOS_KOREAN); + + // build-once fallback chain - also check against locale to avoid another bunch of `if` + if ( fallbackBase == "" && extschinese != FONT_INVALID && (locale == LOCALE_ZH_CN || locale == LOCALE_ZH_HANS) ) { - Application::addFontFallback(FONT_STANDARD_REGULAR, FONT_SCHINESE_REGULAR); - Application::addFontFallback(FONT_STANDARD_REGULAR, FONT_SCHINESE_EXTEND); - Application::addFontFallback(FONT_STANDARD_REGULAR, FONT_TCHINESE_REGULAR); - Application::addFontFallback(FONT_STANDARD_REGULAR, FONT_KOREAN_REGULAR); - regularRedir = FONT_STANDARD_REGULAR; + fallbackBase = LOCALE_ZH_HANS; + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_SCHINESE_EXTEND); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_SCHINESE); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_TCHINESE); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_KOREAN); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_STANDARD); } - // also check against locale to avoid another bunch of `if` - if ( schinese != FONT_INVALID && (locale == LOCALE_ZH_CN || locale == LOCALE_ZH_HANS) ) + // fail-safe chain of S.Chinese + if ( fallbackBase == "" && schinese != FONT_INVALID && (locale == LOCALE_ZH_CN || locale == LOCALE_ZH_HANS) ) { - Application::addFontFallback(FONT_SCHINESE_REGULAR, FONT_SCHINESE_EXTEND); - Application::addFontFallback(FONT_SCHINESE_REGULAR, FONT_TCHINESE_REGULAR); - Application::addFontFallback(FONT_SCHINESE_REGULAR, FONT_STANDARD_REGULAR); - Application::addFontFallback(FONT_SCHINESE_REGULAR, FONT_KOREAN_REGULAR); - regularRedir = FONT_SCHINESE_REGULAR; + fallbackBase = LOCALE_ZH_HANS; + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_SCHINESE); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_SCHINESE_EXTEND); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_TCHINESE); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_KOREAN); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_STANDARD); } - if ( tchinese != FONT_INVALID && (locale == LOCALE_ZH_TW || locale == LOCALE_ZH_HANT) ) + if ( fallbackBase == "" && tchinese != FONT_INVALID && (locale == LOCALE_ZH_TW || locale == LOCALE_ZH_HANT) ) { - Application::addFontFallback(FONT_TCHINESE_REGULAR, FONT_SCHINESE_REGULAR); - Application::addFontFallback(FONT_TCHINESE_REGULAR, FONT_SCHINESE_EXTEND); - Application::addFontFallback(FONT_TCHINESE_REGULAR, FONT_STANDARD_REGULAR); - Application::addFontFallback(FONT_TCHINESE_REGULAR, FONT_KOREAN_REGULAR); - regularRedir = FONT_TCHINESE_REGULAR; + fallbackBase = LOCALE_ZH_HANT; + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_TCHINESE); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_SCHINESE_EXTEND); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_SCHINESE); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_KOREAN); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_STANDARD); } - if ( korean != FONT_INVALID && locale == LOCALE_KO ) + if (fallbackBase == "" && korean != FONT_INVALID && locale == LOCALE_KO) { - Application::addFontFallback(FONT_KOREAN_REGULAR, FONT_STANDARD_REGULAR); - Application::addFontFallback(FONT_KOREAN_REGULAR, FONT_SCHINESE_REGULAR); - Application::addFontFallback(FONT_KOREAN_REGULAR, FONT_SCHINESE_EXTEND); - Application::addFontFallback(FONT_KOREAN_REGULAR, FONT_TCHINESE_REGULAR); - regularRedir = FONT_KOREAN_REGULAR; + fallbackBase = LOCALE_KO; + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_KOREAN); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_SCHINESE); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_SCHINESE_EXTEND); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_TCHINESE); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_STANDARD); } - if (regularRedir != "") + // + if (fallbackBase == "" && standard != FONT_INVALID) { - Logger::info("Using {:s} as regular font", regularRedir); - Application::fontStash[FONT_REGULAR] = Application::getFont(regularRedir); + fallbackBase = FONT_HOS_STANDARD; + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_STANDARD); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_SCHINESE_EXTEND); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_SCHINESE); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_TCHINESE); + Application::addFontFallback(FONT_SWITCH_ICONS, FONT_HOS_KOREAN); + } + if (fallbackBase != "") + { + Logger::info("Built fallback chain for {:s}", fallbackBase); + Application::fontStash[FONT_REGULAR] = Application::getFont(FONT_SWITCH_ICONS); regular = Application::getFont(FONT_REGULAR); // refresh for next check } } if (regular != FONT_INVALID) { - // Switch icons - bool switchIcons = Application::addFontFallback(FONT_REGULAR, FONT_SWITCH_ICONS); - if (!switchIcons) - Logger::warning("Switch icons font was not loaded, icons will not be displayed"); - // Material icons bool materialIcons = Application::addFontFallback(FONT_REGULAR, FONT_MATERIAL_ICONS); if (!materialIcons) diff --git a/library/lib/platforms/switch/switch_font.cpp b/library/lib/platforms/switch/switch_font.cpp index 49367e878..a3927f51c 100644 --- a/library/lib/platforms/switch/switch_font.cpp +++ b/library/lib/platforms/switch/switch_font.cpp @@ -27,73 +27,89 @@ namespace brls void SwitchFontLoader::loadFonts() { - PlFontData font; Result rc; - - // Standard - rc = plGetSharedFontByType(&font, PlSharedFontType_Standard); + PlFontData fonts[PlSharedFontType_Total]; + PlFontData* fontsSorted[PlSharedFontType_Total]; + std::string locale = Application::getLocale(); + + bool useStandardOnly = false; + // Compile-time flag + #ifdef SW_STANDARD_FONT_ONLY + bool useStandardOnly = true; + Logger::warning("switch: saving RAM: use standard shared font only!"); + #endif + + // todo: plGetSharedFont must use (u64)languageCode, conflict with suggested use of (std::string)locale + uint64_t languageCode = 0; + rc = setGetSystemLanguage(&languageCode); if (R_SUCCEEDED(rc)) - Application::loadFontFromMemory(FONT_STANDARD_REGULAR, font.address, font.size, false); - else - Logger::error("switch: could not load Standard shared font: {:#x}", rc); - { - // Detect if non applet - bool isFullFallback = false; - AppletType at = appletGetAppletType(); - if (at == AppletType_Application || at == AppletType_SystemApplication) // title takeover - { - isFullFallback = true; - Logger::info("switch: non applet mode, all shared font will be loaded!"); - } else { - Logger::info("switch: applet mode, only shared font for current locale will be loaded!"); - } - std::string locale = Application::getLocale(); - - if (locale == LOCALE_ZH_CN || locale == LOCALE_ZH_HANS || isFullFallback) + int total_fonts=0; + rc = plGetSharedFont(languageCode, fonts, PlSharedFontType_Total, &total_fonts); + if (R_SUCCEEDED(rc)) { - // S.Chinese - rc = plGetSharedFontByType(&font, PlSharedFontType_ChineseSimplified); - if (R_SUCCEEDED(rc)) - Application::loadFontFromMemory(FONT_SCHINESE_REGULAR, font.address, font.size, false); - else - Logger::error("switch: could not load S.Chinese shared font: {:#x}", rc); - - // Ext S.Chinese - rc = plGetSharedFontByType(&font, PlSharedFontType_ExtChineseSimplified); - if (R_SUCCEEDED(rc)) - Application::loadFontFromMemory(FONT_SCHINESE_EXTEND, font.address, font.size, false); - else - Logger::error("switch: could not load Ext. S.Chinese shared font: {:#x}", rc); + for (int i=0; iaddress, + fontsSorted[PlSharedFontType_Standard]->size, false); - if (locale == LOCALE_KO || isFullFallback) + if (!useStandardOnly) { - // Korean - rc = plGetSharedFontByType(&font, PlSharedFontType_KO); - if (R_SUCCEEDED(rc)) - Application::loadFontFromMemory(FONT_KOREAN_REGULAR, font.address, font.size, false); + bool isFullFallback = false; + // Detect if non applet + AppletType at = appletGetAppletType(); + if (at == AppletType_Application || at == AppletType_SystemApplication) // title takeover + isFullFallback = true; + + // Compile-time flag + #ifdef SW_DISABLE_FONT_FALLBACK + isFullFallback = false; + Logger::warning("switch: saving RAM: full font fallback is disabled!"); + #endif + + if (isFullFallback) + Logger::info("switch: non applet mode, all shared fonts will be loaded!"); else - Logger::error("switch: could not load Korean shared font: {:#x}", rc); + Logger::info("switch: applet mode or disabling fallback, only shared font for current locale will be loaded."); + + if (locale == LOCALE_ZH_CN || locale == LOCALE_ZH_HANS || isFullFallback) + { + // S.Chinese + Application::loadFontFromMemory(FONT_HOS_SCHINESE, + fontsSorted[PlSharedFontType_ChineseSimplified]->address, + fontsSorted[PlSharedFontType_ChineseSimplified]->size, false); + // Ext S.Chinese + Application::loadFontFromMemory(FONT_HOS_SCHINESE_EXTEND, + fontsSorted[PlSharedFontType_ExtChineseSimplified]->address, + fontsSorted[PlSharedFontType_ExtChineseSimplified]->size, false); + } + + if (locale == LOCALE_ZH_TW || locale == LOCALE_ZH_HANT || isFullFallback) + // T.Chinese + Application::loadFontFromMemory(FONT_HOS_TCHINESE, + fontsSorted[PlSharedFontType_ChineseTraditional]->address, + fontsSorted[PlSharedFontType_ChineseTraditional]->size, false); + + if (locale == LOCALE_KO || isFullFallback) + // Korean + Application::loadFontFromMemory(FONT_HOS_KOREAN, + fontsSorted[PlSharedFontType_KO]->address, + fontsSorted[PlSharedFontType_KO]->size, false); } } + else if (R_FAILED(rc)) + Logger::error("switch: shared font loading stopped - could not load languageCode: {:#x}", rc); - // Extented (symbols) - rc = plGetSharedFontByType(&font, PlSharedFontType_NintendoExt); - if (R_SUCCEEDED(rc)) - Application::loadFontFromMemory(FONT_SWITCH_ICONS, font.address, font.size, false); - else - Logger::error("switch: could not load Extented shared font: {:#x}", rc); + Application::loadFontFromMemory(FONT_SWITCH_ICONS, + fontsSorted[PlSharedFontType_NintendoExt]->address, + fontsSorted[PlSharedFontType_NintendoExt]->size, false); // Material icons if (!this->loadMaterialFromResources())