Skip to content

Commit d1cf8de

Browse files
committed
bitmap fix; added Ukrainian language
1 parent 03b12ce commit d1cf8de

File tree

5 files changed

+74
-44
lines changed

5 files changed

+74
-44
lines changed

src/launcher/files.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@
2222

2323

2424
_TRANS = const("""[
25-
{"en": "Paste", "zh": "粘贴", "ja": "貼り付け"},
26-
{"en": "New Directory", "zh": "新建目录", "ja": "新しいディレクトリ"},
27-
{"en": "New File", "zh": "新建文件", "ja": "新しいファイル"},
28-
{"en": "Refresh", "zh": "刷新", "ja": "更新"},
29-
{"en": "Exit to launcher", "zh": "退出到启动器", "ja": "ランチャーに戻る"},
30-
{"en": "Directory name:", "zh": "目录名称:", "ja": "ディレクトリ名:"},
31-
{"en": "File name:", "zh": "文件名称:", "ja": "ファイル名:"},
32-
{"en": "Exiting...", "zh": "正在退出...", "ja": "終了中..."},
33-
{"en": "open", "zh": "打开", "ja": "開く"},
34-
{"en": "copy", "zh": "复制", "ja": "コピー"},
35-
{"en": "rename", "zh": "重命名", "ja": "名前を変更"},
36-
{"en": "delete", "zh": "删除", "ja": "削除"},
37-
{"en": "Opening...", "zh": "正在打开...", "ja": "開いています..."}
25+
{"en": "Paste", "zh": "粘贴", "ja": "貼り付け", "ua": "Вставити"},
26+
{"en": "New Directory", "zh": "新建目录", "ja": "新しいディレクトリ", "ua": "Нова папка"},
27+
{"en": "New File", "zh": "新建文件", "ja": "新しいファイル", "ua": "Новий файл"},
28+
{"en": "Refresh", "zh": "刷新", "ja": "更新", "ua": "Оновити"},
29+
{"en": "Exit to launcher", "zh": "退出到启动器", "ja": "ランチャーに戻る", "ua": "Вийти в меню"},
30+
{"en": "Directory name:", "zh": "目录名称:", "ja": "ディレクトリ名:", "ua": "Назва папки"},
31+
{"en": "File name:", "zh": "文件名称:", "ja": "ファイル名:", "ua": "Назва файлу"},
32+
{"en": "Exiting...", "zh": "正在退出...", "ja": "終了中...", "ua": "Закриваємо..."},
33+
{"en": "open", "zh": "打开", "ja": "開く", "ua": "відкрити"},
34+
{"en": "copy", "zh": "复制", "ja": "コピー", "ua": "копіювати"},
35+
{"en": "rename", "zh": "重命名", "ja": "名前を変更", "ua": "перейменувати"},
36+
{"en": "delete", "zh": "删除", "ja": "削除", "ua": "видалити"},
37+
{"en": "Opening...", "zh": "正在打开...", "ja": "開いています...", "ua": "Відкриваємо..."}
3838
]""")
3939

4040

src/launcher/launcher.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
from launcher.icons import appicons
4646
from lib import battlevel, display, sdcard, userinput
4747
from lib.display.rawbitmap import RawBitmap
48+
from lib.display.char_util import square_char
4849
from lib.hydra import beeper, loader, statusbar
4950
from lib.hydra.config import Config
5051
from lib.hydra.i18n import I18n
@@ -91,19 +92,16 @@
9192
_SCROLL_ANIMATION_QUICK = const(150)
9293

9394

