mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-06 23:57:39 +03:00
## Major Features ### 1. CJK UI Font System - Implemented external font loading system for CJK characters - Added Source Han Sans (思源黑体) as base font for UI rendering - Support for multiple font sizes (20pt, 22pt, 24pt) - Font selection UI for both reader and UI fonts - Automatic fallback to built-in fonts when external fonts unavailable - External UI font now renders ALL characters (including ASCII) for consistent style - Proportional spacing for external fonts (variable width per character) ### 2. Complete I18N Implementation - Added comprehensive internationalization system - Support for English, Chinese Simplified, and Japanese - Translated all UI strings across the entire application - Language selection UI in settings with native language names - English displayed as "English" - Chinese displayed as "简体中文" - Japanese displayed as "日本語" - Dynamic language switching without restart ### 3. Bug Fixes #### Rendering Race Conditions - Fixed race condition where parent and child Activity rendering tasks run simultaneously - Added 500ms delay in child Activity displayTaskLoop() to wait for parent rendering completion - Unified displayTaskLoop() logic: `if (updateRequired && !subActivity)` - Prevents duplicate RED RAM writes and incomplete screen refreshes **Affected Activities:** - CategorySettingsActivity: Unified displayTaskLoop check logic - KOReaderSettingsActivity: Added 500ms delay before first render - CalibreSettingsActivity: Added 500ms delay before first render - FontSelectActivity: Added 500ms delay before first render - ClearCacheActivity: Added 500ms delay and subActivity check - LanguageSelectActivity: Added 500ms delay in displayTaskLoop (not onEnter) #### Button Response Issues - Fixed CrossPointWebServer exit button requiring long press - Added MappedInputManager::update() method - Call update() before wasPressed() in tight HTTP processing loop - Button presses during loop are now properly detected #### ClearCache Crash - Fixed FreeRTOS mutex deadlock when exiting ClearCache activity - Added isExiting flag to prevent operations during exit - Added clearCacheTaskHandle tracking - Wait for clearCache task completion before deleting mutex #### External UI Font Rendering - Fixed ASCII characters not using external UI font (was using built-in EPD font) - Fixed character spacing too wide (now uses proportional spacing via getGlyphMetrics) ## Technical Details **Files Added:** - lib/ExternalFont/: External font loading system - lib/I18n/: Internationalization system - lib/GfxRenderer/cjk_ui_font*.h: Pre-rendered CJK font data - scripts/generate_cjk_ui_font.py: Font generation script - src/activities/settings/FontSelectActivity.*: Font selection UI - src/activities/settings/LanguageSelectActivity.*: Language selection UI - docs/cjk-fonts.md: CJK font documentation - docs/i18n.md: I18N documentation **Files Modified:** - lib/GfxRenderer/: Added CJK font rendering support with proportional spacing - src/activities/: I18N integration across all activities - src/MappedInputManager.*: Added update() method - src/CrossPointSettings.cpp: Added language and font settings **Memory Usage:** - Flash: 94.7% (6204434 bytes / 6553600 bytes) - RAM: 66.4% (217556 bytes / 327680 bytes) ## Testing Notes All rendering race conditions and button response issues have been fixed and tested. ClearCache no longer crashes when exiting. File transfer page now responds to short press on exit button. External UI font now renders all characters with proper proportional spacing. Language selection page displays language names in their native scripts. Co-authored-by: Claude (Anthropic AI Assistant)
1032 lines
57 KiB
C++
1032 lines
57 KiB
C++
#include "I18n.h"
|
|
|
|
#include <HardwareSerial.h>
|
|
#include <SDCardManager.h>
|
|
#include <Serialization.h>
|
|
|
|
#include <algorithm>
|
|
#include <set>
|
|
#include <string>
|
|
|
|
// Settings file path
|
|
static constexpr const char *SETTINGS_FILE = "/.crosspoint/language.bin";
|
|
static constexpr uint8_t SETTINGS_VERSION = 1;
|
|
|
|
I18n &I18n::getInstance() {
|
|
static I18n instance;
|
|
return instance;
|
|
}
|
|
|
|
// English strings
|
|
const char *const I18n::STRINGS_EN[] = {
|
|
// Boot/Sleep
|
|
"CrossPoint", "BOOTING", "SLEEPING", "Entering Sleep...",
|
|
|
|
// Home Menu
|
|
"Browse Files", "File Transfer", "Settings", "Calibre Library",
|
|
"Continue Reading", "No open book", "Start reading below",
|
|
|
|
// File Browser
|
|
"Books", "No books found",
|
|
|
|
// Reader
|
|
"Select Chapter", "No chapters", "End of book", "Empty chapter",
|
|
"Indexing...", "Memory error", "Page load error", "Empty file",
|
|
"Out of bounds", "Loading...", "Failed to load XTC", "Failed to load TXT",
|
|
"Failed to load EPUB", "SD card error",
|
|
|
|
// Network
|
|
"WiFi Networks", "No networks found", "%zu networks found", "Scanning...",
|
|
"Connecting...", "Connected!", "Connection Failed", "Connection timeout",
|
|
"Forget Network?",
|
|
"Save password for next time?", "Remove saved password?",
|
|
"Press OK to scan again", "Press any button to continue",
|
|
"LEFT/RIGHT: Select | OK: Confirm", "How would you like to connect?",
|
|
"Join a Network", "Create Hotspot", "Connect to an existing WiFi network",
|
|
"Create a WiFi network others can join", "Starting Hotspot...",
|
|
"Hotspot Mode", "Connect your device to this WiFi network",
|
|
"Open this URL in your browser", "or http://",
|
|
"or scan QR code with your phone:", "Calibre Wireless", "Calibre Web URL",
|
|
"Connect as Wireless Device", "* = Encrypted | + = Saved", "MAC address:",
|
|
"Checking WiFi...", "Enter WiFi Password", "Enter Text",
|
|
|
|
// Calibre Wireless
|
|
"Discovering Calibre...", "Connecting to ", "Connected to ",
|
|
"Waiting for commands...", "(Connection failed, retrying)",
|
|
"Calibre disconnected", "Waiting for transfer...",
|
|
"If transfer fails, enable\n'Ignore free space' in Calibre's\nSmartDevice plugin settings.",
|
|
"Receiving: ", "Received: ", "Waiting for more...",
|
|
"Failed to create file", "Password required", "Transfer interrupted",
|
|
|
|
// Settings Categories
|
|
"Display", "Reader", "Controls", "System",
|
|
|
|
// Settings
|
|
"Sleep Screen", "Sleep Screen Cover Mode", "Status Bar", "Hide Battery %",
|
|
"Extra Paragraph Spacing", "Text Anti-Aliasing", "Short Power Button Click",
|
|
"Reading Orientation", "Front Button Layout", "Side Button Layout (reader)",
|
|
"Long-press Chapter Skip", "Reader Font Family", "External Reader Font", "Reader Font", "UI Font",
|
|
"UI Font Size", "Reader Line Spacing",
|
|
"ASCII Letter Spacing", "ASCII Digit Spacing", "CJK Spacing", "Color Mode",
|
|
"Reader Screen Margin", "Reader Paragraph Alignment", "Hyphenation", "Time to Sleep",
|
|
"Refresh Frequency", "Calibre Settings", "KOReader Sync", "Check for updates", "Language",
|
|
"Select Wallpaper", "Clear Reading Cache",
|
|
|
|
// Calibre Settings
|
|
"Calibre",
|
|
|
|
// KOReader Settings
|
|
"Username", "Password", "Sync Server URL", "Document Matching", "Authenticate",
|
|
"KOReader Username", "KOReader Password", "Filename", "Binary", "Set credentials first",
|
|
|
|
// KOReader Auth
|
|
"WiFi connection failed", "Authenticating...", "Successfully authenticated!",
|
|
"KOReader Auth", "KOReader sync is ready to use", "Authentication Failed", "Done",
|
|
|
|
// Clear Cache
|
|
"This will clear all cached book data.", "All reading progress will be lost!",
|
|
"Books will need to be re-indexed", "when opened again.",
|
|
"Clearing cache...", "Cache Cleared", "items removed", "failed",
|
|
"Failed to clear cache", "Check serial output for details",
|
|
|
|
// Setting Values
|
|
"Dark", "Light", "Custom", "Cover", "None", "Fit", "Crop", "No Progress",
|
|
"Full", "Never", "In Reader", "Always", "Ignore", "Sleep", "Page Turn",
|
|
"Portrait", "Landscape CW", "Inverted", "Landscape CCW",
|
|
"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm", "Lft, Bck, Cnfrm, Rght",
|
|
"Prev/Next", "Next/Prev", "Bookerly", "Noto Sans", "Open Dyslexic", "Small",
|
|
"Medium",
|
|
"Large", "X Large", "Tight", "Normal", "Wide", "Justify", "Left", "Center",
|
|
"Right", "1 min", "5 min", "10 min", "15 min", "30 min", "1 page",
|
|
"5 pages", "10 pages", "15 pages", "30 pages",
|
|
|
|
// OTA Update
|
|
"Update", "Checking for update...", "New update available!",
|
|
"Current Version: ", "New Version: ", "Updating...", "No update available",
|
|
"Update failed", "Update complete",
|
|
"Press and hold power button to turn back on",
|
|
|
|
// Font Selection
|
|
"External Font", "Built-in (Disabled)",
|
|
|
|
// OPDS Browser
|
|
"No entries found", "Downloading...", "Download failed", "Error:",
|
|
"Unnamed", "No server URL configured", "Failed to fetch feed",
|
|
"Failed to parse feed", "Network: ", "IP Address: ",
|
|
"or scan QR code with your phone to connect to Wifi.",
|
|
|
|
// Buttons
|
|
"\xC2\xAB Back", // « Back
|
|
"\xC2\xAB Exit", // « Exit
|
|
"\xC2\xAB Home", // « Home
|
|
"\xC2\xAB Save", // « Save
|
|
"Select", "Toggle", "Confirm", "Cancel", "Connect", "Open", "Download",
|
|
"Retry", "Yes", "No", "ON", "OFF", "Set", "Not Set", "Left", "Right", "Up",
|
|
"Down", "CAPS", "caps", "OK",
|
|
|
|
// Languages
|
|
"English",
|
|
"\xE7\xAE\x80\xE4\xBD\x93\xE4\xB8\xAD\xE6\x96\x87", // 简体中文
|
|
"\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E", // 日本語
|
|
};
|
|
|
|
// Chinese strings
|
|
const char *const I18n::STRINGS_ZH[] = {
|
|
// Boot/Sleep
|
|
"CrossPoint",
|
|
"\xE5\x90\xAF\xE5\x8A\xA8\xE4\xB8\xAD", // 启动中
|
|
"\xE4\xBC\x91\xE7\x9C\xA0\xE4\xB8\xAD", // 休眠中
|
|
"\xE8\xBF\x9B\xE5\x85\xA5\xE4\xBC\x91\xE7\x9C\xA0...", // 进入休眠...
|
|
|
|
// Home Menu
|
|
"\xE6\xB5\x8F\xE8\xA7\x88\xE6\x96\x87\xE4\xBB\xB6", // 浏览文件
|
|
"\xE6\x96\x87\xE4\xBB\xB6\xE4\xBC\xA0\xE8\xBE\x93", // 文件传输
|
|
"\xE8\xAE\xBE\xE7\xBD\xAE", // 设置
|
|
"Calibre\xE4\xB9\xA6\xE5\xBA\x93", // Calibre书库
|
|
"\xE7\xBB\xA7\xE7\xBB\xAD\xE9\x98\x85\xE8\xAF\xBB", // 继续阅读
|
|
"\xE6\x97\xA0\xE6\x89\x93\xE5\xBC\x80\xE7\x9A\x84\xE4\xB9\xA6\xE7\xB1"
|
|
"\x8D", // 无打开的书籍
|
|
"\xE4\xBB\x8E\xE4\xB8\x8B\xE6\x96\xB9\xE5\xBC\x80\xE5\xA7\x8B\xE9\x98"
|
|
"\x85\xE8\xAF\xBB", // 从下方开始阅读
|
|
|
|
// File Browser
|
|
"\xE4\xB9\xA6\xE7\xB1\x8D", // 书籍
|
|
"\xE6\x9C\xAA\xE6\x89\xBE\xE5\x88\xB0\xE4\xB9\xA6\xE7\xB1\x8D", // 未找到书籍
|
|
|
|
// Reader
|
|
"\xE9\x80\x89\xE6\x8B\xA9\xE7\xAB\xA0\xE8\x8A\x82", // 选择章节
|
|
"\xE6\x97\xA0\xE7\xAB\xA0\xE8\x8A\x82", // 无章节
|
|
"\xE5\xB7\xB2\xE5\x88\xB0\xE4\xB9\xA6\xE6\x9C\xAB", // 已到书末
|
|
"\xE7\xA9\xBA\xE7\xAB\xA0\xE8\x8A\x82", // 空章节
|
|
"\xE7\xB4\xA2\xE5\xBC\x95\xE4\xB8\xAD...", // 索引中...
|
|
"\xE5\x86\x85\xE5\xAD\x98\xE9\x94\x99\xE8\xAF\xAF", // 内存错误
|
|
"\xE9\xA1\xB5\xE9\x9D\xA2\xE5\x8A\xA0\xE8\xBD\xBD\xE9\x94\x99\xE8\xAF"
|
|
"\xAF", // 页面加载错误
|
|
"\xE7\xA9\xBA\xE6\x96\x87\xE4\xBB\xB6", // 空文件
|
|
"\xE8\xB6\x85\xE5\x87\xBA\xE8\x8C\x83\xE5\x9B\xB4", // 超出范围
|
|
"\xE5\x8A\xA0\xE8\xBD\xBD\xE4\xB8\xAD...", // 加载中...
|
|
"\xE5\x8A\xA0\xE8\xBD\xBDXTC\xE5\xA4\xB1\xE8\xB4\xA5", // 加载XTC失败
|
|
"\xE5\x8A\xA0\xE8\xBD\xBDTXT\xE5\xA4\xB1\xE8\xB4\xA5", // 加载TXT失败
|
|
"\xE5\x8A\xA0\xE8\xBD\xBD\x45\x50\x55\x42\xE5\xA4\xB1\xE8\xB4\xA5", // 加载EPUB失败
|
|
"\x53\x44\xE5\x8D\xA1\xE9\x94\x99\xE8\xAF\xAF", // SD卡错误
|
|
|
|
// Network
|
|
"WiFi\xE7\xBD\x91\xE7\xBB\x9C", // WiFi网络
|
|
"\xE6\x9C\xAA\xE6\x89\xBE\xE5\x88\xB0\xE7\xBD\x91\xE7\xBB\x9C", // 未找到网络
|
|
"\xE6\x89\xBE\xE5\x88\xB0%zu\xE4\xB8\xAA\xE7\xBD\x91\xE7\xBB\x9C", // 找到%zu个网络
|
|
"\xE6\x89\xAB\xE6\x8F\x8F\xE4\xB8\xAD...", // 扫描中...
|
|
"\xE8\xBF\x9E\xE6\x8E\xA5\xE4\xB8\xAD...", // 连接中...
|
|
"\xE5\xB7\xB2\xE8\xBF\x9E\xE6\x8E\xA5!", // 已连接!
|
|
"\xE8\xBF\x9E\xE6\x8E\xA5\xE5\xA4\xB1\xE8\xB4\xA5", // 连接失败
|
|
"\xE8\xBF\x9E\xE6\x8E\xA5\xE8\xB6\x85\xE6\x97\xB6", // 连接超时
|
|
"\xE5\xBF\x98\xE8\xAE\xB0\xE7\xBD\x91\xE7\xBB\x9C?", // 忘记网络?
|
|
"\xE4\xBF\x9D\xE5\xAD\x98\xE5\xAF\x86\xE7\xA0\x81?", // 保存密码?
|
|
"\xE5\x88\xA0\xE9\x99\xA4\xE5\xB7\xB2\xE4\xBF\x9D\xE5\xAD\x98\xE5\xAF"
|
|
"\x86\xE7\xA0\x81?", // 删除已保存密码?
|
|
"\xE6\x8C\x89\xE7\xA1\xAE\xE5\xAE\x9A\xE9\x87\x8D\xE6\x96\xB0\xE6\x89"
|
|
"\xAB\xE6\x8F\x8F", // 按确定重新扫描
|
|
"\xE6\x8C\x89\xE4\xBB\xBB\xE6\x84\x8F\xE9\x94\xAE\xE7\xBB\xA7\xE7\xBB"
|
|
"\xAD", // 按任意键继续
|
|
"\xE5\xB7\xA6/\xE5\x8F\xB3:\xE9\x80\x89\xE6\x8B\xA9 | "
|
|
"\xE7\xA1\xAE\xE5\xAE\x9A:\xE7\xA1\xAE\xE8\xAE\xA4", // 左/右:选择 |
|
|
// 确定:确认
|
|
"\xE9\x80\x89\xE6\x8B\xA9\xE8\xBF\x9E\xE6\x8E\xA5\xE6\x96\xB9\xE5\xBC"
|
|
"\x8F", // 选择连接方式
|
|
"\xE5\x8A\xA0\xE5\x85\xA5\xE7\xBD\x91\xE7\xBB\x9C", // 加入网络
|
|
"\xE5\x88\x9B\xE5\xBB\xBA\xE7\x83\xAD\xE7\x82\xB9", // 创建热点
|
|
"\xE8\xBF\x9E\xE6\x8E\xA5\xE5\x88\xB0\xE7\x8E\xB0\xE6\x9C\x89WiFi\xE7"
|
|
"\xBD\x91\xE7\xBB\x9C", // 连接到现有WiFi网络
|
|
"\xE5\x88\x9B\xE5\xBB\xBAWiFi\xE7\xBD\x91\xE7\xBB\x9C\xE4\xBE\x9B\xE4"
|
|
"\xBB\x96\xE4\xBA\xBA\xE8\xBF\x9E\xE6\x8E\xA5", // 创建WiFi网络供他人连接
|
|
"\xE5\x90\xAF\xE5\x8A\xA8\xE7\x83\xAD\xE7\x82\xB9\xE4\xB8\xAD...", // 启动热点中...
|
|
"\xE7\x83\xAD\xE7\x82\xB9\xE6\xA8\xA1\xE5\xBC\x8F", // 热点模式
|
|
"\xE5\xB0\x86\xE8\xAE\xBE\xE5\xA4\x87\xE8\xBF\x9E\xE6\x8E\xA5\xE5\x88"
|
|
"\xB0\xE6\xAD\xA4WiFi", // 将设备连接到此WiFi
|
|
"\xE5\x9C\xA8\xE6\xB5\x8F\xE8\xA7\x88\xE5\x99\xA8\xE4\xB8\xAD\xE6\x89"
|
|
"\x93\xE5\xBC\x80\xE6\xAD\xA4URL", // 在浏览器中打开此URL
|
|
"\xE6\x88\x96\x20\x68\x74\x74\x70\x3A\x2F\x2F", // 或 http://
|
|
"\xE6\x88\x96\xE7\x94\xA8\xE6\x89\x8B\xE6\x9C\xBA\xE6\x89\xAB\xE6\x8F"
|
|
"\x8F\xE4\xBA\x8C\xE7\xBB\xB4\xE7\xA0\x81:", // 或用手机扫描二维码:
|
|
"Calibre\xE6\x97\xA0\xE7\xBA\xBF\xE8\xBF\x9E\xE6\x8E\xA5", // Calibre无线连接
|
|
"Calibre Web\xE5\x9C\xB0\xE5\x9D\x80", // Calibre Web地址
|
|
"\xE4\xBD\x9C\xE4\xB8\xBA\xE6\x97\xA0\xE7\xBA\xBF\xE8\xAE\xBE\xE5\xA4"
|
|
"\x87\xE8\xBF\x9E\xE6\x8E\xA5", // 作为无线设备连接
|
|
"* = \xE5\x8A\xA0\xE5\xAF\x86 | + = "
|
|
"\xE5\xB7\xB2\xE4\xBF\x9D\xE5\xAD\x98", // * = 加密 | + = 已保存
|
|
"MAC\xE5\x9C\xB0\xE5\x9D\x80:", // MAC地址:
|
|
"\xE6\xA3\x80\xE6\x9F\xA5WiFi...", // 检查WiFi...
|
|
"\xE8\xBE\x93\xE5\x85\xA5WiFi\xE5\xAF\x86\xE7\xA0\x81", // 输入WiFi密码
|
|
"\xE8\xBE\x93\xE5\x85\xA5\xE6\x96\x87\xE5\xAD\x97", // 输入文字
|
|
|
|
// Calibre Wireless
|
|
"\xE6\xAD\xA3\xE5\x9C\xA8\xE6\x90\x9C\xE7\xB4\xA2\x43\x61\x6C\x69\x62\x72\x65...", // 正在搜索Calibre...
|
|
"\xE6\xAD\xA3\xE5\x9C\xA8\xE8\xBF\x9E\xE6\x8E\xA5\xE5\x88\xB0 ", // 正在连接到
|
|
"\xE5\xB7\xB2\xE8\xBF\x9E\xE6\x8E\xA5\xE5\x88\xB0 ", // 已连接到
|
|
"\xE7\xAD\x89\xE5\xBE\x85\xE6\x8C\x87\xE4\xBB\xA4\xE4\xB8\xAD...", // 等待指令中...
|
|
"\x28\xE8\xBF\x9E\xE6\x8E\xA5\xE5\xA4\xB1\xE8\xB4\xA5\xEF\xBC\x8C\xE9\x87\x8D\xE8\xAF\x95\xE4\xB8\xAD\x29", // (连接失败,重试中)
|
|
"Calibre\xE5\xB7\xB2\xE6\x96\xAD\xE5\xBC\x80", // Calibre已断开
|
|
"\xE7\xAD\x89\xE5\xBE\x85\xE4\xBC\xA0\xE8\xBE\x93\xE4\xB8\xAD...", // 等待传输中...
|
|
"\xE5\xA6\x82\xE4\xBC\xA0\xE8\xBE\x93\xE5\xA4\xB1\xE8\xB4\xA5\xEF\xBC\x8C\xE8\xAF\xB7\xE5\x9C\xA8\x43\x61\x6C\x69\x62\x72\x65\xE7\x9A\x84\n\x53\x6D\x61\x72\x74\x44\x65\x76\x69\x63\x65\xE6\x8F\x92\xE4\xBB\xB6\xE8\xAE\xBE\xE7\xBD\xAE\xE4\xB8\xAD\n\xE5\x90\xAF\xE7\x94\xA8\x27\x49\x67\x6E\x6F\x72\x65\x20\x66\x72\x65\x65\x20\x73\x70\x61\x63\x65\x27\xE3\x80\x82", // Transfer hint
|
|
"\xE6\xAD\xA3\xE5\x9C\xA8\xE6\x8E\xA5\xE6\x94\xB6: ", // 正在接收:
|
|
"\xE5\xB7\xB2\xE6\x8E\xA5\xE6\x94\xB6: ", // 已接收:
|
|
"\xE7\xAD\x89\xE5\xBE\x85\xE6\x9B\xB4\xE5\xA4\x9A\xE5\x86\x85\xE5\xAE\xB9...", // 等待更多内容...
|
|
"\xE5\x88\x9B\xE5\xBB\xBA\xE6\x96\x87\xE4\xBB\xB6\xE5\xA4\xB1\xE8\xB4\xA5", // 创建文件失败
|
|
"\xE9\x9C\x80\xE8\xA6\x81\xE5\xAF\x86\xE7\xA0\x81", // 需要密码
|
|
"\xE4\xBC\xA0\xE8\xBE\x93\xE4\xB8\xAD\xE6\x96\xAD", // 传输中断
|
|
|
|
// Settings Categories
|
|
"\xE6\x98\xBE\xE7\xA4\xBA", // 显示
|
|
"\xE9\x98\x85\xE8\xAF\xBB", // 阅读
|
|
"\xE6\x8E\xA7\xE5\x88\xB6", // 控制
|
|
"\xE7\xB3\xBB\xE7\xBB\x9F", // 系统
|
|
|
|
// Settings
|
|
"\xE4\xBC\x91\xE7\x9C\xA0\xE5\xB1\x8F\xE5\xB9\x95", // 休眠屏幕
|
|
"\xE5\xB0\x81\xE9\x9D\xA2\xE6\x98\xBE\xE7\xA4\xBA\xE6\xA8\xA1\xE5\xBC"
|
|
"\x8F", // 封面显示模式
|
|
"\xE7\x8A\xB6\xE6\x80\x81\xE6\xA0\x8F", // 状态栏
|
|
"\xE9\x9A\x90\xE8\x97\x8F\xE7\x94\xB5\xE9\x87\x8F\xE7\x99\xBE\xE5\x88"
|
|
"\x86\xE6\xAF\x94", // 隐藏电量百分比
|
|
"\xE6\xAE\xB5\xE8\x90\xBD\xE9\xA2\x9D\xE5\xA4\x96\xE9\x97\xB4\xE8\xB7"
|
|
"\x9D", // 段落额外间距
|
|
"\xE6\x96\x87\xE5\xAD\x97\xE6\x8A\x97\xE9\x94\xAF\xE9\xBD\xBF", // 文字抗锯齿
|
|
"\xE7\x94\xB5\xE6\xBA\x90\xE9\x94\xAE\xE7\x9F\xAD\xE6\x8C\x89", // 电源键短按
|
|
"\xE9\x98\x85\xE8\xAF\xBB\xE6\x96\xB9\xE5\x90\x91", // 阅读方向
|
|
"\xE5\x89\x8D\xE7\xBD\xAE\xE6\x8C\x89\xE9\x92\xAE\xE5\xB8\x83\xE5\xB1"
|
|
"\x80", // 前置按钮布局
|
|
"\xE4\xBE\xA7\xE8\xBE\xB9\xE6\x8C\x89\xE9\x92\xAE\xE5\xB8\x83\xE5\xB1"
|
|
"\x80", // 侧边按钮布局
|
|
"\xE9\x95\xBF\xE6\x8C\x89\xE8\xB7\xB3\xE8\xBD\xAC\xE7\xAB\xA0\xE8\x8A"
|
|
"\x82", // 长按跳转章节
|
|
"\xE9\x98\x85\xE8\xAF\xBB\xE5\xAD\x97\xE4\xBD\x93", // 阅读字体
|
|
"\xE9\x98\x85\xE8\xAF\xBB\xE5\x99\xA8\xE5\xAD\x97\xE4\xBD\x93", // 阅读器字体 (EXT_READER_FONT)
|
|
"\xE9\x98\x85\xE8\xAF\xBB\xE5\x99\xA8\xE5\xAD\x97\xE4\xBD\x93", // 阅读器字体 (EXT_CHINESE_FONT)
|
|
"UI\xE5\xAD\x97\xE4\xBD\x93", // UI字体
|
|
"\xE5\xAD\x97\xE4\xBD\x93\xE5\xA4\xA7\xE5\xB0\x8F", // 字体大小
|
|
"\xE8\xA1\x8C\xE9\x97\xB4\xE8\xB7\x9D", // 行间距
|
|
"\x41\x53\x43\x49\x49\x20\xE5\xAD\x97\xE6\xAF\x8D\xE9\x97\xB4"
|
|
"\xE8\xB7\x9D", // ASCII 字母间距
|
|
"\x41\x53\x43\x49\x49\x20\xE6\x95\xB0\xE5\xAD\x97\xE9\x97\xB4"
|
|
"\xE8\xB7\x9D", // ASCII 数字间距
|
|
"\xE6\xB1\x89\xE5\xAD\x97\xE9\x97\xB4\xE8\xB7\x9D", // 汉字间距
|
|
"\xE9\xA2\x9C\xE8\x89\xB2\xE6\xA8\xA1\xE5\xBC\x8F", // 颜色模式
|
|
"\xE9\xA1\xB5\xE9\x9D\xA2\xE8\xBE\xB9\xE8\xB7\x9D", // 页面边距
|
|
"\xE6\xAE\xB5\xE8\x90\xBD\xE5\xAF\xB9\xE9\xBD\x90", // 段落对齐
|
|
"\xE8\xBF\x9E\xE5\xAD\x97\xE7\xAC\xA6", // 连字符 (HYPHENATION)
|
|
"\xE4\xBC\x91\xE7\x9C\xA0\xE6\x97\xB6\xE9\x97\xB4", // 休眠时间
|
|
"\xE5\x88\xB7\xE6\x96\xB0\xE9\xA2\x91\xE7\x8E\x87", // 刷新频率
|
|
"Calibre\xE8\xAE\xBE\xE7\xBD\xAE", // Calibre设置
|
|
"KOReader\xE5\x90\x8C\xE6\xAD\xA5", // KOReader同步
|
|
"\xE6\xA3\x80\xE6\x9F\xA5\xE6\x9B\xB4\xE6\x96\xB0", // 检查更新
|
|
"\xE8\xAF\xAD\xE8\xA8\x80", // 语言
|
|
"\xE9\x80\x89\xE6\x8B\xA9\xE5\xA3\x81\xE7\xBA\xB8", // 选择壁纸
|
|
"\xE6\xB8\x85\xE7\x90\x86\xE9\x98\x85\xE8\xAF\xBB\xE7\xBC\x93\xE5\xAD\x98", // 清理阅读缓存
|
|
|
|
// Calibre Settings
|
|
"Calibre",
|
|
|
|
// KOReader Settings
|
|
"\xE7\x94\xA8\xE6\x88\xB7\xE5\x90\x8D", // 用户名
|
|
"\xE5\xAF\x86\xE7\xA0\x81", // 密码
|
|
"\xE5\x90\x8C\xE6\xAD\xA5\xE6\x9C\x8D\xE5\x8A\xA1\xE5\x99\xA8\xE5\x9C\xB0\xE5\x9D\x80", // 同步服务器地址
|
|
"\xE6\x96\x87\xE6\xA1\xA3\xE5\x8C\xB9\xE9\x85\x8D", // 文档匹配
|
|
"\xE8\xAE\xA4\xE8\xAF\x81", // 认证
|
|
"KOReader\xE7\x94\xA8\xE6\x88\xB7\xE5\x90\x8D", // KOReader用户名
|
|
"KOReader\xE5\xAF\x86\xE7\xA0\x81", // KOReader密码
|
|
"\xE6\x96\x87\xE4\xBB\xB6\xE5\x90\x8D", // 文件名
|
|
"\xE4\xBA\x8C\xE8\xBF\x9B\xE5\x88\xB6", // 二进制
|
|
"\xE8\xAF\xB7\xE5\x85\x88\xE8\xAE\xBE\xE7\xBD\xAE\xE5\x87\xAD\xE6\x8D\xAE", // 请先设置凭据
|
|
|
|
// KOReader Auth
|
|
"WiFi\xE8\xBF\x9E\xE6\x8E\xA5\xE5\xA4\xB1\xE8\xB4\xA5", // WiFi连接失败
|
|
"\xE8\xAE\xA4\xE8\xAF\x81\xE4\xB8\xAD...", // 认证中...
|
|
"\xE8\xAE\xA4\xE8\xAF\x81\xE6\x88\x90\xE5\x8A\x9F\x21", // 认证成功!
|
|
"KOReader\xE8\xAE\xA4\xE8\xAF\x81", // KOReader认证
|
|
"KOReader\xE5\x90\x8C\xE6\xAD\xA5\xE5\xB7\xB2\xE5\xB0\xB1\xE7\xBB\xAA", // KOReader同步已就绪
|
|
"\xE8\xAE\xA4\xE8\xAF\x81\xE5\xA4\xB1\xE8\xB4\xA5", // 认证失败
|
|
"\xE5\xAE\x8C\xE6\x88\x90", // 完成
|
|
|
|
// Clear Cache
|
|
"\xE8\xBF\x99\xE5\xB0\x86\xE6\xB8\x85\xE9\x99\xA4\xE6\x89\x80\xE6\x9C\x89\xE7\xBC\x93\xE5\xAD\x98\xE7\x9A\x84\xE4\xB9\xA6\xE7\xB1\x8D\xE6\x95\xB0\xE6\x8D\xAE\xE3\x80\x82", // 这将清除所有缓存的书籍数据。
|
|
"\xE6\x89\x80\xE6\x9C\x89\xE9\x98\x85\xE8\xAF\xBB\xE8\xBF\x9B\xE5\xBA\xA6\xE5\xB0\x86\xE4\xB8\xA2\xE5\xA4\xB1\xEF\xBC\x81", // 所有阅读进度将丢失!
|
|
"\xE4\xB9\xA6\xE7\xB1\x8D\xE9\x9C\x80\xE8\xA6\x81\xE9\x87\x8D\xE6\x96\xB0\xE7\xB4\xA2\xE5\xBC\x95", // 书籍需要重新索引
|
|
"\xE5\xBD\x93\xE5\x86\x8D\xE6\xAC\xA1\xE6\x89\x93\xE5\xBC\x80\xE6\x97\xB6\xE3\x80\x82", // 当再次打开时。
|
|
"\xE6\xB8\x85\xE7\x90\x86\xE7\xBC\x93\xE5\xAD\x98\xE4\xB8\xAD...", // 清理缓存中...
|
|
"\xE7\xBC\x93\xE5\xAD\x98\xE5\xB7\xB2\xE6\xB8\x85\xE7\x90\x86", // 缓存已清理
|
|
"\xE9\xA1\xB9\xE5\xB7\xB2\xE5\x88\xA0\xE9\x99\xA4", // 项已删除
|
|
"\xE5\xA4\xB1\xE8\xB4\xA5", // 失败
|
|
"\xE6\xB8\x85\xE7\x90\x86\xE7\xBC\x93\xE5\xAD\x98\xE5\xA4\xB1\xE8\xB4\xA5", // 清理缓存失败
|
|
"\xE6\x9F\xA5\xE7\x9C\x8B\xE4\xB8\xB2\xE5\x8F\xA3\xE8\xBE\x93\xE5\x87\xBA\xE4\xBA\x86\xE8\xA7\xA3\xE8\xAF\xA6\xE6\x83\x85", // 查看串口输出了解详情
|
|
|
|
// Setting Values
|
|
"\xE6\xB7\xB1\xE8\x89\xB2", // 深色
|
|
"\xE6\xB5\x85\xE8\x89\xB2", // 浅色
|
|
"\xE8\x87\xAA\xE5\xAE\x9A\xE4\xB9\x89", // 自定义
|
|
"\xE5\xB0\x81\xE9\x9D\xA2", // 封面
|
|
"\xE6\x97\xA0", // 无
|
|
"\xE9\x80\x82\xE5\xBA\x94", // 适应
|
|
"\xE8\xA3\x81\xE5\x89\xAA", // 裁剪
|
|
"\xE6\x97\xA0\xE8\xBF\x9B\xE5\xBA\xA6", // 无进度
|
|
"\xE5\xAE\x8C\xE6\x95\xB4", // 完整
|
|
"\xE4\xBB\x8E\xE4\xB8\x8D", // 从不
|
|
"\xE9\x98\x85\xE8\xAF\xBB\xE6\x97\xB6", // 阅读时
|
|
"\xE5\xA7\x8B\xE7\xBB\x88", // 始终
|
|
"\xE5\xBF\xBD\xE7\x95\xA5", // 忽略
|
|
"\xE4\xBC\x91\xE7\x9C\xA0", // 休眠
|
|
"\xE7\xBF\xBB\xE9\xA1\xB5", // 翻页
|
|
"\xE7\xAB\x96\xE5\xB1\x8F", // 竖屏
|
|
"\xE6\xA8\xAA\xE5\xB1\x8F\xE9\xA1\xBA\xE6\x97\xB6\xE9\x92\x88", // 横屏顺时针
|
|
"\xE5\x80\x92\xE7\xBD\xAE", // 倒置
|
|
"\xE6\xA8\xAA\xE5\xB1\x8F\xE9\x80\x86\xE6\x97\xB6\xE9\x92\x88", // 横屏逆时针
|
|
"\xE8\xBF\x94\xE5\x9B\x9E\x2C\x20\xE7\xA1\xAE\xE8\xAE\xA4\x2C\x20\xE5\xB7\xA6\x2C\x20\xE5\x8F\xB3", // 返回, 确认, 左, 右
|
|
"\xE5\xB7\xA6\x2C\x20\xE5\x8F\xB3\x2C\x20\xE8\xBF\x94\xE5\x9B\x9E\x2C\x20\xE7\xA1\xAE\xE8\xAE\xA4", // 左, 右, 返回, 确认
|
|
"\xE5\xB7\xA6\x2C\x20\xE8\xBF\x94\xE5\x9B\x9E\x2C\x20\xE7\xA1\xAE\xE8\xAE\xA4\x2C\x20\xE5\x8F\xB3", // 左, 返回, 确认, 右
|
|
"\xE4\xB8\x8A\xE4\xB8\x80\xE9\xA1\xB5/"
|
|
"\xE4\xB8\x8B\xE4\xB8\x80\xE9\xA1\xB5", // 上一页/下一页
|
|
"\xE4\xB8\x8B\xE4\xB8\x80\xE9\xA1\xB5/"
|
|
"\xE4\xB8\x8A\xE4\xB8\x80\xE9\xA1\xB5", // 下一页/上一页
|
|
"Bookerly", "Noto Sans", "Open Dyslexic",
|
|
"\xE5\xB0\x8F", // 小
|
|
"\xE4\xB8\xAD", // 中
|
|
"\xE5\xA4\xA7", // 大
|
|
"\xE7\x89\xB9\xE5\xA4\xA7", // 特大
|
|
"\xE7\xB4\xA7\xE5\x87\x91", // 紧凑
|
|
"\xE6\xAD\xA3\xE5\xB8\xB8", // 正常
|
|
"\xE5\xAE\xBD\xE6\x9D\xBE", // 宽松
|
|
"\xE4\xB8\xA4\xE7\xAB\xAF\xE5\xAF\xB9\xE9\xBD\x90", // 两端对齐
|
|
"\xE5\xB7\xA6\xE5\xAF\xB9\xE9\xBD\x90", // 左对齐
|
|
"\xE5\xB1\x85\xE4\xB8\xAD", // 居中
|
|
"\xE5\x8F\xB3\xE5\xAF\xB9\xE9\xBD\x90", // 右对齐
|
|
"1\xE5\x88\x86\xE9\x92\x9F", // 1分钟
|
|
"5\xE5\x88\x86\xE9\x92\x9F", // 5分钟
|
|
"10\xE5\x88\x86\xE9\x92\x9F", // 10分钟
|
|
"15\xE5\x88\x86\xE9\x92\x9F", // 15分钟
|
|
"30\xE5\x88\x86\xE9\x92\x9F", // 30分钟
|
|
"1\xE9\xA1\xB5", // 1页
|
|
"5\xE9\xA1\xB5", // 5页
|
|
"10\xE9\xA1\xB5", // 10页
|
|
"15\xE9\xA1\xB5", // 15页
|
|
"30\xE9\xA1\xB5", // 30页
|
|
|
|
// OTA Update
|
|
"\xE6\x9B\xB4\xE6\x96\xB0", // 更新
|
|
"\xE6\xA3\x80\xE6\x9F\xA5\xE6\x9B\xB4\xE6\x96\xB0\xE4\xB8\xAD...", // 检查更新中...
|
|
"\xE6\x9C\x89\xE6\x96\xB0\xE7\x89\x88\xE6\x9C\xAC\xE5\x8F\xAF\xE7\x94"
|
|
"\xA8!", // 有新版本可用!
|
|
"\xE5\xBD\x93\xE5\x89\x8D\xE7\x89\x88\xE6\x9C\xAC: ", // 当前版本:
|
|
"\xE6\x96\xB0\xE7\x89\x88\xE6\x9C\xAC: ", // 新版本:
|
|
"\xE6\x9B\xB4\xE6\x96\xB0\xE4\xB8\xAD...", // 更新中...
|
|
"\xE5\xB7\xB2\xE6\x98\xAF\xE6\x9C\x80\xE6\x96\xB0\xE7\x89\x88\xE6\x9C"
|
|
"\xAC", // 已是最新版本
|
|
"\xE6\x9B\xB4\xE6\x96\xB0\xE5\xA4\xB1\xE8\xB4\xA5", // 更新失败
|
|
"\xE6\x9B\xB4\xE6\x96\xB0\xE5\xAE\x8C\xE6\x88\x90", // 更新完成
|
|
"\xE9\x95\xBF\xE6\x8C\x89\xE7\x94\xB5\xE6\xBA\x90\xE9\x94\xAE\xE5\xBC"
|
|
"\x80\xE6\x9C\xBA", // 长按电源键开机
|
|
|
|
// Font Selection
|
|
"\xE5\xA4\x96\xE7\xBD\xAE\xE5\xAD\x97\xE4\xBD\x93", // 外置字体
|
|
"\xE5\x86\x85\xE7\xBD\xAE(\xE5\xB7\xB2\xE7\xA6\x81\xE7\x94\xA8)", // 内置(已禁用)
|
|
|
|
// OPDS Browser
|
|
"\xE6\x97\xA0\xE6\x9D\xA1\xE7\x9B\xAE", // 无条目
|
|
"\xE4\xB8\x8B\xE8\xBD\xBD\xE4\xB8\xAD...", // 下载中...
|
|
"\xE4\xB8\x8B\xE8\xBD\xBD\xE5\xA4\xB1\xE8\xB4\xA5", // 下载失败
|
|
"\xE9\x94\x99\xE8\xAF\xAF:", // 错误:
|
|
"\xE6\x9C\xAA\xE5\x91\xBD\xE5\x90\x8D", // 未命名
|
|
"\xE6\x9C\xAA\xE9\x85\x8D\xE7\xBD\xAE\xE6\x9C\x8D\xE5\x8A\xA1\xE5\x99\xA8\xE5\x9C\xB0\xE5\x9D\x80", // 未配置服务器地址
|
|
"\xE8\x8E\xB7\xE5\x8F\x96\xE8\xAE\xA2\xE9\x98\x85\xE5\xA4\xB1\xE8\xB4\xA5", // 获取订阅失败
|
|
"\xE8\xA7\xA3\xE6\x9E\x90\xE8\xAE\xA2\xE9\x98\x85\xE5\xA4\xB1\xE8\xB4\xA5", // 解析订阅失败
|
|
"\xE7\xBD\x91\xE7\xBB\x9C: ", // 网络:
|
|
"IP\xE5\x9C\xB0\xE5\x9D\x80: ", // IP地址:
|
|
"\xE6\x88\x96\xE7\x94\xA8\xE6\x89\x8B\xE6\x9C\xBA\xE6\x89\xAB\xE6\x8F\x8F"
|
|
"\xE4\xBA\x8C\xE7\xBB\xB4\xE7\xA0\x81\xE8\xBF\x9E\xE6\x8E\xA5WiFi", // 或用手机扫描二维码连接WiFi
|
|
|
|
// Buttons
|
|
"\xC2\xAB \xE8\xBF\x94\xE5\x9B\x9E", // « 返回
|
|
"\xC2\xAB \xE9\x80\x80\xE5\x87\xBA", // « 退出
|
|
"\xC2\xAB \xE4\xB8\xBB\xE9\xA1\xB5", // « 主页
|
|
"\xC2\xAB \xE4\xBF\x9D\xE5\xAD\x98", // « 保存
|
|
"\xE9\x80\x89\xE6\x8B\xA9", // 选择
|
|
"\xE5\x88\x87\xE6\x8D\xA2", // 切换
|
|
"\xE7\xA1\xAE\xE5\xAE\x9A", // 确定
|
|
"\xE5\x8F\x96\xE6\xB6\x88", // 取消
|
|
"\xE8\xBF\x9E\xE6\x8E\xA5", // 连接
|
|
"\xE6\x89\x93\xE5\xBC\x80", // 打开
|
|
"\xE4\xB8\x8B\xE8\xBD\xBD", // 下载
|
|
"\xE9\x87\x8D\xE8\xAF\x95", // 重试
|
|
"\xE6\x98\xAF", // 是
|
|
"\xE5\x90\xA6", // 否
|
|
"\xE5\xBC\x80", // 开
|
|
"\xE5\x85\xB3", // 关
|
|
"\xE5\xB7\xB2\xE8\xAE\xBE\xE7\xBD\xAE", // 已设置
|
|
"\xE6\x9C\xAA\xE8\xAE\xBE\xE7\xBD\xAE", // 未设置
|
|
"\xE5\xB7\xA6", // 左
|
|
"\xE5\x8F\xB3", // 右
|
|
"\xE4\xB8\x8A", // 上
|
|
"\xE4\xB8\x8B", // 下
|
|
"\xE5\xA4\xA7\xE5\x86\x99", // 大写
|
|
"\xE5\xB0\x8F\xE5\x86\x99", // 小写
|
|
"\xE7\xA1\xAE\xE5\xAE\x9A", // 确定
|
|
|
|
// Languages
|
|
"English",
|
|
"\xE7\xAE\x80\xE4\xBD\x93\xE4\xB8\xAD\xE6\x96\x87", // 简体中文
|
|
"\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E", // 日本語
|
|
};
|
|
|
|
// Japanese strings
|
|
const char *const I18n::STRINGS_JA[] = {
|
|
// Boot/Sleep
|
|
"CrossPoint",
|
|
"\xE8\xB5\xB7\xE5\x8B\x95\xE4\xB8\xAD", // 起動中
|
|
"\xE3\x82\xB9\xE3\x83\xAA\xE3\x83\xBC\xE3\x83\x97\xE4\xB8\xAD", // スリープ中
|
|
"\xE3\x82\xB9\xE3\x83\xAA\xE3\x83\xBC\xE3\x83\x97\xE4\xB8\xAD...", // スリープ中...
|
|
|
|
// Home Menu
|
|
"\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\xE4\xB8\x80\xE8"
|
|
"\xA6"
|
|
"\xA7", // ファイル一覧
|
|
"\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\xE8\xBB\xA2\xE9"
|
|
"\x80"
|
|
"\x81", // ファイル転送
|
|
"\xE8\xA8\xAD\xE5\xAE\x9A", // 設定
|
|
"Calibre\xE3\x83\xA9\xE3\x82\xA4\xE3\x83\x96\xE3\x83\xA9\xE3\x83"
|
|
"\xAA", // Calibreライブラリ
|
|
"\xE7\xB6\x9A\xE3\x81\x8D\xE3\x82\x92\xE8\xAA\xAD\xE3\x82\x80", // 続きを読む
|
|
"\xE9\x96\x8B\xE3\x81\x84\xE3\x81\xA6\xE3\x81\x84\xE3\x82\x8B\xE6"
|
|
"\x9C"
|
|
"\xAC\xE3\x81\xAF\xE3\x81\x82\xE3\x82\x8A\xE3\x81\xBE\xE3\x81\x9B"
|
|
"\xE3"
|
|
"\x82\x93", // 開いている本はありません
|
|
"\xE4\xB8\x8B\xE3\x81\x8B\xE3\x82\x89\xE8\xAA\xAD\xE6\x9B\xB8\xE3"
|
|
"\x82"
|
|
"\x92\xE5\xA7\x8B\xE3\x82\x81\xE3\x82\x8B", // 下から読書を始める
|
|
|
|
// File Browser
|
|
"\xE6\x9C\xAC", // 本
|
|
"\xE6\x9C\xAC\xE3\x81\x8C\xE8\xA6\x8B\xE3\x81\xA4\xE3\x81\x8B\xE3"
|
|
"\x82"
|
|
"\x8A\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93", // 本が見つかりません
|
|
|
|
// Reader
|
|
"\xE7\xAB\xA0\xE3\x82\x92\xE9\x81\xB8\xE6\x8A\x9E", // 章を選択
|
|
"\xE7\xAB\xA0\xE3\x81\xAA\xE3\x81\x97", // 章なし
|
|
"\xE6\x9C\xAC\xE3\x81\xAE\xE7\xB5\x82\xE3\x82\x8F\xE3\x82\x8A", // 本の終わり
|
|
"\xE7\xA9\xBA\xE3\x81\xAE\xE7\xAB\xA0", // 空の章
|
|
"\xE3\x82\xA4\xE3\x83\xB3\xE3\x83\x87\xE3\x83\x83\xE3\x82\xAF\xE3"
|
|
"\x82"
|
|
"\xB9\xE4\xB8\xAD...", // インデックス中...
|
|
"\xE3\x83\xA1\xE3\x83\xA2\xE3\x83\xAA\xE3\x82\xA8\xE3\x83\xA9\xE3"
|
|
"\x83"
|
|
"\xBC", // メモリエラー
|
|
"\xE3\x83\x9A\xE3\x83\xBC\xE3\x82\xB8\xE8\xAA\xAD\xE3\x81\xBF\xE8"
|
|
"\xBE"
|
|
"\xBC\xE3\x81\xBF\xE3\x82\xA8\xE3\x83\xA9\xE3\x83\xBC", // ページ読み込みエラー
|
|
"\xE7\xA9\xBA\xE3\x81\xAE\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3"
|
|
"\x83"
|
|
"\xAB", // 空のファイル
|
|
"\xE7\xAF\x84\xE5\x9B\xB2\xE5\xA4\x96", // 範囲外
|
|
"\xE8\xAA\xAD\xE3\x81\xBF\xE8\xBE\xBC\xE3\x81\xBF\xE4\xB8\xAD...", // 読み込み中...
|
|
"\x58\x54\x43\xE3\x81\xAE\xE8\xAA\xAD\xE3\x81\xBF\xE8\xBE\xBC\xE3\x81\xBF\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // XTCの読み込みに失敗しました
|
|
"\x54\x58\x54\xE3\x81\xAE\xE8\xAA\xAD\xE3\x81\xBF\xE8\xBE\xBC\xE3\x81\xBF\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // TXTの読み込みに失敗しました
|
|
"\x45\x50\x55\x42\xE3\x81\xAE\xE8\xAA\xAD\xE3\x81\xBF\xE8\xBE\xBC\xE3\x81\xBF\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // EPUBの読み込みに失敗しました
|
|
"\x53\x44\xE3\x82\xAB\xE3\x83\xBC\xE3\x83\x89\xE3\x82\xA8\xE3\x83\xA9\xE3\x83\xBC", // SDカードエラー
|
|
|
|
// Network
|
|
"WiFi\xE3\x83\x8D\xE3\x83\x83\xE3\x83\x88\xE3\x83\xAF\xE3\x83\xBC"
|
|
"\xE3"
|
|
"\x82\xAF", // WiFiネットワーク
|
|
"\xE3\x83\x8D\xE3\x83\x83\xE3\x83\x88\xE3\x83\xAF\xE3\x83\xBC\xE3"
|
|
"\x82"
|
|
"\xAF\xE3\x81\x8C\xE8\xA6\x8B\xE3\x81\xA4\xE3\x81\x8B\xE3\x82\x8A"
|
|
"\xE3"
|
|
"\x81\xBE\xE3\x81\x9B\xE3\x82\x93", // ネットワークが見つかりません
|
|
"%zu\xE4\xBB\xB6\xE3\x81\xAE\xE3\x83\x8D\xE3\x83\x83\xE3\x83\x88\xE3\x83\xAF\xE3\x83\xBC\xE3\x82\xAF\xE3\x81\x8C\xE8\xA6\x8B\xE3\x81\xA4\xE3\x81\x8B\xE3\x82\x8A\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // %zu件のネットワークが見つかりました
|
|
"\xE3\x82\xB9\xE3\x82\xAD\xE3\x83\xA3\xE3\x83\xB3\xE4\xB8\xAD...", // スキャン中...
|
|
"\xE6\x8E\xA5\xE7\xB6\x9A\xE4\xB8\xAD...", // 接続中...
|
|
"\xE6\x8E\xA5\xE7\xB6\x9A\xE5\xAE\x8C\xE4\xBA\x86!", // 接続完了!
|
|
"\xE6\x8E\xA5\xE7\xB6\x9A\xE5\xA4\xB1\xE6\x95\x97", // 接続失敗
|
|
"\xE6\x8E\xA5\xE7\xB6\x9A\xE3\x82\xBF\xE3\x82\xA4\xE3\x83\xA0\xE3\x82\xA2\xE3\x82\xA6\xE3\x83\x88", // 接続タイムアウト
|
|
"\xE3\x83\x8D\xE3\x83\x83\xE3\x83\x88\xE3\x83\xAF\xE3\x83\xBC\xE3"
|
|
"\x82"
|
|
"\xAF\xE3\x82\x92\xE5\xBF\x98\xE3\x82\x8C\xE3\x82\x8B?", // ネットワークを忘れる?
|
|
"\xE3\x83\x91\xE3\x82\xB9\xE3\x83\xAF\xE3\x83\xBC\xE3\x83\x89\xE3"
|
|
"\x82"
|
|
"\x92\xE4\xBF\x9D\xE5\xAD\x98?", // パスワードを保存?
|
|
"\xE4\xBF\x9D\xE5\xAD\x98\xE3\x81\x97\xE3\x81\x9F\xE3\x83\x91\xE3"
|
|
"\x82"
|
|
"\xB9\xE3\x83\xAF\xE3\x83\xBC\xE3\x83\x89\xE3\x82\x92\xE5\x89\x8A"
|
|
"\xE9"
|
|
"\x99\xA4?", // 保存したパスワードを削除?
|
|
"OK\xE3\x82\x92\xE6\x8A\xBC\xE3\x81\x97\xE3\x81\xA6\xE5\x86\x8D\xE3"
|
|
"\x82"
|
|
"\xB9\xE3\x82\xAD\xE3\x83\xA3\xE3\x83\xB3", // OKを押して再スキャン
|
|
"\xE4\xBB\xBB\xE6\x84\x8F\xE3\x81\xAE\xE3\x83\x9C\xE3\x82\xBF\xE3"
|
|
"\x83"
|
|
"\xB3\xE3\x82\x92\xE6\x8A\xBC\xE3\x81\x97\xE3\x81\xA6\xE7\xB6\x9A"
|
|
"\xE8"
|
|
"\xA1\x8C", // 任意のボタンを押して続行
|
|
"\xE5\xB7\xA6/\xE5\x8F\xB3:\xE9\x81\xB8\xE6\x8A\x9E | "
|
|
"OK:\xE7\xA1\xBA\xE8\xAA\x8D", // 左/右:選択 | OK:確認
|
|
"\xE6\x8E\xA5\xE7\xB6\x9A\xE6\x96\xB9\xE6\xB3\x95\xE3\x82\x92\xE9"
|
|
"\x81"
|
|
"\xB8\xE6\x8A\x9E", // 接続方法を選択
|
|
"\xE3\x83\x8D\xE3\x83\x83\xE3\x83\x88\xE3\x83\xAF\xE3\x83\xBC\xE3"
|
|
"\x82"
|
|
"\xAF\xE3\x81\xAB\xE5\x8F\x82\xE5\x8A\xA0", // ネットワークに参加
|
|
"\xE3\x83\x9B\xE3\x83\x83\xE3\x83\x88\xE3\x82\xB9\xE3\x83\x9D\xE3"
|
|
"\x83"
|
|
"\x83\xE3\x83\x88\xE3\x82\x92\xE4\xBD\x9C\xE6\x88\x90", // ホットスポットを作成
|
|
"\xE6\x97\xA2\xE5\xAD\x98\xE3\x81\xAEWiFi\xE3\x81\xAB\xE6\x8E\xA5"
|
|
"\xE7"
|
|
"\xB6\x9A", // 既存のWiFiに接続
|
|
"WiFi\xE3\x82\x92\xE4\xBD\x9C\xE6\x88\x90\xE3\x81\x97\xE3\x81\xA6"
|
|
"\xE4"
|
|
"\xBB\x96\xE3\x81\xAE\xE4\xBA\xBA\xE3\x81\x8C\xE6\x8E\xA5\xE7\xB6"
|
|
"\x9A", // WiFiを作成して他の人が接続
|
|
"\xE3\x83\x9B\xE3\x83\x83\xE3\x83\x88\xE3\x82\xB9\xE3\x83\x9D\xE3"
|
|
"\x83"
|
|
"\x83\xE3\x83\x88\xE3\x82\x92\xE8\xB5\xB7\xE5\x8B\x95\xE4\xB8\xAD.."
|
|
".", // ホットスポットを起動中...
|
|
"\xE3\x83\x9B\xE3\x83\x83\xE3\x83\x88\xE3\x82\xB9\xE3\x83\x9D\xE3"
|
|
"\x83"
|
|
"\x83\xE3\x83\x88\xE3\x83\xA2\xE3\x83\xBC\xE3\x83\x89", // ホットスポットモード
|
|
"\xE3\x81\x93\xE3\x81\xAEWiFi\xE3\x81\xAB\xE3\x83\x87\xE3\x83\x90"
|
|
"\xE3"
|
|
"\x82\xA4\xE3\x82\xB9\xE3\x82\x92\xE6\x8E\xA5\xE7\xB6\x9A", // このWiFiにデバイスを接続
|
|
"\xE3\x83\x96\xE3\x83\xA9\xE3\x82\xA6\xE3\x82\xB6\xE3\x81\xA7\xE3"
|
|
"\x81"
|
|
"\x93\xE3\x81\xAEURL\xE3\x82\x92\xE9\x96\x8B\xE3\x81\x8F", // ブラウザでこのURLを開く
|
|
"\xE3\x81\xBE\xE3\x81\x9F\xE3\x81\xAF\x20\x68\x74\x74\x70\x3A\x2F\x2F", // または http://
|
|
"\xE3\x82\xB9\xE3\x83\x9E\xE3\x83\x9B\xE3\x81\xA7QR\xE3\x82\xB3\xE3"
|
|
"\x83"
|
|
"\xBC\xE3\x83\x89\xE3\x82\x92\xE3\x82\xB9\xE3\x82\xAD\xE3\x83\xA3"
|
|
"\xE3"
|
|
"\x83\xB3:", // スマホでQRコードをスキャン:
|
|
"Calibre\xE3\x83\xAF\xE3\x82\xA4\xE3\x83\xA4\xE3\x83\xAC\xE3\x82"
|
|
"\xB9", // Calibreワイヤレス
|
|
"\x43\x61\x6C\x69\x62\x72\x65\x20\x57\x65\x62\x20\xE3\x82\xA2\xE3\x83\x89\xE3\x83\xAC\xE3\x82\xB9",
|
|
"\xE3\x83\xAF\xE3\x82\xA4\xE3\x83\xA4\xE3\x83\xAC\xE3\x82\xB9\xE3"
|
|
"\x83"
|
|
"\x87\xE3\x83\x90\xE3\x82\xA4\xE3\x82\xB9\xE3\x81\xA8\xE3\x81\x97"
|
|
"\xE3"
|
|
"\x81\xA6\xE6\x8E\xA5\xE7\xB6\x9A", // ワイヤレスデバイスとして接続
|
|
"* = \xE6\x9A\x97\xE5\x8F\xB7\xE5\x8C\x96 | + = "
|
|
"\xE4\xBF\x9D\xE5\xAD\x98\xE6\xB8\x88\xE3\x81\xBF", // * = 暗号化 |
|
|
// + = 保存済み
|
|
"MAC\xE3\x82\xA2\xE3\x83\x89\xE3\x83\xAC\xE3\x82\xB9:", // MACアドレス:
|
|
"WiFi\xE7\xA2\xBA\xE8\xAA\x8D\xE4\xB8\xAD...", // WiFi確認中...
|
|
"WiFi\xE3\x83\x91\xE3\x82\xB9\xE3\x83\xAF\xE3\x83\xBC\xE3\x83\x89\xE3\x82\x92\xE5\x85\xA5\xE5\x8A\x9B", // WiFiパスワードを入力
|
|
"\xE6\x96\x87\xE5\xAD\x97\xE3\x82\x92\xE5\x85\xA5\xE5\x8A\x9B", // 文字を入力
|
|
|
|
// Calibre Wireless
|
|
"Calibre\xE3\x82\x92\xE6\xA4\x9C\xE7\xB4\xA2\xE4\xB8\xAD...", // Calibreを検索中...
|
|
"\xE6\x8E\xA5\xE7\xB6\x9A\xE4\xB8\xAD: ", // 接続中:
|
|
"\xE6\x8E\xA5\xE7\xB6\x9A\xE5\x85\x88: ", // 接続先:
|
|
"\xE3\x82\xB3\xE3\x83\x9E\xE3\x83\xB3\xE3\x83\x89\xE5\xBE\x85\xE6\xA9\x9F\xE4\xB8\xAD...", // コマンド待機中...
|
|
"\x28\xE6\x8E\xA5\xE7\xB6\x9A\xE5\xA4\xB1\xE6\x95\x97\xE3\x80\x81\xE5\x86\x8D\xE8\xA9\xA6\xE8\xA1\x8C\xE4\xB8\xAD\x29", // (接続失敗、再試行中)
|
|
"Calibre\xE3\x81\x8C\xE5\x88\x87\xE6\x96\xAD\xE3\x81\x95\xE3\x82\x8C\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // Calibreが切断されました
|
|
"\xE8\xBB\xA2\xE9\x80\x81\xE5\xBE\x85\xE6\xA9\x9F\xE4\xB8\xAD...", // 転送待機中...
|
|
"\xE8\xBB\xA2\xE9\x80\x81\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x99\xE3\x82\x8B\xE5\xA0\xB4\xE5\x90\x88\xE3\x81\xAF\xE3\x80\x81\x43\x61\x6C\x69\x62\x72\x65\xE3\x81\xAE\n\x53\x6D\x61\x72\x74\x44\x65\x76\x69\x63\x65\xE3\x83\x97\xE3\x83\xA9\xE3\x82\xB0\xE3\x82\xA4\xE3\x83\xB3\xE8\xA8\xAD\xE5\xAE\x9A\xE3\x81\xA7\n\x27\x49\x67\x6E\x6F\x72\x65\x20\x66\x72\x65\x65\x20\x73\x70\x61\x63\x65\x27\xE3\x82\x92\xE6\x9C\x89\xE5\x8A\xB9\xE3\x81\xAB\xE3\x81\x97\xE3\x81\xA6\xE3\x81\x8F\xE3\x81\xA0\xE3\x81\x95\xE3\x81\x84\xE3\x80\x82", // Transfer hint
|
|
"\xE5\x8F\x97\xE4\xBF\xA1\xE4\xB8\xAD: ", // 受信中:
|
|
"\xE5\x8F\x97\xE4\xBF\xA1\xE6\xB8\x88\xE3\x81\xBF: ", // 受信済み:
|
|
"\xE6\xAC\xA1\xE3\x81\xAE\xE5\x8F\x97\xE4\xBF\xA1\xE5\xBE\x85\xE3\x81\xA1...", // 次の受信待ち...
|
|
"\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\xE3\x81\xAE\xE4\xBD\x9C\xE6\x88\x90\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // ファイルの作成に失敗しました
|
|
"\xE3\x83\x91\xE3\x82\xB9\xE3\x83\xAF\xE3\x83\xBC\xE3\x83\x89\xE3\x81\x8C\xE5\xBF\x85\xE8\xA6\x81\xE3\x81\xA7\xE3\x81\x99", // パスワードが必要です
|
|
"\xE8\xBB\xA2\xE9\x80\x81\xE3\x81\x8C\xE4\xB8\xAD\xE6\x96\xAD\xE3\x81\x95\xE3\x82\x8C\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // 転送が中断されました
|
|
|
|
// Settings Categories
|
|
"\xE3\x83\x87\xE3\x82\xA3\xE3\x82\xB9\xE3\x83\x97\xE3\x83\xAC\xE3\x82\xA4", // ディスプレイ
|
|
"\xE3\x83\xAA\xE3\x83\xBC\xE3\x83\x80\xE3\x83\xBC", // リーダー
|
|
"\xE3\x82\xB3\xE3\x83\xB3\xE3\x83\x88\xE3\x83\xAD\xE3\x83\xBC\xE3\x83\xAB", // コントロール
|
|
"\xE3\x82\xB7\xE3\x82\xB9\xE3\x83\x86\xE3\x83\xA0", // システム
|
|
|
|
// Settings
|
|
"\xE3\x82\xB9\xE3\x83\xAA\xE3\x83\xBC\xE3\x83\x97\xE7\x94\xBB\xE9"
|
|
"\x9D"
|
|
"\xA2", // スリープ画面
|
|
"\xE3\x82\xB9\xE3\x83\xAA\xE3\x83\xBC\xE3\x83\x97\xE7\x94\xBB\xE9"
|
|
"\x9D"
|
|
"\xA2\xE3\x82\xAB\xE3\x83\x90\xE3\x83\xBC\xE3\x83\xA2\xE3\x83\xBC"
|
|
"\xE3"
|
|
"\x83\x89", // スリープ画面カバーモード
|
|
"\xE3\x82\xB9\xE3\x83\x86\xE3\x83\xBC\xE3\x82\xBF\xE3\x82\xB9\xE3"
|
|
"\x83"
|
|
"\x90\xE3\x83\xBC", // ステータスバー
|
|
"\xE3\x83\x90\xE3\x83\x83\xE3\x83\x86\xE3\x83\xAA\xE3\x83\xBC%"
|
|
"\xE3\x82\x92\xE9\x9A\xA0\xE3\x81\x99", // バッテリー%を隠す
|
|
"\xE6\xAE\xB5\xE8\x90\xBD\xE8\xBF\xBD\xE5\x8A\xA0\xE9\x96\x93\xE9"
|
|
"\x9A"
|
|
"\x94", // 段落追加間隔
|
|
"\xE3\x83\x86\xE3\x82\xAD\xE3\x82\xB9\xE3\x83\x88\xE3\x82\xA2\xE3"
|
|
"\x83"
|
|
"\xB3\xE3\x83\x81\xE3\x82\xA8\xE3\x82\xA4\xE3\x83\xAA\xE3\x82\xA2"
|
|
"\xE3"
|
|
"\x82\xB9", // テキストアンチエイリアス
|
|
"\xE9\x9B\xBB\xE6\xBA\x90\xE3\x83\x9C\xE3\x82\xBF\xE3\x83\xB3\xE7"
|
|
"\x9F"
|
|
"\xAD\xE6\x8A\xBC\xE3\x81\x97", // 電源ボタン短押し
|
|
"\xE8\xAA\xAD\xE6\x9B\xB8\xE6\x96\xB9\xE5\x90\x91", // 読書方向
|
|
"\xE5\x89\x8D\xE9\x9D\xA2\xE3\x83\x9C\xE3\x82\xBF\xE3\x83\xB3\xE9"
|
|
"\x85"
|
|
"\x8D\xE7\xBD\xAE", // 前面ボタン配置
|
|
"\xE5\x81\xB4\xE9\x9D\xA2\xE3\x83\x9C\xE3\x82\xBF\xE3\x83\xB3\xE9"
|
|
"\x85"
|
|
"\x8D\xE7\xBD\xAE", // 側面ボタン配置
|
|
"\xE9\x95\xB7\xE6\x8A\xBC\xE3\x81\x97\xE7\xAB\xA0\xE3\x82\xB9\xE3"
|
|
"\x82"
|
|
"\xAD\xE3\x83\x83\xE3\x83\x97", // 長押し章スキップ
|
|
"\xE3\x83\x95\xE3\x82\xA9\xE3\x83\xB3\xE3\x83\x88\xE3\x83\x95\xE3"
|
|
"\x82"
|
|
"\xA1\xE3\x83\x9F\xE3\x83\xAA\xE3\x83\xBC", // フォントファミリー
|
|
"\xE3\x83\xAA\xE3\x83\xBC\xE3\x83\x80\xE3\x83\xBC\xE3\x83\x95\xE3"
|
|
"\x82\xA9"
|
|
"\xE3\x83\xB3\xE3\x83\x88", // リーダーフォント (EXT_READER_FONT)
|
|
"\xE3\x83\xAA\xE3\x83\xBC\xE3\x83\x80\xE3\x83\xBC\xE3\x83\x95\xE3"
|
|
"\x82\xA9"
|
|
"\xE3\x83\xB3\xE3\x83\x88", // リーダーフォント (EXT_CHINESE_FONT)
|
|
"UI\xE3\x83\x95\xE3\x82\xA9\xE3\x83\xB3\xE3\x83\x88", // UIフォント
|
|
"\xE3\x83\x95\xE3\x82\xA9\xE3\x83\xB3\xE3\x83\x88\xE3\x82\xB5\xE3"
|
|
"\x82"
|
|
"\xA4\xE3\x82\xB9", // フォントサイズ
|
|
"\xE8\xA1\x8C\xE9\x96\x93\xE9\x9A\x94", // 行間隔
|
|
"\x41\x53\x43\x49\x49\x20\xE6\x96\x87\xE5\xAD\x97\xE9\x96\x93\xE9"
|
|
"\x9A\x94", // ASCII 文字間隔
|
|
"\x41\x53\x43\x49\x49\x20\xE6\x95\xB0\xE5\xAD\x97\xE9\x96\x93\xE9"
|
|
"\x9A\x94", // ASCII 数字間隔
|
|
"\xE6\xBC\xA2\xE5\xAD\x97\xE9\x96\x93\xE9\x9A\x94", // 漢字間隔
|
|
"\xE3\x82\xAB\xE3\x83\xA9\xE3\x83\xBC\xE3\x83\xA2\xE3\x83\xBC\xE3\x83"
|
|
"\x89", // カラーモード
|
|
"\xE7\x94\xBB\xE9\x9D\xA2\xE4\xBD\x99\xE7\x99\xBD", // 画面余白
|
|
"\xE6\xAE\xB5\xE8\x90\xBD\xE9\x85\x8D\xE7\xBD\xAE", // 段落配置
|
|
"\xE3\x83\x8F\xE3\x82\xA4\xE3\x83\x95\xE3\x83\x8D\xE3\x83\xBC\xE3\x82\xB7\xE3\x83\xA7\xE3\x83\xB3", // ハイフネーション (HYPHENATION)
|
|
"\xE3\x82\xB9\xE3\x83\xAA\xE3\x83\xBC\xE3\x83\x97\xE3\x81\xBE\xE3"
|
|
"\x81"
|
|
"\xA7\xE3\x81\xAE\xE6\x99\x82\xE9\x96\x93", // スリープまでの時間
|
|
"\xE3\x83\xAA\xE3\x83\x95\xE3\x83\xAC\xE3\x83\x83\xE3\x82\xB7\xE3"
|
|
"\x83"
|
|
"\xA5\xE9\xA0\xBB\xE5\xBA\xA6", // リフレッシュ頻度
|
|
"Calibre\xE8\xA8\xAD\xE5\xAE\x9A", // Calibre設定
|
|
"KOReader\xE5\x90\x8C\xE6\x9C\x9F", // KOReader同期 (KOREADER_SYNC)
|
|
"\xE3\x82\xA2\xE3\x83\x83\xE3\x83\x97\xE3\x83\x87\xE3\x83\xBC\xE3"
|
|
"\x83"
|
|
"\x88\xE3\x82\x92\xE7\xA2\xBA\xE8\xAA\x8D", // アップデートを確認
|
|
"\xE8\xA8\x80\xE8\xAA\x9E", // 言語
|
|
"\xE5\xA3\x81\xE7\xB4\x99\xE3\x82\x92\xE9\x81\xB8\xE6\x8A\x9E", // 壁紙を選択
|
|
"\xE8\xAA\xAD\xE6\x9B\xB8\xE3\x82\xAD\xE3\x83\xA3\xE3\x83\x83\xE3\x82\xB7\xE3\x83\xA5\xE3\x82\x92\xE6\xB6\x88\xE5\x8E\xBB", // 読書キャッシュを消去
|
|
|
|
// Calibre Settings
|
|
"Calibre",
|
|
|
|
// KOReader Settings
|
|
"\xE3\x83\xA6\xE3\x83\xBC\xE3\x82\xB6\xE3\x83\xBC\xE5\x90\x8D", // ユーザー名
|
|
"\xE3\x83\x91\xE3\x82\xB9\xE3\x83\xAF\xE3\x83\xBC\xE3\x83\x89", // パスワード
|
|
"\xE5\x90\x8C\xE6\x9C\x9F\xE3\x82\xB5\xE3\x83\xBC\xE3\x83\x90\xE3\x83\xBCURL", // 同期サーバーURL
|
|
"\xE3\x83\x89\xE3\x82\xAD\xE3\x83\xA5\xE3\x83\xA1\xE3\x83\xB3\xE3\x83\x88\xE3\x83\x9E\xE3\x83\x83\xE3\x83\x81\xE3\x83\xB3\xE3\x82\xB0", // ドキュメントマッチング
|
|
"\xE8\xAA\x8D\xE8\xA8\xBC", // 認証
|
|
"KOReader\xE3\x83\xA6\xE3\x83\xBC\xE3\x82\xB6\xE3\x83\xBC\xE5\x90\x8D", // KOReaderユーザー名
|
|
"KOReader\xE3\x83\x91\xE3\x82\xB9\xE3\x83\xAF\xE3\x83\xBC\xE3\x83\x89", // KOReaderパスワード
|
|
"\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\xE5\x90\x8D", // ファイル名
|
|
"\xE3\x83\x90\xE3\x82\xA4\xE3\x83\x8A\xE3\x83\xAA", // バイナリ
|
|
"\xE6\x9C\x80\xE5\x88\x9D\xE3\x81\xAB\xE8\xAA\x8D\xE8\xA8\xBC\xE6\x83\x85\xE5\xA0\xB1\xE3\x82\x92\xE8\xA8\xAD\xE5\xAE\x9A\xE3\x81\x97\xE3\x81\xA6\xE3\x81\x8F\xE3\x81\xA0\xE3\x81\x95\xE3\x81\x84", // 最初に認証情報を設定してください
|
|
|
|
// KOReader Auth
|
|
"WiFi\xE6\x8E\xA5\xE7\xB6\x9A\xE5\xA4\xB1\xE6\x95\x97", // WiFi接続失敗
|
|
"\xE8\xAA\x8D\xE8\xA8\xBC\xE4\xB8\xAD...", // 認証中...
|
|
"\xE8\xAA\x8D\xE8\xA8\xBC\xE6\x88\x90\xE5\x8A\x9F\xEF\xBC\x81", // 認証成功!
|
|
"KOReader\xE8\xAA\x8D\xE8\xA8\xBC", // KOReader認証
|
|
"KOReader\xE5\x90\x8C\xE6\x9C\x9F\xE3\x81\x8C\xE5\x88\xA9\xE7\x94\xA8\xE5\x8F\xAF\xE8\x83\xBD\xE3\x81\xA7\xE3\x81\x99", // KOReader同期が利用可能です
|
|
"\xE8\xAA\x8D\xE8\xA8\xBC\xE5\xA4\xB1\xE6\x95\x97", // 認証失敗
|
|
"\xE5\xAE\x8C\xE4\xBA\x86", // 完了
|
|
|
|
// Clear Cache
|
|
"\xE3\x81\x93\xE3\x82\x8C\xE3\x81\xAB\xE3\x82\x88\xE3\x82\x8A\xE3\x80\x81\xE3\x81\x99\xE3\x81\xB9\xE3\x81\xA6\xE3\x81\xAE\xE3\x82\xAD\xE3\x83\xA3\xE3\x83\x83\xE3\x82\xB7\xE3\x83\xA5\xE3\x81\x95\xE3\x82\x8C\xE3\x81\x9F\xE6\x9B\xB8\xE7\xB1\x8D\xE3\x83\x87\xE3\x83\xBC\xE3\x82\xBF\xE3\x81\x8C\xE6\xB6\x88\xE5\x8E\xBB\xE3\x81\x95\xE3\x82\x8C\xE3\x81\xBE\xE3\x81\x99\xE3\x80\x82", // これにより、すべてのキャッシュされた書籍データが消去されます。
|
|
"\xE3\x81\x99\xE3\x81\xB9\xE3\x81\xA6\xE3\x81\xAE\xE8\xAA\xAD\xE6\x9B\xB8\xE9\x80\xB2\xE6\x8D\x97\xE3\x81\x8C\xE5\xA4\xB1\xE3\x82\x8F\xE3\x82\x8C\xE3\x81\xBE\xE3\x81\x99\xEF\xBC\x81", // すべての読書進捗が失われます!
|
|
"\xE6\x9B\xB8\xE7\xB1\x8D\xE3\x81\xAF\xE5\x86\x8D\xE3\x82\xA4\xE3\x83\xB3\xE3\x83\x87\xE3\x83\x83\xE3\x82\xAF\xE3\x82\xB9\xE3\x81\x8C\xE5\xBF\x85\xE8\xA6\x81\xE3\x81\xA7\xE3\x81\x99", // 書籍は再インデックスが必要です
|
|
"\xE5\x86\x8D\xE5\xBA\xA6\xE9\x96\x8B\xE3\x81\x84\xE3\x81\x9F\xE3\x81\xA8\xE3\x81\x8D\xE3\x81\xAB\xE3\x80\x82", // 再度開いたときに。
|
|
"\xE3\x82\xAD\xE3\x83\xA3\xE3\x83\x83\xE3\x82\xB7\xE3\x83\xA5\xE3\x82\x92\xE6\xB6\x88\xE5\x8E\xBB\xE4\xB8\xAD...", // キャッシュを消去中...
|
|
"\xE3\x82\xAD\xE3\x83\xA3\xE3\x83\x83\xE3\x82\xB7\xE3\x83\xA5\xE6\xB6\x88\xE5\x8E\xBB\xE5\xAE\x8C\xE4\xBA\x86", // キャッシュ消去完了
|
|
"\xE9\xA0\x85\xE7\x9B\xAE\xE3\x82\x92\xE5\x89\x8A\xE9\x99\xA4\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // 項目を削除しました
|
|
"\xE5\xA4\xB1\xE6\x95\x97", // 失敗
|
|
"\xE3\x82\xAD\xE3\x83\xA3\xE3\x83\x83\xE3\x82\xB7\xE3\x83\xA5\xE3\x81\xAE\xE6\xB6\x88\xE5\x8E\xBB\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // キャッシュの消去に失敗しました
|
|
"\xE8\xA9\xB3\xE7\xB4\xB0\xE3\x81\xAF\xE3\x82\xB7\xE3\x83\xAA\xE3\x82\xA2\xE3\x83\xAB\xE5\x87\xBA\xE5\x8A\x9B\xE3\x82\x92\xE7\xA2\xBA\xE8\xAA\x8D\xE3\x81\x97\xE3\x81\xA6\xE3\x81\x8F\xE3\x81\xA0\xE3\x81\x95\xE3\x81\x84", // 詳細はシリアル出力を確認してください
|
|
|
|
// Setting Values
|
|
"\xE3\x83\x80\xE3\x83\xBC\xE3\x82\xAF", // ダーク
|
|
"\xE3\x83\xA9\xE3\x82\xA4\xE3\x83\x88", // ライト
|
|
"\xE3\x82\xAB\xE3\x82\xB9\xE3\x82\xBF\xE3\x83\xA0", // カスタム
|
|
"\xE3\x82\xAB\xE3\x83\x90\xE3\x83\xBC", // カバー
|
|
"\xE3\x81\xAA\xE3\x81\x97", // なし
|
|
"\xE3\x83\x95\xE3\x82\xA3\xE3\x83\x83\xE3\x83\x88", // フィット
|
|
"\xE3\x82\xAF\xE3\x83\xAD\xE3\x83\x83\xE3\x83\x97", // クロップ
|
|
"\xE9\x80\xB2\xE6\x8D\x97\xE3\x81\xAA\xE3\x81\x97", // 進捗なし
|
|
"\xE3\x83\x95\xE3\x83\xAB", // フル
|
|
"\xE3\x81\x97\xE3\x81\xAA\xE3\x81\x84", // しない
|
|
"\xE8\xAA\xAD\xE6\x9B\xB8\xE4\xB8\xAD", // 読書中
|
|
"\xE5\xB8\xB8\xE3\x81\xAB", // 常に
|
|
"\xE7\x84\xA1\xE8\xA6\x96", // 無視
|
|
"\xE3\x82\xB9\xE3\x83\xAA\xE3\x83\xBC\xE3\x83\x97", // スリープ
|
|
"\xE3\x83\x9A\xE3\x83\xBC\xE3\x82\xB8\xE3\x82\x81\xE3\x81\x8F\xE3"
|
|
"\x82"
|
|
"\x8A", // ページめくり
|
|
"\xE7\xB8\xA6\xE5\x90\x91\xE3\x81\x8D", // 縦向き
|
|
"\xE6\xA8\xAA\xE5\x90\x91\xE3\x81\x8D\xE6\x99\x82\xE8\xA8\x88\xE5"
|
|
"\x9B"
|
|
"\x9E\xE3\x82\x8A", // 横向き時計回り
|
|
"\xE5\x8F\x8D\xE8\xBB\xA2", // 反転
|
|
"\xE6\xA8\xAA\xE5\x90\x91\xE3\x81\x8D\xE5\x8F\x8D\xE6\x99\x82\xE8"
|
|
"\xA8"
|
|
"\x88\xE5\x9B\x9E\xE3\x82\x8A", // 横向き反時計回り
|
|
"\xE6\x88\xBB\xE3\x82\x8B\x2C\x20\xE7\xA2\xBA\xE8\xAA\x8D\x2C\x20\xE5\xB7\xA6\x2C\x20\xE5\x8F\xB3", // 戻る, 確認, 左, 右
|
|
"\xE5\xB7\xA6\x2C\x20\xE5\x8F\xB3\x2C\x20\xE6\x88\xBB\xE3\x82\x8B\x2C\x20\xE7\xA2\xBA\xE8\xAA\x8D", // 左, 右, 戻る, 確認
|
|
"\xE5\xB7\xA6\x2C\x20\xE6\x88\xBB\xE3\x82\x8B\x2C\x20\xE7\xA2\xBA\xE8\xAA\x8D\x2C\x20\xE5\x8F\xB3", // 左, 戻る, 確認, 右
|
|
"\xE5\x89\x8D/\xE6\xAC\xA1", // 前/次
|
|
"\xE6\xAC\xA1/\xE5\x89\x8D", // 次/前
|
|
"Bookerly", "Noto Sans", "Open Dyslexic",
|
|
"\xE5\xB0\x8F", // 小
|
|
"\xE4\xB8\xAD", // 中
|
|
"\xE5\xA4\xA7", // 大
|
|
"\xE7\x89\xB9\xE5\xA4\xA7", // 特大
|
|
"\xE7\x8B\xAD\xE3\x81\x84", // 狭い
|
|
"\xE6\x99\xAE\xE9\x80\x9A", // 普通
|
|
"\xE5\xBA\x83\xE3\x81\x84", // 広い
|
|
"\xE4\xB8\xA1\xE7\xAB\xAF\xE6\x8F\x83\xE3\x81\x88", // 両端揃え
|
|
"\xE5\xB7\xA6\xE6\x8F\x83\xE3\x81\x88", // 左揃え
|
|
"\xE4\xB8\xAD\xE5\xA4\xAE\xE6\x8F\x83\xE3\x81\x88", // 中央揃え
|
|
"\xE5\x8F\xB3\xE6\x8F\x83\xE3\x81\x88", // 右揃え
|
|
"1\xE5\x88\x86", // 1分
|
|
"5\xE5\x88\x86", // 5分
|
|
"10\xE5\x88\x86", // 10分
|
|
"15\xE5\x88\x86", // 15分
|
|
"30\xE5\x88\x86", // 30分
|
|
"1\xE3\x83\x9A\xE3\x83\xBC\xE3\x82\xB8", // 1ページ
|
|
"5\xE3\x83\x9A\xE3\x83\xBC\xE3\x82\xB8", // 5ページ
|
|
"10\xE3\x83\x9A\xE3\x83\xBC\xE3\x82\xB8", // 10ページ
|
|
"15\xE3\x83\x9A\xE3\x83\xBC\xE3\x82\xB8", // 15ページ
|
|
"30\xE3\x83\x9A\xE3\x83\xBC\xE3\x82\xB8", // 30ページ
|
|
|
|
// OTA Update
|
|
"\xE3\x82\xA2\xE3\x83\x83\xE3\x83\x97\xE3\x83\x87\xE3\x83\xBC\xE3"
|
|
"\x83"
|
|
"\x88", // アップデート
|
|
"\xE3\x82\xA2\xE3\x83\x83\xE3\x83\x97\xE3\x83\x87\xE3\x83\xBC\xE3"
|
|
"\x83"
|
|
"\x88\xE3\x82\x92\xE7\xA2\xBA\xE8\xAA\x8D\xE4\xB8\xAD...", // アップデートを確認中...
|
|
"\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x82\xA2\xE3\x83\x83\xE3"
|
|
"\x83"
|
|
"\x97\xE3\x83\x87\xE3\x83\xBC\xE3\x83\x88\xE3\x81\x8C\xE3\x81\x82"
|
|
"\xE3"
|
|
"\x82\x8A\xE3\x81\xBE\xE3\x81\x99!", // 新しいアップデートがあります!
|
|
"\xE7\x8F\xBE\xE5\x9C\xA8\xE3\x81\xAE\xE3\x83\x90\xE3\x83\xBC\xE3"
|
|
"\x82"
|
|
"\xB8\xE3\x83\xA7\xE3\x83\xB3: ", // 現在のバージョン:
|
|
"\xE6\x96\xB0\xE3\x83\x90\xE3\x83\xBC\xE3\x82\xB8\xE3\x83\xA7\xE3"
|
|
"\x83"
|
|
"\xB3: ", // 新バージョン:
|
|
"\xE3\x82\xA2\xE3\x83\x83\xE3\x83\x97\xE3\x83\x87\xE3\x83\xBC\xE3"
|
|
"\x83"
|
|
"\x88\xE4\xB8\xAD...", // アップデート中...
|
|
"\xE6\x9C\x80\xE6\x96\xB0\xE3\x81\xA7\xE3\x81\x99", // 最新です
|
|
"\xE3\x82\xA2\xE3\x83\x83\xE3\x83\x97\xE3\x83\x87\xE3\x83\xBC\xE3"
|
|
"\x83"
|
|
"\x88\xE5\xA4\xB1\xE6\x95\x97", // アップデート失敗
|
|
"\xE3\x82\xA2\xE3\x83\x83\xE3\x83\x97\xE3\x83\x87\xE3\x83\xBC\xE3"
|
|
"\x83"
|
|
"\x88\xE5\xAE\x8C\xE4\xBA\x86", // アップデート完了
|
|
"\xE9\x9B\xBB\xE6\xBA\x90\xE3\x83\x9C\xE3\x82\xBF\xE3\x83\xB3\xE3"
|
|
"\x82"
|
|
"\x92\xE9\x95\xB7\xE6\x8A\xBC\xE3\x81\x97\xE3\x81\x97\xE3\x81\xA6"
|
|
"\xE9"
|
|
"\x9B\xBB\xE6\xBA\x90ON", // 電源ボタンを長押しして電源ON
|
|
|
|
// Font Selection
|
|
"\xE5\xA4\x96\xE9\x83\xA8\xE3\x83\x95\xE3\x82\xA9\xE3\x83\xB3\xE3"
|
|
"\x83"
|
|
"\x88", // 外部フォント
|
|
"\xE5\x86\x85\xE8\x94\xB5(\xE7\x84\xA1\xE5\x8A\xB9)", // 内蔵(無効)
|
|
|
|
// OPDS Browser
|
|
"\xE3\x82\xA8\xE3\x83\xB3\xE3\x83\x88\xE3\x83\xAA\xE3\x81\x8C\xE8\xA6"
|
|
"\x8B\xE3\x81\xA4\xE3\x81\x8B\xE3\x82\x8A\xE3\x81\xBE\xE3\x81\x9B\xE3"
|
|
"\x82\x93", // エントリが見つかりません
|
|
"\xE3\x83\x80\xE3\x83\xA6\xE3\x83\xB3\xE3\x83\xAD\xE3\x83\xBC\xE3\x83"
|
|
"\x89\xE4\xB8\xAD...", // ダウンロード中...
|
|
"\xE3\x83\x80\xE3\x82\xA6\xE3\x83\xB3\xE3\x83\xAD\xE3\x83\xBC\xE3\x83"
|
|
"\x89\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x97\xE3\x81\xBE\xE3"
|
|
"\x81\x97\xE3\x81\x9F", // ダウンロードに失敗しました
|
|
"\xE3\x82\xA8\xE3\x83\xA9\xE3\x83\xBC:", // エラー:
|
|
"\xE7\x84\xA1\xE9\xA1\x8C", // 無題
|
|
"\xE3\x82\xB5\xE3\x83\xBC\xE3\x83\x90\xE3\x83\xBC\x55\x52\x4C\xE3\x81\x8C\xE8\xA8\xAD\xE5\xAE\x9A\xE3\x81\x95\xE3\x82\x8C\xE3\x81\xA6\xE3\x81\x84\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93", // サーバーURLが設定されていません
|
|
"\xE3\x83\x95\xE3\x82\xA3\xE3\x83\xBC\xE3\x83\x89\xE3\x81\xAE\xE5\x8F\x96\xE5\xBE\x97\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // フィードの取得に失敗しました
|
|
"\xE3\x83\x95\xE3\x82\xA3\xE3\x83\xBC\xE3\x83\x89\xE3\x81\xAE\xE8\xA7\xA3\xE6\x9E\x90\xE3\x81\xAB\xE5\xA4\xB1\xE6\x95\x97\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x97\xE3\x81\x9F", // フィードの解析に失敗しました
|
|
"\xE3\x83\x8D\xE3\x83\x83\xE3\x83\x88\xE3\x83\xAF\xE3\x83\xBC\xE3\x82"
|
|
"\xAF: ", // ネットワーク:
|
|
"IP\xE3\x82\xA2\xE3\x83\x89\xE3\x83\xAC\xE3\x82\xB9: ", // IPアドレス:
|
|
"\xE3\x82\xB9\xE3\x83\x9E\xE3\x83\x9B\xE3\x81\xA7QR\xE3\x82\xB3\xE3\x83"
|
|
"\xBC\xE3\x83\x89\xE3\x82\x92\xE3\x82\xB9\xE3\x82\xAD\xE3\x83\xA3\xE3"
|
|
"\x83\xB3\xE3\x81\x97\xE3\x81\xA6WiFi\xE3\x81\xAB\xE6\x8E\xA5\xE7\xB6"
|
|
"\x9A", // スマホでQRコードをスキャンしてWiFiに接続
|
|
|
|
// Buttons
|
|
"\xC2\xAB \xE6\x88\xBB\xE3\x82\x8B", // « 戻る
|
|
"\xC2\xAB \xE7\xB5\x82\xE4\xBA\x86", // « 終了
|
|
"\xC2\xAB \xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0", // « ホーム
|
|
"\xC2\xAB \xE4\xBF\x9D\xE5\xAD\x98", // « 保存
|
|
"\xE9\x81\xB8\xE6\x8A\x9E", // 選択
|
|
"\xE5\x88\x87\xE6\x9B\xBF", // 切替
|
|
"\xE7\xA2\xBA\xE8\xAA\x8D", // 確認
|
|
"\xE3\x82\xAD\xE3\x83\xA3\xE3\x83\xB3\xE3\x82\xBB\xE3\x83\xAB", // キャンセル
|
|
"\xE6\x8E\xA5\xE7\xB6\x9A", // 接続
|
|
"\xE9\x96\x8B\xE3\x81\x8F", // 開く
|
|
"\xE3\x83\x80\xE3\x82\xA6\xE3\x83\xB3\xE3\x83\xAD\xE3\x83\xBC\xE3\x83\x89", // ダウンロード
|
|
"\xE5\x86\x8D\xE8\xA9\xA6\xE8\xA1\x8C", // 再試行
|
|
"\xE3\x81\xAF\xE3\x81\x84", // はい
|
|
"\xE3\x81\x84\xE3\x81\x84\xE3\x81\x88", // いいえ
|
|
"ON", "OFF",
|
|
"\xE8\xA8\xAD\xE5\xAE\x9A\xE6\xB8\x88\xE3\x81\xBF", // 設定済み
|
|
"\xE6\x9C\xAA\xE8\xA8\xAD\xE5\xAE\x9A", // 未設定
|
|
"\xE5\xB7\xA6", // 左
|
|
"\xE5\x8F\xB3", // 右
|
|
"\xE4\xB8\x8A", // 上
|
|
"\xE4\xB8\x8B", // 下
|
|
"\xE5\xA4\xA7\xE6\x96\x87\xE5\xAD\x97", // 大文字
|
|
"\xE5\xB0\x8F\xE6\x96\x87\xE5\xAD\x97", // 小文字
|
|
"\xE6\xB1\xBA\xE5\xAE\x9A", // 決定
|
|
|
|
// Languages
|
|
"English",
|
|
"\xE7\xAE\x80\xE4\xBD\x93\xE4\xB8\xAD\xE6\x96\x87", // 简体中文
|
|
"\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E", // 日本語
|
|
};
|
|
|
|
// Compile-time check for array sizes
|
|
static_assert(sizeof(I18n::STRINGS_EN) / sizeof(I18n::STRINGS_EN[0]) ==
|
|
static_cast<size_t>(StrId::_COUNT),
|
|
"STRINGS_EN size mismatch");
|
|
static_assert(sizeof(I18n::STRINGS_ZH) / sizeof(I18n::STRINGS_ZH[0]) ==
|
|
static_cast<size_t>(StrId::_COUNT),
|
|
"STRINGS_ZH size mismatch");
|
|
static_assert(sizeof(I18n::STRINGS_JA) / sizeof(I18n::STRINGS_JA[0]) ==
|
|
static_cast<size_t>(StrId::_COUNT),
|
|
"STRINGS_JA size mismatch");
|
|
|
|
const char *I18n::get(StrId id) const {
|
|
const auto index = static_cast<size_t>(id);
|
|
if (index >= static_cast<size_t>(StrId::_COUNT)) {
|
|
return "???";
|
|
}
|
|
|
|
switch (_language) {
|
|
case Language::CHINESE_SIMPLIFIED:
|
|
return STRINGS_ZH[index];
|
|
case Language::JAPANESE:
|
|
return STRINGS_JA[index];
|
|
case Language::ENGLISH:
|
|
default:
|
|
return STRINGS_EN[index];
|
|
}
|
|
}
|
|
|
|
void I18n::setLanguage(Language lang) {
|
|
if (lang >= Language::_COUNT) {
|
|
return;
|
|
}
|
|
_language = lang;
|
|
saveSettings();
|
|
}
|
|
|
|
void I18n::saveSettings() {
|
|
SdMan.mkdir("/.crosspoint");
|
|
|
|
FsFile file;
|
|
if (!SdMan.openFileForWrite("I18N", SETTINGS_FILE, file)) {
|
|
Serial.printf("[I18N] Failed to save settings\n");
|
|
return;
|
|
}
|
|
|
|
serialization::writePod(file, SETTINGS_VERSION);
|
|
serialization::writePod(file, static_cast<uint8_t>(_language));
|
|
|
|
file.close();
|
|
Serial.printf("[I18N] Settings saved: language=%d\n",
|
|
static_cast<int>(_language));
|
|
}
|
|
|
|
void I18n::loadSettings() {
|
|
FsFile file;
|
|
if (!SdMan.openFileForRead("I18N", SETTINGS_FILE, file)) {
|
|
Serial.printf("[I18N] No settings file, using default (English)\n");
|
|
return;
|
|
}
|
|
|
|
uint8_t version;
|
|
serialization::readPod(file, version);
|
|
if (version != SETTINGS_VERSION) {
|
|
Serial.printf("[I18N] Settings version mismatch\n");
|
|
file.close();
|
|
return;
|
|
}
|
|
|
|
uint8_t lang;
|
|
serialization::readPod(file, lang);
|
|
if (lang < static_cast<uint8_t>(Language::_COUNT)) {
|
|
_language = static_cast<Language>(lang);
|
|
Serial.printf("[I18N] Loaded language: %d\n", static_cast<int>(_language));
|
|
}
|
|
|
|
file.close();
|
|
}
|
|
|
|
// Generate character set for a specific language
|
|
const char *I18n::getCharacterSet(Language lang) {
|
|
static std::string charsetEN;
|
|
static std::string charsetZH;
|
|
static std::string charsetJA;
|
|
|
|
const char *const *strings;
|
|
std::string *charset;
|
|
|
|
switch (lang) {
|
|
case Language::CHINESE_SIMPLIFIED:
|
|
strings = STRINGS_ZH;
|
|
charset = &charsetZH;
|
|
break;
|
|
case Language::JAPANESE:
|
|
strings = STRINGS_JA;
|
|
charset = &charsetJA;
|
|
break;
|
|
case Language::ENGLISH:
|
|
default:
|
|
strings = STRINGS_EN;
|
|
charset = &charsetEN;
|
|
break;
|
|
}
|
|
|
|
// Only generate once
|
|
if (!charset->empty()) {
|
|
return charset->c_str();
|
|
}
|
|
|
|
std::set<uint32_t> uniqueChars;
|
|
|
|
// Iterate through all strings
|
|
for (size_t i = 0; i < static_cast<size_t>(StrId::_COUNT); i++) {
|
|
const char *str = strings[i];
|
|
while (*str) {
|
|
// Decode UTF-8
|
|
uint32_t cp = 0;
|
|
uint8_t b = static_cast<uint8_t>(*str);
|
|
|
|
if ((b & 0x80) == 0) {
|
|
// ASCII
|
|
cp = b;
|
|
str++;
|
|
} else if ((b & 0xE0) == 0xC0) {
|
|
// 2-byte UTF-8
|
|
cp = (b & 0x1F) << 6;
|
|
cp |= (static_cast<uint8_t>(str[1]) & 0x3F);
|
|
str += 2;
|
|
} else if ((b & 0xF0) == 0xE0) {
|
|
// 3-byte UTF-8
|
|
cp = (b & 0x0F) << 12;
|
|
cp |= (static_cast<uint8_t>(str[1]) & 0x3F) << 6;
|
|
cp |= (static_cast<uint8_t>(str[2]) & 0x3F);
|
|
str += 3;
|
|
} else if ((b & 0xF8) == 0xF0) {
|
|
// 4-byte UTF-8
|
|
cp = (b & 0x07) << 18;
|
|
cp |= (static_cast<uint8_t>(str[1]) & 0x3F) << 12;
|
|
cp |= (static_cast<uint8_t>(str[2]) & 0x3F) << 6;
|
|
cp |= (static_cast<uint8_t>(str[3]) & 0x3F);
|
|
str += 4;
|
|
} else {
|
|
str++; // Invalid byte, skip
|
|
continue;
|
|
}
|
|
|
|
uniqueChars.insert(cp);
|
|
}
|
|
}
|
|
|
|
// Convert to sorted UTF-8 string
|
|
for (uint32_t cp : uniqueChars) {
|
|
if (cp < 0x80) {
|
|
*charset += static_cast<char>(cp);
|
|
} else if (cp < 0x800) {
|
|
*charset += static_cast<char>(0xC0 | (cp >> 6));
|
|
*charset += static_cast<char>(0x80 | (cp & 0x3F));
|
|
} else if (cp < 0x10000) {
|
|
*charset += static_cast<char>(0xE0 | (cp >> 12));
|
|
*charset += static_cast<char>(0x80 | ((cp >> 6) & 0x3F));
|
|
*charset += static_cast<char>(0x80 | (cp & 0x3F));
|
|
} else {
|
|
*charset += static_cast<char>(0xF0 | (cp >> 18));
|
|
*charset += static_cast<char>(0x80 | ((cp >> 12) & 0x3F));
|
|
*charset += static_cast<char>(0x80 | ((cp >> 6) & 0x3F));
|
|
*charset += static_cast<char>(0x80 | (cp & 0x3F));
|
|
}
|
|
}
|
|
|
|
return charset->c_str();
|
|
}
|