feat: Full UI internationalization, pool hashrate stats, and layout caching

- Replace all hardcoded English strings with TR() translation keys across
  every tab, dialog, and component (~20 UI files)
- Expand all 8 language files (de, es, fr, ja, ko, pt, ru, zh) with
  complete translations (~37k lines added)
- Improve i18n loader with exe-relative path fallback and English base
  fallback for missing keys
- Add pool-side hashrate polling via pool stats API in xmrig_manager
- Introduce Layout::beginFrame() per-frame caching and refresh balance
  layout config only on schema generation change
- Offload daemon output parsing to worker thread
- Add CJK subset fallback font for Chinese/Japanese/Korean glyphs
This commit is contained in:
2026-03-11 00:40:50 -05:00
parent f416ff3d09
commit 2c5a658ea5
71 changed files with 43567 additions and 5267 deletions

View File

@@ -246,11 +246,14 @@ ImFont* Typography::loadFont(ImGuiIO& io, int weight, float size, const char* na
cfg.PixelSnapH = true;
// Include default ASCII + Latin, Latin Extended (for Spanish/multilingual),
// plus arrows (⇄ U+21C4), math (≈ U+2248),
// general punctuation (— U+2014, … U+2026, etc.)
// Cyrillic (for Russian), Greek, plus arrows (⇄ U+21C4),
// math (≈ U+2248), general punctuation (— U+2014, … U+2026, etc.)
static const ImWchar glyphRanges[] = {
0x0020, 0x00FF, // Basic Latin + Latin-1 Supplement
0x0100, 0x024F, // Latin Extended-A + Latin Extended-B (Spanish, etc.)
0x0370, 0x03FF, // Greek and Coptic
0x0400, 0x04FF, // Cyrillic (Russian, Ukrainian, etc.)
0x0500, 0x052F, // Cyrillic Supplement
0x2000, 0x206F, // General Punctuation (em dash, ellipsis, etc.)
0x2190, 0x21FF, // Arrows (includes ⇄ U+21C4, ↻ U+21BB)
0x2200, 0x22FF, // Mathematical Operators (includes ≈ U+2248)
@@ -269,6 +272,36 @@ ImFont* Typography::loadFont(ImGuiIO& io, int weight, float size, const char* na
if (font) {
DEBUG_LOGF("Typography: Loaded %s (%.0fpx) as '%s'\n", name, size, cfg.Name);
// Merge CJK fallback glyphs (Chinese/Japanese/Korean) from subset font
if (g_noto_cjk_subset_size > 0) {
void* cjkCopy = IM_ALLOC(g_noto_cjk_subset_size);
memcpy(cjkCopy, g_noto_cjk_subset_data, g_noto_cjk_subset_size);
ImFontConfig cjkCfg;
cjkCfg.FontDataOwnedByAtlas = true;
cjkCfg.MergeMode = true; // merge into the font we just loaded
cjkCfg.OversampleH = 1;
cjkCfg.OversampleV = 1;
cjkCfg.PixelSnapH = true;
cjkCfg.GlyphMinAdvanceX = 0;
// CJK Unified Ideographs + Hiragana + Katakana + Hangul + fullwidth punctuation
static const ImWchar cjkRanges[] = {
0x2E80, 0x2FDF, // CJK Radicals
0x3000, 0x30FF, // CJK Symbols, Hiragana, Katakana
0x3100, 0x312F, // Bopomofo
0x31F0, 0x31FF, // Katakana Extensions
0x3400, 0x4DBF, // CJK Extension A
0x4E00, 0x9FFF, // CJK Unified Ideographs
0xAC00, 0xD7AF, // Hangul Syllables
0xFF00, 0xFFEF, // Fullwidth Forms
0,
};
cjkCfg.GlyphRanges = cjkRanges;
snprintf(cjkCfg.Name, sizeof(cjkCfg.Name), "NotoSansCJK %.0fpx (merge)", size);
io.Fonts->AddFontFromMemoryTTF(cjkCopy, g_noto_cjk_subset_size, size, &cjkCfg);
}
} else {
DEBUG_LOGF("Typography: Failed to load %s\n", name);
IM_FREE(fontDataCopy);