94-
_ASCII_MAX = const(128)
95-
96-
9795
_TRANS = const("""[
98-
{"en": "Loading...", "zh": "加载中...", "ja": "読み込み中..."},
99-
{"en": "Files", "zh": "文件", "ja": "ファイル"},
100-
{"en": "Terminal", "zh": "终端", "ja": "端末"},
101-
{"en": "Get Apps", "zh": "应用商店", "ja": "アプリストア"},
102-
{"en": "Reload Apps", "zh": "重新加载应用", "ja": "アプリ再読"},
103-
{"en": "UI Sound", "zh": "界面声音", "ja": "UIサウンド"},
104-
{"en": "Settings", "zh": "设置", "ja": "設定"},
105-
{"en": "On", "zh": "开", "ja": "オン"},
106-
{"en": "Off", "zh": "关", "ja": "オフ"}
96+
{"en": "Loading...", "zh": "加载中...", "ja": "読み込み中...", "ua": "Завантаження..."},
97+
{"en": "Files", "zh": "文件", "ja": "ファイル", "ua": "Файли"},
98+
{"en": "Terminal", "zh": "终端", "ja": "端末", "ua": "Термінал"},
99+
{"en": "Get Apps", "zh": "应用商店", "ja": "アプリストア", "ua": "Отримати ПЗ"},
100+
{"en": "Reload Apps", "zh": "重新加载应用", "ja": "アプリ再読", "ua": "Оновити список"},
101+
{"en": "UI Sound", "zh": "界面声音", "ja": "UIサウンド", "ua": "Звуки меню"},
102+
{"en": "Settings", "zh": "设置", "ja": "設定", "ua": "Налаштування"},
103+
{"en": "On", "zh": "开", "ja": "オン", "ua": "Ввімк"},
104+
{"en": "Off", "zh": "关", "ja": "オフ", "ua": "Вимк"}
107105
]""")
108106

109107

@@ -288,7 +286,7 @@ def launch_app(app_path):
288286
if app_path.endswith(".cli.py"):
289287
loader.launch_app(APP_PATHS['Terminal'], f"${app_path}")
290288
loader.launch_app(app_path)
291-
289+
292290

