From 227965e646fce668b22ce23ec9adf858513e65e4 Mon Sep 17 00:00:00 2001 From: vgmoose Date: Fri, 22 Mar 2024 20:04:42 -0400 Subject: [PATCH] internationalization changes, use std::string in more places --- .gitlab-ci.yml | 10 ++++---- src/Button.cpp | 2 +- src/Button.hpp | 2 +- src/EKeyboard.cpp | 4 +-- src/RootDisplay.cpp | 12 ++++----- src/TextElement.cpp | 61 ++++++++++++++++++++++++++++++++++++++++----- src/TextElement.hpp | 15 +++++++++-- 7 files changed, 82 insertions(+), 24 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 14a905d..1a0f423 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -49,11 +49,11 @@ Switch: PLATFORM: switch EXT: nro -3ds: - <<: *common - variables: - PLATFORM: 3ds - EXT: 3dsx +# 3ds: +# <<: *common +# variables: +# PLATFORM: 3ds +# EXT: 3dsx Wii: <<: *common diff --git a/src/Button.cpp b/src/Button.cpp index aa71286..f637871 100644 --- a/src/Button.cpp +++ b/src/Button.cpp @@ -6,7 +6,7 @@ CST_Color Button::colors[2] = { { 0xff, 0xff, 0xff, 0xff }, // dark }; -Button::Button(const char* message, int button, bool dark, int size, int width) +Button::Button(std::string message, int button, bool dark, int size, int width) : physical(button) , dark(dark) , icon(getUnicode(button), (size / SCALER) * 1.25, &colors[dark], ICON) diff --git a/src/Button.hpp b/src/Button.hpp index cab0a8a..a0af842 100644 --- a/src/Button.hpp +++ b/src/Button.hpp @@ -6,7 +6,7 @@ class Button : public Element { public: - Button(const char* text, int button, bool dark = false, int size = 20, int width = 0); + Button(std::string text, int button, bool dark = false, int size = 20, int width = 0); bool process(InputEvents* event); diff --git a/src/EKeyboard.cpp b/src/EKeyboard.cpp index da5db63..3b33b3a 100644 --- a/src/EKeyboard.cpp +++ b/src/EKeyboard.cpp @@ -504,12 +504,12 @@ void EKeyboard::updateSize() if (!hasRoundedKeys) { for (int x = 0; x < rowCount(); x++) { - TextElement* rowText = new TextElement(rows[x]->c_str(), textSize, &gray, true); + TextElement* rowText = new TextElement(rows[x]->c_str(), textSize, &gray, ICON); // rowText->customFontPath = RAMFS "res/lightsans.ttf"; if (targetHeight < 0) { targetHeight = rowText->height; } - // rowText->update(true); + rowText->update(true); rowText->position(kXPad + x * kXOff, kYPad + x * kYOff + targetHeight/2 - rowText->height/2); this->elements.push_back(rowText); } diff --git a/src/RootDisplay.cpp b/src/RootDisplay.cpp index 60b2526..5fbde46 100644 --- a/src/RootDisplay.cpp +++ b/src/RootDisplay.cpp @@ -196,15 +196,13 @@ void RootDisplay::processWiiUHomeOverlay() { int RootDisplay::mainLoop() { - // consoleDebugInit(debugDevice_SVC); - // stdout = stderr; // for yuzu + DownloadQueue::init(); -#if defined(__WIIU__) - // WHBLogUdpInit(); - // WHBLogCafeInit(); -#endif + // always load english first, to initialize defaults + TextElement::loadI18nCache("en-us"); - DownloadQueue::init(); + // TODO: detect language and system, and store preference + // TextElement::loadI18nCache("zh-cn"); #ifdef __WIIU__ // setup procui callback for resuming application to force a chesto render diff --git a/src/TextElement.cpp b/src/TextElement.cpp index 2cf988a..885e488 100644 --- a/src/TextElement.cpp +++ b/src/TextElement.cpp @@ -1,19 +1,58 @@ #include "TextElement.hpp" #include "RootDisplay.hpp" +#include const char *TextElement::fontPaths[] = { - RAMFS "./res/opensans.ttf", // 0 = NORMAL - RAMFS "./res/mono.ttf", // 1 = MONOSPACED - RAMFS "./res/nxicons.ttf", // 2 = ICON + RAMFS "./res/fonts/OpenSans-Regular.ttf", // 0 = NORMAL + RAMFS "./res/fonts/UbuntuMono-Regular.ttf", // 1 = MONOSPACED + RAMFS "./res/fonts/oldmono.ttf", // 2 = OLD_MONOSPACED + RAMFS "./res/fonts/PTSerif-Regular.ttf", // 3 = SERIF + RAMFS "./res/fonts/NotoSansSC-Regular.ttf", // 4 = SIMPLIFIED_CHINESE }; +std::unordered_map TextElement::i18nCache = {}; + +bool TextElement::useSimplifiedChineseFont = false; + TextElement::TextElement() { } -TextElement::TextElement(const char* text, int size, CST_Color* color, int font_type, int wrapped_width) +// static method to load i18n cache +void TextElement::loadI18nCache(std::string locale) { + // en-us, zh-cn + std::string localePath = RAMFS "res/i18n/" + locale + ".ini"; + std::ifstream file(localePath); + printf("Loading i18n cache from %s\n", localePath.c_str()); + if (file.is_open()) { + std::string line; + while (std::getline(file, line)) { + size_t pos = line.find(" ="); + if (pos == std::string::npos) { + continue; // bad format + } + std::string key = line.substr(0, pos); + pos = line.find("= "); + if (pos == std::string::npos) { + continue; + } + std::string value = line.substr(pos + 2); + TextElement::i18nCache[key] = value; + printf("Loaded i18n key %s with value %s\n", key.c_str(), value.c_str()); + } + file.close(); + + // if locale is zh-cn, we need to force the simple chinese font + if (locale == "zh-cn") { + printf("Overriding font choice\n"); + TextElement::useSimplifiedChineseFont = true; + } + } +} + +TextElement::TextElement(std::string text, int size, CST_Color* color, int font_type, int wrapped_width) { - std::string sText = std::string(text); + std::string sText = text; setText(sText); setSize(size); if (color) setColor(*color); @@ -55,7 +94,10 @@ void TextElement::update(bool forceUpdate) if (!loadFromCache(key) || forceUpdate) { - auto fontPath = fontPaths[textFont % 3]; + if (TextElement::useSimplifiedChineseFont && textFont == NORMAL) { + textFont = SIMPLIFIED_CHINESE; + } + auto fontPath = fontPaths[textFont % 5]; if (customFontPath != "") { fontPath = customFontPath.c_str(); } @@ -74,3 +116,10 @@ void TextElement::update(bool forceUpdate) getTextureSize(&width, &height); } + +std::string& i18n(std::string key) { + if (TextElement::i18nCache.find(key) != TextElement::i18nCache.end()) { + return TextElement::i18nCache[key]; + } + return key; +} \ No newline at end of file diff --git a/src/TextElement.hpp b/src/TextElement.hpp index 185233b..051c089 100644 --- a/src/TextElement.hpp +++ b/src/TextElement.hpp @@ -5,14 +5,19 @@ #define NORMAL 0 #define MONOSPACED 1 -#define ICON 2 +#define ICON 2 // old icon font, no longer used +#define OLD_MONOSPACED 2 +#define SERIF 3 +#define SIMPLIFIED_CHINESE 4 + +std::string& i18n(std::string key); class TextElement : public Texture { public: // constructors TextElement(); - TextElement(const char* text, int size, CST_Color* color = 0, int font_type = NORMAL, int wrapped_width = 0); + TextElement(std::string text, int size, CST_Color* color = 0, int font_type = NORMAL, int wrapped_width = 0); // change TextElement void setText(const std::string& text); @@ -28,6 +33,12 @@ class TextElement : public Texture // if specified, will override any font_type setting std::string customFontPath = ""; + static std::unordered_map i18nCache; + static void loadI18nCache(std::string locale); + + // if true, replaces all NORMAL fonts with SIMPLIFIED_CHINESE + static bool useSimplifiedChineseFont; + private: // default values int textSize = 16;