Skip to content

Commit

Permalink
switch/application : shared font workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
CaiMiao committed Feb 11, 2021
1 parent 30da1a8 commit 65acc8d
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 22 deletions.
6 changes: 6 additions & 0 deletions library/include/borealis/core/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ class Application
*/
static bool loadFontFromMemory(std::string fontName, void* data, size_t size, bool freeData);

/**
* Wrapper for adding font fallback with nvgAddFallbackFontId.
* Returns true if both font stash exists and the operation succeeded.
*/
static bool addFontFallback(NVGcontext *ctx, std::string baseFontName, std::string fallbackFontName);

/**
* Returns the nanovg handle to the given font name, or FONT_INVALID if
* no such font is currently loaded.
Expand Down
12 changes: 8 additions & 4 deletions library/include/borealis/core/font.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ namespace brls

static constexpr const int FONT_INVALID = -1;

static const std::string FONT_REGULAR = "regular"; // regular Latin font
static const std::string FONT_KOREAN_REGULAR = "korean"; // regular Korean 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_REGULAR = "regular"; // regular 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_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)

typedef std::unordered_map<std::string, int> FontStash;

Expand Down
2 changes: 1 addition & 1 deletion library/include/borealis/core/i18n.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const std::string LOCALE_ZH_CN = "zh-CN";
const std::string LOCALE_ZH_HANS = "zh-Hans";
const std::string LOCALE_ZH_HANT = "zh-Hant";
const std::string LOCALE_ZH_TW = "zh-TW";
const std::string LOCALE_Ko = "ko";
const std::string LOCALE_KO = "ko";
const std::string LOCALE_NL = "nl";
const std::string LOCALE_PT = "pt";
const std::string LOCALE_PT_BR = "pt-BR";
Expand Down
82 changes: 72 additions & 10 deletions library/lib/core/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,23 +136,70 @@ void Application::createWindow(std::string windowTitle)
// Load fonts and setup fallbacks
Application::platform->getFontLoader()->loadFonts();

NVGcontext* vg = Application::getNVGContext();
std::string locale = Application::getLocale();
int regular = Application::getFont(FONT_REGULAR);
if (regular != FONT_INVALID)

// when defined font stash exists, determine regular font and try to build fallback chain, all fallback failures won't logged
int standard = Application::getFont(FONT_STANDARD_REGULAR);
int schinese = Application::getFont(FONT_SCHINESE_REGULAR);
// int extschinese = Application::getFont(FONT_SCHINESE_EXTEND);
int tchinese = Application::getFont(FONT_TCHINESE_REGULAR);
int korean = Application::getFont(FONT_KOREAN_REGULAR);
std::string regularRedir = "nope";
if (regular == FONT_INVALID)
{
NVGcontext* vg = Application::getNVGContext();
Logger::info("no regular font loaded at the moment, checking the rest of font stash");
if (standard != FONT_INVALID)
{
Application::addFontFallback(vg, FONT_STANDARD_REGULAR, FONT_SCHINESE_REGULAR);
Application::addFontFallback(vg, FONT_STANDARD_REGULAR, FONT_SCHINESE_EXTEND);
Application::addFontFallback(vg, FONT_STANDARD_REGULAR, FONT_TCHINESE_REGULAR);
Application::addFontFallback(vg, FONT_STANDARD_REGULAR, FONT_KOREAN_REGULAR);
regularRedir = FONT_STANDARD_REGULAR;
}
if ( schinese != FONT_INVALID && (locale == LOCALE_ZH_CN || locale == LOCALE_ZH_HANS) )
{
Application::addFontFallback(vg, FONT_SCHINESE_REGULAR, FONT_SCHINESE_EXTEND);
Application::addFontFallback(vg, FONT_SCHINESE_REGULAR, FONT_TCHINESE_REGULAR);
Application::addFontFallback(vg, FONT_SCHINESE_REGULAR, FONT_STANDARD_REGULAR);
Application::addFontFallback(vg, FONT_SCHINESE_REGULAR, FONT_KOREAN_REGULAR);
regularRedir = FONT_SCHINESE_REGULAR;
}
if ( tchinese != FONT_INVALID && (locale == LOCALE_ZH_TW || locale == LOCALE_ZH_HANT) )
{
Application::addFontFallback(vg, FONT_TCHINESE_REGULAR, FONT_SCHINESE_REGULAR);
Application::addFontFallback(vg, FONT_TCHINESE_REGULAR, FONT_SCHINESE_EXTEND);
Application::addFontFallback(vg, FONT_TCHINESE_REGULAR, FONT_STANDARD_REGULAR);
Application::addFontFallback(vg, FONT_TCHINESE_REGULAR, FONT_KOREAN_REGULAR);
regularRedir = FONT_TCHINESE_REGULAR;
}
if ( korean != FONT_INVALID && locale == LOCALE_KO )
{
Application::addFontFallback(vg, FONT_KOREAN_REGULAR, FONT_STANDARD_REGULAR);
Application::addFontFallback(vg, FONT_KOREAN_REGULAR, FONT_SCHINESE_REGULAR);
Application::addFontFallback(vg, FONT_KOREAN_REGULAR, FONT_SCHINESE_EXTEND);
Application::addFontFallback(vg, FONT_KOREAN_REGULAR, FONT_TCHINESE_REGULAR);
regularRedir = FONT_KOREAN_REGULAR;
}
if (regularRedir != "nope")
{
Logger::info("using {:s} as regular font", regularRedir);
Application::fontStash[FONT_REGULAR] = Application::getFont(regularRedir);
}
}

regular = Application::getFont(FONT_REGULAR);
if (regular != FONT_INVALID)
{
// Switch icons
int switchIcons = Application::getFont(FONT_SWITCH_ICONS);
if (switchIcons != FONT_INVALID)
nvgAddFallbackFontId(vg, regular, switchIcons);
else
bool switchIcons = Application::addFontFallback(vg, FONT_REGULAR, FONT_SWITCH_ICONS);
if (!switchIcons)
Logger::warning("Switch icons font was not loaded, icons will not be displayed");

// Material icons
int materialIcons = Application::getFont(FONT_MATERIAL_ICONS);
if (materialIcons != FONT_INVALID)
nvgAddFallbackFontId(vg, regular, materialIcons);
else
bool materialIcons = Application::addFontFallback(vg, FONT_REGULAR, FONT_MATERIAL_ICONS);
if (!materialIcons)
Logger::warning("Material icons font was not loaded, icons will not be displayed");
}
else
Expand Down Expand Up @@ -755,6 +802,21 @@ bool Application::loadFontFromMemory(std::string fontName, void* address, size_t
return true;
}

bool Application::addFontFallback(NVGcontext *ctx, std::string baseFontName, std::string fallbackFontName)
{
int baseFont = Application::getFont(baseFontName);
if (baseFont != FONT_INVALID)
{
int fallbackFont = Application::getFont(fallbackFontName);
if (fallbackFont != FONT_INVALID)
{
nvgAddFallbackFontId(ctx, baseFont, fallbackFont);
return true;
}
}
return false;
}

void Application::crash(std::string text)
{
/* CrashFrame* crashFrame = new CrashFrame(text);
Expand Down
57 changes: 50 additions & 7 deletions library/lib/platforms/switch/switch_font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <borealis/core/application.hpp>
#include <borealis/core/logger.hpp>
#include <borealis/core/i18n.hpp>
#include <borealis/platforms/switch/switch_font.hpp>

namespace brls
Expand All @@ -31,19 +32,61 @@ void SwitchFontLoader::loadFonts()
PlFontData font;
Result 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();

// Standard
rc = plGetSharedFontByType(&font, PlSharedFontType_Standard);
if (R_SUCCEEDED(rc))
Application::loadFontFromMemory(FONT_REGULAR, font.address, font.size, false);
Application::loadFontFromMemory(FONT_STANDARD_REGULAR, font.address, font.size, false);
else
Logger::error("switch: could not load Standard shared font: {:#x}", rc);

// Korean
rc = plGetSharedFontByType(&font, PlSharedFontType_KO);
if (R_SUCCEEDED(rc))
Application::loadFontFromMemory(FONT_KOREAN_REGULAR, font.address, font.size, false);
else
Logger::error("switch: could not load Korean shared font: {:#x}", rc);
if (locale == LOCALE_ZH_CN || locale == LOCALE_ZH_HANS || isFullFallback)
{
// 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);
}

if (locale == LOCALE_ZH_TW || locale == LOCALE_ZH_HANT || isFullFallback)
{
// T.Chinese
rc = plGetSharedFontByType(&font, PlSharedFontType_ChineseTraditional);
if (R_SUCCEEDED(rc))
Application::loadFontFromMemory(FONT_TCHINESE_REGULAR, font.address, font.size, false);
else
Logger::error("switch: could not load T.Chinese shared font: {:#x}", rc);
}

if (locale == LOCALE_KO || isFullFallback)
{
// Korean
rc = plGetSharedFontByType(&font, PlSharedFontType_KO);
if (R_SUCCEEDED(rc))
Application::loadFontFromMemory(FONT_KOREAN_REGULAR, font.address, font.size, false);
else
Logger::error("switch: could not load Korean shared font: {:#x}", rc);
}

// Extented (symbols)
rc = plGetSharedFontByType(&font, PlSharedFontType_NintendoExt);
Expand Down

0 comments on commit 65acc8d

Please sign in to comment.