293291
def center_text_x(text: str) -> int:
294292
"""Calculate the x coordinate to draw a text string, to make it horizontally centered.
@@ -298,7 +296,7 @@ def center_text_x(text: str) -> int:
298296
# calculate length
299297
x = _DISPLAY_WIDTH_HALF
300298
for char in text:
301-
if ord(char) > _ASCII_MAX:
299+
if square_char(ord(char)):
302300
x -= _FONT_WIDTH
303301
else:
304302
x -= _FONT_WIDTH_HALF
@@ -825,4 +823,5 @@ def main_loop():
825823

826824

827825
# run the main loop!
828-
main_loop()
826+
main_loop()
827+

src/launcher/settings.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@
2323

2424
# this defines the translations passed to hydra.menu and hydra.popup
2525
_TRANS = const("""[
26-
{"en": "language", "zh": "语言/Lang", "ja": "言語/Lang"},
27-
{"en": "volume", "zh": "音量", "ja": "音量"},
28-
{"en": "ui_color", "zh": "UI颜色", "ja": "UIの色"},
29-
{"en": "bg_color", "zh": "背景颜色", "ja": "背景色"},
30-
{"en": "wifi_ssid", "zh": "WiFi名称", "ja": "WiFi名前"},
31-
{"en": "wifi_pass", "zh": "WiFi密码", "ja": "WiFiパスワード"},
32-
{"en": "sync_clock", "zh": "同步时钟", "ja": "時計同期"},
33-
{"en": "24h_clock", "zh": "24小时制", "ja": "24時間制"},
34-
{"en": "timezone", "zh": "时区", "ja": "タイムゾーン"},
35-
{"en": "Confirm", "zh": "确认", "ja": "確認"}
26+
{"en": "language", "zh": "语言/Lang", "ja": "言語/Lang", "ua": "Мова/Lang"},
27+
{"en": "volume", "zh": "音量", "ja": "音量", "ua": "Гучність"},
28+
{"en": "ui_color", "zh": "UI颜色", "ja": "UIの色", "ua": "Колір меню"},
29+
{"en": "bg_color", "zh": "背景颜色", "ja": "背景色", "ua": "Колір фону"},
30+
{"en": "wifi_ssid", "zh": "WiFi名称", "ja": "WiFi名前", "ua": "Мережа WiFi"},
31+
{"en": "wifi_pass", "zh": "WiFi密码", "ja": "WiFiパスワード", "ua": "Пароль WiFi"},
32+
{"en": "sync_clock", "zh": "同步时钟", "ja": "時計同期", "ua": "Синхр. часу"},
33+
{"en": "24h_clock", "zh": "24小时制", "ja": "24時間制", "ua": "24 год. час"},
34+
{"en": "timezone", "zh": "时区", "ja": "タイムゾーン", "ua": "Часовий пояс"},
35+
{"en": "Confirm", "zh": "确认", "ja": "確認", "ua": "Зберегти"}
3636
]""")
3737

3838

@@ -44,7 +44,7 @@
4444
I18N = I18n(_TRANS)
4545
overlay = UIOverlay(i18n=I18N)
4646

47-
LANGS = ['en', 'zh', 'ja']
47+
LANGS = ['en', 'zh', 'ja', 'ua']
4848
LANGS.sort()
4949

5050
# try mounting SDCard for settings import/export
@@ -189,3 +189,5 @@ def build_menu() -> hydramenu.Menu:
189189
# this loop lets us restart the new menu if it is stopped/recreated by the callbacks above
190190
while True:
191191
menu.main()
192+
193+

src/lib/display/char_util.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
def square_char(char: int) -> bool:
2+
"""Checks if the character is square"""
3+
# CJK Unified Ideographs
4+
if 0x4E00 <= char <= 0x9FFF:
5+
return True
6+
# Hiragana
7+
if 0x3040 <= char <= 0x309F:
8+
return True
9+
# Katakana
10+
if 0x30A0 <= char <= 0x30FF:
11+
return True
12+
# Halfwidth and Fullwidth Forms (used for Katakana and punctuation)
13+
if 0xFF00 <= char <= 0xFFEF:
14+
return True
15+
# CJK Compatibility Ideographs
16+
if 0xF900 <= char <= 0xFAFF:
17+
return True
18+
# CJK Unified Ideographs Extension A
19+
if 0x3400 <= char <= 0x4DBF:
20+
return True
21+
return False
22+
23+
def ascii_char(char: int) -> bool:
24+
"""Checks if the character is in ASCII range"""
25+
return char < 128

src/lib/display/displaycore.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import framebuf
55
from .palette import Palette
6+
from .char_util import square_char, ascii_char
67
import lib.hydra.config
78
from lib.hydra.utils import get_instance
89
from machine import PWM
@@ -412,11 +413,13 @@ def _bitmap_text(self, font, text, x:int, y:int, color:int):
412413
@micropython.viper
413414
def _utf8_putc(self, char:int, x:int, y:int, color:int, scale:int) -> int:
414415
"""Render a single UTF8 character on the screen."""
415-
width = 4 if char < 128 else 8
416+
width = 4 if ascii_char(char) else 8
416417
height = 8
418+
if not square_char(char):
419+
scale = scale >> 1
417420

418-
if not 0x0000 <= char <= 0xFFFF:
419-
return width * scale
421+
if scale > 1 and not square_char(char):
422+
scale = scale >> 1
420423

421424
# set up viper variables
422425
use_tiny_fbuf = bool(self.use_tiny_buf)
@@ -494,7 +497,7 @@ def _utf8_text(self, text, x:int, y:int, color:int):
494497
while idx < str_len:
495498
char = text[idx]
496499
ch_ord = int(ord(char))
497-
if ch_ord >= 128:
500+
if not ascii_char(ch_ord):
498501
x += int(self._utf8_putc(ch_ord, x, y, color, 1))
499502
else:
500503
self.fbuf.text(char, x, y, color)
@@ -637,7 +640,7 @@ def _bitmap(self, bitmap, x:int, y:int, draw_width:int, draw_height:int, index:i
637640
btmp_x = (x_idx - x)*btmp_width // draw_width
638641

639642
# Find the start bit for the pixel we want
640-
btmp_bit_idx = starting_bit + (btmp_y*btmp_width + btmp_x) * bpp
643+
btmp_bit_idx = starting_bit + (btmp_y * ((btmp_width * bpp + 7) & ~7)) + btmp_x * bpp
641644
# calculate the byte, and byte shift needed to read that bit
642645
btmp_byte_idx = btmp_bit_idx // 8
643646
byte_shift = 7 - (btmp_bit_idx % 8)
@@ -669,3 +672,4 @@ def _bitmap(self, bitmap, x:int, y:int, draw_width:int, draw_height:int, index:i
669672

670673
x_idx += 1
671674
y_idx+=1
675+

0 commit comments

Comments
 (0)