## 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)
6.6 KiB
CJK Font Support
This guide explains how to use Chinese, Japanese, and Korean (CJK) fonts on your CrossPoint Reader.
Overview
CrossPoint Reader supports external CJK fonts for both:
- UI Font - Used for menus, settings, and system interface
- Reader Font - Used for reading ebook content
The device includes a built-in CJK UI font (Source Han Sans subset) for basic interface rendering, and supports loading custom external fonts from the SD card.
Prerequisites
- CrossPoint Reader device with firmware version supporting CJK fonts
- SD card with available space for font files
- TrueType font files (.ttf) converted to the CrossPoint font format
Font File Format
CrossPoint Reader uses a custom binary font format optimized for e-ink displays. Font files must be placed in the /fonts/ directory on the SD card.
File Naming Convention
Font files must follow this naming pattern:
{FontName}_{Size}_{Width}x{Height}.bin
Examples:
SourceHanSansCN-Medium_20_20x20.binKingHwaOldSong_38_33x39.binYozai-Medium_36_31x31.bin
Font File Structure
The binary font file contains:
-
Header (variable length)
- Font name (null-terminated string)
- Font size (uint8_t)
- Character width (uint8_t)
- Character height (uint8_t)
- Bytes per character (uint16_t)
-
Character Data
- Sequential bitmap data for each character
- Characters are stored in Unicode order
- Each character uses
width * height / 8bytes (1-bit per pixel)
Generating Font Files
Use the provided Python script to convert TrueType fonts:
python scripts/generate_cjk_ui_font.py \
--font /path/to/font.ttf \
--size 20 \
--output /path/to/output.bin
Script Options
| Option | Description |
|---|---|
--font |
Path to TrueType font file (.ttf) |
--size |
Font size in points |
--output |
Output binary file path |
--chars |
(Optional) Custom character set file |
Character Set
By default, the script generates fonts for:
- Basic ASCII characters (0x20-0x7E)
- Common CJK characters (GB2312 subset)
- Japanese Hiragana and Katakana
- Common punctuation marks
Installing Fonts
-
Create the fonts directory (if it doesn't exist):
/fonts/ -
Copy font files to the
/fonts/directory on your SD card -
Restart the device or go to Settings to scan for new fonts
Selecting Fonts
UI Font
- Go to Settings → Display
- Select External UI Font
- Choose from available fonts or select Built-in (Disabled) to use the default font
Reader Font
- Go to Settings → Reader
- Select External Reader Font
- Choose from available fonts or select Built-in (Disabled) to use the default font
Built-in CJK UI Font
The firmware includes a pre-rendered subset of Source Han Sans (思源黑体) for UI rendering. This font covers:
- All ASCII characters
- Common Chinese characters used in the UI
- Japanese Hiragana and Katakana
- Common punctuation marks
The built-in font is automatically used when:
- No external UI font is selected
- The external font file is missing or corrupted
External UI Font Features
When an external UI font is selected:
Full Character Coverage
- All characters (including ASCII letters, numbers, and punctuation) are rendered using the external font
- This ensures consistent visual style across the entire UI
- If a character is missing from the external font, the system falls back to built-in fonts
Proportional Spacing
- External fonts use proportional spacing (variable width)
- Each character advances by its actual width, not a fixed width
- This makes English text look more natural with proper letter spacing
- CJK characters still use their full width as designed
Recommended Fonts
For UI (Small sizes, 18-24pt)
| Font | Description | License |
|---|---|---|
| Source Han Sans | Clean, modern sans-serif | OFL |
| Noto Sans CJK | Google's CJK font family | OFL |
| WenQuanYi Micro Hei | Compact Chinese font | GPL |
For Reading (Larger sizes, 28-40pt)
| Font | Description | License |
|---|---|---|
| Source Han Serif | Traditional serif style | OFL |
| Noto Serif CJK | Google's serif CJK font | OFL |
| FangSong | Classic Chinese style | Varies |
Memory Considerations
External fonts consume RAM when loaded. Consider these guidelines:
| Font Size | Approx. Memory Usage |
|---|---|
| 20pt | ~50KB per 1000 characters |
| 28pt | ~100KB per 1000 characters |
| 36pt | ~160KB per 1000 characters |
Tips:
- Use smaller font sizes for UI (18-24pt)
- Larger fonts (32pt+) are better for reader content
- Only one UI font and one reader font are loaded at a time
Troubleshooting
Font not appearing in selection list
- Check the file is in
/fonts/directory - Verify the filename follows the naming convention
- Ensure the file is not corrupted (try regenerating)
Characters displaying as boxes or question marks
- The character may not be included in the font
- Try a font with broader character coverage
- Check if the font file was generated correctly
Device running slowly after selecting font
- The font file may be too large
- Try a smaller font size
- Reduce the character set when generating the font
Font looks blurry or pixelated
- E-ink displays work best with specific font sizes
- Try sizes that are multiples of the display's native resolution
- Ensure anti-aliasing is disabled for 1-bit rendering
Technical Details
Font Manager API
The FontManager class provides:
// Scan for available fonts
FontMgr.scanFonts();
// Get font count
int count = FontMgr.getFontCount();
// Get font info
const FontInfo* info = FontMgr.getFontInfo(index);
// Select reader font (-1 to disable)
FontMgr.selectFont(index);
// Select UI font (-1 to disable)
FontMgr.selectUiFont(index);
// Check if external font is enabled
bool enabled = FontMgr.isExternalFontEnabled();
Font Info Structure
struct FontInfo {
char name[32]; // Font name
uint8_t size; // Font size in points
uint8_t width; // Character width in pixels
uint8_t height; // Character height in pixels
uint16_t bytesPerChar; // Bytes per character
char path[64]; // Full path to font file
};
Related Documentation
- Internationalization (I18N) - Multi-language support
- File Formats - Binary file format specifications
- Troubleshooting - General troubleshooting guide