From 0dc28e6d56bbd11dd2644f3457fbc73e5b0e1240 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Mon, 10 Mar 2025 22:37:39 -0400 Subject: [PATCH] Automatically add Japanese, Chinese, and emoji fallback fonts in Window::loadFont(). Add Window::loadFontWithoutFallbacks(). --- include/window/Window.hpp | 3 +++ src/window/Window.cpp | 53 +++++++++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/include/window/Window.hpp b/include/window/Window.hpp index 9dc5b537..481495ec 100644 --- a/include/window/Window.hpp +++ b/include/window/Window.hpp @@ -105,8 +105,11 @@ struct Window { /** Loads and caches a Font from a file path. Do not store this reference across screen frames, as the Window may have changed, invalidating the Font. + Automatically adds fallback fonts such as Japanese, Chinese, and emoji. */ std::shared_ptr loadFont(const std::string& filename); + /** Loads and caches a Font without adding fallback fonts. */ + std::shared_ptr loadFontWithoutFallbacks(const std::string& filename); /** Loads and caches an Image from a file path. Do not store this reference across screen frames, as the Window may have changed, invalidating the Image. */ diff --git a/src/window/Window.cpp b/src/window/Window.cpp index adb47937..d4eeca06 100644 --- a/src/window/Window.cpp +++ b/src/window/Window.cpp @@ -364,18 +364,8 @@ Window::Window() { // Load UI fonts uiFont = loadFont(asset::system("res/fonts/DejaVuSans.ttf")); - if (uiFont) { - std::shared_ptr jpFont = loadFont(asset::system("res/fonts/NotoSansJP-Medium.otf")); - if (jpFont) - nvgAddFallbackFontId(vg, uiFont->handle, jpFont->handle); - std::shared_ptr scFont = loadFont(asset::system("res/fonts/NotoSansSC-Medium.otf")); - if (scFont) - nvgAddFallbackFontId(vg, uiFont->handle, scFont->handle); - std::shared_ptr emojiFont = loadFont(asset::system("res/fonts/NotoEmoji-Medium.ttf")); - if (emojiFont) - nvgAddFallbackFontId(vg, uiFont->handle, emojiFont->handle); + if (uiFont) bndSetFont(uiFont->handle); - } if (APP->scene) { widget::Widget::ContextCreateEvent e; @@ -758,14 +748,39 @@ double Window::getFrameDurationRemaining() { std::shared_ptr Window::loadFont(const std::string& filename) { - const auto& pair = internal->fontCache.find(filename); - if (pair != internal->fontCache.end()) - return pair->second; + // If font is already cached, no need to add fallback fonts again. + const auto& it = internal->fontCache.find(filename); + if (it != internal->fontCache.end()) + return it->second; + + // This redundantly searches the font cache, but it's not a performance issue because it only happens when font is first loaded. + std::shared_ptr font = loadFontWithoutFallbacks(filename); + if (!font) + return NULL; + + std::shared_ptr jpFont = loadFontWithoutFallbacks(asset::system("res/fonts/NotoSansJP-Medium.otf")); + if (jpFont) + nvgAddFallbackFontId(vg, font->handle, jpFont->handle); + std::shared_ptr scFont = loadFontWithoutFallbacks(asset::system("res/fonts/NotoSansSC-Medium.otf")); + if (scFont) + nvgAddFallbackFontId(vg, font->handle, scFont->handle); + std::shared_ptr emojiFont = loadFontWithoutFallbacks(asset::system("res/fonts/NotoEmoji-Medium.ttf")); + if (emojiFont) + nvgAddFallbackFontId(vg, font->handle, emojiFont->handle); + + return font; +} + + +std::shared_ptr Window::loadFontWithoutFallbacks(const std::string& filename) { + // Return cached font, even if null + const auto& it = internal->fontCache.find(filename); + if (it != internal->fontCache.end()) + return it->second; // Load font - std::shared_ptr font; + std::shared_ptr font = std::make_shared(); try { - font = std::make_shared(); font->loadFile(filename, vg); } catch (Exception& e) { @@ -778,9 +793,9 @@ std::shared_ptr Window::loadFont(const std::string& filename) { std::shared_ptr Window::loadImage(const std::string& filename) { - const auto& pair = internal->imageCache.find(filename); - if (pair != internal->imageCache.end()) - return pair->second; + const auto& it = internal->imageCache.find(filename); + if (it != internal->imageCache.end()) + return it->second; // Load image std::shared_ptr image;