From d53245f8a3efb6194e94c1aa2c08d251d2a3b4fb Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Sat, 10 Apr 2021 19:40:33 +0800 Subject: [PATCH 01/19] Simplify some Python code --- Translations/make_translation.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Translations/make_translation.py b/Translations/make_translation.py index 296fc9a3..fc3ebbd0 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -608,14 +608,11 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: f" // {offset + remapped.str_start_offset: >4}: {escape(str_table[j])}\n" ) str_offsets[j] = offset + remapped.str_start_offset - converted_str = convert_string(symbol_conversion_table, source_str) - f.write(f' "{converted_str}"') + converted_bytes = convert_string_bytes(symbol_conversion_table, source_str) + f.write(f' "{bytes_to_escaped(converted_bytes)}"') str_offsets[i] = offset - # Sanity check: Each "char" in `converted_str` should be in format - # `\xFF`, so the length should be divisible by 4. - assert len(converted_str) % 4 == 0 # Add the length and the null terminator - offset += len(converted_str) // 4 + 1 + offset += len(converted_bytes) + 1 f.write("\n};\n\n") def get_offset(idx: int) -> int: From 570fa16d442587b4eb1d9926fa2da64a766b28d6 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Sun, 11 Apr 2021 00:05:06 +0800 Subject: [PATCH 02/19] Some refactoring of make_translation.py --- Translations/make_translation.py | 206 ++++++++++++++++++------------- 1 file changed, 119 insertions(+), 87 deletions(-) diff --git a/Translations/make_translation.py b/Translations/make_translation.py index fc3ebbd0..a05643a6 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -79,7 +79,7 @@ def write_start(f: TextIO): f.write('#include "Translation.h"\n') -def get_constants() -> List[Tuple[str, str]]: +def get_constants(build_version: str) -> List[Tuple[str, str]]: # Extra constants that are used in the firmware that are shared across all languages return [ ("SymbolPlus", "+"), @@ -94,7 +94,7 @@ def get_constants() -> List[Tuple[str, str]]: ("SymbolVolts", "V"), ("SymbolDC", "DC"), ("SymbolCellCount", "S"), - ("SymbolVersionNumber", buildVersion), + ("SymbolVersionNumber", build_version), ] @@ -116,7 +116,7 @@ def get_debug_menu() -> List[str]: ] -def get_letter_counts(defs: dict, lang: dict) -> List[str]: +def get_letter_counts(defs: dict, lang: dict, build_version: str) -> List[str]: text_list = [] # iterate over all strings obj = lang["menuOptions"] @@ -169,7 +169,7 @@ def get_letter_counts(defs: dict, lang: dict) -> List[str]: for mod in defs["menuGroups"]: eid = mod["id"] text_list.append(obj[eid]["desc"]) - constants = get_constants() + constants = get_constants(build_version) for x in constants: text_list.append(x[1]) text_list.extend(get_debug_menu()) @@ -290,7 +290,15 @@ def bytes_to_escaped(b: bytes) -> str: return "".join((f"\\x{i:02X}" for i in b)) -def get_font_map_and_table(text_list: List[str]) -> Tuple[str, Dict[str, bytes]]: +@dataclass +class FontMap: + font12: Dict[str, str] + font06: Dict[str, str] + + +def get_font_map_and_table( + text_list: List[str], +) -> Tuple[List[str], FontMap, Dict[str, bytes]]: # the text list is sorted # allocate out these in their order as number codes symbol_map: Dict[str, bytes] = {"\n": bytes([1])} @@ -324,56 +332,56 @@ def get_font_map_and_table(text_list: List[str]) -> Tuple[str, Dict[str, bytes]] logging.info(f"Generating fonts for {total_symbol_count} symbols") - for sym in chain(ordered_normal_sym_list, ordered_cjk_sym_list): + sym_list = ordered_normal_sym_list + ordered_cjk_sym_list + for sym in sym_list: if sym in symbol_map: raise ValueError("Symbol not found in symbol map") symbol_map[sym] = get_bytes_from_font_index(index) index += 1 - font_table_strings = [] - font_small_table_strings = [] + font12_map: Dict[str, str] = {} + font06_map: Dict[str, str] = {} for sym in ordered_normal_sym_list: if sym not in font_table: logging.error(f"Missing Large font element for {sym}") sys.exit(1) - font_line: str = font_table[sym] - font_table_strings.append( - f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}" - ) + font12_map[sym] = font_table[sym] if sym not in font_small_table: logging.error(f"Missing Small font element for {sym}") sys.exit(1) - font_line = font_small_table[sym] - font_small_table_strings.append( - f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}" - ) + font06_map[sym] = font_small_table[sym] for sym in ordered_cjk_sym_list: if sym in font_table: raise ValueError("Symbol already exists in font_table") - font_line = get_cjk_glyph(sym) + font_line: str = get_cjk_glyph(sym) if font_line is None: logging.error(f"Missing Large font element for {sym}") sys.exit(1) - font_table_strings.append( - f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}" - ) + font12_map[sym] = font_line # No data to add to the small font table - font_small_table_strings.append( - f"// {bytes_to_escaped(symbol_map[sym])} -> {sym}" - ) + font06_map[sym] = "// " # placeholder + return sym_list, FontMap(font12_map, font06_map), symbol_map + + +def make_font_table_cpp( + sym_list: List[str], font_map: FontMap, symbol_map: Dict[str, bytes] +) -> str: output_table = "const uint8_t USER_FONT_12[] = {\n" - for line in font_table_strings: - # join font table int one large string - output_table += line + "\n" + for sym in sym_list: + output_table += ( + f"{font_map.font12[sym]}//{bytes_to_escaped(symbol_map[sym])} -> {sym}\n" + ) output_table += "};\n" + output_table += "const uint8_t USER_FONT_6x8[] = {\n" - for line in font_small_table_strings: - # join font table int one large string - output_table += line + "\n" + for sym in sym_list: + output_table += ( + f"{font_map.font06[sym]}//{bytes_to_escaped(symbol_map[sym])} -> {sym}\n" + ) output_table += "};\n" - return output_table, symbol_map + return output_table def convert_string_bytes(symbol_conversion_table: Dict[str, bytes], text: str) -> bytes: @@ -403,13 +411,14 @@ class TranslationItem: str_index: int -def write_language(lang: dict, defs: dict, f: TextIO) -> None: +def write_language(lang: dict, defs: dict, build_version: str, f: TextIO) -> None: language_code: str = lang["languageCode"] logging.info(f"Generating block for {language_code}") # Iterate over all of the text to build up the symbols & counts - text_list = get_letter_counts(defs, lang) + text_list = get_letter_counts(defs, lang, build_version) # From the letter counts, need to make a symbol translator & write out the font - font_table_text, symbol_conversion_table = get_font_map_and_table(text_list) + sym_list, font_map, symbol_conversion_table = get_font_map_and_table(text_list) + font_table_text = make_font_table_cpp(sym_list, font_map, symbol_conversion_table) try: lang_name = lang["languageLocalName"] @@ -420,6 +429,50 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: f.write(font_table_text) f.write(f"\n// ---- {lang_name} ----\n\n") + translation_common_text = get_translation_common_text( + defs, symbol_conversion_table, build_version + ) + f.write(translation_common_text) + f.write( + f"const bool HasFahrenheit = {('true' if lang.get('tempUnitFahrenheit', True) else 'false')};\n\n" + ) + + translation_strings_and_indices_text = get_translation_strings_and_indices_text( + lang, defs, symbol_conversion_table + ) + f.write(translation_strings_and_indices_text) + f.write("const TranslationIndexTable *const Tr = &TranslationIndices;\n") + f.write("const char *const TranslationStrings = TranslationStringsData;\n\n") + + sanity_checks_text = get_translation_sanity_checks_text(defs) + f.write(sanity_checks_text) + + +def get_translation_common_text( + defs: dict, symbol_conversion_table: Dict[str, bytes], build_version +) -> str: + translation_common_text = "" + + # Write out firmware constant options + constants = get_constants(build_version) + for x in constants: + translation_common_text += f'const char* {x[0]} = "{convert_string(symbol_conversion_table, x[1])}";//{x[1]} \n' + translation_common_text += "\n" + + # Debug Menu + translation_common_text += "const char* DebugMenu[] = {\n" + + for c in get_debug_menu(): + translation_common_text += ( + f'\t "{convert_string(symbol_conversion_table, c)}",//{c} \n' + ) + translation_common_text += "};\n\n" + return translation_common_text + + +def get_translation_strings_and_indices_text( + lang: dict, defs: dict, symbol_conversion_table: Dict[str, bytes] +) -> str: str_table: List[str] = [] str_group_messages: List[TranslationItem] = [] str_group_messageswarn: List[TranslationItem] = [] @@ -478,21 +531,6 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: str_group_characters.append(TranslationItem(eid, len(str_table))) str_table.append(obj[eid]) - # Write out firmware constant options - constants = get_constants() - for x in constants: - f.write( - f'const char* {x[0]} = "{convert_string(symbol_conversion_table, x[1])}";//{x[1]} \n' - ) - f.write("\n") - - # Debug Menu - f.write("const char* DebugMenu[] = {\n") - - for c in get_debug_menu(): - f.write(f'\t "{convert_string(symbol_conversion_table, c)}",//{c} \n') - f.write("};\n\n") - # ----- Reading SettingsDescriptions obj = lang["menuOptions"] @@ -537,8 +575,6 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: ) str_table.append(obj[eid]["desc"]) - f.write("\n") - @dataclass class RemappedTranslationItem: str_index: int @@ -573,14 +609,13 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: str_offsets = [-1] * len(str_table) offset = 0 write_null = False - f.write("const char TranslationStringsData[] = {\n") + translation_strings_text = "const char TranslationStringsData[] = {\n" for i, source_str in enumerate(str_table): - if write_null: - f.write(' "\\0"\n') - write_null = True if str_remapping[i] is not None: - write_null = False continue + if write_null: + translation_strings_text += ' "\\0"\n' + write_null = True # Find what items use this string str_used_by = [i] + [ j for j, r in enumerate(str_remapping) if r and r.str_index == i @@ -597,37 +632,35 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: ]: for item in group: if item.str_index == j: - f.write(f" // - {pre_info} {item.info}\n") + translation_strings_text += ( + f" // - {pre_info} {item.info}\n" + ) if j == i: - f.write(f" // {offset: >4}: {escape(source_str)}\n") + translation_strings_text += f" // {offset: >4}: {escape(source_str)}\n" str_offsets[j] = offset else: remapped = str_remapping[j] assert remapped is not None - f.write( - f" // {offset + remapped.str_start_offset: >4}: {escape(str_table[j])}\n" - ) + translation_strings_text += f" // {offset + remapped.str_start_offset: >4}: {escape(str_table[j])}\n" str_offsets[j] = offset + remapped.str_start_offset converted_bytes = convert_string_bytes(symbol_conversion_table, source_str) - f.write(f' "{bytes_to_escaped(converted_bytes)}"') + translation_strings_text += f' "{bytes_to_escaped(converted_bytes)}"' str_offsets[i] = offset # Add the length and the null terminator offset += len(converted_bytes) + 1 - f.write("\n};\n\n") + translation_strings_text += "\n}; // TranslationStringsData\n\n" def get_offset(idx: int) -> int: assert str_offsets[idx] >= 0 return str_offsets[idx] - f.write("const TranslationIndexTable TranslationIndices = {\n") + translation_indices_text = "const TranslationIndexTable TranslationIndices = {\n" # ----- Write the messages string indices: for group in [str_group_messages, str_group_messageswarn, str_group_characters]: for item in group: - f.write( - f" .{item.info} = {get_offset(item.str_index)}, // {escape(str_table[item.str_index])}\n" - ) - f.write("\n") + translation_indices_text += f" .{item.info} = {get_offset(item.str_index)}, // {escape(str_table[item.str_index])}\n" + translation_indices_text += "\n" # ----- Write the settings index tables: for group, name in [ @@ -637,30 +670,25 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None: (str_group_settingmenuentriesdesc, "SettingsMenuEntriesDescriptions"), ]: max_len = 30 - f.write(f" .{name} = {{\n") + translation_indices_text += f" .{name} = {{\n" for item in group: - f.write( - f" /* {item.info.ljust(max_len)[:max_len]} */ {get_offset(item.str_index)}, // {escape(str_table[item.str_index])}\n" - ) - f.write(f" }}, // {name}\n\n") + translation_indices_text += f" /* {item.info.ljust(max_len)[:max_len]} */ {get_offset(item.str_index)}, // {escape(str_table[item.str_index])}\n" + translation_indices_text += f" }}, // {name}\n\n" - f.write("}; // TranslationIndices\n\n") - f.write("const TranslationIndexTable *const Tr = &TranslationIndices;\n") - f.write("const char *const TranslationStrings = TranslationStringsData;\n\n") + translation_indices_text += "}; // TranslationIndices\n\n" - f.write( - f"const bool HasFahrenheit = {('true' if lang.get('tempUnitFahrenheit', True) else 'false')};\n" - ) + return translation_strings_text + translation_indices_text - f.write("\n// Verify SettingsItemIndex values:\n") + +def get_translation_sanity_checks_text(defs: dict) -> str: + sanity_checks_text = "\n// Verify SettingsItemIndex values:\n" for i, mod in enumerate(defs["menuOptions"]): eid = mod["id"] - f.write( + sanity_checks_text += ( f"static_assert(static_cast(SettingsItemIndex::{eid}) == {i});\n" ) - f.write( - f"static_assert(static_cast(SettingsItemIndex::NUM_ITEMS) == {len(defs['menuOptions'])});\n" - ) + sanity_checks_text += f"static_assert(static_cast(SettingsItemIndex::NUM_ITEMS) == {len(defs['menuOptions'])});\n" + return sanity_checks_text def read_version() -> str: @@ -687,23 +715,27 @@ def parse_args() -> argparse.Namespace: return parser.parse_args() -if __name__ == "__main__": +def main() -> None: json_dir = HERE args = parse_args() try: - buildVersion = read_version() + build_version = read_version() except FileNotFoundError: logging.error("error: Could not find version info ") sys.exit(1) - logging.info(f"Build version: {buildVersion}") + logging.info(f"Build version: {build_version}") logging.info(f"Making {args.languageCode} from {json_dir}") lang_ = read_translation(json_dir, args.languageCode) defs_ = load_json(os.path.join(json_dir, "translations_def.js"), True) out_ = args.output write_start(out_) - write_language(lang_, defs_, out_) + write_language(lang_, defs_, build_version, out_) logging.info("Done") + + +if __name__ == "__main__": + main() From 2f2575c0b7760d36838644eb2a171f94088375e6 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Mon, 12 Apr 2021 17:20:19 +0800 Subject: [PATCH 03/19] Refactor make_translation.py to split parsing and writing --- Translations/make_translation.py | 38 +++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/Translations/make_translation.py b/Translations/make_translation.py index a05643a6..c7787c94 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -406,18 +406,37 @@ def escape(string: str) -> str: @dataclass -class TranslationItem: - info: str - str_index: int +class LanguageData: + lang: dict + defs: dict + build_version: str + sym_list: List[str] + font_map: FontMap + symbol_conversion_table: Dict[str, bytes] -def write_language(lang: dict, defs: dict, build_version: str, f: TextIO) -> None: +def prepare_language(lang: dict, defs: dict, build_version: str) -> LanguageData: language_code: str = lang["languageCode"] - logging.info(f"Generating block for {language_code}") + logging.info(f"Preparing language data for {language_code}") # Iterate over all of the text to build up the symbols & counts text_list = get_letter_counts(defs, lang, build_version) # From the letter counts, need to make a symbol translator & write out the font sym_list, font_map, symbol_conversion_table = get_font_map_and_table(text_list) + return LanguageData( + lang, defs, build_version, sym_list, font_map, symbol_conversion_table + ) + + +def write_language(data: LanguageData, f: TextIO) -> None: + lang = data.lang + defs = data.defs + build_version = data.build_version + sym_list = data.sym_list + font_map = data.font_map + symbol_conversion_table = data.symbol_conversion_table + + language_code: str = lang["languageCode"] + logging.info(f"Generating block for {language_code}") font_table_text = make_font_table_cpp(sym_list, font_map, symbol_conversion_table) try: @@ -470,6 +489,12 @@ def get_translation_common_text( return translation_common_text +@dataclass +class TranslationItem: + info: str + str_index: int + + def get_translation_strings_and_indices_text( lang: dict, defs: dict, symbol_conversion_table: Dict[str, bytes] ) -> str: @@ -730,9 +755,10 @@ def main() -> None: lang_ = read_translation(json_dir, args.languageCode) defs_ = load_json(os.path.join(json_dir, "translations_def.js"), True) + language_data = prepare_language(lang_, defs_, build_version) out_ = args.output write_start(out_) - write_language(lang_, defs_, build_version, out_) + write_language(language_data, out_) logging.info("Done") From 07fb8adb7f7bbbd48ac57b58e76bd6fac6cd7499 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Mon, 12 Apr 2021 19:57:29 +0800 Subject: [PATCH 04/19] Impl. initial translation strings compression --- Translations/make_translation.py | 117 +++++++-- source/Core/Drivers/OLED.cpp | 4 +- source/Core/Inc/Translation.h | 8 +- source/Core/Threads/GUIThread.cpp | 2 + source/Core/lzfx/README.md | 79 ++++++ source/Core/lzfx/lzfx-host-compress.c | 52 ++++ source/Core/lzfx/lzfx.c | 352 ++++++++++++++++++++++++++ source/Core/lzfx/lzfx.h | 98 +++++++ source/Makefile | 87 ++++++- 9 files changed, 771 insertions(+), 28 deletions(-) create mode 100644 source/Core/lzfx/README.md create mode 100644 source/Core/lzfx/lzfx-host-compress.c create mode 100644 source/Core/lzfx/lzfx.c create mode 100644 source/Core/lzfx/lzfx.h diff --git a/Translations/make_translation.py b/Translations/make_translation.py index c7787c94..8c858387 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -5,13 +5,14 @@ import functools import json import logging import os +import pickle import re import subprocess import sys from datetime import datetime from itertools import chain from pathlib import Path -from typing import Dict, List, Optional, TextIO, Tuple, Union +from typing import BinaryIO, Dict, List, Optional, TextIO, Tuple, Union from dataclasses import dataclass from bdflib import reader as bdfreader @@ -405,6 +406,17 @@ def escape(string: str) -> str: return json.dumps(string, ensure_ascii=False) +def write_bytes_as_c_array( + f: TextIO, name: str, data: bytes, indent: int = 2, bytes_per_line: int = 16 +) -> None: + f.write(f"const uint8_t {name}[] = {{\n") + for i in range(0, len(data), bytes_per_line): + f.write(" " * indent) + f.write(", ".join((f"0x{b:02X}" for b in data[i : i + bytes_per_line]))) + f.write(",\n") + f.write(f"}}; // {name}\n\n") + + @dataclass class LanguageData: lang: dict @@ -427,7 +439,9 @@ def prepare_language(lang: dict, defs: dict, build_version: str) -> LanguageData ) -def write_language(data: LanguageData, f: TextIO) -> None: +def write_language( + data: LanguageData, f: TextIO, lzfx_strings: Optional[bytes] = None +) -> None: lang = data.lang defs = data.defs build_version = data.build_version @@ -444,6 +458,9 @@ def write_language(data: LanguageData, f: TextIO) -> None: except KeyError: lang_name = language_code + if lzfx_strings: + f.write('#include "lzfx.h"\n') + f.write(f"\n// ---- {lang_name} ----\n\n") f.write(font_table_text) f.write(f"\n// ---- {lang_name} ----\n\n") @@ -456,12 +473,31 @@ def write_language(data: LanguageData, f: TextIO) -> None: f"const bool HasFahrenheit = {('true' if lang.get('tempUnitFahrenheit', True) else 'false')};\n\n" ) - translation_strings_and_indices_text = get_translation_strings_and_indices_text( - lang, defs, symbol_conversion_table - ) - f.write(translation_strings_and_indices_text) - f.write("const TranslationIndexTable *const Tr = &TranslationIndices;\n") - f.write("const char *const TranslationStrings = TranslationStringsData;\n\n") + if not lzfx_strings: + translation_strings_and_indices_text = get_translation_strings_and_indices_text( + lang, defs, symbol_conversion_table + ) + f.write(translation_strings_and_indices_text) + f.write( + "const TranslationIndexTable *const Tr = &TranslationIndices;\n" + "const char *const TranslationStrings = TranslationStringsData;\n\n" + "extern const uint8_t *const Font_12x16 = USER_FONT_12;\n" + "extern const uint8_t *const Font_6x8 = USER_FONT_6x8;\n\n" + "void prepareTranslations() {}\n\n" + ) + else: + write_bytes_as_c_array(f, "translation_data_lzfx", lzfx_strings) + f.write( + "static uint8_t translation_data_out_buffer[4096] __attribute__((__aligned__(2)));\n\n" + "const TranslationIndexTable *const Tr = reinterpret_cast(translation_data_out_buffer);\n" + "const char *const TranslationStrings = reinterpret_cast(translation_data_out_buffer) + sizeof(TranslationIndexTable);\n\n" + "extern const uint8_t *const Font_12x16 = USER_FONT_12;\n" + "extern const uint8_t *const Font_6x8 = USER_FONT_6x8;\n\n" + "void prepareTranslations() {\n" + " unsigned int outsize = sizeof(translation_data_out_buffer);\n" + " lzfx_decompress(translation_data_lzfx, sizeof(translation_data_lzfx), translation_data_out_buffer, &outsize);\n" + "}\n\n" + ) sanity_checks_text = get_translation_sanity_checks_text(defs) f.write(sanity_checks_text) @@ -733,6 +769,27 @@ def read_version() -> str: def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser() + parser.add_argument( + "--output-pickled", + help="Write pickled language data for later reuse", + type=argparse.FileType("wb"), + required=False, + dest="output_pickled", + ) + parser.add_argument( + "--input-pickled", + help="Use previously generated pickled language data", + type=argparse.FileType("rb"), + required=False, + dest="input_pickled", + ) + parser.add_argument( + "--lzfx-strings", + help="Use compressed TranslationIndices + TranslationStrings data", + type=argparse.FileType("rb"), + required=False, + dest="lzfx_strings", + ) parser.add_argument( "--output", "-o", help="Target file", type=argparse.FileType("w"), required=True ) @@ -744,21 +801,45 @@ def main() -> None: json_dir = HERE args = parse_args() - try: - build_version = read_version() - except FileNotFoundError: - logging.error("error: Could not find version info ") + if args.input_pickled and args.output_pickled: + logging.error("error: Both --output-pickled and --input-pickled are specified") sys.exit(1) - logging.info(f"Build version: {build_version}") - logging.info(f"Making {args.languageCode} from {json_dir}") + language_data: LanguageData + if args.input_pickled: + logging.info(f"Reading pickled language data from {args.input_pickled.name}...") + language_data = pickle.load(args.input_pickled) + if language_data.lang["languageCode"] != args.languageCode: + logging.error( + f"error: languageCode {args.languageCode} does not match language data {language_data.lang['languageCode']}" + ) + sys.exit(1) + logging.info(f"Read language data for {language_data.lang['languageCode']}") + logging.info(f"Build version: {language_data.build_version}") + else: + try: + build_version = read_version() + except FileNotFoundError: + logging.error("error: Could not find version info ") + sys.exit(1) + + logging.info(f"Build version: {build_version}") + logging.info(f"Making {args.languageCode} from {json_dir}") + + lang_ = read_translation(json_dir, args.languageCode) + defs_ = load_json(os.path.join(json_dir, "translations_def.js"), True) + language_data = prepare_language(lang_, defs_, build_version) - lang_ = read_translation(json_dir, args.languageCode) - defs_ = load_json(os.path.join(json_dir, "translations_def.js"), True) - language_data = prepare_language(lang_, defs_, build_version) out_ = args.output write_start(out_) - write_language(language_data, out_) + if args.lzfx_strings: + write_language(language_data, out_, args.lzfx_strings.read()) + else: + write_language(language_data, out_) + + if args.output_pickled: + logging.info(f"Writing pickled data to {args.output_pickled.name}") + pickle.dump(language_data, args.output_pickled) logging.info("Done") diff --git a/source/Core/Drivers/OLED.cpp b/source/Core/Drivers/OLED.cpp index 309fe87c..ac6ca524 100644 --- a/source/Core/Drivers/OLED.cpp +++ b/source/Core/Drivers/OLED.cpp @@ -117,7 +117,7 @@ void OLED::drawChar(const uint16_t charCode, const FontStyle fontStyle) { static uint8_t fontWidth, fontHeight; switch (fontStyle) { case FontStyle::SMALL: - currentFont = USER_FONT_6x8; + currentFont = Font_6x8; fontHeight = 8; fontWidth = 6; break; @@ -128,7 +128,7 @@ void OLED::drawChar(const uint16_t charCode, const FontStyle fontStyle) { break; case FontStyle::LARGE: default: - currentFont = USER_FONT_12; + currentFont = Font_12x16; fontHeight = 16; fontWidth = 12; break; diff --git a/source/Core/Inc/Translation.h b/source/Core/Inc/Translation.h index 67277906..9c5bcb5d 100644 --- a/source/Core/Inc/Translation.h +++ b/source/Core/Inc/Translation.h @@ -8,8 +8,7 @@ #ifndef TRANSLATION_H_ #define TRANSLATION_H_ #include "stdint.h" -extern const uint8_t USER_FONT_12[]; -extern const uint8_t USER_FONT_6x8[]; + extern const bool HasFahrenheit; extern const char *SymbolPlus; @@ -114,10 +113,15 @@ struct TranslationIndexTable { extern const TranslationIndexTable *const Tr; extern const char *const TranslationStrings; +extern const uint8_t *const Font_12x16; +extern const uint8_t *const Font_6x8; + constexpr uint8_t settings_item_index(const SettingsItemIndex i) { return static_cast(i); } // Use a constexpr function for type-checking. #define SETTINGS_DESC(i) (settings_item_index(i) + 1) const char *translatedString(uint16_t index); +void prepareTranslations(); + #endif /* TRANSLATION_H_ */ diff --git a/source/Core/Threads/GUIThread.cpp b/source/Core/Threads/GUIThread.cpp index 3c72b758..54fd006c 100644 --- a/source/Core/Threads/GUIThread.cpp +++ b/source/Core/Threads/GUIThread.cpp @@ -746,6 +746,8 @@ void showWarnings() { uint8_t idleScreenBGF[sizeof(idleScreenBG)]; /* StartGUITask function */ void startGUITask(void const *argument __unused) { + prepareTranslations(); + OLED::initialize(); // start up the LCD uint8_t tempWarningState = 0; diff --git a/source/Core/lzfx/README.md b/source/Core/lzfx/README.md new file mode 100644 index 00000000..82420cf0 --- /dev/null +++ b/source/Core/lzfx/README.md @@ -0,0 +1,79 @@ +This directory contains file originally by other people. + + +## Simplified LZFX-based compression library + +- `lzfx.c` +- `lzfx.h` + +The above files are obtained from https://github.com/janding/lzfx (commit +448017f). It is a fork by Jan Ding (GitHub user "janding") based on the LZFX +compression library by Andrew Collette. + +### License: + +``` +LZFX is copyright (c) 2009 Andrew Collette and subject to the BSD license +(below). Original LZF copyright statement follows. + +Copyright (c) 2000-2007 Marc Alexander Lehmann + +Redistribution and use in source and binary forms, with or without modifica- +tion, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- +CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- +CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- +ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. +``` + + +## lzfx-boot + +- `lzfx-host-compress.c` (original: `lzfx-raw.c`) + +The above file is obtained from https://github.com/janding/lzfx-boot (commit +88b1596). + +### License: + +``` +BSD 2-Clause License + +Copyright (c) 2017, Jan Ding +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` diff --git a/source/Core/lzfx/lzfx-host-compress.c b/source/Core/lzfx/lzfx-host-compress.c new file mode 100644 index 00000000..1a3e6f79 --- /dev/null +++ b/source/Core/lzfx/lzfx-host-compress.c @@ -0,0 +1,52 @@ +#include +#include + +#include "lzfx.h" + +/* Program to demonstrate file compression. Don't use it in the real world! */ + +int main(int argc, char **argv) +{ + if (argc == 3) + { + /* open input */ + FILE *f = fopen(argv[1], "rb"); + if (!f) { + printf("Error: %s\n", argv[1]); + return 1; + } + + /* get size */ + fseek(f, 0, SEEK_END); + int inputsize = ftell(f); + fseek(f, 0, SEEK_SET); + + /* read */ + char *input = malloc(inputsize); + fread(input, inputsize, 1, f); + fclose(f); + + /* compress */ + int outputsize = inputsize + 1; /* buffer overflow */ + char *output = malloc(outputsize); + lzfx_compress(input, inputsize, output, &outputsize); + + /* open output */ + f = fopen(argv[2], "wb"); + if (!f) { + printf("Error: %s\n", argv[1]); + return 1; + } + + /* write */ + fwrite(output, outputsize, 1, f); + fclose(f); + + return 0; + } + else + { + printf("Compresses a file.\n\nUsage: lzfx-raw input output\n"); + return 1; + } +} \ No newline at end of file diff --git a/source/Core/lzfx/lzfx.c b/source/Core/lzfx/lzfx.c new file mode 100644 index 00000000..47b387a2 --- /dev/null +++ b/source/Core/lzfx/lzfx.c @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2009 Andrew Collette + * http://lzfx.googlecode.com + * + * Implements an LZF-compatible compressor/decompressor based on the liblzf + * codebase written by Marc Lehmann. This code is released under the BSD + * license. License and original copyright statement follow. + * + * + * Copyright (c) 2000-2008 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "lzfx.h" + +#define LZFX_HSIZE (1 << (LZFX_HLOG)) + +/* We need this for memset */ +#ifdef __cplusplus +# include +#else +# include +#endif + +#if __GNUC__ >= 3 +# define fx_expect_false(expr) __builtin_expect((expr) != 0, 0) +# define fx_expect_true(expr) __builtin_expect((expr) != 0, 1) +#else +# define fx_expect_false(expr) (expr) +# define fx_expect_true(expr) (expr) +#endif + +typedef unsigned char u8; +typedef const u8 *LZSTATE[LZFX_HSIZE]; + +/* Define the hash function */ +#define LZFX_FRST(p) (((p[0]) << 8) | p[1]) +#define LZFX_NEXT(v,p) (((v) << 8) | p[2]) +#define LZFX_IDX(h) ((( h >> (3*8 - LZFX_HLOG)) - h ) & (LZFX_HSIZE - 1)) + +/* These cannot be changed, as they are related to the compressed format. */ +#define LZFX_MAX_LIT (1 << 5) - 1 +#define LZFX_MAX_OFF (1 << 13) +#define LZFX_MAX_REF ((1 << 8) + (1 << 3) - 2) + +static +int lzfx_getsize(const void* ibuf, unsigned int ilen, unsigned int *olen); + +/* Compressed format + + There are two kinds of structures in LZF/LZFX: literal runs and back + references. Literals are encoded as follows: + + LLLLL000 + + Back references are encoded as follows. The smallest possible encoded + length value is 1, as otherwise the control byte would be recognized as + a literal run. At least three bytes must match for a back reference + to be inserted. The offset (distance to the desired data in the output + buffer) is encoded as o - 1, as all offsets are at least 1. The binary + format is: + + oooooLLL oooooooo for backrefs of real length < 7 (1 <= L < 7) + ooooo111 LLLLLLLL oooooooo for backrefs of real length >= 7 (L >= 7) +*/ +int lzfx_compress(const void *const ibuf, const unsigned int ilen, + void *obuf, unsigned int *const olen){ + + /* Hash table; an array of u8*'s which point + to various locations in the input buffer */ + const u8 *htab[LZFX_HSIZE]; + + const u8 **hslot; /* Pointer to entry in hash table */ + unsigned int hval; /* Hash value generated by macros above */ + const u8 *ref; /* Pointer to candidate match location in input */ + + const u8 *ip = (const u8 *)ibuf; + const u8 *const in_end = ip + ilen; + + u8 *op = (u8 *)obuf; + const u8 *const out_end = (olen == NULL ? NULL : op + *olen); + + int lit; /* # of bytes in current literal run */ + +#if defined (WIN32) && defined (_M_X64) + unsigned _int64 off; /* workaround for missing POSIX compliance */ +#else + unsigned long off; +#endif + + if(olen == NULL) return LZFX_EARGS; + if(ibuf == NULL){ + if(ilen != 0) return LZFX_EARGS; + *olen = 0; + return 0; + } + if(obuf == NULL) return LZFX_EARGS; + + memset(htab, 0, sizeof(htab)); + + /* Start a literal run. Whenever we do this the output pointer is + advanced because the current byte will hold the encoded length. */ + lit = 0; op++; + + hval = LZFX_FRST(ip); + + while(ip + 2 < in_end){ /* The NEXT macro reads 2 bytes ahead */ + + hval = LZFX_NEXT(hval, ip); + hslot = htab + LZFX_IDX(hval); + + ref = *hslot; *hslot = ip; + + if( ref < ip + && (off = ip - ref - 1) < LZFX_MAX_OFF + && ip + 4 < in_end /* Backref takes up to 3 bytes, so don't bother */ + && ref > (u8 *)ibuf + && ref[0] == ip[0] + && ref[1] == ip[1] + && ref[2] == ip[2] ) { + + unsigned int len = 3; /* We already know 3 bytes match */ + const unsigned int maxlen = in_end - ip - 2 > LZFX_MAX_REF ? + LZFX_MAX_REF : in_end - ip - 2; + + /* lit == 0: op + 3 must be < out_end (because we undo the run) + lit != 0: op + 3 + 1 must be < out_end */ + if(fx_expect_false(op - !lit + 3 + 1 >= out_end)) + return LZFX_ESIZE; + + op [- lit - 1] = lit << 3;/* Terminate literal run */ + op -= !lit; /* Undo run if length is zero */ + + /* Start checking at the fourth byte */ + while (len < maxlen && ref[len] == ip[len]) + len++; + + /* Format 1: [oooooLLL oooooooo] */ + if (len < 7) { + *op++ = ((off >> 8) << 3) + len; + *op++ = off; + + /* Format 2: [ooooo111 LLLLLLLL oooooooo] */ + } else { + *op++ = ((off >> 8) << 3) + 7; + *op++ = len - 7; + *op++ = off; + } + + lit = 0; op++; + + ip += len - 1; /* ip = initial ip + #octets - 1 */ + + if (fx_expect_false (ip + 3 >= in_end)){ + ip++; /* Code following expects exit at bottom of loop */ + break; + } + + hval = LZFX_FRST (ip); + hval = LZFX_NEXT (hval, ip); + htab[LZFX_IDX (hval)] = ip; + + ip++; /* ip = initial ip + #octets */ + + } else { + /* Keep copying literal bytes */ + + if (fx_expect_false (op >= out_end)) return LZFX_ESIZE; + + lit++; *op++ = *ip++; + + if (fx_expect_false (lit == LZFX_MAX_LIT)) { + op [- lit - 1] = lit << 3; /* stop run */ + lit = 0; op++; /* start run */ + } + + } /* if() found match in htab */ + + } /* while(ip < ilen -2) */ + + /* At most 3 bytes remain in input. We therefore need 4 bytes available + in the output buffer to store them (3 data + ctrl byte).*/ + if (op + 3 > out_end) return LZFX_ESIZE; + + while (ip < in_end) { + + lit++; *op++ = *ip++; + + if (fx_expect_false (lit == LZFX_MAX_LIT)){ + op [- lit - 1] = lit << 3; + lit = 0; op++; + } + } + + op [- lit - 1] = lit << 3; + op -= !lit; + + *olen = op - (u8 *)obuf; + return 0; +} + +/* Decompressor */ +int lzfx_decompress(const void* ibuf, unsigned int ilen, + void* obuf, unsigned int *olen){ + + u8 const *ip = (const u8 *)ibuf; + u8 const *const in_end = ip + ilen; + u8 *op = (u8 *)obuf; + u8 const *const out_end = (olen == NULL ? NULL : op + *olen); + + unsigned int remain_len = 0; + int rc; + + if(olen == NULL) return LZFX_EARGS; + if(ibuf == NULL){ + if(ilen != 0) return LZFX_EARGS; + *olen = 0; + return 0; + } + if(obuf == NULL){ + if(olen != 0) return LZFX_EARGS; + return lzfx_getsize(ibuf, ilen, olen); + } + + do { + unsigned int ctrl = *ip++; + + /* Format LLLLL000: a literal byte string follows, of length L */ + if((ctrl & 0x7) == 0) { + unsigned int len = ctrl >> 3; + + if(fx_expect_false(op + len > out_end)){ + --ip; /* Rewind to control byte */ + goto guess; + } + if(fx_expect_false(ip + len > in_end)) return LZFX_ECORRUPT; + + do + *op++ = *ip++; + while(--len); + + /* Format #1 [oooooLLL oooooooo]: backref of length L+1 + ^^^^^ ^^^^^^^^ + A B + #2 [ooooo111 LLLLLLLL oooooooo] backref of length L+7 + ^^^^^ ^^^^^^^^ + A B + In both cases the location of the backref is computed from the + remaining part of the data as follows: + + location = op - A*256 - B - 1 + */ + } else { + + unsigned int len = ctrl & 0x7; + u8 *ref = op - ((ctrl >> 3) << 8) - 1; + + if(len==7) len += *ip++; /* i.e. format #2 */ + + if(fx_expect_false(op + len > out_end)){ + ip -= (len >= 7) ? 2 : 1; /* Rewind to control byte */ + goto guess; + } + if(fx_expect_false(ip >= in_end)) return LZFX_ECORRUPT; + + ref -= *ip++; + + if(fx_expect_false(ref < (u8*)obuf)) return LZFX_ECORRUPT; + + do + *op++ = *ref++; + while (--len); + } + + } while (ip < in_end); + + *olen = op - (u8 *)obuf; + + return 0; + +guess: + rc = lzfx_getsize(ip, ilen - (ip-(u8*)ibuf), &remain_len); + if(rc>=0) *olen = remain_len + (op - (u8*)obuf); + return rc; +} + +/* Guess len. No parameters may be NULL; this is not checked. */ +static +int lzfx_getsize(const void* ibuf, unsigned int ilen, unsigned int *olen){ + + u8 const *ip = (const u8 *)ibuf; + u8 const *const in_end = ip + ilen; + int tot_len = 0; + + while (ip < in_end) { + + unsigned int ctrl = *ip++; + + if((ctrl & 0x7) == 0) { + + if(ip + (ctrl >> 3) > in_end) + return LZFX_ECORRUPT; + + tot_len += (ctrl >> 3); + ip += (ctrl >> 3); + + } else { + + unsigned int len = ctrl & 0x7; + + if(len==7){ /* i.e. format #2 */ + len += *ip++; + } + + if(ip >= in_end) return LZFX_ECORRUPT; + + ip++; /* skip the ref byte */ + + tot_len += len; + + } + + } + + *olen = tot_len; + + return 0; +} + + + + diff --git a/source/Core/lzfx/lzfx.h b/source/Core/lzfx/lzfx.h new file mode 100644 index 00000000..4d7c560b --- /dev/null +++ b/source/Core/lzfx/lzfx.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2009 Andrew Collette + * http://lzfx.googlecode.com + * + * Implements an LZF-compatible compressor/decompressor based on the liblzf + * codebase written by Marc Lehmann. This code is released under the BSD + * license. License and original copyright statement follow. + * + * + * Copyright (c) 2000-2008 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef LZFX_H +#define LZFX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Documented behavior, including function signatures and error codes, + is guaranteed to remain unchanged for releases with the same major + version number. Releases of the same major version are also able + to read each other's output, although the output itself is not + guaranteed to be byte-for-byte identical. +*/ +#define LZFX_VERSION_MAJOR 0 +#define LZFX_VERSION_MINOR 1 +#define LZFX_VERSION_STRING "0.1" + +/* Hashtable size (2**LZFX_HLOG entries) */ +#ifndef LZFX_HLOG +# define LZFX_HLOG 16 +#endif + +/* Predefined errors. */ +#define LZFX_ESIZE -1 /* Output buffer too small */ +#define LZFX_ECORRUPT -2 /* Invalid data for decompression */ +#define LZFX_EARGS -3 /* Arguments invalid (NULL) */ + +/* Buffer-to buffer compression. + + Supply pre-allocated input and output buffers via ibuf and obuf, and + their size in bytes via ilen and olen. Buffers may not overlap. + + On success, the function returns a non-negative value and the argument + olen contains the compressed size in bytes. On failure, a negative + value is returned and olen is not modified. +*/ +int lzfx_compress(const void* ibuf, unsigned int ilen, + void* obuf, unsigned int *olen); + +/* Buffer-to-buffer decompression. + + Supply pre-allocated input and output buffers via ibuf and obuf, and + their size in bytes via ilen and olen. Buffers may not overlap. + + On success, the function returns a non-negative value and the argument + olen contains the uncompressed size in bytes. On failure, a negative + value is returned. + + If the failure code is LZFX_ESIZE, olen contains the minimum buffer size + required to hold the decompressed data. Otherwise, olen is not modified. + + Supplying a zero *olen is a valid and supported strategy to determine the + required buffer size. This does not require decompression of the entire + stream and is consequently very fast. Argument obuf may be NULL in + this case only. +*/ +int lzfx_decompress(const void* ibuf, unsigned int ilen, + void* obuf, unsigned int *olen); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/source/Makefile b/source/Makefile index eb988648..73568409 100644 --- a/source/Makefile +++ b/source/Makefile @@ -13,8 +13,16 @@ endif ALL_LANGUAGES=BG CS DA DE EN ES FI FR HR HU IT LT NL NL_BE NO PL PT RU SK SL SR_CYRL SR_LATN SV TR UK YUE_HK ZH_CN ZH_TW +# Defines for host tools +ifeq ($(HOST_CC),) +HOST_CC := gcc +endif +HOST_OUTPUT_DIR=Objects/host + + # Enumerate all of the include directories APP_INC_DIR = ./Core/Inc +LZFX_INC_DIR = ./Core/lzfx MINIWARE_INC_CMSIS_DEVICE = ./Core/BSP/Miniware/Vendor/CMSIS/Device/ST/STM32F1xx/Include MINIWARE_CMSIS_CORE_INC_DIR = ./Core/BSP/Miniware/Vendor/CMSIS/Include MINIWARE_HAL_INC_DIR = ./Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Inc @@ -34,6 +42,7 @@ PINE_NMSIS_INC_DIR = ./Core/BSP/Pine64/Vendor/NMSIS/Core/Include PINE_FREERTOS_PORT_INC_DIR = ./Core/BSP/Pine64/Vendor/OS/FreeRTOS/Source/portable/GCC SOURCE_THREADS_DIR = ./Core/Threads SOURCE_CORE_DIR = ./Core/Src +SOURCE_LZFX_DIR = ./Core/lzfx SOURCE_DRIVERS_DIR = ./Core/Drivers INC_PD_DRIVERS_DIR = ./Core/Drivers/FUSB302 SOURCE_MIDDLEWARES_DIR = ./Middlewares @@ -101,6 +110,7 @@ DEV_CXXFLAGS= -MMD -MP -MF "$(@:%.o=%.d)" -MT "$@" endif INCLUDES = -I$(APP_INC_DIR) \ + -I$(LZFX_INC_DIR) \ -I$(FRTOS_CMIS_INC_DIR) \ -I$(FRTOS_INC_DIR) \ -I$(DRIVER_INC_DIR) \ @@ -114,7 +124,8 @@ SOURCE := $(shell find $(SOURCE_THREADS_DIR) -type f -name '*.c') \ $(shell find $(SOURCE_CORE_DIR) -type f -name '*.c') \ $(shell find $(SOURCE_DRIVERS_DIR) -type f -name '*.c') \ $(shell find $(DEVICE_BSP_DIR) -type f -name '*.c') \ -$(shell find $(SOURCE_MIDDLEWARES_DIR) -type f -name '*.c') +$(shell find $(SOURCE_MIDDLEWARES_DIR) -type f -name '*.c') \ +$(SOURCE_LZFX_DIR)/lzfx.c SOURCE_CPP := $(shell find $(SOURCE_THREADS_DIR) -type f -name '*.cpp') \ $(shell find $(SOURCE_CORE_DIR) -type f -name '*.cpp') \ $(shell find $(SOURCE_DRIVERS_DIR) -type f -name '*.cpp') \ @@ -296,10 +307,25 @@ all: $(ALL_FIRMWARE_TARGETS) $(SIZE) --format=berkeley $< $(OBJCOPY) $< -O binary $@ -$(HEXFILE_DIR)/$(model)_%.elf : $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) $(OUTPUT_DIR)/Core/Gen/Translation.%.o Makefile $(LDSCRIPT) +$(HEXFILE_DIR)/$(model)_%.elf : \ + $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation.%.o \ + Makefile $(LDSCRIPT) @test -d $(@D) || mkdir -p $(@D) @echo Linking $@ - @$(CPP) $(CXXFLAGS) $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) $(OUTPUT_DIR)/Core/Gen/Translation.$*.o $(LIBS) $(LINKER_FLAGS) -o$@ -Wl,-Map=$@.map + @$(CPP) $(CXXFLAGS) $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation.$*.o \ + $(LIBS) $(LINKER_FLAGS) -o$@ -Wl,-Map=$@.map + +$(HEXFILE_DIR)/$(model)_string_compressed_%.elf : \ + $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation_lzfx.%.o \ + Makefile $(LDSCRIPT) + @test -d $(@D) || mkdir -p $(@D) + @echo Linking $@ + @$(CPP) $(CXXFLAGS) $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation_lzfx.$*.o \ + $(LIBS) $(LINKER_FLAGS) -o$@ -Wl,-Map=$@.map $(OUT_OBJS): $(OUTPUT_DIR)/%.o : %.c Makefile @test -d $(@D) || mkdir -p $(@D) @@ -316,10 +342,57 @@ $(OUT_OBJS_S): $(OUTPUT_DIR)/%.o: %.S Makefile @echo 'Building file: $<' @$(AS) -c $(AFLAGS) $< -o $@ -Core/Gen/Translation.%.cpp: ../Translations/translation_%.json Makefile ../Translations/make_translation.py ../Translations/translations_def.js ../Translations/font_tables.py ../Translations/wqy-bitmapsong/wenquanyi_9pt.bdf - @test -d $(@D) || mkdir -p $(@D) +Core/Gen/Translation.%.cpp $(OUTPUT_DIR)/Core/Gen/translation.files/%.pickle: ../Translations/translation_%.json \ + ../Translations/make_translation.py \ + ../Translations/translations_def.js \ + ../Translations/font_tables.py \ + Makefile ../Translations/wqy-bitmapsong/wenquanyi_9pt.bdf + @test -d Core/Gen || mkdir -p Core/Gen + @test -d $(OUTPUT_DIR)/Core/Gen/translation.files || mkdir -p $(OUTPUT_DIR)/Core/Gen/translation.files @echo 'Generating translations for language $*' - @python3 ../Translations/make_translation.py -o $(PWD)/$@ $* + @python3 ../Translations/make_translation.py \ + -o $(PWD)/Core/Gen/Translation.$*.cpp \ + --output-pickled $(OUTPUT_DIR)/Core/Gen/translation.files/$*.pickle \ + $* + +# +# The recipes to produce compressed translation data: +# + +$(OUTPUT_DIR)/Core/Gen/translation.files/%.o: Core/Gen/Translation.%.cpp + @test -d $(@D) || mkdir -p $(@D) + @echo Generating $@ + @$(CPP) -c $(filter-out -flto -g3,$(CXXFLAGS)) $< -o $@ + +$(HOST_OUTPUT_DIR)/lzfx/lzfx-host-compress: Core/lzfx/lzfx-host-compress.c Core/lzfx/lzfx.c + @test -d $(@D) || mkdir -p $(@D) + @echo Building host lzfx tool $@ + @$(HOST_CC) -Wno-unused-result -O $^ -o $@ + +$(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.bin: $(OUTPUT_DIR)/Core/Gen/translation.files/%.o + @echo Dumping translation strings data from $< + @# Extract the raw strings data from the object file + @$(OBJCOPY) -O binary -j .rodata._ZL18TranslationIndices $< $(@D)/$*.data.TranslationIndices.bin + @test -s $(@D)/$*.data.TranslationIndices.bin || (rm $(@D)/$*.data.TranslationIndices.bin; echo 'ERROR: Output for .rodata._ZL18TranslationIndices is empty!' >&2; false) + @$(OBJCOPY) -O binary -j .rodata._ZL22TranslationStringsData $< $(@D)/$*.data.TranslationStrings.bin + @test -s $(@D)/$*.data.TranslationStrings.bin || (rm $(@D)/$*.data.TranslationStrings.bin; echo 'ERROR: Output for .rodata._ZL22TranslationStringsData is empty!' >&2; false) + @cat $(@D)/$*.data.TranslationIndices.bin $(@D)/$*.data.TranslationStrings.bin > $@ + +$(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.lzfx: $(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.bin $(HOST_OUTPUT_DIR)/lzfx/lzfx-host-compress + @echo Compressing translation strings data for $* + @$(HOST_OUTPUT_DIR)/lzfx/lzfx-host-compress $< $@ + @echo Compressed from $$(stat --printf="%s" $<) to $$(stat --printf="%s" $@) bytes + +Core/Gen/Translation_lzfx.%.cpp: $(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.lzfx $(OUTPUT_DIR)/Core/Gen/translation.files/%.pickle + @test -d $(@D) || mkdir -p $(@D) + @echo Generating lzfx compressed translation for $* + @python3 ../Translations/make_translation.py \ + -o $(PWD)/Core/Gen/Translation_lzfx.$*.cpp \ + --input-pickled $(OUTPUT_DIR)/Core/Gen/translation.files/$*.pickle \ + --lzfx-strings $(OUTPUT_DIR)/Core/Gen/translation.files/$*.strings.lzfx \ + $* + + clean : rm -Rf Core/Gen @@ -350,3 +423,5 @@ check-style: -include $(OUT_OBJS:.o=.d) -include $(OUT_OBJS_CPP:.o=.d) -include $(OUTPUT_DIR)/Core/Gen/Translation.*.d +-include $(OUTPUT_DIR)/Core/Gen/Translation_*.d +-include $(OUTPUT_DIR)/Core/Gen/translation.files/*.d From 11f40cfc1b5b8f935d0ff13f4e72a060f6d2dc3a Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Mon, 12 Apr 2021 20:07:06 +0800 Subject: [PATCH 05/19] Reformat lzfx sources --- source/Core/lzfx/lzfx-host-compress.c | 74 ++-- source/Core/lzfx/lzfx.c | 505 +++++++++++++------------- source/Core/lzfx/lzfx.h | 33 +- 3 files changed, 305 insertions(+), 307 deletions(-) diff --git a/source/Core/lzfx/lzfx-host-compress.c b/source/Core/lzfx/lzfx-host-compress.c index 1a3e6f79..b135b975 100644 --- a/source/Core/lzfx/lzfx-host-compress.c +++ b/source/Core/lzfx/lzfx-host-compress.c @@ -5,48 +5,44 @@ /* Program to demonstrate file compression. Don't use it in the real world! */ -int main(int argc, char **argv) -{ - if (argc == 3) - { - /* open input */ - FILE *f = fopen(argv[1], "rb"); - if (!f) { - printf("Error: %s\n", argv[1]); - return 1; - } +int main(int argc, char **argv) { + if (argc == 3) { + /* open input */ + FILE *f = fopen(argv[1], "rb"); + if (!f) { + printf("Error: %s\n", argv[1]); + return 1; + } - /* get size */ - fseek(f, 0, SEEK_END); - int inputsize = ftell(f); - fseek(f, 0, SEEK_SET); + /* get size */ + fseek(f, 0, SEEK_END); + int inputsize = ftell(f); + fseek(f, 0, SEEK_SET); - /* read */ - char *input = malloc(inputsize); - fread(input, inputsize, 1, f); - fclose(f); + /* read */ + char *input = malloc(inputsize); + fread(input, inputsize, 1, f); + fclose(f); - /* compress */ - int outputsize = inputsize + 1; /* buffer overflow */ - char *output = malloc(outputsize); - lzfx_compress(input, inputsize, output, &outputsize); + /* compress */ + int outputsize = inputsize + 1; /* buffer overflow */ + char *output = malloc(outputsize); + lzfx_compress(input, inputsize, output, &outputsize); - /* open output */ - f = fopen(argv[2], "wb"); - if (!f) { - printf("Error: %s\n", argv[1]); - return 1; - } + /* open output */ + f = fopen(argv[2], "wb"); + if (!f) { + printf("Error: %s\n", argv[1]); + return 1; + } - /* write */ - fwrite(output, outputsize, 1, f); - fclose(f); + /* write */ + fwrite(output, outputsize, 1, f); + fclose(f); - return 0; - } - else - { - printf("Compresses a file.\n\nUsage: lzfx-raw input output\n"); - return 1; - } -} \ No newline at end of file + return 0; + } else { + printf("Compresses a file.\n\nUsage: lzfx-raw input output\n"); + return 1; + } +} diff --git a/source/Core/lzfx/lzfx.c b/source/Core/lzfx/lzfx.c index 47b387a2..81d1560a 100644 --- a/source/Core/lzfx/lzfx.c +++ b/source/Core/lzfx/lzfx.c @@ -6,19 +6,19 @@ * codebase written by Marc Lehmann. This code is released under the BSD * license. License and original copyright statement follow. * - * + * * Copyright (c) 2000-2008 Marc Alexander Lehmann - * + * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO @@ -29,7 +29,7 @@ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + */ #include "lzfx.h" @@ -37,34 +37,33 @@ /* We need this for memset */ #ifdef __cplusplus -# include +#include #else -# include +#include #endif #if __GNUC__ >= 3 -# define fx_expect_false(expr) __builtin_expect((expr) != 0, 0) -# define fx_expect_true(expr) __builtin_expect((expr) != 0, 1) +#define fx_expect_false(expr) __builtin_expect((expr) != 0, 0) +#define fx_expect_true(expr) __builtin_expect((expr) != 0, 1) #else -# define fx_expect_false(expr) (expr) -# define fx_expect_true(expr) (expr) +#define fx_expect_false(expr) (expr) +#define fx_expect_true(expr) (expr) #endif typedef unsigned char u8; -typedef const u8 *LZSTATE[LZFX_HSIZE]; +typedef const u8 * LZSTATE[LZFX_HSIZE]; /* Define the hash function */ -#define LZFX_FRST(p) (((p[0]) << 8) | p[1]) -#define LZFX_NEXT(v,p) (((v) << 8) | p[2]) -#define LZFX_IDX(h) ((( h >> (3*8 - LZFX_HLOG)) - h ) & (LZFX_HSIZE - 1)) +#define LZFX_FRST(p) (((p[0]) << 8) | p[1]) +#define LZFX_NEXT(v, p) (((v) << 8) | p[2]) +#define LZFX_IDX(h) (((h >> (3 * 8 - LZFX_HLOG)) - h) & (LZFX_HSIZE - 1)) /* These cannot be changed, as they are related to the compressed format. */ -#define LZFX_MAX_LIT (1 << 5) - 1 -#define LZFX_MAX_OFF (1 << 13) -#define LZFX_MAX_REF ((1 << 8) + (1 << 3) - 2) +#define LZFX_MAX_LIT (1 << 5) - 1 +#define LZFX_MAX_OFF (1 << 13) +#define LZFX_MAX_REF ((1 << 8) + (1 << 3) - 2) -static -int lzfx_getsize(const void* ibuf, unsigned int ilen, unsigned int *olen); +static int lzfx_getsize(const void *ibuf, unsigned int ilen, unsigned int *olen); /* Compressed format @@ -83,270 +82,276 @@ int lzfx_getsize(const void* ibuf, unsigned int ilen, unsigned int *olen); oooooLLL oooooooo for backrefs of real length < 7 (1 <= L < 7) ooooo111 LLLLLLLL oooooooo for backrefs of real length >= 7 (L >= 7) */ -int lzfx_compress(const void *const ibuf, const unsigned int ilen, - void *obuf, unsigned int *const olen){ +int lzfx_compress(const void *const ibuf, const unsigned int ilen, void *obuf, unsigned int *const olen) { - /* Hash table; an array of u8*'s which point - to various locations in the input buffer */ - const u8 *htab[LZFX_HSIZE]; + /* Hash table; an array of u8*'s which point + to various locations in the input buffer */ + const u8 *htab[LZFX_HSIZE]; - const u8 **hslot; /* Pointer to entry in hash table */ - unsigned int hval; /* Hash value generated by macros above */ - const u8 *ref; /* Pointer to candidate match location in input */ + const u8 ** hslot; /* Pointer to entry in hash table */ + unsigned int hval; /* Hash value generated by macros above */ + const u8 * ref; /* Pointer to candidate match location in input */ - const u8 *ip = (const u8 *)ibuf; - const u8 *const in_end = ip + ilen; + const u8 * ip = (const u8 *)ibuf; + const u8 *const in_end = ip + ilen; - u8 *op = (u8 *)obuf; - const u8 *const out_end = (olen == NULL ? NULL : op + *olen); + u8 * op = (u8 *)obuf; + const u8 *const out_end = (olen == NULL ? NULL : op + *olen); - int lit; /* # of bytes in current literal run */ + int lit; /* # of bytes in current literal run */ -#if defined (WIN32) && defined (_M_X64) - unsigned _int64 off; /* workaround for missing POSIX compliance */ +#if defined(WIN32) && defined(_M_X64) + unsigned _int64 off; /* workaround for missing POSIX compliance */ #else - unsigned long off; + unsigned long off; #endif - if(olen == NULL) return LZFX_EARGS; - if(ibuf == NULL){ - if(ilen != 0) return LZFX_EARGS; - *olen = 0; - return 0; - } - if(obuf == NULL) return LZFX_EARGS; - - memset(htab, 0, sizeof(htab)); - - /* Start a literal run. Whenever we do this the output pointer is - advanced because the current byte will hold the encoded length. */ - lit = 0; op++; - - hval = LZFX_FRST(ip); - - while(ip + 2 < in_end){ /* The NEXT macro reads 2 bytes ahead */ - - hval = LZFX_NEXT(hval, ip); - hslot = htab + LZFX_IDX(hval); - - ref = *hslot; *hslot = ip; - - if( ref < ip - && (off = ip - ref - 1) < LZFX_MAX_OFF - && ip + 4 < in_end /* Backref takes up to 3 bytes, so don't bother */ - && ref > (u8 *)ibuf - && ref[0] == ip[0] - && ref[1] == ip[1] - && ref[2] == ip[2] ) { - - unsigned int len = 3; /* We already know 3 bytes match */ - const unsigned int maxlen = in_end - ip - 2 > LZFX_MAX_REF ? - LZFX_MAX_REF : in_end - ip - 2; - - /* lit == 0: op + 3 must be < out_end (because we undo the run) - lit != 0: op + 3 + 1 must be < out_end */ - if(fx_expect_false(op - !lit + 3 + 1 >= out_end)) - return LZFX_ESIZE; - - op [- lit - 1] = lit << 3;/* Terminate literal run */ - op -= !lit; /* Undo run if length is zero */ - - /* Start checking at the fourth byte */ - while (len < maxlen && ref[len] == ip[len]) - len++; - - /* Format 1: [oooooLLL oooooooo] */ - if (len < 7) { - *op++ = ((off >> 8) << 3) + len; - *op++ = off; - - /* Format 2: [ooooo111 LLLLLLLL oooooooo] */ - } else { - *op++ = ((off >> 8) << 3) + 7; - *op++ = len - 7; - *op++ = off; - } - - lit = 0; op++; - - ip += len - 1; /* ip = initial ip + #octets - 1 */ - - if (fx_expect_false (ip + 3 >= in_end)){ - ip++; /* Code following expects exit at bottom of loop */ - break; - } - - hval = LZFX_FRST (ip); - hval = LZFX_NEXT (hval, ip); - htab[LZFX_IDX (hval)] = ip; - - ip++; /* ip = initial ip + #octets */ - - } else { - /* Keep copying literal bytes */ - - if (fx_expect_false (op >= out_end)) return LZFX_ESIZE; - - lit++; *op++ = *ip++; - - if (fx_expect_false (lit == LZFX_MAX_LIT)) { - op [- lit - 1] = lit << 3; /* stop run */ - lit = 0; op++; /* start run */ - } - - } /* if() found match in htab */ - - } /* while(ip < ilen -2) */ - - /* At most 3 bytes remain in input. We therefore need 4 bytes available - in the output buffer to store them (3 data + ctrl byte).*/ - if (op + 3 > out_end) return LZFX_ESIZE; - - while (ip < in_end) { - - lit++; *op++ = *ip++; - - if (fx_expect_false (lit == LZFX_MAX_LIT)){ - op [- lit - 1] = lit << 3; - lit = 0; op++; - } - } - - op [- lit - 1] = lit << 3; - op -= !lit; - - *olen = op - (u8 *)obuf; + if (olen == NULL) + return LZFX_EARGS; + if (ibuf == NULL) { + if (ilen != 0) + return LZFX_EARGS; + *olen = 0; return 0; + } + if (obuf == NULL) + return LZFX_EARGS; + + memset(htab, 0, sizeof(htab)); + + /* Start a literal run. Whenever we do this the output pointer is + advanced because the current byte will hold the encoded length. */ + lit = 0; + op++; + + hval = LZFX_FRST(ip); + + while (ip + 2 < in_end) { /* The NEXT macro reads 2 bytes ahead */ + + hval = LZFX_NEXT(hval, ip); + hslot = htab + LZFX_IDX(hval); + + ref = *hslot; + *hslot = ip; + + if (ref < ip && (off = ip - ref - 1) < LZFX_MAX_OFF && ip + 4 < in_end /* Backref takes up to 3 bytes, so don't bother */ + && ref > (u8 *)ibuf && ref[0] == ip[0] && ref[1] == ip[1] && ref[2] == ip[2]) { + + unsigned int len = 3; /* We already know 3 bytes match */ + const unsigned int maxlen = in_end - ip - 2 > LZFX_MAX_REF ? LZFX_MAX_REF : in_end - ip - 2; + + /* lit == 0: op + 3 must be < out_end (because we undo the run) + lit != 0: op + 3 + 1 must be < out_end */ + if (fx_expect_false(op - !lit + 3 + 1 >= out_end)) + return LZFX_ESIZE; + + op[-lit - 1] = lit << 3; /* Terminate literal run */ + op -= !lit; /* Undo run if length is zero */ + + /* Start checking at the fourth byte */ + while (len < maxlen && ref[len] == ip[len]) + len++; + + /* Format 1: [oooooLLL oooooooo] */ + if (len < 7) { + *op++ = ((off >> 8) << 3) + len; + *op++ = off; + + /* Format 2: [ooooo111 LLLLLLLL oooooooo] */ + } else { + *op++ = ((off >> 8) << 3) + 7; + *op++ = len - 7; + *op++ = off; + } + + lit = 0; + op++; + + ip += len - 1; /* ip = initial ip + #octets - 1 */ + + if (fx_expect_false(ip + 3 >= in_end)) { + ip++; /* Code following expects exit at bottom of loop */ + break; + } + + hval = LZFX_FRST(ip); + hval = LZFX_NEXT(hval, ip); + htab[LZFX_IDX(hval)] = ip; + + ip++; /* ip = initial ip + #octets */ + + } else { + /* Keep copying literal bytes */ + + if (fx_expect_false(op >= out_end)) + return LZFX_ESIZE; + + lit++; + *op++ = *ip++; + + if (fx_expect_false(lit == LZFX_MAX_LIT)) { + op[-lit - 1] = lit << 3; /* stop run */ + lit = 0; + op++; /* start run */ + } + + } /* if() found match in htab */ + + } /* while(ip < ilen -2) */ + + /* At most 3 bytes remain in input. We therefore need 4 bytes available + in the output buffer to store them (3 data + ctrl byte).*/ + if (op + 3 > out_end) + return LZFX_ESIZE; + + while (ip < in_end) { + + lit++; + *op++ = *ip++; + + if (fx_expect_false(lit == LZFX_MAX_LIT)) { + op[-lit - 1] = lit << 3; + lit = 0; + op++; + } + } + + op[-lit - 1] = lit << 3; + op -= !lit; + + *olen = op - (u8 *)obuf; + return 0; } /* Decompressor */ -int lzfx_decompress(const void* ibuf, unsigned int ilen, - void* obuf, unsigned int *olen){ +int lzfx_decompress(const void *ibuf, unsigned int ilen, void *obuf, unsigned int *olen) { - u8 const *ip = (const u8 *)ibuf; - u8 const *const in_end = ip + ilen; - u8 *op = (u8 *)obuf; - u8 const *const out_end = (olen == NULL ? NULL : op + *olen); - - unsigned int remain_len = 0; - int rc; + u8 const * ip = (const u8 *)ibuf; + u8 const *const in_end = ip + ilen; + u8 * op = (u8 *)obuf; + u8 const *const out_end = (olen == NULL ? NULL : op + *olen); - if(olen == NULL) return LZFX_EARGS; - if(ibuf == NULL){ - if(ilen != 0) return LZFX_EARGS; - *olen = 0; - return 0; - } - if(obuf == NULL){ - if(olen != 0) return LZFX_EARGS; - return lzfx_getsize(ibuf, ilen, olen); - } - - do { - unsigned int ctrl = *ip++; - - /* Format LLLLL000: a literal byte string follows, of length L */ - if((ctrl & 0x7) == 0) { - unsigned int len = ctrl >> 3; - - if(fx_expect_false(op + len > out_end)){ - --ip; /* Rewind to control byte */ - goto guess; - } - if(fx_expect_false(ip + len > in_end)) return LZFX_ECORRUPT; - - do - *op++ = *ip++; - while(--len); - - /* Format #1 [oooooLLL oooooooo]: backref of length L+1 - ^^^^^ ^^^^^^^^ - A B - #2 [ooooo111 LLLLLLLL oooooooo] backref of length L+7 - ^^^^^ ^^^^^^^^ - A B - In both cases the location of the backref is computed from the - remaining part of the data as follows: - - location = op - A*256 - B - 1 - */ - } else { - - unsigned int len = ctrl & 0x7; - u8 *ref = op - ((ctrl >> 3) << 8) - 1; - - if(len==7) len += *ip++; /* i.e. format #2 */ - - if(fx_expect_false(op + len > out_end)){ - ip -= (len >= 7) ? 2 : 1; /* Rewind to control byte */ - goto guess; - } - if(fx_expect_false(ip >= in_end)) return LZFX_ECORRUPT; - - ref -= *ip++; - - if(fx_expect_false(ref < (u8*)obuf)) return LZFX_ECORRUPT; - - do - *op++ = *ref++; - while (--len); - } - - } while (ip < in_end); - - *olen = op - (u8 *)obuf; + unsigned int remain_len = 0; + int rc; + if (olen == NULL) + return LZFX_EARGS; + if (ibuf == NULL) { + if (ilen != 0) + return LZFX_EARGS; + *olen = 0; return 0; + } + if (obuf == NULL) { + if (olen != 0) + return LZFX_EARGS; + return lzfx_getsize(ibuf, ilen, olen); + } + + do { + unsigned int ctrl = *ip++; + + /* Format LLLLL000: a literal byte string follows, of length L */ + if ((ctrl & 0x7) == 0) { + unsigned int len = ctrl >> 3; + + if (fx_expect_false(op + len > out_end)) { + --ip; /* Rewind to control byte */ + goto guess; + } + if (fx_expect_false(ip + len > in_end)) + return LZFX_ECORRUPT; + + do + *op++ = *ip++; + while (--len); + + /* Format #1 [oooooLLL oooooooo]: backref of length L+1 + ^^^^^ ^^^^^^^^ + A B + #2 [ooooo111 LLLLLLLL oooooooo] backref of length L+7 + ^^^^^ ^^^^^^^^ + A B + In both cases the location of the backref is computed from the + remaining part of the data as follows: + + location = op - A*256 - B - 1 + */ + } else { + + unsigned int len = ctrl & 0x7; + u8 * ref = op - ((ctrl >> 3) << 8) - 1; + + if (len == 7) + len += *ip++; /* i.e. format #2 */ + + if (fx_expect_false(op + len > out_end)) { + ip -= (len >= 7) ? 2 : 1; /* Rewind to control byte */ + goto guess; + } + if (fx_expect_false(ip >= in_end)) + return LZFX_ECORRUPT; + + ref -= *ip++; + + if (fx_expect_false(ref < (u8 *)obuf)) + return LZFX_ECORRUPT; + + do + *op++ = *ref++; + while (--len); + } + + } while (ip < in_end); + + *olen = op - (u8 *)obuf; + + return 0; guess: - rc = lzfx_getsize(ip, ilen - (ip-(u8*)ibuf), &remain_len); - if(rc>=0) *olen = remain_len + (op - (u8*)obuf); - return rc; + rc = lzfx_getsize(ip, ilen - (ip - (u8 *)ibuf), &remain_len); + if (rc >= 0) + *olen = remain_len + (op - (u8 *)obuf); + return rc; } /* Guess len. No parameters may be NULL; this is not checked. */ -static -int lzfx_getsize(const void* ibuf, unsigned int ilen, unsigned int *olen){ +static int lzfx_getsize(const void *ibuf, unsigned int ilen, unsigned int *olen) { - u8 const *ip = (const u8 *)ibuf; - u8 const *const in_end = ip + ilen; - int tot_len = 0; - - while (ip < in_end) { + u8 const * ip = (const u8 *)ibuf; + u8 const *const in_end = ip + ilen; + int tot_len = 0; - unsigned int ctrl = *ip++; + while (ip < in_end) { - if((ctrl & 0x7) == 0) { + unsigned int ctrl = *ip++; - if(ip + (ctrl >> 3) > in_end) - return LZFX_ECORRUPT; + if ((ctrl & 0x7) == 0) { - tot_len += (ctrl >> 3); - ip += (ctrl >> 3); + if (ip + (ctrl >> 3) > in_end) + return LZFX_ECORRUPT; - } else { + tot_len += (ctrl >> 3); + ip += (ctrl >> 3); - unsigned int len = ctrl & 0x7; + } else { - if(len==7){ /* i.e. format #2 */ - len += *ip++; - } + unsigned int len = ctrl & 0x7; - if(ip >= in_end) return LZFX_ECORRUPT; + if (len == 7) { /* i.e. format #2 */ + len += *ip++; + } - ip++; /* skip the ref byte */ + if (ip >= in_end) + return LZFX_ECORRUPT; - tot_len += len; - - } + ip++; /* skip the ref byte */ + tot_len += len; } + } - *olen = tot_len; + *olen = tot_len; - return 0; + return 0; } - - - - diff --git a/source/Core/lzfx/lzfx.h b/source/Core/lzfx/lzfx.h index 4d7c560b..7b6e472e 100644 --- a/source/Core/lzfx/lzfx.h +++ b/source/Core/lzfx/lzfx.h @@ -6,19 +6,19 @@ * codebase written by Marc Lehmann. This code is released under the BSD * license. License and original copyright statement follow. * - * + * * Copyright (c) 2000-2008 Marc Alexander Lehmann - * + * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO @@ -29,7 +29,7 @@ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + */ #ifndef LZFX_H #define LZFX_H @@ -44,19 +44,19 @@ extern "C" { to read each other's output, although the output itself is not guaranteed to be byte-for-byte identical. */ -#define LZFX_VERSION_MAJOR 0 -#define LZFX_VERSION_MINOR 1 -#define LZFX_VERSION_STRING "0.1" +#define LZFX_VERSION_MAJOR 0 +#define LZFX_VERSION_MINOR 1 +#define LZFX_VERSION_STRING "0.1" /* Hashtable size (2**LZFX_HLOG entries) */ #ifndef LZFX_HLOG -# define LZFX_HLOG 16 +#define LZFX_HLOG 16 #endif /* Predefined errors. */ -#define LZFX_ESIZE -1 /* Output buffer too small */ -#define LZFX_ECORRUPT -2 /* Invalid data for decompression */ -#define LZFX_EARGS -3 /* Arguments invalid (NULL) */ +#define LZFX_ESIZE -1 /* Output buffer too small */ +#define LZFX_ECORRUPT -2 /* Invalid data for decompression */ +#define LZFX_EARGS -3 /* Arguments invalid (NULL) */ /* Buffer-to buffer compression. @@ -67,8 +67,7 @@ extern "C" { olen contains the compressed size in bytes. On failure, a negative value is returned and olen is not modified. */ -int lzfx_compress(const void* ibuf, unsigned int ilen, - void* obuf, unsigned int *olen); +int lzfx_compress(const void *ibuf, unsigned int ilen, void *obuf, unsigned int *olen); /* Buffer-to-buffer decompression. @@ -87,9 +86,7 @@ int lzfx_compress(const void* ibuf, unsigned int ilen, stream and is consequently very fast. Argument obuf may be NULL in this case only. */ -int lzfx_decompress(const void* ibuf, unsigned int ilen, - void* obuf, unsigned int *olen); - +int lzfx_decompress(const void *ibuf, unsigned int ilen, void *obuf, unsigned int *olen); #ifdef __cplusplus } /* extern "C" */ From 001d91988c890386c8a4f8b0de40dd22ec1039c8 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Mon, 12 Apr 2021 20:45:26 +0800 Subject: [PATCH 06/19] Fix formatting --- source/Core/Inc/Translation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Core/Inc/Translation.h b/source/Core/Inc/Translation.h index 9c5bcb5d..62327d7f 100644 --- a/source/Core/Inc/Translation.h +++ b/source/Core/Inc/Translation.h @@ -9,7 +9,7 @@ #define TRANSLATION_H_ #include "stdint.h" -extern const bool HasFahrenheit; +extern const bool HasFahrenheit; extern const char *SymbolPlus; extern const char *SymbolMinus; From 460d48fafbff36d677d9bba08ac9c8b5d6204fe4 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Tue, 13 Apr 2021 18:30:27 +0800 Subject: [PATCH 07/19] Reduce code duplication --- Translations/make_translation.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Translations/make_translation.py b/Translations/make_translation.py index 8c858387..4aad6fc5 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -471,6 +471,8 @@ def write_language( f.write(translation_common_text) f.write( f"const bool HasFahrenheit = {('true' if lang.get('tempUnitFahrenheit', True) else 'false')};\n\n" + "extern const uint8_t *const Font_12x16 = USER_FONT_12;\n" + "extern const uint8_t *const Font_6x8 = USER_FONT_6x8;\n\n" ) if not lzfx_strings: @@ -481,8 +483,6 @@ def write_language( f.write( "const TranslationIndexTable *const Tr = &TranslationIndices;\n" "const char *const TranslationStrings = TranslationStringsData;\n\n" - "extern const uint8_t *const Font_12x16 = USER_FONT_12;\n" - "extern const uint8_t *const Font_6x8 = USER_FONT_6x8;\n\n" "void prepareTranslations() {}\n\n" ) else: @@ -491,8 +491,6 @@ def write_language( "static uint8_t translation_data_out_buffer[4096] __attribute__((__aligned__(2)));\n\n" "const TranslationIndexTable *const Tr = reinterpret_cast(translation_data_out_buffer);\n" "const char *const TranslationStrings = reinterpret_cast(translation_data_out_buffer) + sizeof(TranslationIndexTable);\n\n" - "extern const uint8_t *const Font_12x16 = USER_FONT_12;\n" - "extern const uint8_t *const Font_6x8 = USER_FONT_6x8;\n\n" "void prepareTranslations() {\n" " unsigned int outsize = sizeof(translation_data_out_buffer);\n" " lzfx_decompress(translation_data_lzfx, sizeof(translation_data_lzfx), translation_data_out_buffer, &outsize);\n" From f11a70ab2bb2299746cd706eb72c851bac02da5e Mon Sep 17 00:00:00 2001 From: Pauli Jokela Date: Tue, 13 Apr 2021 14:14:47 +0300 Subject: [PATCH 08/19] Updated Finnish translation --- Translations/translation_FI.json | 181 +++++++++++++++---------------- 1 file changed, 89 insertions(+), 92 deletions(-) diff --git a/Translations/translation_FI.json b/Translations/translation_FI.json index d263d7ec..8346f7ee 100644 --- a/Translations/translation_FI.json +++ b/Translations/translation_FI.json @@ -3,43 +3,40 @@ "languageLocalName": "Suomi", "cyrillicGlyphs": false, "messages": { - "SettingsCalibrationDone": "Calibration done!", "SettingsCalibrationWarning": "Varmista että kärki on huoneenlämpöinen ennen jatkamista!", "SettingsResetWarning": "Haluatko varmasti palauttaa oletusarvot?", - "UVLOWarningString": "DC LOW", + "UVLOWarningString": "DC ALH.", "UndervoltageString": "Alijännite", "InputVoltageString": "Jännite: ", - "WarningTipTempString": "Lämpötila: ", - "BadTipString": "VIKATILA", "SleepingSimpleString": "Zzzz", "SleepingAdvancedString": "Lepotila...", - "WarningSimpleString": "HOT", - "WarningAdvancedString": "! KÄRKI KUUMA !", "SleepingTipAdvancedString": "Kärki:", - "IdleTipString": "Kärki:", - "IdleSetString": " Asetus:", - "TipDisconnectedString": "KÄRKI ON IRTI", + "IdleTipString": "Pää:", + "IdleSetString": "Aseta:", + "TipDisconnectedString": "KÄRKI PUUTTUU", "SolderingAdvancedPowerPrompt": "Teho: ", - "OffString": "OFF", - "YourGainMessage": "Your gain:" + "OffString": "Off" }, "messagesWarn": { - "ResetOKMessage": "Reset OK", + "ResetOKMessage": [ + "Palautus", + "onnistui" + ], "SettingsResetMessage": [ - "Settings were", - "reset!" + "Asetukset", + "palautettu!" ], "NoAccelerometerMessage": [ - "No accelerometer", - "detected!" + "Kiihtyvyysanturi", + "puuttuu!" ], "NoPowerDeliveryMessage": [ - "No USB-PD IC", - "detected!" + "USB-PD IC", + "puuttuu!" ], - "LockingKeysString": " LOCKED", - "UnlockingKeysString": "UNLOCKED", - "WarningKeysLockedString": "!LOCKED!" + "LockingKeysString": " LUKITTU", + "UnlockingKeysString": "AUKI", + "WarningKeysLockedString": "!LUKKO!" }, "characters": { "SettingRightChar": "O", @@ -48,27 +45,27 @@ "SettingFastChar": "N", "SettingSlowChar": "H", "SettingMediumChar": "M", - "SettingOffChar": "O", - "SettingStartSolderingChar": "T", - "SettingStartSleepChar": "S", - "SettingStartSleepOffChar": "O", - "SettingStartNoneChar": "F", - "SettingSensitivityOff": "O", - "SettingSensitivityLow": "L", - "SettingSensitivityMedium": "M", - "SettingSensitivityHigh": "H", - "SettingLockDisableChar": "D", - "SettingLockBoostChar": "B", - "SettingLockFullChar": "F", + "SettingOffChar": "P", + "SettingStartSolderingChar": "K", + "SettingStartSleepChar": "L", + "SettingStartSleepOffChar": "N", + "SettingStartNoneChar": "E", + "SettingSensitivityOff": "P", + "SettingSensitivityLow": "A", + "SettingSensitivityMedium": "K", + "SettingSensitivityHigh": "S", + "SettingLockDisableChar": "P", + "SettingLockBoostChar": "V", + "SettingLockFullChar": "K", "SettingNAChar": "N/A" }, "menuGroups": { "PowerMenu": { "text2": [ - "Power", - "settings" + "Virta-", + "asetukset" ], - "desc": "Power settings" + "desc": "Virta-asetukset" }, "SolderingMenu": { "text2": [ @@ -105,56 +102,56 @@ "Virtalähde", "DC" ], - "desc": "Käytettävä virtalähde. Asettaa katkaisujänniteen. " + "desc": "Virtalähde. Asettaa katkaisujännitteen. " }, "SleepTemperature": { "text2": [ "Lepotilan", "lämpötila" ], - "desc": "Lepotilan lämpötila. " + "desc": "Kärjen lämpötila \"lepotilassa\"" }, "SleepTimeout": { "text2": [ "Lepotilan", "viive" ], - "desc": "Lepotilan viive. " + "desc": "\"Lepotilan\" ajastus " }, "ShutdownTimeout": { "text2": [ "Sammutus", "viive" ], - "desc": "Automaattisen sammutuksen aikaviive. " + "desc": "Automaattisen sammutuksen ajastus " }, "MotionSensitivity": { "text2": [ "Liikkeen", "herkkyys" ], - "desc": "Liikkeentunnistuksen herkkyys. <0=pois, 1=epäherkin, 9=herkin>" + "desc": "0=pois päältä | 1=vähäinen herkkyys | ... | 9=suurin herkkyys" }, "TemperatureUnit": { "text2": [ "Lämpötilan", "yksikkö" ], - "desc": "Lämpötilan yksikkö. " + "desc": "" }, "AdvancedIdle": { "text2": [ "Tiedot", "lepotilassa" ], - "desc": "Näyttää yksityiskohtaisemmat tiedot lepotilassa." + "desc": "Näyttää yksityiskohtaisemmat pienemmällä fontilla tiedot lepotilassa." }, "DisplayRotation": { "text2": [ "Näytön", "kierto" ], - "desc": "Näytön kierto. " + "desc": "A=automaattinen | V=vasenkätinen | O=oikeakätinen" }, "BoostTemperature": { "text2": [ @@ -175,133 +172,133 @@ "Jäähdytyksen", "vilkutus" ], - "desc": "Vilkuttaa jäähtyessä juotoskärjen lämpötilaa sen ollessa vielä vaarallisen kuuma." + "desc": "Vilkuttaa jäähtyessä juotoskärjen lämpötilaa sen ollessa vielä vaarallisen kuuma" }, "TemperatureCalibration": { "text2": [ "Kalibroi", "lämpötila?" ], - "desc": "Kalibroi kärjen lämpötilaeron." + "desc": "Kalibroi kärjen lämpötilaeron" }, "SettingsReset": { "text2": [ "Palauta", "tehdasasetukset?" ], - "desc": "Palauta kaikki asetukset oletusarvoihin." + "desc": "Palauta kaikki asetukset oletusarvoihin" }, "VoltageCalibration": { "text2": [ "Kalibroi", "tulojännite?" ], - "desc": "Tulojännitten kalibrointi (VIN). Painikkeilla säädetään ja pitkään painamalla poistutaan." + "desc": "Tulojännitten kalibrointi (VIN) " }, "AdvancedSoldering": { "text2": [ "Tarkempi", "juotosnäyttö" ], - "desc": "Näyttää yksityiskohtaisemmat tiedot juotostilassa." + "desc": "Näyttää yksityiskohtaisemmat tiedot pienellä fontilla juotostilassa" }, "ScrollingSpeed": { "text2": [ - "Tietojen", - "näyttönopeus" + "Selityksien", + "nopeus" ], - "desc": "Näiden selitetekstien vieritysnopeus." + "desc": "Selityksien vieritysnopeus " }, "QCMaxVoltage": { "text2": [ - "Power", - "Wattage" + "QC", + "jännite" ], - "desc": "Power Wattage of the power adapter used" + "desc": "Ensisijainen maksimi QC jännite" }, "PowerLimit": { "text2": [ - "Power", - "Limit" + "Tehon-", + "rajoitus" ], - "desc": "Maximum power the iron can use " + "desc": "Suurin sallittu teho " }, "ReverseButtonTempChange": { "text2": [ - "Key +-", - "reverse?" + "Suunnanvaihto", + "+ - näppäimille" ], - "desc": "Reverse the tip temperature change buttons plus minus assignment." + "desc": "Lämpötilapainikkeiden suunnan vaihtaminen" }, "TempChangeShortStep": { "text2": [ - "Temp change", - "short?" + "Lämmön muutos", + "lyhyt painal." ], - "desc": "Temperature change steps on short button press!" + "desc": "Lämpötilan muutos lyhyellä painalluksella" }, "TempChangeLongStep": { "text2": [ - "Temp change", - "long?" + "Lämmön muutos", + "pitkä painal." ], - "desc": "Temperature change steps on long button press!" + "desc": "Lämpötilan muutos pitkällä painalluksella" }, "PowerPulsePower": { "text2": [ - "Power", - "Pulse W" + "Herätyspulssin", + "voimakkuus" ], - "desc": "Keep awake pulse power intensity" + "desc": "Herätyspulssin voimakkuus " }, "HallEffSensitivity": { "text2": [ - "Hall Eff", - "Sensitivity" + "Hall-", + "herk." ], - "desc": "Sensitivity of the Hall effect sensor in detecting sleep " + "desc": "Hall-efektianturin herkkyys lepotilan tunnistuksessa " }, "LockingMode": { "text2": [ - "Allow buttons", - "locking" + "Salli nappien", + "lukitus" ], - "desc": "When soldering, long press on both buttons lock them " + "desc": "Kolvatessa paina molempia näppäimiä lukitaksesi ne " }, "MinVolCell": { "text2": [ - "Minimum", - "voltage" + "Pienin", + "jännite" ], - "desc": "Minimum allowed voltage per cell <3S: 3.0V - 3.7V, 4/5/6S: 2.4V - 3.7V>" + "desc": "Pienin sallittu jännite per kenno <3S: 3.0V - 3.7V, 4/5/6S: 2.4V - 3.7V>" }, "AnimLoop": { "text2": [ - "Anim.", - "loop" + "Animaation", + "toistaminen" ], - "desc": "Loop icon animations in root menu" + "desc": "Toista animaatiot valikossa" }, "AnimSpeed": { "text2": [ - "Anim.", - "speed" + "Animaation", + "nopeus" ], - "desc": "Speed of icon animations in menu " + "desc": "Animaatioiden nopeus valikossa " }, "PowerPulseWait": { "text2": [ - "Power pulse", - "wait time" + "Pulssin", + "odotusaika" ], - "desc": "Time to wait before triggering every keep-awake pulse (x 2.5s)" + "desc": "Odotusaika herätyspulssin lähetykseen (x 2.5s)" }, "PowerPulseDuration": { "text2": [ - "Power pulse", - "duration" + "Pulssin", + "kesto" ], - "desc": "Keep-awake-pulse duration (x 250ms)" + "desc": "Herätyspulssin kesto (x 250ms)" } } -} +} \ No newline at end of file From d1d6ce54031db5dc34b1ac40c566f9e3aa0799fc Mon Sep 17 00:00:00 2001 From: discip <53649486+discip@users.noreply.github.com> Date: Thu, 15 Apr 2021 03:19:45 +0200 Subject: [PATCH 09/19] Update translation_DE.json --- Translations/translation_DE.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Translations/translation_DE.json b/Translations/translation_DE.json index 1226dfad..691b13a1 100644 --- a/Translations/translation_DE.json +++ b/Translations/translation_DE.json @@ -58,10 +58,10 @@ "SettingSensitivityLow": "N", "SettingSensitivityMedium": "M", "SettingSensitivityHigh": "H", - "SettingLockDisableChar": "D", + "SettingLockDisableChar": "A", "SettingLockBoostChar": "B", "SettingLockFullChar": "V", - "SettingNAChar": "N/A" + "SettingNAChar": "-" }, "menuGroups": { "PowerMenu": { @@ -267,7 +267,7 @@ "Tasten-", "sperre" ], - "desc": "Langes drücken beider Tasten im Lötmodus sperrt diese " + "desc": "Langes drücken beider Tasten im Lötmodus sperrt diese " }, "MinVolCell": { "text2": [ @@ -288,14 +288,14 @@ "Anim.", "Geschw." ], - "desc": "Geschwindigkeit der Icon-Animationen im Menü " + "desc": "Geschwindigkeit der Icon-Animationen im Menü " }, "PowerPulseWait": { "text2": [ "Leistungsimpulse", "Wartezeit" ], - "desc": "Wartezeit vor dem Auslösen jedes Wachhalteimpulses (x 2,5s)" + "desc": "Dauer vor Abgabe von Wachhalteimpulsen (x 2,5s)" }, "PowerPulseDuration": { "text2": [ From 64fdf0b7ec74d86d7bf3332d1688fd62a66a82b4 Mon Sep 17 00:00:00 2001 From: discip <53649486+discip@users.noreply.github.com> Date: Thu, 15 Apr 2021 03:31:57 +0200 Subject: [PATCH 10/19] Update translation_EN.json --- Translations/translation_EN.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Translations/translation_EN.json b/Translations/translation_EN.json index 51d79ea0..46c64a1c 100644 --- a/Translations/translation_EN.json +++ b/Translations/translation_EN.json @@ -281,21 +281,21 @@ "Anim.", "loop" ], - "desc": "Loop icon animations in root menu" + "desc": "Loop icon animations in main menu" }, "AnimSpeed": { "text2": [ "Anim.", "speed" ], - "desc": "Speed of icon animations in menu " + "desc": "Pace of icon animations in menu " }, "PowerPulseWait": { "text2": [ "Power pulse", - "wait time" + "delay" ], - "desc": "Time to wait before triggering every keep-awake pulse (x 2.5s)" + "desc": "Delay before keep-awake pulse is triggered (x 2.5s)" }, "PowerPulseDuration": { "text2": [ From 4f28b3d48a9fb9199e66b0bd5cc76c18d32474aa Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Thu, 15 Apr 2021 14:32:09 +0800 Subject: [PATCH 11/19] Split font tables into sections --- Translations/font_tables.py | 487 ++++++++++++++++++++---------------- 1 file changed, 269 insertions(+), 218 deletions(-) diff --git a/Translations/font_tables.py b/Translations/font_tables.py index b5d9635a..a66aee13 100755 --- a/Translations/font_tables.py +++ b/Translations/font_tables.py @@ -1,6 +1,9 @@ -# coding=utf-8 -def get_font_map(): +import functools + + +def get_font_map_ascii_basic(): font = { + # U+0000..U+007F Basic Latin " ": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", "!": "0x00,0x00,0x00,0x00,0x7C,0xFF,0xFF,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x00,0x00,0x00,0x00,0x00,", '"': "0x00,0x00,0x00,0x3C,0x3C,0x00,0x00,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", @@ -50,7 +53,6 @@ def get_font_map(): "N": "0x00,0xFF,0xFF,0x0E,0x38,0xF0,0xC0,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x03,0x07,0x1C,0x3F,0x3F,0x00,", "O": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", "P": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,", - "Р": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,", "Q": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x36,0x3E,0x1C,0x3F,0x33,0x00,", "R": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x03,0x07,0x0F,0x1D,0x38,0x30,0x00,", "S": "0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC7,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", @@ -97,6 +99,13 @@ def get_font_map(): "|": "0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", "}": "0x00,0x00,0x03,0x03,0x03,0x07,0x7E,0xFC,0xC0,0x80,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x70,0x3F,0x1F,0x01,0x00,0x00,0x00,", "~": "0x00,0x10,0x18,0x0C,0x04,0x0C,0x18,0x10,0x18,0x0C,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", + } + return font + + +def get_font_map_latin_extended(): + font = { + # U+0080..U+00FF Latin-1 Supplement "¡": "0x00,0x00,0x00,0x00,0x80,0xF3,0xF3,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x3F,0x3F,0x0F,0x00,0x00,0x00,0x00,", "¢": "0x00,0x00,0xE0,0xF0,0x38,0xFE,0xFE,0x18,0x38,0x30,0x00,0x00,0x00,0x00,0x03,0x07,0x0E,0x3F,0x3F,0x0C,0x0E,0x06,0x00,0x00,", "£": "0x00,0x00,0x00,0x80,0xF8,0xFC,0x8C,0x8C,0x1C,0x18,0x00,0x00,0x00,0x00,0x18,0x1C,0x1F,0x0B,0x18,0x18,0x18,0x18,0x08,0x00,", @@ -184,104 +193,7 @@ def get_font_map(): "ý": "0x00,0x00,0x60,0xE0,0x80,0x10,0x18,0x8C,0xE4,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,", "þ": "0x00,0x00,0x03,0xFF,0xFF,0x1B,0x18,0x18,0xF8,0xF0,0x00,0x00,0x00,0x00,0x30,0x3F,0x3F,0x36,0x06,0x06,0x07,0x03,0x00,0x00,", "ÿ": "0x00,0x00,0x60,0xEC,0x8C,0x00,0x00,0x8C,0xEC,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,", - "Ѐ": "0x00,0xFC,0xFC,0x8D,0x8F,0x8E,0x8C,0x8C,0x8C,0x0C,0x0C,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "Ё": "0x00,0xFE,0xFE,0xC7,0xC7,0xC6,0xC6,0xC7,0xC7,0x06,0x06,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "Ђ": "0x00,0x03,0xFF,0xFF,0x83,0xC3,0xC3,0xC3,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x00,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Ѓ": "0x00,0xFC,0xFC,0x0C,0x0C,0x0C,0x0E,0x0F,0x0D,0x0C,0x0C,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Є": "0x00,0xF8,0xFC,0xCE,0xC7,0xC3,0xC3,0xC3,0x07,0x0E,0x0C,0x00,0x00,0x07,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "Ѕ": "0x00,0x3C,0x7E,0x67,0xE3,0xC3,0xC3,0xC3,0x87,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x31,0x39,0x1F,0x0F,0x00,", - "І": "0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ї": "0x00,0x00,0x00,0x0D,0x0D,0xFC,0xFC,0x0D,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ј": "0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x0E,0x1E,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Љ": "0x00,0x00,0xFE,0xFF,0x03,0x03,0xFF,0xFF,0xC0,0xC0,0x80,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x3F,0x3F,0x30,0x39,0x1F,0x0F,", - "Њ": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xFF,0xFF,0xC0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x3F,0x3F,0x30,0x39,0x1F,0x0F,", - "Ћ": "0x00,0x03,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x00,0x00,0x00,0x01,0x3F,0x3F,0x00,", - "Ќ": "0x00,0xFF,0xFF,0xC0,0xE2,0xF3,0x39,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,", - "Ѝ": "0x00,0xFF,0xFF,0x00,0x01,0xC3,0xF2,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Ў": "0x00,0x07,0x1F,0x7C,0xF1,0xC1,0xC1,0xF1,0x7C,0x1F,0x07,0x00,0x00,0x00,0x30,0x30,0x3C,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,", - "Џ": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x1F,0x1F,0x18,0x18,0x78,0x78,0x18,0x18,0x1F,0x1F,0x00,", - "А": "0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", - "Б": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x83,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "В": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Г": "0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Ґ": "0x00,0xFC,0xFC,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x0F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Д": "0x00,0x00,0xF8,0xFE,0x0F,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x70,0x7F,0x1F,0x18,0x18,0x18,0x18,0x1F,0x7F,0x70,0x00,", - "Е": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "Ж": "0x00,0x03,0x0F,0xFC,0xE0,0xFF,0xFF,0xE0,0xFC,0x0F,0x03,0x00,0x00,0x38,0x3F,0x07,0x00,0x3F,0x3F,0x00,0x07,0x3F,0x38,0x00,", - "З": "0x0C,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC3,0xC3,0xE7,0x7E,0x3C,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0E,", - "И": "0x00,0xFF,0xFF,0x00,0x00,0xC0,0xF0,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Й": "0x00,0xFF,0xFF,0x00,0x02,0xC3,0xF1,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "К": "0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,", - "Л": "0x00,0x00,0xF0,0xFC,0x1E,0x07,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "М": "0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,", - "Н": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "О": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "П": "0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Р": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,", - "С": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "Т": "0x00,0x03,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "У": "0x00,0x07,0x1F,0x7C,0xF0,0xC0,0xC0,0xF0,0x7C,0x1F,0x07,0x00,0x00,0x00,0x30,0x30,0x3C,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,", - "Ф": "0x00,0xF8,0xFC,0x0E,0x06,0xFF,0xFF,0x06,0x0E,0xFC,0xF8,0x00,0x00,0x03,0x07,0x0E,0x0C,0x3F,0x3F,0x0C,0x0E,0x07,0x03,0x00,", - "Х": "0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x03,0x0F,0x3C,0x30,0x00,", - "Ц": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x1F,0x1F,0x18,0x18,0x18,0x18,0x18,0x1F,0x7F,0x78,0x00,", - "Ч": "0x00,0x7F,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Ш": "0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,", - "Щ": "0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x1F,0x1F,0x18,0x18,0x1F,0x1F,0x18,0x18,0x1F,0x7F,0x70,", - "Ъ": "0x03,0x03,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Ы": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x00,0x3F,0x3F,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,0x3F,0x3F,", - "Ь": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Э": "0x00,0x0C,0x0E,0x07,0xC3,0xC3,0xC3,0xC7,0xCE,0xFC,0xF8,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0F,0x07,0x00,", - "Ю": "0x00,0xFF,0xFF,0xC0,0xFC,0xFE,0x07,0x03,0x07,0xFE,0xFC,0x00,0x00,0x3F,0x3F,0x00,0x0F,0x1F,0x38,0x30,0x38,0x1F,0x0F,0x00,", - "Я": "0x00,0x7C,0xFE,0xC7,0x83,0x83,0x83,0x83,0x83,0xFF,0xFF,0x00,0x00,0x30,0x38,0x1D,0x0F,0x07,0x03,0x01,0x01,0x3F,0x3F,0x00,", - "а": "0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1E,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "б": "0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,", - "в": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x00,0x3F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,", - "г": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "ґ": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x3C,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "д": "0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x00,0x60,0x7F,0x3F,0x30,0x30,0x30,0x30,0x3F,0x7F,0x60,0x00,", - "е": "0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", - "ж": "0x00,0x30,0xF0,0xC0,0x00,0xF0,0xF0,0x00,0xC0,0xF0,0x30,0x00,0x00,0x30,0x3C,0x0F,0x03,0x3F,0x3F,0x03,0x0F,0x3C,0x30,0x00,", - "з": "0x00,0x60,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x18,0x38,0x30,0x33,0x33,0x33,0x33,0x33,0x3F,0x1D,0x00,", - "и": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "й": "0x00,0xF0,0xF0,0x00,0x04,0x08,0x88,0xC4,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "к": "0x00,0xF0,0xF0,0x80,0x80,0xC0,0xE0,0x70,0x30,0x10,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x07,0x0E,0x1C,0x38,0x30,0x20,0x00,", - "л": "0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "м": "0x00,0xF0,0xF0,0xE0,0xC0,0x80,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "н": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,", - "о": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "п": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "р": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,", - "с": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x18,0x08,0x00,", - "т": "0x00,0x30,0x30,0x30,0x30,0xF0,0xF0,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "у": "0x00,0x30,0xF0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xF0,0x30,0x00,0x00,0x60,0xE0,0xC3,0xE7,0x7C,0x3C,0x0F,0x03,0x00,0x00,0x00,", - "ф": "0x00,0x80,0xC0,0x60,0x60,0xF0,0xF0,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x30,0x30,0xFF,0xFF,0x30,0x30,0x1F,0x0F,0x00,", - "х": "0x00,0x30,0x70,0xC0,0x80,0x00,0x00,0x80,0xC0,0x70,0x30,0x00,0x00,0x30,0x38,0x0C,0x07,0x03,0x03,0x07,0x0C,0x38,0x30,0x00,", - "ц": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x3F,0xFF,0xF0,0x00,", - "ч": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,", - "ш": "0x00,0xF0,0xF0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,", - "щ": "0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0xFF,0xE0,", - "ъ": "0x30,0x30,0xF0,0xF0,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "ы": "0x00,0xF0,0xF0,0x80,0x80,0x80,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x31,0x31,0x3B,0x1F,0x0E,0x00,0x3F,0x3F,0x00,", - "ь": "0x00,0xF0,0xF0,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "э": "0x00,0x40,0x60,0x70,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x08,0x18,0x38,0x30,0x33,0x33,0x33,0x3B,0x1F,0x0F,0x00,", - "ю": "0x00,0xF0,0xF0,0x00,0xE0,0xF0,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x3F,0x3F,0x03,0x1F,0x3F,0x30,0x30,0x30,0x3F,0x1F,0x00,", - "я": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x21,0x33,0x3B,0x1E,0x0E,0x06,0x06,0x06,0x3F,0x3F,0x00,", - "ѐ": "0x00,0xE0,0xF0,0x32,0x36,0x36,0x34,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", - "ё": "0x00,0xE0,0xF0,0x34,0x34,0x30,0x30,0x34,0x34,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", - "ђ": "0x00,0x30,0xFC,0xFC,0x30,0xB0,0xB0,0xB0,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x07,0x03,0x01,0x01,0xC1,0xFF,0x3F,0x00,", - "ѓ": "0x00,0xF0,0xF0,0x30,0x30,0x34,0x36,0x32,0x30,0x30,0x30,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "є": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x30,0x38,0x18,0x08,0x00,", - "ѕ": "0x00,0xE0,0xF0,0xB0,0xB0,0x30,0x30,0x30,0x30,0x70,0x60,0x00,0x00,0x18,0x39,0x31,0x33,0x33,0x33,0x37,0x36,0x3E,0x1C,0x00,", - "і": "0x00,0x00,0x00,0x00,0x30,0xF6,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ї": "0x00,0x00,0x00,0x04,0x34,0xF0,0xF4,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ј": "0x00,0x00,0x00,0x00,0x00,0x30,0x30,0xF6,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xE0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00,", - "љ": "0x00,0x00,0xE0,0xF0,0x30,0x30,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x3F,0x3F,0x33,0x33,0x1E,0x0C,", - "њ": "0x00,0xF0,0xF0,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x03,0x3F,0x3F,0x33,0x33,0x1E,0x0C,", - "ћ": "0x00,0x30,0xFC,0xFC,0xB0,0xB0,0xB0,0xB0,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x3F,0x3F,0x00,", - "ќ": "0x00,0xF0,0xF0,0x80,0x88,0xCC,0xE4,0x70,0x30,0x10,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x07,0x0E,0x1C,0x38,0x30,0x20,0x00,", - "ѝ": "0x00,0xF0,0xF0,0x00,0x06,0x0C,0x88,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "ў": "0x00,0x30,0xF0,0xC0,0x04,0x08,0x08,0x04,0xC0,0xF0,0x30,0x00,0x00,0x60,0xE0,0xC3,0xE7,0x7C,0x3C,0x0F,0x03,0x00,0x00,0x00,", - "џ": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0xF0,0xF0,0x30,0x30,0x3F,0x3F,0x00,", + # U+0100..U+017F Latin Extended A "Ā": "0x00,0x00,0x00,0xE0,0xF9,0x1D,0x1D,0xF9,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", "ā": "0x00,0x00,0x40,0x60,0x68,0x68,0x68,0x68,0x68,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", "Ă": "0x00,0x00,0x00,0xE0,0xF9,0x1A,0x1A,0xF9,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", @@ -414,8 +326,114 @@ def get_font_map(): return font -def get_small_font_map(): +def get_font_map_cyrillic(): font = { + # U+0400..U+04FF Cyrillic + "Ѐ": "0x00,0xFC,0xFC,0x8D,0x8F,0x8E,0x8C,0x8C,0x8C,0x0C,0x0C,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", + "Ё": "0x00,0xFE,0xFE,0xC7,0xC7,0xC6,0xC6,0xC7,0xC7,0x06,0x06,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", + "Ђ": "0x00,0x03,0xFF,0xFF,0x83,0xC3,0xC3,0xC3,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x00,0x30,0x30,0x39,0x1F,0x0F,0x00,", + "Ѓ": "0x00,0xFC,0xFC,0x0C,0x0C,0x0C,0x0E,0x0F,0x0D,0x0C,0x0C,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", + "Є": "0x00,0xF8,0xFC,0xCE,0xC7,0xC3,0xC3,0xC3,0x07,0x0E,0x0C,0x00,0x00,0x07,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", + "Ѕ": "0x00,0x3C,0x7E,0x67,0xE3,0xC3,0xC3,0xC3,0x87,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x31,0x39,0x1F,0x0F,0x00,", + "І": "0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", + "Ї": "0x00,0x00,0x00,0x0D,0x0D,0xFC,0xFC,0x0D,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", + "Ј": "0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x0E,0x1E,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", + "Љ": "0x00,0x00,0xFE,0xFF,0x03,0x03,0xFF,0xFF,0xC0,0xC0,0x80,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x3F,0x3F,0x30,0x39,0x1F,0x0F,", + "Њ": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xFF,0xFF,0xC0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x3F,0x3F,0x30,0x39,0x1F,0x0F,", + "Ћ": "0x00,0x03,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x00,0x00,0x00,0x01,0x3F,0x3F,0x00,", + "Ќ": "0x00,0xFF,0xFF,0xC0,0xE2,0xF3,0x39,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,", + "Ѝ": "0x00,0xFF,0xFF,0x00,0x01,0xC3,0xF2,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", + "Ў": "0x00,0x07,0x1F,0x7C,0xF1,0xC1,0xC1,0xF1,0x7C,0x1F,0x07,0x00,0x00,0x00,0x30,0x30,0x3C,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,", + "Џ": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x1F,0x1F,0x18,0x18,0x78,0x78,0x18,0x18,0x1F,0x1F,0x00,", + "А": "0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", + "Б": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x83,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", + "В": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", + "Г": "0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", + "Ґ": "0x00,0xFC,0xFC,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x0F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", + "Д": "0x00,0x00,0xF8,0xFE,0x0F,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x70,0x7F,0x1F,0x18,0x18,0x18,0x18,0x1F,0x7F,0x70,0x00,", + "Е": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", + "Ж": "0x00,0x03,0x0F,0xFC,0xE0,0xFF,0xFF,0xE0,0xFC,0x0F,0x03,0x00,0x00,0x38,0x3F,0x07,0x00,0x3F,0x3F,0x00,0x07,0x3F,0x38,0x00,", + "З": "0x0C,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC3,0xC3,0xE7,0x7E,0x3C,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0E,", + "И": "0x00,0xFF,0xFF,0x00,0x00,0xC0,0xF0,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", + "Й": "0x00,0xFF,0xFF,0x00,0x02,0xC3,0xF1,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", + "К": "0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,", + "Л": "0x00,0x00,0xF0,0xFC,0x1E,0x07,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", + "М": "0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,", + "Н": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", + "О": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", + "П": "0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", + "Р": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,", + "С": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", + "Т": "0x00,0x03,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", + "У": "0x00,0x07,0x1F,0x7C,0xF0,0xC0,0xC0,0xF0,0x7C,0x1F,0x07,0x00,0x00,0x00,0x30,0x30,0x3C,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,", + "Ф": "0x00,0xF8,0xFC,0x0E,0x06,0xFF,0xFF,0x06,0x0E,0xFC,0xF8,0x00,0x00,0x03,0x07,0x0E,0x0C,0x3F,0x3F,0x0C,0x0E,0x07,0x03,0x00,", + "Х": "0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x03,0x0F,0x3C,0x30,0x00,", + "Ц": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x1F,0x1F,0x18,0x18,0x18,0x18,0x18,0x1F,0x7F,0x78,0x00,", + "Ч": "0x00,0x7F,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", + "Ш": "0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,", + "Щ": "0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x1F,0x1F,0x18,0x18,0x1F,0x1F,0x18,0x18,0x1F,0x7F,0x70,", + "Ъ": "0x03,0x03,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", + "Ы": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x00,0x3F,0x3F,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,0x3F,0x3F,", + "Ь": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", + "Э": "0x00,0x0C,0x0E,0x07,0xC3,0xC3,0xC3,0xC7,0xCE,0xFC,0xF8,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0F,0x07,0x00,", + "Ю": "0x00,0xFF,0xFF,0xC0,0xFC,0xFE,0x07,0x03,0x07,0xFE,0xFC,0x00,0x00,0x3F,0x3F,0x00,0x0F,0x1F,0x38,0x30,0x38,0x1F,0x0F,0x00,", + "Я": "0x00,0x7C,0xFE,0xC7,0x83,0x83,0x83,0x83,0x83,0xFF,0xFF,0x00,0x00,0x30,0x38,0x1D,0x0F,0x07,0x03,0x01,0x01,0x3F,0x3F,0x00,", + "а": "0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1E,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", + "б": "0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,", + "в": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x00,0x3F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,", + "г": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", + "ґ": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x3C,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", + "д": "0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x00,0x60,0x7F,0x3F,0x30,0x30,0x30,0x30,0x3F,0x7F,0x60,0x00,", + "е": "0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", + "ж": "0x00,0x30,0xF0,0xC0,0x00,0xF0,0xF0,0x00,0xC0,0xF0,0x30,0x00,0x00,0x30,0x3C,0x0F,0x03,0x3F,0x3F,0x03,0x0F,0x3C,0x30,0x00,", + "з": "0x00,0x60,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x18,0x38,0x30,0x33,0x33,0x33,0x33,0x33,0x3F,0x1D,0x00,", + "и": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", + "й": "0x00,0xF0,0xF0,0x00,0x04,0x08,0x88,0xC4,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", + "к": "0x00,0xF0,0xF0,0x80,0x80,0xC0,0xE0,0x70,0x30,0x10,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x07,0x0E,0x1C,0x38,0x30,0x20,0x00,", + "л": "0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", + "м": "0x00,0xF0,0xF0,0xE0,0xC0,0x80,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x03,0x01,0x00,0x3F,0x3F,0x00,", + "н": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,", + "о": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", + "п": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", + "р": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,", + "с": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x18,0x08,0x00,", + "т": "0x00,0x30,0x30,0x30,0x30,0xF0,0xF0,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", + "у": "0x00,0x30,0xF0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xF0,0x30,0x00,0x00,0x60,0xE0,0xC3,0xE7,0x7C,0x3C,0x0F,0x03,0x00,0x00,0x00,", + "ф": "0x00,0x80,0xC0,0x60,0x60,0xF0,0xF0,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x30,0x30,0xFF,0xFF,0x30,0x30,0x1F,0x0F,0x00,", + "х": "0x00,0x30,0x70,0xC0,0x80,0x00,0x00,0x80,0xC0,0x70,0x30,0x00,0x00,0x30,0x38,0x0C,0x07,0x03,0x03,0x07,0x0C,0x38,0x30,0x00,", + "ц": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x3F,0xFF,0xF0,0x00,", + "ч": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,", + "ш": "0x00,0xF0,0xF0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,", + "щ": "0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0xFF,0xE0,", + "ъ": "0x30,0x30,0xF0,0xF0,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", + "ы": "0x00,0xF0,0xF0,0x80,0x80,0x80,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x31,0x31,0x3B,0x1F,0x0E,0x00,0x3F,0x3F,0x00,", + "ь": "0x00,0xF0,0xF0,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", + "э": "0x00,0x40,0x60,0x70,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x08,0x18,0x38,0x30,0x33,0x33,0x33,0x3B,0x1F,0x0F,0x00,", + "ю": "0x00,0xF0,0xF0,0x00,0xE0,0xF0,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x3F,0x3F,0x03,0x1F,0x3F,0x30,0x30,0x30,0x3F,0x1F,0x00,", + "я": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x21,0x33,0x3B,0x1E,0x0E,0x06,0x06,0x06,0x3F,0x3F,0x00,", + "ѐ": "0x00,0xE0,0xF0,0x32,0x36,0x36,0x34,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", + "ё": "0x00,0xE0,0xF0,0x34,0x34,0x30,0x30,0x34,0x34,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", + "ђ": "0x00,0x30,0xFC,0xFC,0x30,0xB0,0xB0,0xB0,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x07,0x03,0x01,0x01,0xC1,0xFF,0x3F,0x00,", + "ѓ": "0x00,0xF0,0xF0,0x30,0x30,0x34,0x36,0x32,0x30,0x30,0x30,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", + "є": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x30,0x38,0x18,0x08,0x00,", + "ѕ": "0x00,0xE0,0xF0,0xB0,0xB0,0x30,0x30,0x30,0x30,0x70,0x60,0x00,0x00,0x18,0x39,0x31,0x33,0x33,0x33,0x37,0x36,0x3E,0x1C,0x00,", + "і": "0x00,0x00,0x00,0x00,0x30,0xF6,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", + "ї": "0x00,0x00,0x00,0x04,0x34,0xF0,0xF4,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", + "ј": "0x00,0x00,0x00,0x00,0x00,0x30,0x30,0xF6,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xE0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00,", + "љ": "0x00,0x00,0xE0,0xF0,0x30,0x30,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x3F,0x3F,0x33,0x33,0x1E,0x0C,", + "њ": "0x00,0xF0,0xF0,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x03,0x3F,0x3F,0x33,0x33,0x1E,0x0C,", + "ћ": "0x00,0x30,0xFC,0xFC,0xB0,0xB0,0xB0,0xB0,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x3F,0x3F,0x00,", + "ќ": "0x00,0xF0,0xF0,0x80,0x88,0xCC,0xE4,0x70,0x30,0x10,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x07,0x0E,0x1C,0x38,0x30,0x20,0x00,", + "ѝ": "0x00,0xF0,0xF0,0x00,0x06,0x0C,0x88,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", + "ў": "0x00,0x30,0xF0,0xC0,0x04,0x08,0x08,0x04,0xC0,0xF0,0x30,0x00,0x00,0x60,0xE0,0xC3,0xE7,0x7C,0x3C,0x0F,0x03,0x00,0x00,0x00,", + "џ": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0xF0,0xF0,0x30,0x30,0x3F,0x3F,0x00,", + } + return font + + +def get_small_font_map_ascii_basic(): + font = { + # U+0000..U+007F Basic Latin " ": "0x00, 0x00, 0x00, 0x00, 0x00, 0x00,", "!": "0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,", '"': "0x00, 0x07, 0x00, 0x07, 0x00, 0x00,", @@ -511,6 +529,13 @@ def get_small_font_map(): "|": "0x00, 0x00, 0x77, 0x00, 0x00, 0x00,", "}": "0x00, 0x00, 0x41, 0x36, 0x08, 0x00,", "~": "0x02, 0x01, 0x02, 0x04, 0x02, 0x00,", + } + return font + + +def get_small_font_map_latin_extended(): + font = { + # U+0080..U+00FF Latin-1 Supplement "¡": "0x00, 0x00, 0x79, 0x00, 0x00, 0x00,", "¢": "0x1c, 0x22, 0x7f, 0x22, 0x10, 0x00,", "£": "0x50, 0x7e, 0x51, 0x41, 0x42, 0x00,", @@ -562,7 +587,6 @@ def get_small_font_map(): "Ô": "0x38, 0x46, 0x45, 0x46, 0x38, 0x00,", "Õ": "0x32, 0x49, 0x4a, 0x31, 0x00, 0x00,", "Ö": "0x38, 0x45, 0x44, 0x45, 0x38, 0x00,", - "ő": "0x38, 0x45, 0x44, 0x45, 0x38, 0x00,", "×": "0x22, 0x14, 0x08, 0x14, 0x22, 0x00,", "Ø": "0x58, 0x24, 0x54, 0x48, 0x34, 0x00,", "Ù": "0x38, 0x41, 0x42, 0x40, 0x38, 0x00,", @@ -605,6 +629,130 @@ def get_small_font_map(): "ý": "0x44, 0x48, 0x32, 0x11, 0x0c, 0x00,", "þ": "0x7c, 0x28, 0x28, 0x10, 0x00, 0x00,", "ÿ": "0x44, 0x49, 0x30, 0x11, 0x0c, 0x00,", + # U+0100..U+017F Latin Extended A + "Ā": "0x78, 0x15, 0x15, 0x15, 0x78, 0x00,", + "ā": "0x20, 0x55, 0x55, 0x55, 0x78, 0x00,", + "Ă": "0x78, 0x15, 0x16, 0x15, 0x78, 0x00,", + "ă": "0x20, 0x55, 0x56, 0x55, 0x78, 0x00,", + "Ą": "0x7e, 0x09, 0x09, 0x49, 0xbe, 0x00,", + "ą": "0x20, 0x54, 0x54, 0xd4, 0x78, 0x00,", + "Ć": "0x38, 0x44, 0x46, 0x45, 0x28, 0x00,", + "ć": "0x38, 0x44, 0x46, 0x45, 0x20, 0x00,", + "Ĉ": "0x38, 0x46, 0x45, 0x46, 0x28, 0x00,", + "ĉ": "0x38, 0x46, 0x45, 0x46, 0x20, 0x00,", + "Ċ": "0x38, 0x44, 0x45, 0x44, 0x28, 0x00,", + "ċ": "0x38, 0x44, 0x45, 0x44, 0x20, 0x00,", + "Č": "0x38, 0x45, 0x46, 0x45, 0x28, 0x00,", + "č": "0x38, 0x45, 0x46, 0x45, 0x20, 0x00,", + "Ď": "0x7c, 0x45, 0x46, 0x29, 0x10, 0x00,", + "ď": "0x38, 0x44, 0x44, 0x4A, 0x7F, 0x00,", + "Đ": "0x08, 0x7f, 0x49, 0x22, 0x1c, 0x00,", + "đ": "0x38, 0x44, 0x44, 0x4A, 0x7F, 0x00,", + "Ē": "0x7c, 0x55, 0x55, 0x55, 0x44, 0x00,", + "ē": "0x38, 0x55, 0x55, 0x55, 0x08, 0x00,", + "Ĕ": "0x7c, 0x55, 0x56, 0x55, 0x44, 0x00,", + "ĕ": "0x38, 0x55, 0x56, 0x55, 0x08, 0x00,", + "Ė": "0x7c, 0x54, 0x55, 0x54, 0x44, 0x00,", + "ė": "0x38, 0x54, 0x55, 0x54, 0x08, 0x00,", + "Ę": "0x7f, 0x49, 0x49, 0xc9, 0x41, 0x00,", + "ę": "0x38, 0x54, 0x54, 0xd4, 0x18, 0x00,", + "Ě": "0x7c, 0x55, 0x56, 0x55, 0x44, 0x00,", + "ě": "0x38, 0x55, 0x56, 0x55, 0x08, 0x00,", + "Ĝ": "0x38, 0x46, 0x55, 0x56, 0x70, 0x00,", + "ĝ": "0x08, 0x56, 0x55, 0x56, 0x3c, 0x00,", + "Ğ": "0x38, 0x45, 0x56, 0x55, 0x30, 0x00,", + "ğ": "0x08, 0x55, 0x56, 0x55, 0x3c, 0x00,", + "Ġ": "0x38, 0x44, 0x55, 0x54, 0x30, 0x00,", + "ġ": "0x08, 0x54, 0x55, 0x54, 0x3c, 0x00,", + "Ģ": "0x0e, 0x51, 0x35, 0x15, 0x1c, 0x00,", + "Ĥ": "0x7c, 0x12, 0x11, 0x12, 0x7c, 0x00,", + "ĥ": "0x02, 0x79, 0x22, 0x10, 0x60, 0x00,", + "Ħ": "0x02, 0x7f, 0x0a, 0x7f, 0x02, 0x00,", + "ħ": "0x02, 0x7f, 0x12, 0x08, 0x70, 0x00,", + "Ĩ": "0x4a, 0x49, 0x7a, 0x49, 0x48, 0x00,", + "ĩ": "0x02, 0x49, 0x7a, 0x41, 0x00, 0x00,", + "Ī": "0x44, 0x45, 0x7d, 0x45, 0x44, 0x00,", + "ī": "0x00, 0x45, 0x7d, 0x41, 0x00, 0x00,", + "Ĭ": "0x44, 0x45, 0x7e, 0x45, 0x44, 0x00,", + "ĭ": "0x00, 0x45, 0x7e, 0x41, 0x00, 0x00,", + "Į": "0x00, 0x41, 0x7f, 0xc1, 0x00, 0x00,", + "į": "0x00, 0x44, 0x7d, 0xc0, 0x00, 0x00,", + "İ": "0x44, 0x44, 0x7d, 0x44, 0x44, 0x00,", + "ı": "0x00, 0x44, 0x7c, 0x40, 0x00, 0x00,", + "ij": "0x44, 0x7d, 0x40, 0x44, 0x3d, 0x00,", + "Ĵ": "0x20, 0x40, 0x46, 0x3d, 0x06, 0x00,", + "ĵ": "0x00, 0x20, 0x46, 0x3d, 0x02, 0x00,", + "Ķ": "0x1f, 0x44, 0x2a, 0x11, 0x00, 0x00,", + "ķ": "0x1f, 0x44, 0x2a, 0x11, 0x00, 0x00,", + "ĸ": "0x7c, 0x10, 0x28, 0x44, 0x00, 0x00,", + "Ĺ": "0x7c, 0x40, 0x42, 0x41, 0x40, 0x00,", + "Ľ": "0x7c, 0x40, 0x42, 0x41, 0x40, 0x00,", + "ĺ": "0x00, 0x44, 0x7e, 0x41, 0x00, 0x00,", + "Ļ": "0x1f, 0x50, 0x30, 0x10, 0x10, 0x00,", + "ļ": "0x00, 0x51, 0x3f, 0x10, 0x00, 0x00,", + "ľ": "0x00, 0x41, 0x7f, 0x40, 0x03, 0x00,", + "Ŀ": "0x7f, 0x40, 0x40, 0x48, 0x40, 0x00,", + "ŀ": "0x00, 0x41, 0x7f, 0x40, 0x08, 0x00,", + "Ł": "0x10, 0x7F, 0x48, 0x44, 0x40, 0x00,", + "ł": "0x00, 0x49, 0x7F, 0x44, 0x00, 0x00,", + "Ń": "0x7c, 0x08, 0x12, 0x21, 0x7c, 0x00,", + "ń": "0x7c, 0x08, 0x06, 0x05, 0x78, 0x00,", + "Ņ": "0x1f, 0x42, 0x24, 0x08, 0x1f, 0x00,", + "ņ": "0x1f, 0x42, 0x21, 0x01, 0x1e, 0x00,", + "Ň": "0x7c, 0x09, 0x12, 0x21, 0x7c, 0x00,", + "ň": "0x7c, 0x09, 0x06, 0x05, 0x78, 0x00,", + "Ō": "0x38, 0x45, 0x45, 0x45, 0x38, 0x00,", + "ō": "0x38, 0x45, 0x45, 0x45, 0x38, 0x00,", + "Ŏ": "0x38, 0x45, 0x46, 0x45, 0x38, 0x00,", + "ŏ": "0x38, 0x45, 0x46, 0x45, 0x38, 0x00,", + "ő": "0x38, 0x45, 0x44, 0x45, 0x38, 0x00,", + "Œ": "0x3e, 0x41, 0x7f, 0x49, 0x49, 0x00,", + "œ": "0x38, 0x44, 0x7c, 0x54, 0x58, 0x00,", + "Ŕ": "0x7c, 0x14, 0x16, 0x15, 0x68, 0x00,", + "ŕ": "0x7c, 0x08, 0x06, 0x05, 0x08, 0x00,", + "Ŗ": "0x1f, 0x45, 0x25, 0x05, 0x1a, 0x00,", + "ŗ": "0x1f, 0x42, 0x21, 0x01, 0x02, 0x00,", + "Ř": "0x7c, 0x15, 0x16, 0x15, 0x68, 0x00,", + "ř": "0x7c, 0x09, 0x06, 0x05, 0x08, 0x00,", + "Ś": "0x08, 0x54, 0x56, 0x55, 0x20, 0x00,", + "ś": "0x48, 0x54, 0x56, 0x55, 0x24, 0x00,", + "Ŝ": "0x08, 0x56, 0x55, 0x56, 0x20, 0x00,", + "ŝ": "0x48, 0x56, 0x55, 0x56, 0x24, 0x00,", + "Ş": "0x02, 0x55, 0x35, 0x15, 0x08, 0x00,", + "ş": "0x12, 0x55, 0x35, 0x15, 0x09, 0x00,", + "Š": "0x08, 0x55, 0x56, 0x55, 0x20, 0x00,", + "š": "0x48, 0x55, 0x56, 0x55, 0x24, 0x00,", + "Ţ": "0x01, 0x41, 0x3f, 0x01, 0x01, 0x00,", + "ţ": "0x02, 0x4f, 0x32, 0x10, 0x08, 0x00,", + "Ť": "0x04, 0x05, 0x7e, 0x05, 0x04, 0x00,", + "ť": "0x04, 0x3e, 0x44, 0x40, 0x23, 0x00,", + "Ŧ": "0x01, 0x09, 0x7f, 0x09, 0x01, 0x00,", + "ŧ": "0x14, 0x3e, 0x54, 0x40, 0x20, 0x00,", + "Ū": "0x3c, 0x41, 0x41, 0x41, 0x3c, 0x00,", + "ū": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", + "Ŭ": "0x3c, 0x41, 0x42, 0x41, 0x3c, 0x00,", + "ŭ": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", + "Ů": "0x3c, 0x40, 0x41, 0x40, 0x3c, 0x00,", + "ů": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", + "Ŵ": "0x3c, 0x42, 0x39, 0x42, 0x3c, 0x00,", + "ŵ": "0x3c, 0x42, 0x31, 0x42, 0x3c, 0x00,", + "Ŷ": "0x04, 0x0a, 0x71, 0x0a, 0x04, 0x00,", + "ŷ": "0x04, 0x4a, 0x31, 0x12, 0x0c, 0x00,", + "Ÿ": "0x04, 0x09, 0x70, 0x09, 0x04, 0x00,", + "Ź": "0x44, 0x64, 0x56, 0x4d, 0x44, 0x00,", + "ź": "0x44, 0x64, 0x56, 0x4d, 0x44, 0x00,", + "Ż": "0x44, 0x64, 0x55, 0x4c, 0x44, 0x00,", + "ż": "0x44, 0x64, 0x55, 0x4c, 0x44, 0x00,", + "Ž": "0x44, 0x65, 0x56, 0x4d, 0x44, 0x00,", + "ž": "0x44, 0x65, 0x56, 0x4d, 0x44, 0x00,", + "ſ": "0x00, 0x04, 0x7e, 0x01, 0x01, 0x00,", + } + return font + + +def get_small_font_map_cyrillic(): + font = { + # U+0400..U+04FF Cyrillic "Ѐ": "0x7c, 0x55, 0x56, 0x44, 0x44, 0x00,", "Ё": "0x7c, 0x55, 0x54, 0x45, 0x44, 0x00,", "Ђ": "0x01, 0x7f, 0x09, 0x49, 0x31, 0x00,", @@ -703,120 +851,23 @@ def get_small_font_map(): "ѝ": "0x7c, 0x21, 0x12, 0x08, 0x7c, 0x00,", "ў": "0x4c, 0x51, 0x22, 0x11, 0x0c, 0x00,", "џ": "0x3c, 0x20, 0x60, 0x20, 0x3c, 0x00,", - "Ā": "0x78, 0x15, 0x15, 0x15, 0x78, 0x00,", - "ā": "0x20, 0x55, 0x55, 0x55, 0x78, 0x00,", - "Ă": "0x78, 0x15, 0x16, 0x15, 0x78, 0x00,", - "ă": "0x20, 0x55, 0x56, 0x55, 0x78, 0x00,", - "Ą": "0x7e, 0x09, 0x09, 0x49, 0xbe, 0x00,", - "ą": "0x20, 0x54, 0x54, 0xd4, 0x78, 0x00,", - "Ć": "0x38, 0x44, 0x46, 0x45, 0x28, 0x00,", - "ć": "0x38, 0x44, 0x46, 0x45, 0x20, 0x00,", - "Ĉ": "0x38, 0x46, 0x45, 0x46, 0x28, 0x00,", - "ĉ": "0x38, 0x46, 0x45, 0x46, 0x20, 0x00,", - "Ċ": "0x38, 0x44, 0x45, 0x44, 0x28, 0x00,", - "ċ": "0x38, 0x44, 0x45, 0x44, 0x20, 0x00,", - "Č": "0x38, 0x45, 0x46, 0x45, 0x28, 0x00,", - "č": "0x38, 0x45, 0x46, 0x45, 0x20, 0x00,", - "Ď": "0x7c, 0x45, 0x46, 0x29, 0x10, 0x00,", - "ď": "0x38, 0x44, 0x44, 0x4A, 0x7F, 0x00,", - "Đ": "0x08, 0x7f, 0x49, 0x22, 0x1c, 0x00,", - "đ": "0x38, 0x44, 0x44, 0x4A, 0x7F, 0x00,", - "Ē": "0x7c, 0x55, 0x55, 0x55, 0x44, 0x00,", - "ē": "0x38, 0x55, 0x55, 0x55, 0x08, 0x00,", - "Ĕ": "0x7c, 0x55, 0x56, 0x55, 0x44, 0x00,", - "ĕ": "0x38, 0x55, 0x56, 0x55, 0x08, 0x00,", - "Ė": "0x7c, 0x54, 0x55, 0x54, 0x44, 0x00,", - "ė": "0x38, 0x54, 0x55, 0x54, 0x08, 0x00,", - "Ę": "0x7f, 0x49, 0x49, 0xc9, 0x41, 0x00,", - "ę": "0x38, 0x54, 0x54, 0xd4, 0x18, 0x00,", - "Ě": "0x7c, 0x55, 0x56, 0x55, 0x44, 0x00,", - "ě": "0x38, 0x55, 0x56, 0x55, 0x08, 0x00,", - "Ĝ": "0x38, 0x46, 0x55, 0x56, 0x70, 0x00,", - "ĝ": "0x08, 0x56, 0x55, 0x56, 0x3c, 0x00,", - "Ğ": "0x38, 0x45, 0x56, 0x55, 0x30, 0x00,", - "ğ": "0x08, 0x55, 0x56, 0x55, 0x3c, 0x00,", - "Ġ": "0x38, 0x44, 0x55, 0x54, 0x30, 0x00,", - "ġ": "0x08, 0x54, 0x55, 0x54, 0x3c, 0x00,", - "Ģ": "0x0e, 0x51, 0x35, 0x15, 0x1c, 0x00,", - "Ĥ": "0x7c, 0x12, 0x11, 0x12, 0x7c, 0x00,", - "ĥ": "0x02, 0x79, 0x22, 0x10, 0x60, 0x00,", - "Ħ": "0x02, 0x7f, 0x0a, 0x7f, 0x02, 0x00,", - "ħ": "0x02, 0x7f, 0x12, 0x08, 0x70, 0x00,", - "Ĩ": "0x4a, 0x49, 0x7a, 0x49, 0x48, 0x00,", - "ĩ": "0x02, 0x49, 0x7a, 0x41, 0x00, 0x00,", - "Ī": "0x44, 0x45, 0x7d, 0x45, 0x44, 0x00,", - "ī": "0x00, 0x45, 0x7d, 0x41, 0x00, 0x00,", - "Ĭ": "0x44, 0x45, 0x7e, 0x45, 0x44, 0x00,", - "ĭ": "0x00, 0x45, 0x7e, 0x41, 0x00, 0x00,", - "Į": "0x00, 0x41, 0x7f, 0xc1, 0x00, 0x00,", - "į": "0x00, 0x44, 0x7d, 0xc0, 0x00, 0x00,", - "İ": "0x44, 0x44, 0x7d, 0x44, 0x44, 0x00,", - "ı": "0x00, 0x44, 0x7c, 0x40, 0x00, 0x00,", - "ij": "0x44, 0x7d, 0x40, 0x44, 0x3d, 0x00,", - "Ĵ": "0x20, 0x40, 0x46, 0x3d, 0x06, 0x00,", - "ĵ": "0x00, 0x20, 0x46, 0x3d, 0x02, 0x00,", - "Ķ": "0x1f, 0x44, 0x2a, 0x11, 0x00, 0x00,", - "ķ": "0x1f, 0x44, 0x2a, 0x11, 0x00, 0x00,", - "ĸ": "0x7c, 0x10, 0x28, 0x44, 0x00, 0x00,", - "Ĺ": "0x7c, 0x40, 0x42, 0x41, 0x40, 0x00,", - "Ľ": "0x7c, 0x40, 0x42, 0x41, 0x40, 0x00,", - "ĺ": "0x00, 0x44, 0x7e, 0x41, 0x00, 0x00,", - "Ļ": "0x1f, 0x50, 0x30, 0x10, 0x10, 0x00,", - "ļ": "0x00, 0x51, 0x3f, 0x10, 0x00, 0x00,", - "ľ": "0x00, 0x41, 0x7f, 0x40, 0x03, 0x00,", - "Ŀ": "0x7f, 0x40, 0x40, 0x48, 0x40, 0x00,", - "ŀ": "0x00, 0x41, 0x7f, 0x40, 0x08, 0x00,", - "Ł": "0x10, 0x7F, 0x48, 0x44, 0x40, 0x00,", - "ł": "0x00, 0x49, 0x7F, 0x44, 0x00, 0x00,", - "Ń": "0x7c, 0x08, 0x12, 0x21, 0x7c, 0x00,", - "ń": "0x7c, 0x08, 0x06, 0x05, 0x78, 0x00,", - "Ņ": "0x1f, 0x42, 0x24, 0x08, 0x1f, 0x00,", - "ņ": "0x1f, 0x42, 0x21, 0x01, 0x1e, 0x00,", - "Ň": "0x7c, 0x09, 0x12, 0x21, 0x7c, 0x00,", - "ň": "0x7c, 0x09, 0x06, 0x05, 0x78, 0x00,", - "Ō": "0x38, 0x45, 0x45, 0x45, 0x38, 0x00,", - "ō": "0x38, 0x45, 0x45, 0x45, 0x38, 0x00,", - "Ŏ": "0x38, 0x45, 0x46, 0x45, 0x38, 0x00,", - "ŏ": "0x38, 0x45, 0x46, 0x45, 0x38, 0x00,", - "Œ": "0x3e, 0x41, 0x7f, 0x49, 0x49, 0x00,", - "œ": "0x38, 0x44, 0x7c, 0x54, 0x58, 0x00,", - "Ŕ": "0x7c, 0x14, 0x16, 0x15, 0x68, 0x00,", - "ŕ": "0x7c, 0x08, 0x06, 0x05, 0x08, 0x00,", - "Ŗ": "0x1f, 0x45, 0x25, 0x05, 0x1a, 0x00,", - "ŗ": "0x1f, 0x42, 0x21, 0x01, 0x02, 0x00,", - "Ř": "0x7c, 0x15, 0x16, 0x15, 0x68, 0x00,", - "ř": "0x7c, 0x09, 0x06, 0x05, 0x08, 0x00,", - "Ś": "0x08, 0x54, 0x56, 0x55, 0x20, 0x00,", - "ś": "0x48, 0x54, 0x56, 0x55, 0x24, 0x00,", - "Ŝ": "0x08, 0x56, 0x55, 0x56, 0x20, 0x00,", - "ŝ": "0x48, 0x56, 0x55, 0x56, 0x24, 0x00,", - "Ş": "0x02, 0x55, 0x35, 0x15, 0x08, 0x00,", - "ş": "0x12, 0x55, 0x35, 0x15, 0x09, 0x00,", - "Š": "0x08, 0x55, 0x56, 0x55, 0x20, 0x00,", - "š": "0x48, 0x55, 0x56, 0x55, 0x24, 0x00,", - "Ţ": "0x01, 0x41, 0x3f, 0x01, 0x01, 0x00,", - "ţ": "0x02, 0x4f, 0x32, 0x10, 0x08, 0x00,", - "Ť": "0x04, 0x05, 0x7e, 0x05, 0x04, 0x00,", - "ť": "0x04, 0x3e, 0x44, 0x40, 0x23, 0x00,", - "Ŧ": "0x01, 0x09, 0x7f, 0x09, 0x01, 0x00,", - "ŧ": "0x14, 0x3e, 0x54, 0x40, 0x20, 0x00,", - "Ū": "0x3c, 0x41, 0x41, 0x41, 0x3c, 0x00,", - "ū": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", - "Ŭ": "0x3c, 0x41, 0x42, 0x41, 0x3c, 0x00,", - "ŭ": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", - "Ů": "0x3c, 0x40, 0x41, 0x40, 0x3c, 0x00,", - "ů": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", - "Ŵ": "0x3c, 0x42, 0x39, 0x42, 0x3c, 0x00,", - "ŵ": "0x3c, 0x42, 0x31, 0x42, 0x3c, 0x00,", - "Ŷ": "0x04, 0x0a, 0x71, 0x0a, 0x04, 0x00,", - "ŷ": "0x04, 0x4a, 0x31, 0x12, 0x0c, 0x00,", - "Ÿ": "0x04, 0x09, 0x70, 0x09, 0x04, 0x00,", - "Ź": "0x44, 0x64, 0x56, 0x4d, 0x44, 0x00,", - "ź": "0x44, 0x64, 0x56, 0x4d, 0x44, 0x00,", - "Ż": "0x44, 0x64, 0x55, 0x4c, 0x44, 0x00,", - "ż": "0x44, 0x64, 0x55, 0x4c, 0x44, 0x00,", - "Ž": "0x44, 0x65, 0x56, 0x4d, 0x44, 0x00,", - "ž": "0x44, 0x65, 0x56, 0x4d, 0x44, 0x00,", - "ſ": "0x00, 0x04, 0x7e, 0x01, 0x01, 0x00,", } return font + + +@functools.lru_cache(maxsize=None) +def get_font_map(): + return { + **get_font_map_ascii_basic(), + **get_font_map_latin_extended(), + **get_font_map_cyrillic(), + } + + +@functools.lru_cache(maxsize=None) +def get_small_font_map(): + return { + **get_small_font_map_ascii_basic(), + **get_small_font_map_latin_extended(), + **get_small_font_map_cyrillic(), + } From e601b762b056ae6f2a24a9d69e7cddc8106175c3 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Thu, 15 Apr 2021 14:32:09 +0800 Subject: [PATCH 12/19] Change font table in Python to use bytes literals --- Translations/font_tables.py | 1637 +++++++++++++------------ Translations/make_translation.py | 41 +- Translations/make_translation_test.py | 6 + 3 files changed, 848 insertions(+), 836 deletions(-) diff --git a/Translations/font_tables.py b/Translations/font_tables.py index a66aee13..4d2068d0 100755 --- a/Translations/font_tables.py +++ b/Translations/font_tables.py @@ -1,862 +1,863 @@ import functools +from typing import Dict -def get_font_map_ascii_basic(): +def get_font_map_ascii_basic() -> Dict[str, bytes]: font = { # U+0000..U+007F Basic Latin - " ": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "!": "0x00,0x00,0x00,0x00,0x7C,0xFF,0xFF,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x00,0x00,0x00,0x00,0x00,", - '"': "0x00,0x00,0x00,0x3C,0x3C,0x00,0x00,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "#": "0x00,0x00,0x10,0x90,0xF0,0x7E,0x1E,0x90,0xF0,0x7E,0x1E,0x10,0x00,0x02,0x1E,0x1F,0x03,0x02,0x1E,0x1F,0x03,0x02,0x00,0x00,", - "$": "0x00,0x00,0x78,0xFC,0xCC,0xFF,0xFF,0xCC,0xCC,0x88,0x00,0x00,0x00,0x00,0x04,0x0C,0x0C,0x3F,0x3F,0x0C,0x0F,0x07,0x00,0x00,", - "%": "0x00,0x00,0x38,0x38,0x38,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x00,0x30,0x38,0x1C,0x0E,0x07,0x03,0x01,0x38,0x38,0x38,0x00,", - "&": "0x00,0x00,0x00,0xB8,0xFC,0xC6,0xE2,0x3E,0x1C,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x31,0x21,0x37,0x1E,0x1C,0x36,0x22,0x00,", - "'": "0x00,0x00,0x00,0x00,0x27,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "(": "0x00,0x00,0x00,0xF0,0xFC,0xFE,0x07,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x1F,0x38,0x20,0x20,0x00,0x00,0x00,", - ")": "0x00,0x00,0x00,0x01,0x01,0x07,0xFE,0xFC,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x38,0x1F,0x0F,0x03,0x00,0x00,0x00,", - "*": "0x00,0x00,0x98,0xB8,0xE0,0xF8,0xF8,0xE0,0xB8,0x98,0x00,0x00,0x00,0x00,0x0C,0x0E,0x03,0x0F,0x0F,0x03,0x0E,0x0C,0x00,0x00,", - "+": "0x00,0x00,0x80,0x80,0x80,0xF0,0xF0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0F,0x0F,0x01,0x01,0x01,0x00,0x00,", - ",": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB8,0xF8,0x78,0x00,0x00,0x00,0x00,0x00,", - "-": "0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,", - ".": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,", - "/": "0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x00,0x18,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,", - "0": "0x00,0xF8,0xFE,0x06,0x03,0x83,0xC3,0x63,0x33,0x1E,0xFE,0xF8,0x00,0x07,0x1F,0x1E,0x33,0x31,0x30,0x30,0x30,0x18,0x1F,0x07,", - "1": "0x00,0x00,0x00,0x0C,0x0C,0x0E,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x3F,0x3F,0x30,0x30,0x30,0x00,", - "2": "0x00,0x1C,0x1E,0x07,0x03,0x03,0x83,0xC3,0xE3,0x77,0x3E,0x1C,0x00,0x30,0x38,0x3C,0x3E,0x37,0x33,0x31,0x30,0x30,0x30,0x30,", - "3": "0x00,0x0C,0x0E,0x07,0xC3,0xC3,0xC3,0xC3,0xC3,0xE7,0x7E,0x3C,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0E,", - "4": "0x00,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0xFF,0xFF,0x00,0x00,0x00,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x03,0x03,", - "5": "0x00,0x3F,0x7F,0x63,0x63,0x63,0x63,0x63,0x63,0xE3,0xC3,0x83,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,", - "6": "0x00,0xC0,0xF0,0xF8,0xDC,0xCE,0xC7,0xC3,0xC3,0xC3,0x80,0x00,0x00,0x0F,0x1F,0x39,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,", - "7": "0x00,0x03,0x03,0x03,0x03,0x03,0x03,0xC3,0xF3,0x3F,0x0F,0x03,0x00,0x00,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00,", - "8": "0x00,0x00,0xBC,0xFE,0xE7,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x0F,0x1F,0x39,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,", - "9": "0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xFC,0x00,0x00,0x00,0x30,0x30,0x30,0x38,0x1C,0x0E,0x07,0x03,0x00,", - ":": "0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00,", - ";": "0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9C,0xFC,0x7C,0x00,0x00,0x00,0x00,0x00,", - "<": "0x00,0x00,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,0x00,", - "=": "0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x00,", - ">": "0x00,0x00,0x03,0x07,0x0E,0x1C,0x38,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x30,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,", - "?": "0x00,0x1C,0x1E,0x07,0x03,0x83,0xC3,0xE3,0x77,0x3E,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x37,0x00,0x00,0x00,0x00,0x00,", - "@": "0x00,0xF8,0xFE,0x07,0xF3,0xFB,0x1B,0xFB,0xFB,0x07,0xFE,0xF8,0x00,0x0F,0x1F,0x18,0x33,0x37,0x36,0x37,0x37,0x36,0x03,0x01,", - "A": "0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", - "B": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "C": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "D": "0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "E": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "F": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "G": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC7,0xC6,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,", - "H": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "I": "0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "J": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x0E,0x1E,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "K": "0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,", - "L": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "M": "0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,", - "N": "0x00,0xFF,0xFF,0x0E,0x38,0xF0,0xC0,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x03,0x07,0x1C,0x3F,0x3F,0x00,", - "O": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "P": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,", - "Q": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x36,0x3E,0x1C,0x3F,0x33,0x00,", - "R": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x03,0x07,0x0F,0x1D,0x38,0x30,0x00,", - "S": "0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC7,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "T": "0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "U": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "V": "0x00,0x07,0x3F,0xF8,0xC0,0x00,0x00,0xC0,0xF8,0x3F,0x07,0x00,0x00,0x00,0x00,0x01,0x0F,0x3E,0x3E,0x0F,0x01,0x00,0x00,0x00,", - "W": "0x00,0xFF,0xFF,0x00,0x00,0x80,0x80,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x06,0x03,0x03,0x06,0x1C,0x3F,0x3F,0x00,", - "X": "0x00,0x03,0x0F,0x1C,0x30,0xE0,0xE0,0x30,0x1C,0x0F,0x03,0x00,0x00,0x30,0x3C,0x0E,0x03,0x01,0x01,0x03,0x0E,0x3C,0x30,0x00,", - "Y": "0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "Z": "0x00,0x03,0x03,0x03,0x03,0xC3,0xE3,0x33,0x1F,0x0F,0x03,0x00,0x00,0x30,0x3C,0x3E,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x00,", - "[": "0x00,0x00,0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x00,0x00,0x00,", - "\\": "0x00,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x18,", - "]": "0x00,0x00,0x00,0x03,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,0x00,0x00,", - "^": "0x00,0x60,0x70,0x38,0x1C,0x0E,0x07,0x0E,0x1C,0x38,0x70,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "_": "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,", - "`": "0x00,0x00,0x00,0x00,0x00,0x3E,0x7E,0x4E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "a": "0x00,0x00,0x40,0x60,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "b": "0x00,0xFF,0xFF,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "c": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,", - "d": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xE0,0xC0,0xFF,0xFF,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,", - "e": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,", - "f": "0x00,0xC0,0xC0,0xFC,0xFE,0xC7,0xC3,0xC3,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "g": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,", - "h": "0x00,0xFF,0xFF,0xC0,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,", - "i": "0x00,0x00,0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "j": "0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xE0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00,", - "k": "0x00,0x00,0xFF,0xFF,0x00,0x80,0xC0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x07,0x0F,0x1C,0x38,0x30,0x00,0x00,", - "l": "0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "m": "0x00,0xE0,0xC0,0xE0,0xE0,0xC0,0xC0,0xE0,0xE0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,", - "n": "0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "o": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "p": "0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x0C,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,", - "q": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x0C,0xFF,0xFF,0x00,", - "r": "0x00,0x00,0xE0,0xE0,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "s": "0x00,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,", - "t": "0x00,0x60,0x60,0xFE,0xFE,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x30,0x30,0x30,0x30,0x00,0x00,0x00,", - "u": "0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "v": "0x00,0x60,0xE0,0x80,0x00,0x00,0x00,0x00,0x80,0xE0,0x60,0x00,0x00,0x00,0x01,0x07,0x1E,0x38,0x38,0x1E,0x07,0x01,0x00,0x00,", - "w": "0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x07,0x1F,0x38,0x1C,0x0F,0x0F,0x1C,0x38,0x1F,0x07,0x00,", - "x": "0x00,0x60,0xE0,0xC0,0x80,0x00,0x80,0xC0,0xE0,0x60,0x00,0x00,0x00,0x30,0x38,0x1D,0x0F,0x07,0x0F,0x1D,0x38,0x30,0x00,0x00,", - "y": "0x00,0x00,0x60,0xE0,0x80,0x00,0x00,0x80,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,", - "z": "0x00,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x60,0x20,0x00,0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x30,0x00,0x00,", - "{": "0x00,0x00,0x80,0xC0,0xFC,0x7E,0x07,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x1F,0x3F,0x70,0x60,0x60,0x60,0x00,0x00,", - "|": "0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "}": "0x00,0x00,0x03,0x03,0x03,0x07,0x7E,0xFC,0xC0,0x80,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x70,0x3F,0x1F,0x01,0x00,0x00,0x00,", - "~": "0x00,0x10,0x18,0x0C,0x04,0x0C,0x18,0x10,0x18,0x0C,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", + " ": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "!": b"\x00\x00\x00\x00\x7C\xFF\xFF\x7C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x33\x00\x00\x00\x00\x00", + '"': b"\x00\x00\x00\x3C\x3C\x00\x00\x3C\x3C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "#": b"\x00\x00\x10\x90\xF0\x7E\x1E\x90\xF0\x7E\x1E\x10\x00\x02\x1E\x1F\x03\x02\x1E\x1F\x03\x02\x00\x00", + "$": b"\x00\x00\x78\xFC\xCC\xFF\xFF\xCC\xCC\x88\x00\x00\x00\x00\x04\x0C\x0C\x3F\x3F\x0C\x0F\x07\x00\x00", + "%": b"\x00\x00\x38\x38\x38\x00\x80\xC0\xE0\x70\x38\x1C\x00\x30\x38\x1C\x0E\x07\x03\x01\x38\x38\x38\x00", + "&": b"\x00\x00\x00\xB8\xFC\xC6\xE2\x3E\x1C\x00\x00\x00\x00\x00\x1F\x3F\x31\x21\x37\x1E\x1C\x36\x22\x00", + "'": b"\x00\x00\x00\x00\x27\x3F\x1F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "(": b"\x00\x00\x00\xF0\xFC\xFE\x07\x01\x01\x00\x00\x00\x00\x00\x00\x03\x0F\x1F\x38\x20\x20\x00\x00\x00", + ")": b"\x00\x00\x00\x01\x01\x07\xFE\xFC\xF0\x00\x00\x00\x00\x00\x00\x20\x20\x38\x1F\x0F\x03\x00\x00\x00", + "*": b"\x00\x00\x98\xB8\xE0\xF8\xF8\xE0\xB8\x98\x00\x00\x00\x00\x0C\x0E\x03\x0F\x0F\x03\x0E\x0C\x00\x00", + "+": b"\x00\x00\x80\x80\x80\xF0\xF0\x80\x80\x80\x00\x00\x00\x00\x01\x01\x01\x0F\x0F\x01\x01\x01\x00\x00", + ",": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xB8\xF8\x78\x00\x00\x00\x00\x00", + "-": b"\x00\x00\x80\x80\x80\x80\x80\x80\x80\x80\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00", + ".": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x38\x38\x38\x00\x00\x00\x00\x00", + "/": b"\x00\x00\x00\x00\x00\x80\xC0\xE0\x70\x38\x1C\x0E\x00\x18\x1C\x0E\x07\x03\x01\x00\x00\x00\x00\x00", + "0": b"\x00\xF8\xFE\x06\x03\x83\xC3\x63\x33\x1E\xFE\xF8\x00\x07\x1F\x1E\x33\x31\x30\x30\x30\x18\x1F\x07", + "1": b"\x00\x00\x00\x0C\x0C\x0E\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x30\x30\x30\x3F\x3F\x30\x30\x30\x00", + "2": b"\x00\x1C\x1E\x07\x03\x03\x83\xC3\xE3\x77\x3E\x1C\x00\x30\x38\x3C\x3E\x37\x33\x31\x30\x30\x30\x30", + "3": b"\x00\x0C\x0E\x07\xC3\xC3\xC3\xC3\xC3\xE7\x7E\x3C\x00\x0C\x1C\x38\x30\x30\x30\x30\x30\x39\x1F\x0E", + "4": b"\x00\xC0\xE0\x70\x38\x1C\x0E\x07\xFF\xFF\x00\x00\x00\x03\x03\x03\x03\x03\x03\x03\x3F\x3F\x03\x03", + "5": b"\x00\x3F\x7F\x63\x63\x63\x63\x63\x63\xE3\xC3\x83\x00\x0C\x1C\x38\x30\x30\x30\x30\x30\x38\x1F\x0F", + "6": b"\x00\xC0\xF0\xF8\xDC\xCE\xC7\xC3\xC3\xC3\x80\x00\x00\x0F\x1F\x39\x30\x30\x30\x30\x30\x39\x1F\x0F", + "7": b"\x00\x03\x03\x03\x03\x03\x03\xC3\xF3\x3F\x0F\x03\x00\x00\x00\x00\x30\x3C\x0F\x03\x00\x00\x00\x00", + "8": b"\x00\x00\xBC\xFE\xE7\xC3\xC3\xC3\xE7\xFE\xBC\x00\x00\x0F\x1F\x39\x30\x30\x30\x30\x30\x39\x1F\x0F", + "9": b"\x00\x3C\x7E\xE7\xC3\xC3\xC3\xC3\xC3\xE7\xFE\xFC\x00\x00\x00\x30\x30\x30\x38\x1C\x0E\x07\x03\x00", + ":": b"\x00\x00\x00\x00\x70\x70\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1C\x1C\x1C\x00\x00\x00\x00\x00", + ";": b"\x00\x00\x00\x00\x70\x70\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9C\xFC\x7C\x00\x00\x00\x00\x00", + "<": b"\x00\x00\xC0\xE0\xF0\x38\x1C\x0E\x07\x03\x00\x00\x00\x00\x00\x01\x03\x07\x0E\x1C\x38\x30\x00\x00", + "=": b"\x00\x00\x60\x60\x60\x60\x60\x60\x60\x60\x60\x00\x00\x00\x06\x06\x06\x06\x06\x06\x06\x06\x06\x00", + ">": b"\x00\x00\x03\x07\x0E\x1C\x38\xF0\xE0\xC0\x00\x00\x00\x00\x30\x38\x1C\x0E\x07\x03\x01\x00\x00\x00", + "?": b"\x00\x1C\x1E\x07\x03\x83\xC3\xE3\x77\x3E\x1C\x00\x00\x00\x00\x00\x00\x37\x37\x00\x00\x00\x00\x00", + "@": b"\x00\xF8\xFE\x07\xF3\xFB\x1B\xFB\xFB\x07\xFE\xF8\x00\x0F\x1F\x18\x33\x37\x36\x37\x37\x36\x03\x01", + "A": b"\x00\x00\x00\xE0\xFC\x1F\x1F\xFC\xE0\x00\x00\x00\x00\x38\x3F\x07\x06\x06\x06\x06\x07\x3F\x38\x00", + "B": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xE7\xFE\xBC\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x39\x1F\x0F\x00", + "C": b"\x00\xF0\xFC\x0E\x07\x03\x03\x03\x07\x0E\x0C\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "D": b"\x00\xFF\xFF\x03\x03\x03\x03\x07\x0E\xFC\xF0\x00\x00\x3F\x3F\x30\x30\x30\x30\x38\x1C\x0F\x03\x00", + "E": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xC3\xC3\x03\x03\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "F": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xC3\xC3\x03\x03\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "G": b"\x00\xF0\xFC\x0E\x07\x03\xC3\xC3\xC3\xC7\xC6\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x30\x3F\x3F\x00", + "H": b"\x00\xFF\xFF\xC0\xC0\xC0\xC0\xC0\xC0\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "I": b"\x00\x00\x00\x03\x03\xFF\xFF\x03\x03\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "J": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x0E\x1E\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "K": b"\x00\xFF\xFF\xC0\xE0\xF0\x38\x1C\x0E\x07\x03\x00\x00\x3F\x3F\x00\x01\x03\x07\x0E\x1C\x38\x30\x00", + "L": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "M": b"\x00\xFF\xFF\x1E\x78\xE0\xE0\x78\x1E\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x01\x01\x00\x00\x3F\x3F\x00", + "N": b"\x00\xFF\xFF\x0E\x38\xF0\xC0\x00\x00\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x03\x07\x1C\x3F\x3F\x00", + "O": b"\x00\xF0\xFC\x0E\x07\x03\x03\x07\x0E\xFC\xF0\x00\x00\x03\x0F\x1C\x38\x30\x30\x38\x1C\x0F\x03\x00", + "P": b"\x00\xFF\xFF\x83\x83\x83\x83\x83\xC7\xFE\x7C\x00\x00\x3F\x3F\x01\x01\x01\x01\x01\x01\x00\x00\x00", + "Q": b"\x00\xF0\xFC\x0E\x07\x03\x03\x07\x0E\xFC\xF0\x00\x00\x03\x0F\x1C\x38\x30\x36\x3E\x1C\x3F\x33\x00", + "R": b"\x00\xFF\xFF\x83\x83\x83\x83\x83\xC7\xFE\x7C\x00\x00\x3F\x3F\x01\x01\x03\x07\x0F\x1D\x38\x30\x00", + "S": b"\x00\x3C\x7E\xE7\xC3\xC3\xC3\xC3\xC7\x8E\x0C\x00\x00\x0C\x1C\x38\x30\x30\x30\x30\x39\x1F\x0F\x00", + "T": b"\x00\x00\x03\x03\x03\xFF\xFF\x03\x03\x03\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "U": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "V": b"\x00\x07\x3F\xF8\xC0\x00\x00\xC0\xF8\x3F\x07\x00\x00\x00\x00\x01\x0F\x3E\x3E\x0F\x01\x00\x00\x00", + "W": b"\x00\xFF\xFF\x00\x00\x80\x80\x00\x00\xFF\xFF\x00\x00\x3F\x3F\x1C\x06\x03\x03\x06\x1C\x3F\x3F\x00", + "X": b"\x00\x03\x0F\x1C\x30\xE0\xE0\x30\x1C\x0F\x03\x00\x00\x30\x3C\x0E\x03\x01\x01\x03\x0E\x3C\x30\x00", + "Y": b"\x00\x03\x0F\x3C\xF0\xC0\xC0\xF0\x3C\x0F\x03\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "Z": b"\x00\x03\x03\x03\x03\xC3\xE3\x33\x1F\x0F\x03\x00\x00\x30\x3C\x3E\x33\x31\x30\x30\x30\x30\x30\x00", + "[": b"\x00\x00\x00\xFF\xFF\x03\x03\x03\x03\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x00\x00\x00", + "\\": b"\x00\x0E\x1C\x38\x70\xE0\xC0\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x07\x0E\x1C\x18", + "]": b"\x00\x00\x00\x03\x03\x03\x03\xFF\xFF\x00\x00\x00\x00\x00\x00\x30\x30\x30\x30\x3F\x3F\x00\x00\x00", + "^": b"\x00\x60\x70\x38\x1C\x0E\x07\x0E\x1C\x38\x70\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "_": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0", + "`": b"\x00\x00\x00\x00\x00\x3E\x7E\x4E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "a": b"\x00\x00\x40\x60\x60\x60\x60\x60\x60\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "b": b"\x00\xFF\xFF\xC0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x38\x1F\x0F\x00", + "c": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\x60\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x18\x08\x00", + "d": b"\x00\x80\xC0\xE0\x60\x60\x60\xE0\xC0\xFF\xFF\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x3F\x3F\x00", + "e": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\x60\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x01\x00", + "f": b"\x00\xC0\xC0\xFC\xFE\xC7\xC3\xC3\x03\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00", + "g": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\x60\xE0\xE0\x00\x00\x03\xC7\xCE\xCC\xCC\xCC\xCC\xE6\x7F\x3F\x00", + "h": b"\x00\xFF\xFF\xC0\x60\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00\x00", + "i": b"\x00\x00\x00\x00\x60\xEC\xEC\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "j": b"\x00\x00\x00\x00\x00\x00\x60\xEC\xEC\x00\x00\x00\x00\x00\x00\x60\xE0\xC0\xC0\xFF\x7F\x00\x00\x00", + "k": b"\x00\x00\xFF\xFF\x00\x80\xC0\xE0\x60\x00\x00\x00\x00\x00\x3F\x3F\x03\x07\x0F\x1C\x38\x30\x00\x00", + "l": b"\x00\x00\x00\x00\x03\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "m": b"\x00\xE0\xC0\xE0\xE0\xC0\xC0\xE0\xE0\xC0\x80\x00\x00\x3F\x3F\x00\x00\x3F\x3F\x00\x00\x3F\x3F\x00", + "n": b"\x00\x00\xE0\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "o": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "p": b"\x00\xE0\xE0\x60\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\xFF\xFF\x0C\x18\x18\x18\x18\x1C\x0F\x07\x00", + "q": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\x60\xE0\xE0\x00\x00\x07\x0F\x1C\x18\x18\x18\x18\x0C\xFF\xFF\x00", + "r": b"\x00\x00\xE0\xE0\xC0\x60\x60\x60\x60\xE0\xC0\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00", + "s": b"\x00\xC0\xE0\x60\x60\x60\x60\x60\x40\x00\x00\x00\x00\x11\x33\x33\x33\x33\x33\x3F\x1E\x00\x00\x00", + "t": b"\x00\x60\x60\xFE\xFE\x60\x60\x60\x00\x00\x00\x00\x00\x00\x00\x1F\x3F\x30\x30\x30\x30\x00\x00\x00", + "u": b"\x00\xE0\xE0\x00\x00\x00\x00\x00\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "v": b"\x00\x60\xE0\x80\x00\x00\x00\x00\x80\xE0\x60\x00\x00\x00\x01\x07\x1E\x38\x38\x1E\x07\x01\x00\x00", + "w": b"\x00\xE0\xE0\x00\x00\xE0\xE0\x00\x00\xE0\xE0\x00\x00\x07\x1F\x38\x1C\x0F\x0F\x1C\x38\x1F\x07\x00", + "x": b"\x00\x60\xE0\xC0\x80\x00\x80\xC0\xE0\x60\x00\x00\x00\x30\x38\x1D\x0F\x07\x0F\x1D\x38\x30\x00\x00", + "y": b"\x00\x00\x60\xE0\x80\x00\x00\x80\xE0\x60\x00\x00\x00\x00\x00\x81\xE7\x7E\x1E\x07\x01\x00\x00\x00", + "z": b"\x00\x60\x60\x60\x60\x60\xE0\xE0\x60\x20\x00\x00\x00\x30\x38\x3C\x36\x33\x31\x30\x30\x30\x00\x00", + "{": b"\x00\x00\x80\xC0\xFC\x7E\x07\x03\x03\x03\x00\x00\x00\x00\x00\x01\x1F\x3F\x70\x60\x60\x60\x00\x00", + "|": b"\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "}": b"\x00\x00\x03\x03\x03\x07\x7E\xFC\xC0\x80\x00\x00\x00\x00\x60\x60\x60\x70\x3F\x1F\x01\x00\x00\x00", + "~": b"\x00\x10\x18\x0C\x04\x0C\x18\x10\x18\x0C\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", } return font -def get_font_map_latin_extended(): +def get_font_map_latin_extended() -> Dict[str, bytes]: font = { # U+0080..U+00FF Latin-1 Supplement - "¡": "0x00,0x00,0x00,0x00,0x80,0xF3,0xF3,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x3F,0x3F,0x0F,0x00,0x00,0x00,0x00,", - "¢": "0x00,0x00,0xE0,0xF0,0x38,0xFE,0xFE,0x18,0x38,0x30,0x00,0x00,0x00,0x00,0x03,0x07,0x0E,0x3F,0x3F,0x0C,0x0E,0x06,0x00,0x00,", - "£": "0x00,0x00,0x00,0x80,0xF8,0xFC,0x8C,0x8C,0x1C,0x18,0x00,0x00,0x00,0x00,0x18,0x1C,0x1F,0x0B,0x18,0x18,0x18,0x18,0x08,0x00,", - "¤": "0x00,0xF6,0xFE,0x18,0x0C,0x0C,0x0C,0x0C,0x18,0xFE,0xF6,0x00,0x00,0x1B,0x1F,0x06,0x0C,0x0C,0x0C,0x0C,0x06,0x1F,0x1B,0x00,", - "¥": "0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x00,0x0A,0x0A,0x0A,0x3F,0x3F,0x0A,0x0A,0x0A,0x00,0x00,", - "¦": "0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "§": "0x00,0x00,0xDC,0xFE,0x22,0x22,0x22,0x22,0xE6,0xC4,0x00,0x00,0x00,0x00,0x08,0x19,0x11,0x11,0x11,0x11,0x1F,0x0E,0x00,0x00,", - "¨": "0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "©": "0x00,0xF0,0xF8,0x1C,0xCC,0xEC,0x2C,0x6C,0x4C,0x1C,0xF8,0xF0,0x00,0x07,0x0F,0x1C,0x19,0x1B,0x1A,0x1B,0x19,0x1C,0x0F,0x07,", - "«": "0x00,0x80,0xC0,0x60,0x20,0x00,0x80,0xC0,0x60,0x20,0x00,0x00,0x00,0x00,0x01,0x03,0x02,0x00,0x00,0x01,0x03,0x02,0x00,0x00,", - "¬": "0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,", - "®": "0x00,0xF0,0xF8,0x1C,0xEC,0xEC,0xAC,0xEC,0x4C,0x1C,0xF8,0xF0,0x00,0x07,0x0F,0x1C,0x1B,0x1B,0x18,0x1B,0x1B,0x1C,0x0F,0x07,", - "¯": "0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "°": "0x00,0x00,0x00,0x1E,0x3F,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "±": "0x00,0x00,0x00,0xC0,0xC0,0xF0,0xF0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x1B,0x1B,0x18,0x18,0x00,0x00,0x00,", - "²": "0x00,0x00,0x19,0x1D,0x15,0x17,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "³": "0x00,0x00,0x11,0x15,0x15,0x1F,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "´": "0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "µ": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0xFF,0xFF,0x0E,0x0C,0x0C,0x0C,0x06,0x0F,0x0F,0x00,0x00,", - "¶": "0x00,0x38,0x7C,0xC6,0x82,0xFE,0xFE,0x02,0xFE,0xFE,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x3F,0x3F,0x00,0x00,", - "¹": "0x00,0x00,0x12,0x1F,0x1F,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "»": "0x00,0x20,0x60,0xC0,0x80,0x00,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x00,0x02,0x03,0x01,0x00,0x00,0x00,", - "¼": "0x00,0x48,0x7C,0x7C,0x40,0x80,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x06,0x07,0x04,0x1F,0x1F,0x00,", - "½": "0x00,0x48,0x7C,0x7C,0x40,0x80,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00,0x19,0x1D,0x17,0x12,0x00,", - "¾": "0x00,0x44,0x54,0x7C,0x28,0x80,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x06,0x07,0x04,0x1F,0x1F,0x00,", - "¿": "0x00,0x00,0x00,0x80,0xC0,0xFB,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x1F,0x3B,0x31,0x30,0x30,0x30,0x38,0x1E,0x0E,0x00,", - "À": "0x00,0x00,0x00,0x80,0xE1,0x7B,0x7E,0xE4,0x80,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Á": "0x00,0x00,0x00,0x80,0xE4,0x7E,0x7B,0xE1,0x80,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Â": "0x00,0x00,0x00,0x84,0xE6,0x7B,0x7B,0xE6,0x84,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Ã": "0x00,0x00,0x00,0x82,0xE3,0x79,0x7B,0xE2,0x83,0x01,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Ä": "0x00,0x00,0x00,0x83,0xE3,0x78,0x78,0xE3,0x83,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Å": "0x00,0x00,0x00,0x80,0xE2,0x75,0x75,0xE2,0x80,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,", - "Æ": "0x00,0x00,0x80,0xF0,0x7C,0x1F,0xFF,0xFF,0xC3,0xC3,0x03,0x00,0x00,0x3C,0x3F,0x07,0x06,0x06,0x3F,0x3F,0x30,0x30,0x30,0x00,", - "Ç": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x1E,0x1C,0x00,0x00,0x01,0x07,0xCE,0xDC,0xF8,0xF8,0x18,0x1C,0x0E,0x06,0x00,", - "È": "0x00,0xF8,0xF8,0x99,0x9B,0x9E,0x9C,0x98,0x98,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "É": "0x00,0xF8,0xF8,0x98,0x98,0x9C,0x9E,0x9B,0x99,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "Ê": "0x00,0xF8,0xF8,0x9C,0x9E,0x9B,0x9B,0x9E,0x9C,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "Ë": "0x00,0xF8,0xF8,0x9B,0x9B,0x98,0x98,0x9B,0x9B,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "Ì": "0x00,0x00,0x00,0x19,0x1B,0xFE,0xFC,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Í": "0x00,0x00,0x00,0x18,0x18,0xFC,0xFE,0x1B,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Î": "0x00,0x00,0x00,0x1C,0x1E,0xFB,0xFB,0x1E,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ï": "0x00,0x00,0x00,0x1B,0x1B,0xF8,0xF8,0x1B,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ð": "0x00,0xC0,0xFF,0xFF,0xC3,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "Ñ": "0x00,0xF8,0xF8,0x72,0xE3,0xC1,0x83,0x02,0x03,0xF9,0xF8,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x03,0x07,0x0E,0x3F,0x3F,0x00,", - "Ò": "0x00,0xE0,0xF0,0x39,0x1B,0x1E,0x1C,0x18,0x38,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Ó": "0x00,0xE0,0xF0,0x38,0x18,0x1C,0x1E,0x1B,0x39,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Ô": "0x00,0xE0,0xF0,0x3C,0x1E,0x1B,0x1B,0x1E,0x3C,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Õ": "0x00,0xE0,0xF0,0x3A,0x1B,0x19,0x1B,0x1A,0x3B,0xF1,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Ö": "0x00,0xE0,0xF0,0x3B,0x1B,0x18,0x18,0x1B,0x3B,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "×": "0x00,0xF0,0xF8,0x1C,0x0C,0x8C,0xEC,0x7C,0x18,0xFC,0xF4,0x00,0x00,0x2F,0x3F,0x18,0x3E,0x37,0x31,0x30,0x38,0x1F,0x0F,0x00,", - "Ù": "0x00,0xF8,0xF8,0x01,0x03,0x06,0x04,0x00,0x00,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "Ú": "0x00,0xF8,0xF8,0x00,0x00,0x04,0x06,0x03,0x01,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "Û": "0x00,0xF8,0xF8,0x04,0x06,0x03,0x03,0x06,0x04,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "Ü": "0x00,0xF8,0xF8,0x03,0x03,0x00,0x00,0x03,0x03,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "Ý": "0x00,0x08,0x18,0x30,0x60,0xC4,0xC6,0x63,0x31,0x18,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "ß": "0x00,0x00,0xC0,0xE0,0x30,0x10,0x10,0x30,0xE0,0xC0,0x00,0x00,0x00,0x00,0xFF,0xFF,0x21,0x21,0x21,0x33,0x3F,0x1E,0x00,0x00,", - "à": "0x00,0x00,0x40,0x60,0x62,0x66,0x6C,0x68,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "á": "0x00,0x00,0x40,0x60,0x68,0x6C,0x66,0x62,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "â": "0x00,0x00,0x40,0x68,0x6C,0x66,0x66,0x6C,0x68,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "ã": "0x00,0x00,0x40,0x68,0x6C,0x64,0x6C,0x68,0x6C,0xE4,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "ä": "0x00,0x00,0x40,0x6C,0x6C,0x60,0x60,0x6C,0x6C,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "å": "0x00,0x00,0x40,0x60,0x64,0x6A,0x6A,0x64,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "æ": "0x00,0x80,0xC0,0x40,0x40,0xC0,0x80,0x40,0x40,0xC0,0x80,0x00,0x00,0x1C,0x3E,0x22,0x22,0x1F,0x3F,0x22,0x22,0x33,0x11,0x00,", - "ç": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0xB8,0xB0,0xF0,0xF0,0x30,0x38,0x18,0x08,0x00,", - "è": "0x00,0x80,0xC0,0xE0,0x62,0x66,0x6C,0x68,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x33,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,", - "é": "0x00,0x80,0xC0,0xE0,0x60,0x68,0x6C,0x66,0x62,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,", - "ê": "0x00,0x80,0xC0,0xE8,0x6C,0x66,0x66,0x6C,0x68,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x33,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,", - "ë": "0x00,0x80,0xC0,0xEC,0x6C,0x60,0x60,0x6C,0x6C,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x33,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,", - "ì": "0x00,0x00,0x00,0x00,0x62,0xE6,0xEC,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "í": "0x00,0x00,0x00,0x00,0x68,0xEC,0xE6,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "î": "0x00,0x00,0x00,0x08,0x6C,0xE6,0xE6,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ï": "0x00,0x00,0x00,0x0C,0x6C,0xE0,0xEC,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ñ": "0x00,0x00,0xE0,0xE8,0x6C,0x64,0x6C,0x68,0xEC,0xC4,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "ò": "0x00,0x80,0xC0,0xE0,0x62,0x66,0x6C,0x68,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "ó": "0x00,0x80,0xC0,0xE0,0x68,0x6C,0x66,0x62,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "ô": "0x00,0x80,0xC0,0xE8,0x6C,0x66,0x66,0x6C,0xE8,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "õ": "0x00,0x80,0xC8,0xEC,0x64,0x6C,0x68,0x6C,0xE4,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "ö": "0x00,0x80,0xC0,0xEC,0x6C,0x60,0x60,0x6C,0xEC,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "÷": "0x00,0x00,0x80,0x80,0x80,0xB0,0xB0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0D,0x0D,0x01,0x01,0x01,0x00,0x00,", - "ø": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xE0,0xC0,0xE0,0xA0,0x00,0x00,0x2F,0x3F,0x18,0x3C,0x36,0x33,0x31,0x38,0x1F,0x0F,0x00,", - "ù": "0x00,0xE0,0xE0,0x00,0x02,0x06,0x0C,0x08,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "ú": "0x00,0xE0,0xE0,0x00,0x08,0x0C,0x06,0x02,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "û": "0x00,0xE0,0xE0,0x08,0x0C,0x06,0x06,0x0C,0x08,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "ü": "0x00,0xE0,0xE0,0x0C,0x0C,0x00,0x00,0x0C,0x0C,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "ý": "0x00,0x00,0x60,0xE0,0x80,0x10,0x18,0x8C,0xE4,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,", - "þ": "0x00,0x00,0x03,0xFF,0xFF,0x1B,0x18,0x18,0xF8,0xF0,0x00,0x00,0x00,0x00,0x30,0x3F,0x3F,0x36,0x06,0x06,0x07,0x03,0x00,0x00,", - "ÿ": "0x00,0x00,0x60,0xEC,0x8C,0x00,0x00,0x8C,0xEC,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,", + "¡": b"\x00\x00\x00\x00\x80\xF3\xF3\x80\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x3F\x3F\x0F\x00\x00\x00\x00", + "¢": b"\x00\x00\xE0\xF0\x38\xFE\xFE\x18\x38\x30\x00\x00\x00\x00\x03\x07\x0E\x3F\x3F\x0C\x0E\x06\x00\x00", + "£": b"\x00\x00\x00\x80\xF8\xFC\x8C\x8C\x1C\x18\x00\x00\x00\x00\x18\x1C\x1F\x0B\x18\x18\x18\x18\x08\x00", + "¤": b"\x00\xF6\xFE\x18\x0C\x0C\x0C\x0C\x18\xFE\xF6\x00\x00\x1B\x1F\x06\x0C\x0C\x0C\x0C\x06\x1F\x1B\x00", + "¥": b"\x00\x03\x0F\x3C\xF0\xC0\xC0\xF0\x3C\x0F\x03\x00\x00\x00\x0A\x0A\x0A\x3F\x3F\x0A\x0A\x0A\x00\x00", + "¦": b"\x00\x00\x00\x00\x00\x1F\x1F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "§": b"\x00\x00\xDC\xFE\x22\x22\x22\x22\xE6\xC4\x00\x00\x00\x00\x08\x19\x11\x11\x11\x11\x1F\x0E\x00\x00", + "¨": b"\x00\x00\x00\x03\x03\x00\x00\x03\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "©": b"\x00\xF0\xF8\x1C\xCC\xEC\x2C\x6C\x4C\x1C\xF8\xF0\x00\x07\x0F\x1C\x19\x1B\x1A\x1B\x19\x1C\x0F\x07", + "«": b"\x00\x80\xC0\x60\x20\x00\x80\xC0\x60\x20\x00\x00\x00\x00\x01\x03\x02\x00\x00\x01\x03\x02\x00\x00", + "¬": b"\x18\x18\x18\x18\x18\x18\x18\x18\x18\xF8\xF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x03\x00", + "®": b"\x00\xF0\xF8\x1C\xEC\xEC\xAC\xEC\x4C\x1C\xF8\xF0\x00\x07\x0F\x1C\x1B\x1B\x18\x1B\x1B\x1C\x0F\x07", + "¯": b"\x00\x00\x00\x00\x00\x0C\x0C\x0C\x0C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "°": b"\x00\x00\x00\x1E\x3F\x33\x33\x3F\x1E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "±": b"\x00\x00\x00\xC0\xC0\xF0\xF0\xC0\xC0\x00\x00\x00\x00\x00\x00\x18\x18\x1B\x1B\x18\x18\x00\x00\x00", + "²": b"\x00\x00\x19\x1D\x15\x17\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "³": b"\x00\x00\x11\x15\x15\x1F\x0A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "´": b"\x00\x00\x00\x00\x04\x06\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "µ": b"\x00\xF0\xF0\x00\x00\x00\x00\x00\xF0\xF0\x00\x00\x00\xFF\xFF\x0E\x0C\x0C\x0C\x06\x0F\x0F\x00\x00", + "¶": b"\x00\x38\x7C\xC6\x82\xFE\xFE\x02\xFE\xFE\x02\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x3F\x3F\x00\x00", + "¹": b"\x00\x00\x12\x1F\x1F\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "»": b"\x00\x20\x60\xC0\x80\x00\x20\x60\xC0\x80\x00\x00\x00\x02\x03\x01\x00\x00\x02\x03\x01\x00\x00\x00", + "¼": b"\x00\x48\x7C\x7C\x40\x80\xC0\x60\x30\x10\x00\x00\x00\x00\x04\x06\x03\x01\x06\x07\x04\x1F\x1F\x00", + "½": b"\x00\x48\x7C\x7C\x40\x80\xC0\x60\x30\x10\x00\x00\x00\x00\x04\x06\x03\x01\x00\x19\x1D\x17\x12\x00", + "¾": b"\x00\x44\x54\x7C\x28\x80\xC0\x60\x30\x10\x00\x00\x00\x00\x04\x06\x03\x01\x06\x07\x04\x1F\x1F\x00", + "¿": b"\x00\x00\x00\x80\xC0\xFB\x7B\x00\x00\x00\x00\x00\x00\x0E\x1F\x3B\x31\x30\x30\x30\x38\x1E\x0E\x00", + "À": b"\x00\x00\x00\x80\xE1\x7B\x7E\xE4\x80\x00\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Á": b"\x00\x00\x00\x80\xE4\x7E\x7B\xE1\x80\x00\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Â": b"\x00\x00\x00\x84\xE6\x7B\x7B\xE6\x84\x00\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Ã": b"\x00\x00\x00\x82\xE3\x79\x7B\xE2\x83\x01\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Ä": b"\x00\x00\x00\x83\xE3\x78\x78\xE3\x83\x00\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Å": b"\x00\x00\x00\x80\xE2\x75\x75\xE2\x80\x00\x00\x00\x00\x38\x3E\x0F\x0D\x0C\x0C\x0D\x0F\x3E\x38\x00", + "Æ": b"\x00\x00\x80\xF0\x7C\x1F\xFF\xFF\xC3\xC3\x03\x00\x00\x3C\x3F\x07\x06\x06\x3F\x3F\x30\x30\x30\x00", + "Ç": b"\x00\xF0\xFC\x0E\x07\x03\x03\x03\x07\x1E\x1C\x00\x00\x01\x07\xCE\xDC\xF8\xF8\x18\x1C\x0E\x06\x00", + "È": b"\x00\xF8\xF8\x99\x9B\x9E\x9C\x98\x98\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "É": b"\x00\xF8\xF8\x98\x98\x9C\x9E\x9B\x99\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "Ê": b"\x00\xF8\xF8\x9C\x9E\x9B\x9B\x9E\x9C\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "Ë": b"\x00\xF8\xF8\x9B\x9B\x98\x98\x9B\x9B\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "Ì": b"\x00\x00\x00\x19\x1B\xFE\xFC\x18\x18\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Í": b"\x00\x00\x00\x18\x18\xFC\xFE\x1B\x19\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Î": b"\x00\x00\x00\x1C\x1E\xFB\xFB\x1E\x1C\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ï": b"\x00\x00\x00\x1B\x1B\xF8\xF8\x1B\x1B\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ð": b"\x00\xC0\xFF\xFF\xC3\x03\x03\x07\x0E\xFC\xF0\x00\x00\x00\x3F\x3F\x30\x30\x30\x38\x1C\x0F\x03\x00", + "Ñ": b"\x00\xF8\xF8\x72\xE3\xC1\x83\x02\x03\xF9\xF8\x00\x00\x3F\x3F\x00\x00\x01\x03\x07\x0E\x3F\x3F\x00", + "Ò": b"\x00\xE0\xF0\x39\x1B\x1E\x1C\x18\x38\xF0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Ó": b"\x00\xE0\xF0\x38\x18\x1C\x1E\x1B\x39\xF0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Ô": b"\x00\xE0\xF0\x3C\x1E\x1B\x1B\x1E\x3C\xF0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Õ": b"\x00\xE0\xF0\x3A\x1B\x19\x1B\x1A\x3B\xF1\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Ö": b"\x00\xE0\xF0\x3B\x1B\x18\x18\x1B\x3B\xF0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "×": b"\x00\xF0\xF8\x1C\x0C\x8C\xEC\x7C\x18\xFC\xF4\x00\x00\x2F\x3F\x18\x3E\x37\x31\x30\x38\x1F\x0F\x00", + "Ù": b"\x00\xF8\xF8\x01\x03\x06\x04\x00\x00\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "Ú": b"\x00\xF8\xF8\x00\x00\x04\x06\x03\x01\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "Û": b"\x00\xF8\xF8\x04\x06\x03\x03\x06\x04\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "Ü": b"\x00\xF8\xF8\x03\x03\x00\x00\x03\x03\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "Ý": b"\x00\x08\x18\x30\x60\xC4\xC6\x63\x31\x18\x08\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "ß": b"\x00\x00\xC0\xE0\x30\x10\x10\x30\xE0\xC0\x00\x00\x00\x00\xFF\xFF\x21\x21\x21\x33\x3F\x1E\x00\x00", + "à": b"\x00\x00\x40\x60\x62\x66\x6C\x68\x60\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "á": b"\x00\x00\x40\x60\x68\x6C\x66\x62\x60\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "â": b"\x00\x00\x40\x68\x6C\x66\x66\x6C\x68\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "ã": b"\x00\x00\x40\x68\x6C\x64\x6C\x68\x6C\xE4\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "ä": b"\x00\x00\x40\x6C\x6C\x60\x60\x6C\x6C\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "å": b"\x00\x00\x40\x60\x64\x6A\x6A\x64\x60\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "æ": b"\x00\x80\xC0\x40\x40\xC0\x80\x40\x40\xC0\x80\x00\x00\x1C\x3E\x22\x22\x1F\x3F\x22\x22\x33\x11\x00", + "ç": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x0F\x1F\xB8\xB0\xF0\xF0\x30\x38\x18\x08\x00", + "è": b"\x00\x80\xC0\xE0\x62\x66\x6C\x68\x60\xC0\x80\x00\x00\x0F\x1F\x33\x33\x33\x33\x33\x33\x13\x03\x00", + "é": b"\x00\x80\xC0\xE0\x60\x68\x6C\x66\x62\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x03\x00", + "ê": b"\x00\x80\xC0\xE8\x6C\x66\x66\x6C\x68\xC0\x80\x00\x00\x0F\x1F\x33\x33\x33\x33\x33\x33\x13\x03\x00", + "ë": b"\x00\x80\xC0\xEC\x6C\x60\x60\x6C\x6C\xC0\x80\x00\x00\x0F\x1F\x33\x33\x33\x33\x33\x33\x13\x03\x00", + "ì": b"\x00\x00\x00\x00\x62\xE6\xEC\x08\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "í": b"\x00\x00\x00\x00\x68\xEC\xE6\x02\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "î": b"\x00\x00\x00\x08\x6C\xE6\xE6\x0C\x08\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ï": b"\x00\x00\x00\x0C\x6C\xE0\xEC\x0C\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ñ": b"\x00\x00\xE0\xE8\x6C\x64\x6C\x68\xEC\xC4\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "ò": b"\x00\x80\xC0\xE0\x62\x66\x6C\x68\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "ó": b"\x00\x80\xC0\xE0\x68\x6C\x66\x62\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "ô": b"\x00\x80\xC0\xE8\x6C\x66\x66\x6C\xE8\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "õ": b"\x00\x80\xC8\xEC\x64\x6C\x68\x6C\xE4\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "ö": b"\x00\x80\xC0\xEC\x6C\x60\x60\x6C\xEC\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "÷": b"\x00\x00\x80\x80\x80\xB0\xB0\x80\x80\x80\x00\x00\x00\x00\x01\x01\x01\x0D\x0D\x01\x01\x01\x00\x00", + "ø": b"\x00\x80\xC0\xE0\x60\x60\x60\xE0\xC0\xE0\xA0\x00\x00\x2F\x3F\x18\x3C\x36\x33\x31\x38\x1F\x0F\x00", + "ù": b"\x00\xE0\xE0\x00\x02\x06\x0C\x08\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "ú": b"\x00\xE0\xE0\x00\x08\x0C\x06\x02\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "û": b"\x00\xE0\xE0\x08\x0C\x06\x06\x0C\x08\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "ü": b"\x00\xE0\xE0\x0C\x0C\x00\x00\x0C\x0C\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "ý": b"\x00\x00\x60\xE0\x80\x10\x18\x8C\xE4\x60\x00\x00\x00\x00\x00\x81\xE7\x7E\x1E\x07\x01\x00\x00\x00", + "þ": b"\x00\x00\x03\xFF\xFF\x1B\x18\x18\xF8\xF0\x00\x00\x00\x00\x30\x3F\x3F\x36\x06\x06\x07\x03\x00\x00", + "ÿ": b"\x00\x00\x60\xEC\x8C\x00\x00\x8C\xEC\x60\x00\x00\x00\x00\x00\x81\xE7\x7E\x1E\x07\x01\x00\x00\x00", # U+0100..U+017F Latin Extended A - "Ā": "0x00,0x00,0x00,0xE0,0xF9,0x1D,0x1D,0xF9,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", - "ā": "0x00,0x00,0x40,0x60,0x68,0x68,0x68,0x68,0x68,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "Ă": "0x00,0x00,0x00,0xE0,0xF9,0x1A,0x1A,0xF9,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", - "ă": "0x00,0x00,0x40,0x60,0x64,0x68,0x68,0x68,0x64,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "Ą": "0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x67,0xBF,0xB8,0x00,", - "ą": "0x00,0x00,0x40,0x60,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x73,0xBF,0xBF,0x00,", - "Ć": "0x00,0x80,0xE0,0x70,0x38,0x18,0x1A,0x1B,0x39,0x70,0x60,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "ć": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x68,0x6C,0x64,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,", - "Ĉ": "0x00,0x80,0xE0,0x70,0x3A,0x1B,0x19,0x1B,0x3A,0x70,0x60,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "ĉ": "0x00,0x80,0xC0,0xE0,0x68,0x6C,0x64,0x6C,0x68,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,", - "Ċ": "0x00,0x80,0xE0,0x70,0x38,0x18,0x1A,0x18,0x38,0x70,0x60,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "ċ": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x68,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,", - "Č": "0x00,0x80,0xE0,0x70,0x39,0x1B,0x1A,0x1B,0x39,0x70,0x60,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "č": "0x00,0x80,0xC0,0xE0,0x64,0x6C,0x68,0x6C,0x64,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,", - "Ď": "0x00,0xF8,0xF8,0x19,0x1B,0x1A,0x1B,0x39,0x70,0xE0,0x80,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "ď": "0x00,0x80,0xC0,0xE0,0x60,0x60,0xE0,0xFF,0xFF,0x00,0x05,0x03,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x3F,0x3F,0x00,0x00,0x00,", - "Đ": "0xC0,0xFF,0xFF,0xC3,0xC3,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "đ": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xE4,0xC4,0xFF,0xFF,0x04,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,", - "Ē": "0x00,0xFC,0xFC,0x8C,0x8D,0x8D,0x8D,0x8D,0x8C,0x0C,0x0C,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "ē": "0x00,0x80,0xC0,0xE0,0x68,0x68,0x68,0x68,0x68,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,", - "Ĕ": "0x00,0xF8,0xF8,0x98,0x99,0x9A,0x9A,0x99,0x98,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "ĕ": "0x00,0x80,0xC0,0xE0,0x64,0x68,0x68,0x68,0x64,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,", - "Ė": "0x00,0xF8,0xF8,0x98,0x98,0x98,0x9A,0x98,0x98,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "ė": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x68,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,", - "Ę": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x70,0xB0,0xB0,0x00,", - "ę": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x73,0xB3,0xB3,0x13,0x01,0x00,", - "Ě": "0x00,0xF8,0xF8,0x98,0x99,0x9B,0x9A,0x9B,0x99,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "ě": "0x00,0x80,0xC0,0xE0,0x64,0x6C,0x68,0x6C,0x64,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,", - "Ĝ": "0x00,0x80,0xE0,0x70,0x1A,0x1B,0x19,0x1B,0x1A,0x38,0x30,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "ĝ": "0x00,0x80,0xC0,0xE0,0x68,0x6C,0x64,0x6C,0x68,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,", - "Ğ": "0x00,0x80,0xE0,0x70,0x1A,0x19,0x19,0x19,0x1A,0x38,0x30,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "ğ": "0x00,0x80,0xC0,0xE0,0x68,0x64,0x64,0x64,0x68,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,", - "Ġ": "0x00,0x80,0xE0,0x70,0x18,0x18,0x1A,0x18,0x18,0x38,0x30,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "ġ": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x68,0x60,0x60,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,", - "Ģ": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC7,0xC6,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0xB0,0x70,0x30,0x3F,0x3F,0x00,", - "ģ": "0x00,0x80,0xC0,0xE0,0x60,0x60,0x6C,0x6A,0x60,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,", - "Ĥ": "0x00,0xFC,0xFC,0x80,0x82,0x81,0x81,0x82,0x80,0xFC,0xFC,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x3F,0x3F,0x00,", - "ĥ": "0x00,0xFE,0xFE,0xC0,0x62,0x63,0x61,0xE3,0xC2,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,", - "Ħ": "0x02,0xFF,0xFF,0xC2,0xC2,0xC2,0xC2,0xC2,0xC2,0xFF,0xFF,0x02,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "ħ": "0x04,0xFF,0xFF,0xC4,0x64,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,", - "Ĩ": "0x00,0x00,0x00,0x1A,0x19,0xFB,0xFB,0x1A,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ĩ": "0x00,0x00,0x00,0x08,0x64,0xEC,0xE8,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ī": "0x00,0x00,0x00,0x0C,0x0D,0xFD,0xFD,0x0D,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ī": "0x00,0x00,0x00,0x08,0x68,0xE8,0xE8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ĭ": "0x00,0x00,0x00,0x18,0x19,0xFA,0xFA,0x19,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ĭ": "0x00,0x00,0x00,0x00,0x64,0xE8,0xE8,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Į": "0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x7F,0xBF,0xB0,0x30,0x00,0x00,0x00,", - "į": "0x00,0x00,0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x7F,0xBF,0xB0,0x30,0x00,0x00,0x00,", - "İ": "0x00,0x00,0x00,0x18,0x18,0xF8,0xFA,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ı": "0x00,0x00,0x00,0x00,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "IJ": "0x00,0x03,0xFF,0xFF,0x03,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x30,0x3F,0x3F,0x30,0x0C,0x1C,0x30,0x30,0x3F,0x1F,0x00,", - "ij": "0x00,0x00,0x20,0xEC,0xEC,0x00,0x00,0x20,0xEC,0xEC,0x00,0x00,0x00,0x00,0x30,0x3F,0x3F,0x70,0xC0,0xC0,0xFF,0x7F,0x00,0x00,", - "Ĵ": "0x00,0x00,0x00,0x00,0x02,0x03,0x01,0x03,0x02,0xF8,0xF8,0x00,0x00,0x0E,0x1E,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ĵ": "0x00,0x00,0x00,0x00,0x00,0x08,0x6C,0xE4,0xEC,0x08,0x00,0x00,0x00,0x00,0x00,0x60,0xE0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00,", - "Ķ": "0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0xA3,0x67,0x0E,0x1C,0x38,0x30,0x00,", - "ķ": "0x00,0x00,0xFF,0xFF,0x00,0x80,0xC0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0xA7,0x6F,0x1C,0x38,0x30,0x00,0x00,", - "ĸ": "0x00,0x00,0xE0,0xE0,0x00,0x80,0xC0,0xE0,0x60,0x20,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x07,0x0F,0x1C,0x38,0x30,0x00,0x00,", - "Ĺ": "0x00,0xF8,0xFA,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "ĺ": "0x00,0x00,0x00,0x00,0x18,0xFA,0xFB,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ļ": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0xB0,0x70,0x30,0x30,0x30,0x30,0x00,", - "ļ": "0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0xBF,0x7F,0x30,0x30,0x00,0x00,0x00,", - "Ľ": "0x00,0xFF,0xFF,0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "ľ": "0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ŀ": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "ŀ": "0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ł": "0x80,0xFF,0xFF,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "ł": "0x00,0x00,0x00,0x00,0x83,0xFF,0xFF,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ń": "0x00,0xFF,0xFF,0x0E,0x38,0xF2,0xC3,0x01,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x03,0x07,0x1C,0x3F,0x3F,0x00,", - "ń": "0x00,0x00,0xE0,0xE0,0x60,0x68,0x6C,0x64,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Ņ": "0x00,0xFF,0xFF,0x0E,0x38,0xF0,0xC0,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0xA0,0x63,0x07,0x1C,0x3F,0x3F,0x00,", - "ņ": "0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0xA0,0x60,0x00,0x3F,0x3F,0x00,", - "Ň": "0x00,0xFF,0xFF,0x0E,0x38,0xF1,0xC2,0x01,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x03,0x07,0x1C,0x3F,0x3F,0x00,", - "ň": "0x00,0x00,0xE0,0xE0,0x64,0x6C,0x68,0x6C,0xE4,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "ʼn": "0x00,0x0A,0xE6,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Ŋ": "0x00,0x00,0xFF,0xFF,0x06,0x03,0x03,0x03,0x07,0xFE,0xFC,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x20,0x20,0x30,0x1F,0x0F,0x00,", - "ŋ": "0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0xC0,0xC0,0xFF,0x7F,0x00,", - "Ō": "0x00,0xC0,0xF0,0x38,0x1D,0x0D,0x0D,0x1D,0x38,0xF0,0xC0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "ō": "0x00,0x80,0xC0,0xE0,0x68,0x68,0x68,0x68,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Ŏ": "0x00,0x80,0xE0,0x70,0x39,0x1A,0x1A,0x39,0x70,0xE0,0x80,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "ŏ": "0x00,0x80,0xC0,0xE0,0x64,0x68,0x68,0x64,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Ő": "0x00,0x80,0xE0,0x70,0x3A,0x19,0x1A,0x39,0x70,0xE0,0x80,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "ő": "0x00,0x80,0xC0,0xE0,0x68,0x64,0x68,0x64,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Œ": "0xF0,0xFC,0x0E,0x03,0x03,0x07,0xFE,0xFF,0xC3,0xC3,0xC3,0x00,0x03,0x0F,0x1C,0x30,0x30,0x38,0x1F,0x3F,0x30,0x30,0x30,0x00,", - "œ": "0x80,0xC0,0xE0,0x60,0x60,0xE0,0xC0,0x60,0x60,0x60,0x40,0x80,0x0F,0x1F,0x38,0x30,0x30,0x1F,0x1F,0x3B,0x33,0x33,0x1B,0x09,", - "Ŕ": "0x00,0xF8,0xF8,0x98,0x98,0x9A,0x9B,0x99,0xF8,0xF0,0x60,0x00,0x00,0x3F,0x3F,0x01,0x01,0x03,0x07,0x0F,0x1D,0x38,0x30,0x00,", - "ŕ": "0x00,0x00,0xE0,0xE0,0xC0,0x60,0x68,0x6C,0x64,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Ŗ": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0xA3,0x67,0x0F,0x1D,0x38,0x30,0x00,", - "ŗ": "0x00,0x00,0xE0,0xE0,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00,", - "Ř": "0x00,0xF8,0xF8,0x99,0x9B,0x9A,0x9B,0x99,0xF8,0xF0,0x60,0x00,0x00,0x3F,0x3F,0x01,0x01,0x03,0x07,0x0F,0x1D,0x38,0x30,0x00,", - "ř": "0x00,0x00,0xE0,0xE0,0xC4,0x6C,0x68,0x6C,0x64,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Ś": "0x00,0x60,0xF0,0xF8,0x98,0x9A,0x9B,0x99,0x98,0x30,0x20,0x00,0x00,0x0C,0x1C,0x39,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "ś": "0x00,0xC0,0xE0,0x60,0x68,0x6C,0x64,0x60,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,", - "Ŝ": "0x00,0x60,0xF0,0xF8,0x9A,0x9B,0x99,0x9B,0x9A,0x30,0x20,0x00,0x00,0x0C,0x1C,0x39,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "ŝ": "0x00,0xC0,0xE0,0x68,0x6C,0x64,0x6C,0x68,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,", - "Ş": "0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC7,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0xB0,0xF0,0x30,0x39,0x1F,0x0F,0x00,", - "ş": "0x00,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0xB3,0xF3,0x33,0x3F,0x1E,0x00,0x00,0x00,", - "Š": "0x00,0x60,0xF0,0xF8,0x99,0x9B,0x9A,0x9B,0x99,0x30,0x20,0x00,0x00,0x0C,0x1C,0x39,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "š": "0x00,0xC0,0xE0,0x64,0x6C,0x68,0x6C,0x64,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,", - "Ţ": "0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,0xBF,0x60,0x00,0x00,0x00,0x00,", - "ţ": "0x00,0x60,0x60,0xFE,0xFE,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0xB0,0xB0,0xF0,0x30,0x00,0x00,0x00,", - "Ť": "0x00,0x00,0x18,0x19,0x1B,0xFA,0xFA,0x1B,0x19,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "ť": "0x00,0x60,0x60,0xFE,0xFE,0x60,0x65,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x30,0x30,0x30,0x30,0x00,0x00,0x00,", - "Ŧ": "0x00,0x00,0x03,0xC3,0xC3,0xFF,0xFF,0xC3,0xC3,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "ŧ": "0x00,0x30,0x30,0xFE,0xFE,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x1F,0x3F,0x33,0x33,0x30,0x30,0x00,0x00,0x00,", - "Ũ": "0x00,0xF8,0xF8,0x02,0x01,0x03,0x03,0x02,0x01,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ũ": "0x00,0xE0,0xE0,0x08,0x04,0x0C,0x0C,0x08,0x04,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "Ū": "0x00,0xFC,0xFC,0x00,0x01,0x01,0x01,0x01,0x00,0xFC,0xFC,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ū": "0x00,0xE0,0xE0,0x00,0x08,0x08,0x08,0x08,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "Ŭ": "0x00,0xFC,0xFC,0x00,0x01,0x02,0x02,0x01,0x00,0xFC,0xFC,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ŭ": "0x00,0xE0,0xE0,0x00,0x04,0x08,0x08,0x04,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "Ů": "0x00,0xF8,0xF8,0x00,0x06,0x09,0x09,0x06,0x00,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ů": "0x00,0xE0,0xE0,0x00,0x0C,0x12,0x12,0x0C,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "Ű": "0x00,0xF8,0xF8,0x00,0x02,0x01,0x02,0x01,0x00,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,", - "ű": "0x00,0xE0,0xE0,0x00,0x08,0x04,0x08,0x04,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,", - "Ų": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x07,0x1F,0x38,0x30,0xF0,0xB0,0xB0,0x38,0x1F,0x07,0x00,", - "ų": "0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0xF0,0xB0,0xB0,0x18,0x3F,0x3F,0x00,", - "Ŵ": "0x00,0xFC,0xFC,0x00,0x02,0x81,0x81,0x02,0x00,0xFC,0xFC,0x00,0x00,0x3F,0x3F,0x1C,0x06,0x03,0x03,0x06,0x1C,0x3F,0x3F,0x00,", - "ŵ": "0x00,0xE0,0xE0,0x00,0x04,0xE8,0xE8,0x04,0x00,0xE0,0xE0,0x00,0x00,0x07,0x1F,0x38,0x1C,0x0F,0x0F,0x1C,0x38,0x1F,0x07,0x00,", - "Ŷ": "0x00,0x02,0x0E,0x3C,0xF2,0xC1,0xC1,0xF2,0x3C,0x0E,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "ŷ": "0x00,0x00,0x60,0xE0,0x88,0x04,0x04,0x88,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,", - "Ÿ": "0x00,0x02,0x0E,0x3C,0xF1,0xC0,0xC0,0xF1,0x3C,0x0E,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "Ź": "0x00,0x18,0x18,0x18,0x18,0x1A,0x9B,0xD9,0xF8,0x78,0x38,0x00,0x00,0x30,0x38,0x3C,0x3E,0x37,0x33,0x31,0x30,0x30,0x30,0x00,", - "ź": "0x00,0x60,0x60,0x60,0x68,0x6C,0xE4,0xE0,0x60,0x20,0x00,0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x30,0x00,0x00,", - "Ż": "0x00,0x18,0x18,0x18,0x18,0x18,0x9A,0xD8,0xF8,0x78,0x38,0x00,0x00,0x30,0x38,0x3C,0x3E,0x37,0x33,0x31,0x30,0x30,0x30,0x00,", - "ż": "0x00,0x60,0x60,0x60,0x60,0x68,0xE0,0xE0,0x60,0x20,0x00,0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x30,0x00,0x00,", - "Ž": "0x00,0x18,0x18,0x18,0x19,0x1B,0x9A,0xDB,0xF9,0x78,0x38,0x00,0x00,0x30,0x38,0x3C,0x3E,0x37,0x33,0x31,0x30,0x30,0x30,0x00,", - "ž": "0x00,0x60,0x60,0x64,0x6C,0x68,0xEC,0xE4,0x60,0x20,0x00,0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x30,0x00,0x00,", - "ſ": "0x00,0x00,0x00,0x00,0xFC,0xFE,0x06,0x06,0x0E,0x0C,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x00,0x00,0x00,0x00,0x00,", + "Ā": b"\x00\x00\x00\xE0\xF9\x1D\x1D\xF9\xE0\x00\x00\x00\x00\x38\x3F\x07\x06\x06\x06\x06\x07\x3F\x38\x00", + "ā": b"\x00\x00\x40\x60\x68\x68\x68\x68\x68\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "Ă": b"\x00\x00\x00\xE0\xF9\x1A\x1A\xF9\xE0\x00\x00\x00\x00\x38\x3F\x07\x06\x06\x06\x06\x07\x3F\x38\x00", + "ă": b"\x00\x00\x40\x60\x64\x68\x68\x68\x64\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "Ą": b"\x00\x00\x00\xE0\xFC\x1F\x1F\xFC\xE0\x00\x00\x00\x00\x38\x3F\x07\x06\x06\x06\x06\x67\xBF\xB8\x00", + "ą": b"\x00\x00\x40\x60\x60\x60\x60\x60\x60\xE0\xC0\x00\x00\x1C\x3E\x33\x33\x33\x33\x33\x73\xBF\xBF\x00", + "Ć": b"\x00\x80\xE0\x70\x38\x18\x1A\x1B\x39\x70\x60\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "ć": b"\x00\x80\xC0\xE0\x60\x60\x68\x6C\x64\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x18\x08\x00", + "Ĉ": b"\x00\x80\xE0\x70\x3A\x1B\x19\x1B\x3A\x70\x60\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "ĉ": b"\x00\x80\xC0\xE0\x68\x6C\x64\x6C\x68\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x18\x08\x00", + "Ċ": b"\x00\x80\xE0\x70\x38\x18\x1A\x18\x38\x70\x60\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "ċ": b"\x00\x80\xC0\xE0\x60\x60\x68\x60\x60\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x18\x08\x00", + "Č": b"\x00\x80\xE0\x70\x39\x1B\x1A\x1B\x39\x70\x60\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "č": b"\x00\x80\xC0\xE0\x64\x6C\x68\x6C\x64\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x18\x08\x00", + "Ď": b"\x00\xF8\xF8\x19\x1B\x1A\x1B\x39\x70\xE0\x80\x00\x00\x3F\x3F\x30\x30\x30\x30\x38\x1C\x0F\x03\x00", + "ď": b"\x00\x80\xC0\xE0\x60\x60\xE0\xFF\xFF\x00\x05\x03\x00\x0F\x1F\x38\x30\x30\x30\x3F\x3F\x00\x00\x00", + "Đ": b"\xC0\xFF\xFF\xC3\xC3\x03\x03\x07\x0E\xFC\xF0\x00\x00\x3F\x3F\x30\x30\x30\x30\x38\x1C\x0F\x03\x00", + "đ": b"\x00\x80\xC0\xE0\x60\x60\x60\xE4\xC4\xFF\xFF\x04\x00\x0F\x1F\x38\x30\x30\x30\x30\x30\x3F\x3F\x00", + "Ē": b"\x00\xFC\xFC\x8C\x8D\x8D\x8D\x8D\x8C\x0C\x0C\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "ē": b"\x00\x80\xC0\xE0\x68\x68\x68\x68\x68\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x01\x00", + "Ĕ": b"\x00\xF8\xF8\x98\x99\x9A\x9A\x99\x98\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "ĕ": b"\x00\x80\xC0\xE0\x64\x68\x68\x68\x64\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x01\x00", + "Ė": b"\x00\xF8\xF8\x98\x98\x98\x9A\x98\x98\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "ė": b"\x00\x80\xC0\xE0\x60\x60\x68\x60\x60\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x01\x00", + "Ę": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xC3\xC3\x03\x03\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x70\xB0\xB0\x00", + "ę": b"\x00\x80\xC0\xE0\x60\x60\x60\x60\x60\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x73\xB3\xB3\x13\x01\x00", + "Ě": b"\x00\xF8\xF8\x98\x99\x9B\x9A\x9B\x99\x18\x18\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "ě": b"\x00\x80\xC0\xE0\x64\x6C\x68\x6C\x64\xC0\x80\x00\x00\x0F\x1F\x3B\x33\x33\x33\x33\x33\x13\x01\x00", + "Ĝ": b"\x00\x80\xE0\x70\x1A\x1B\x19\x1B\x1A\x38\x30\x00\x00\x03\x0F\x1C\x38\x30\x33\x33\x33\x3F\x3F\x00", + "ĝ": b"\x00\x80\xC0\xE0\x68\x6C\x64\x6C\x68\xE0\xE0\x00\x00\x03\xC7\xCE\xCC\xCC\xCC\xCC\xE6\x7F\x3F\x00", + "Ğ": b"\x00\x80\xE0\x70\x1A\x19\x19\x19\x1A\x38\x30\x00\x00\x03\x0F\x1C\x38\x30\x33\x33\x33\x3F\x3F\x00", + "ğ": b"\x00\x80\xC0\xE0\x68\x64\x64\x64\x68\xE0\xE0\x00\x00\x03\xC7\xCE\xCC\xCC\xCC\xCC\xE6\x7F\x3F\x00", + "Ġ": b"\x00\x80\xE0\x70\x18\x18\x1A\x18\x18\x38\x30\x00\x00\x03\x0F\x1C\x38\x30\x33\x33\x33\x3F\x3F\x00", + "ġ": b"\x00\x80\xC0\xE0\x60\x60\x68\x60\x60\xE0\xE0\x00\x00\x03\xC7\xCE\xCC\xCC\xCC\xCC\xE6\x7F\x3F\x00", + "Ģ": b"\x00\xF0\xFC\x0E\x07\x03\xC3\xC3\xC3\xC7\xC6\x00\x00\x03\x0F\x1C\x38\x30\xB0\x70\x30\x3F\x3F\x00", + "ģ": b"\x00\x80\xC0\xE0\x60\x60\x6C\x6A\x60\xE0\xE0\x00\x00\x03\xC7\xCE\xCC\xCC\xCC\xCC\xE6\x7F\x3F\x00", + "Ĥ": b"\x00\xFC\xFC\x80\x82\x81\x81\x82\x80\xFC\xFC\x00\x00\x3F\x3F\x01\x01\x01\x01\x01\x01\x3F\x3F\x00", + "ĥ": b"\x00\xFE\xFE\xC0\x62\x63\x61\xE3\xC2\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00\x00", + "Ħ": b"\x02\xFF\xFF\xC2\xC2\xC2\xC2\xC2\xC2\xFF\xFF\x02\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "ħ": b"\x04\xFF\xFF\xC4\x64\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00\x00", + "Ĩ": b"\x00\x00\x00\x1A\x19\xFB\xFB\x1A\x19\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ĩ": b"\x00\x00\x00\x08\x64\xEC\xE8\x04\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ī": b"\x00\x00\x00\x0C\x0D\xFD\xFD\x0D\x0C\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ī": b"\x00\x00\x00\x08\x68\xE8\xE8\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ĭ": b"\x00\x00\x00\x18\x19\xFA\xFA\x19\x18\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ĭ": b"\x00\x00\x00\x00\x64\xE8\xE8\x04\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Į": b"\x00\x00\x00\x03\x03\xFF\xFF\x03\x03\x00\x00\x00\x00\x00\x00\x30\x30\x7F\xBF\xB0\x30\x00\x00\x00", + "į": b"\x00\x00\x00\x00\x60\xEC\xEC\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x7F\xBF\xB0\x30\x00\x00\x00", + "İ": b"\x00\x00\x00\x18\x18\xF8\xFA\x18\x18\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ı": b"\x00\x00\x00\x00\x60\xE0\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "IJ": b"\x00\x03\xFF\xFF\x03\x00\x00\x00\x03\xFF\xFF\x00\x00\x30\x3F\x3F\x30\x0C\x1C\x30\x30\x3F\x1F\x00", + "ij": b"\x00\x00\x20\xEC\xEC\x00\x00\x20\xEC\xEC\x00\x00\x00\x00\x30\x3F\x3F\x70\xC0\xC0\xFF\x7F\x00\x00", + "Ĵ": b"\x00\x00\x00\x00\x02\x03\x01\x03\x02\xF8\xF8\x00\x00\x0E\x1E\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ĵ": b"\x00\x00\x00\x00\x00\x08\x6C\xE4\xEC\x08\x00\x00\x00\x00\x00\x60\xE0\xC0\xC0\xFF\x7F\x00\x00\x00", + "Ķ": b"\x00\xFF\xFF\xC0\xE0\xF0\x38\x1C\x0E\x07\x03\x00\x00\x3F\x3F\x00\x01\xA3\x67\x0E\x1C\x38\x30\x00", + "ķ": b"\x00\x00\xFF\xFF\x00\x80\xC0\xE0\x60\x00\x00\x00\x00\x00\x3F\x3F\x03\xA7\x6F\x1C\x38\x30\x00\x00", + "ĸ": b"\x00\x00\xE0\xE0\x00\x80\xC0\xE0\x60\x20\x00\x00\x00\x00\x3F\x3F\x03\x07\x0F\x1C\x38\x30\x00\x00", + "Ĺ": b"\x00\xF8\xFA\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "ĺ": b"\x00\x00\x00\x00\x18\xFA\xFB\x01\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ļ": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\xB0\x70\x30\x30\x30\x30\x00", + "ļ": b"\x00\x00\x00\x00\x03\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\xBF\x7F\x30\x30\x00\x00\x00", + "Ľ": b"\x00\xFF\xFF\x00\x00\x05\x03\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "ľ": b"\x00\x00\x00\x00\x03\xFF\xFF\x00\x05\x03\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ŀ": b"\x00\xFF\xFF\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "ŀ": b"\x00\x00\x00\x00\x03\xFF\xFF\x00\x40\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ł": b"\x80\xFF\xFF\x20\x10\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "ł": b"\x00\x00\x00\x00\x83\xFF\xFF\x20\x10\x00\x00\x00\x00\x00\x00\x31\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ń": b"\x00\xFF\xFF\x0E\x38\xF2\xC3\x01\x00\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x03\x07\x1C\x3F\x3F\x00", + "ń": b"\x00\x00\xE0\xE0\x60\x68\x6C\x64\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "Ņ": b"\x00\xFF\xFF\x0E\x38\xF0\xC0\x00\x00\xFF\xFF\x00\x00\x3F\x3F\x00\x00\xA0\x63\x07\x1C\x3F\x3F\x00", + "ņ": b"\x00\x00\xE0\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\xA0\x60\x00\x3F\x3F\x00", + "Ň": b"\x00\xFF\xFF\x0E\x38\xF1\xC2\x01\x00\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x03\x07\x1C\x3F\x3F\x00", + "ň": b"\x00\x00\xE0\xE0\x64\x6C\x68\x6C\xE4\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "ʼn": b"\x00\x0A\xE6\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "Ŋ": b"\x00\x00\xFF\xFF\x06\x03\x03\x03\x07\xFE\xFC\x00\x00\x00\x3F\x3F\x00\x00\x20\x20\x30\x1F\x0F\x00", + "ŋ": b"\x00\x00\xE0\xE0\x60\x60\x60\x60\xE0\xC0\x80\x00\x00\x00\x3F\x3F\x00\x00\x00\xC0\xC0\xFF\x7F\x00", + "Ō": b"\x00\xC0\xF0\x38\x1D\x0D\x0D\x1D\x38\xF0\xC0\x00\x00\x03\x0F\x1C\x38\x30\x30\x38\x1C\x0F\x03\x00", + "ō": b"\x00\x80\xC0\xE0\x68\x68\x68\x68\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Ŏ": b"\x00\x80\xE0\x70\x39\x1A\x1A\x39\x70\xE0\x80\x00\x00\x03\x0F\x1C\x38\x30\x30\x38\x1C\x0F\x03\x00", + "ŏ": b"\x00\x80\xC0\xE0\x64\x68\x68\x64\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Ő": b"\x00\x80\xE0\x70\x3A\x19\x1A\x39\x70\xE0\x80\x00\x00\x03\x0F\x1C\x38\x30\x30\x38\x1C\x0F\x03\x00", + "ő": b"\x00\x80\xC0\xE0\x68\x64\x68\x64\xE0\xC0\x80\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Œ": b"\xF0\xFC\x0E\x03\x03\x07\xFE\xFF\xC3\xC3\xC3\x00\x03\x0F\x1C\x30\x30\x38\x1F\x3F\x30\x30\x30\x00", + "œ": b"\x80\xC0\xE0\x60\x60\xE0\xC0\x60\x60\x60\x40\x80\x0F\x1F\x38\x30\x30\x1F\x1F\x3B\x33\x33\x1B\x09", + "Ŕ": b"\x00\xF8\xF8\x98\x98\x9A\x9B\x99\xF8\xF0\x60\x00\x00\x3F\x3F\x01\x01\x03\x07\x0F\x1D\x38\x30\x00", + "ŕ": b"\x00\x00\xE0\xE0\xC0\x60\x68\x6C\x64\xE0\xC0\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00", + "Ŗ": b"\x00\xFF\xFF\x83\x83\x83\x83\x83\xC7\xFE\x7C\x00\x00\x3F\x3F\x01\x01\xA3\x67\x0F\x1D\x38\x30\x00", + "ŗ": b"\x00\x00\xE0\xE0\xC0\x60\x60\x60\x60\xE0\xC0\x00\x00\x00\x3F\x3F\x00\xA0\x60\x00\x00\x00\x00\x00", + "Ř": b"\x00\xF8\xF8\x99\x9B\x9A\x9B\x99\xF8\xF0\x60\x00\x00\x3F\x3F\x01\x01\x03\x07\x0F\x1D\x38\x30\x00", + "ř": b"\x00\x00\xE0\xE0\xC4\x6C\x68\x6C\x64\xE0\xC0\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00", + "Ś": b"\x00\x60\xF0\xF8\x98\x9A\x9B\x99\x98\x30\x20\x00\x00\x0C\x1C\x39\x31\x31\x31\x31\x3B\x1F\x0E\x00", + "ś": b"\x00\xC0\xE0\x60\x68\x6C\x64\x60\x40\x00\x00\x00\x00\x11\x33\x33\x33\x33\x33\x3F\x1E\x00\x00\x00", + "Ŝ": b"\x00\x60\xF0\xF8\x9A\x9B\x99\x9B\x9A\x30\x20\x00\x00\x0C\x1C\x39\x31\x31\x31\x31\x3B\x1F\x0E\x00", + "ŝ": b"\x00\xC0\xE0\x68\x6C\x64\x6C\x68\x40\x00\x00\x00\x00\x11\x33\x33\x33\x33\x33\x3F\x1E\x00\x00\x00", + "Ş": b"\x00\x3C\x7E\xE7\xC3\xC3\xC3\xC3\xC7\x8E\x0C\x00\x00\x0C\x1C\x38\x30\xB0\xF0\x30\x39\x1F\x0F\x00", + "ş": b"\x00\xC0\xE0\x60\x60\x60\x60\x60\x40\x00\x00\x00\x00\x11\x33\x33\xB3\xF3\x33\x3F\x1E\x00\x00\x00", + "Š": b"\x00\x60\xF0\xF8\x99\x9B\x9A\x9B\x99\x30\x20\x00\x00\x0C\x1C\x39\x31\x31\x31\x31\x3B\x1F\x0E\x00", + "š": b"\x00\xC0\xE0\x64\x6C\x68\x6C\x64\x40\x00\x00\x00\x00\x11\x33\x33\x33\x33\x33\x3F\x1E\x00\x00\x00", + "Ţ": b"\x00\x00\x03\x03\x03\xFF\xFF\x03\x03\x03\x00\x00\x00\x00\x00\x00\x00\xBF\xBF\x60\x00\x00\x00\x00", + "ţ": b"\x00\x60\x60\xFE\xFE\x60\x60\x60\x00\x00\x00\x00\x00\x00\x00\x1F\x3F\xB0\xB0\xF0\x30\x00\x00\x00", + "Ť": b"\x00\x00\x18\x19\x1B\xFA\xFA\x1B\x19\x18\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "ť": b"\x00\x60\x60\xFE\xFE\x60\x65\x63\x00\x00\x00\x00\x00\x00\x00\x1F\x3F\x30\x30\x30\x30\x00\x00\x00", + "Ŧ": b"\x00\x00\x03\xC3\xC3\xFF\xFF\xC3\xC3\x03\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "ŧ": b"\x00\x30\x30\xFE\xFE\x30\x30\x30\x00\x00\x00\x00\x00\x03\x03\x1F\x3F\x33\x33\x30\x30\x00\x00\x00", + "Ũ": b"\x00\xF8\xF8\x02\x01\x03\x03\x02\x01\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ũ": b"\x00\xE0\xE0\x08\x04\x0C\x0C\x08\x04\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "Ū": b"\x00\xFC\xFC\x00\x01\x01\x01\x01\x00\xFC\xFC\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ū": b"\x00\xE0\xE0\x00\x08\x08\x08\x08\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "Ŭ": b"\x00\xFC\xFC\x00\x01\x02\x02\x01\x00\xFC\xFC\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ŭ": b"\x00\xE0\xE0\x00\x04\x08\x08\x04\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "Ů": b"\x00\xF8\xF8\x00\x06\x09\x09\x06\x00\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ů": b"\x00\xE0\xE0\x00\x0C\x12\x12\x0C\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "Ű": b"\x00\xF8\xF8\x00\x02\x01\x02\x01\x00\xF8\xF8\x00\x00\x07\x1F\x38\x30\x30\x30\x30\x38\x1F\x07\x00", + "ű": b"\x00\xE0\xE0\x00\x08\x04\x08\x04\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x18\x3F\x3F\x00", + "Ų": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x07\x1F\x38\x30\xF0\xB0\xB0\x38\x1F\x07\x00", + "ų": b"\x00\xE0\xE0\x00\x00\x00\x00\x00\x00\xE0\xE0\x00\x00\x0F\x1F\x38\x30\xF0\xB0\xB0\x18\x3F\x3F\x00", + "Ŵ": b"\x00\xFC\xFC\x00\x02\x81\x81\x02\x00\xFC\xFC\x00\x00\x3F\x3F\x1C\x06\x03\x03\x06\x1C\x3F\x3F\x00", + "ŵ": b"\x00\xE0\xE0\x00\x04\xE8\xE8\x04\x00\xE0\xE0\x00\x00\x07\x1F\x38\x1C\x0F\x0F\x1C\x38\x1F\x07\x00", + "Ŷ": b"\x00\x02\x0E\x3C\xF2\xC1\xC1\xF2\x3C\x0E\x02\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "ŷ": b"\x00\x00\x60\xE0\x88\x04\x04\x88\xE0\x60\x00\x00\x00\x00\x00\x81\xE7\x7E\x1E\x07\x01\x00\x00\x00", + "Ÿ": b"\x00\x02\x0E\x3C\xF1\xC0\xC0\xF1\x3C\x0E\x02\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "Ź": b"\x00\x18\x18\x18\x18\x1A\x9B\xD9\xF8\x78\x38\x00\x00\x30\x38\x3C\x3E\x37\x33\x31\x30\x30\x30\x00", + "ź": b"\x00\x60\x60\x60\x68\x6C\xE4\xE0\x60\x20\x00\x00\x00\x30\x38\x3C\x36\x33\x31\x30\x30\x30\x00\x00", + "Ż": b"\x00\x18\x18\x18\x18\x18\x9A\xD8\xF8\x78\x38\x00\x00\x30\x38\x3C\x3E\x37\x33\x31\x30\x30\x30\x00", + "ż": b"\x00\x60\x60\x60\x60\x68\xE0\xE0\x60\x20\x00\x00\x00\x30\x38\x3C\x36\x33\x31\x30\x30\x30\x00\x00", + "Ž": b"\x00\x18\x18\x18\x19\x1B\x9A\xDB\xF9\x78\x38\x00\x00\x30\x38\x3C\x3E\x37\x33\x31\x30\x30\x30\x00", + "ž": b"\x00\x60\x60\x64\x6C\x68\xEC\xE4\x60\x20\x00\x00\x00\x30\x38\x3C\x36\x33\x31\x30\x30\x30\x00\x00", + "ſ": b"\x00\x00\x00\x00\xFC\xFE\x06\x06\x0E\x0C\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x00\x00\x00\x00\x00", } return font -def get_font_map_cyrillic(): +def get_font_map_cyrillic() -> Dict[str, bytes]: font = { # U+0400..U+04FF Cyrillic - "Ѐ": "0x00,0xFC,0xFC,0x8D,0x8F,0x8E,0x8C,0x8C,0x8C,0x0C,0x0C,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,", - "Ё": "0x00,0xFE,0xFE,0xC7,0xC7,0xC6,0xC6,0xC7,0xC7,0x06,0x06,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "Ђ": "0x00,0x03,0xFF,0xFF,0x83,0xC3,0xC3,0xC3,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x00,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Ѓ": "0x00,0xFC,0xFC,0x0C,0x0C,0x0C,0x0E,0x0F,0x0D,0x0C,0x0C,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Є": "0x00,0xF8,0xFC,0xCE,0xC7,0xC3,0xC3,0xC3,0x07,0x0E,0x0C,0x00,0x00,0x07,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "Ѕ": "0x00,0x3C,0x7E,0x67,0xE3,0xC3,0xC3,0xC3,0x87,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x31,0x39,0x1F,0x0F,0x00,", - "І": "0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ї": "0x00,0x00,0x00,0x0D,0x0D,0xFC,0xFC,0x0D,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "Ј": "0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x0E,0x1E,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "Љ": "0x00,0x00,0xFE,0xFF,0x03,0x03,0xFF,0xFF,0xC0,0xC0,0x80,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x3F,0x3F,0x30,0x39,0x1F,0x0F,", - "Њ": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xFF,0xFF,0xC0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x3F,0x3F,0x30,0x39,0x1F,0x0F,", - "Ћ": "0x00,0x03,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x00,0x00,0x00,0x01,0x3F,0x3F,0x00,", - "Ќ": "0x00,0xFF,0xFF,0xC0,0xE2,0xF3,0x39,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,", - "Ѝ": "0x00,0xFF,0xFF,0x00,0x01,0xC3,0xF2,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Ў": "0x00,0x07,0x1F,0x7C,0xF1,0xC1,0xC1,0xF1,0x7C,0x1F,0x07,0x00,0x00,0x00,0x30,0x30,0x3C,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,", - "Џ": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x1F,0x1F,0x18,0x18,0x78,0x78,0x18,0x18,0x1F,0x1F,0x00,", - "А": "0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,", - "Б": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x83,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "В": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Г": "0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Ґ": "0x00,0xFC,0xFC,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x0F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "Д": "0x00,0x00,0xF8,0xFE,0x0F,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x70,0x7F,0x1F,0x18,0x18,0x18,0x18,0x1F,0x7F,0x70,0x00,", - "Е": "0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,", - "Ж": "0x00,0x03,0x0F,0xFC,0xE0,0xFF,0xFF,0xE0,0xFC,0x0F,0x03,0x00,0x00,0x38,0x3F,0x07,0x00,0x3F,0x3F,0x00,0x07,0x3F,0x38,0x00,", - "З": "0x0C,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC3,0xC3,0xE7,0x7E,0x3C,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0E,", - "И": "0x00,0xFF,0xFF,0x00,0x00,0xC0,0xF0,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Й": "0x00,0xFF,0xFF,0x00,0x02,0xC3,0xF1,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "К": "0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,", - "Л": "0x00,0x00,0xF0,0xFC,0x1E,0x07,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "М": "0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,", - "Н": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "О": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,", - "П": "0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Р": "0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,", - "С": "0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,", - "Т": "0x00,0x03,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "У": "0x00,0x07,0x1F,0x7C,0xF0,0xC0,0xC0,0xF0,0x7C,0x1F,0x07,0x00,0x00,0x00,0x30,0x30,0x3C,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,", - "Ф": "0x00,0xF8,0xFC,0x0E,0x06,0xFF,0xFF,0x06,0x0E,0xFC,0xF8,0x00,0x00,0x03,0x07,0x0E,0x0C,0x3F,0x3F,0x0C,0x0E,0x07,0x03,0x00,", - "Х": "0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x03,0x0F,0x3C,0x30,0x00,", - "Ц": "0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x1F,0x1F,0x18,0x18,0x18,0x18,0x18,0x1F,0x7F,0x78,0x00,", - "Ч": "0x00,0x7F,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "Ш": "0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,", - "Щ": "0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x1F,0x1F,0x18,0x18,0x1F,0x1F,0x18,0x18,0x1F,0x7F,0x70,", - "Ъ": "0x03,0x03,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Ы": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x00,0x3F,0x3F,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,0x3F,0x3F,", - "Ь": "0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,", - "Э": "0x00,0x0C,0x0E,0x07,0xC3,0xC3,0xC3,0xC7,0xCE,0xFC,0xF8,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0F,0x07,0x00,", - "Ю": "0x00,0xFF,0xFF,0xC0,0xFC,0xFE,0x07,0x03,0x07,0xFE,0xFC,0x00,0x00,0x3F,0x3F,0x00,0x0F,0x1F,0x38,0x30,0x38,0x1F,0x0F,0x00,", - "Я": "0x00,0x7C,0xFE,0xC7,0x83,0x83,0x83,0x83,0x83,0xFF,0xFF,0x00,0x00,0x30,0x38,0x1D,0x0F,0x07,0x03,0x01,0x01,0x3F,0x3F,0x00,", - "а": "0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1E,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,", - "б": "0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,", - "в": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x00,0x3F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,", - "г": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "ґ": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x3C,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "д": "0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x00,0x60,0x7F,0x3F,0x30,0x30,0x30,0x30,0x3F,0x7F,0x60,0x00,", - "е": "0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", - "ж": "0x00,0x30,0xF0,0xC0,0x00,0xF0,0xF0,0x00,0xC0,0xF0,0x30,0x00,0x00,0x30,0x3C,0x0F,0x03,0x3F,0x3F,0x03,0x0F,0x3C,0x30,0x00,", - "з": "0x00,0x60,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x18,0x38,0x30,0x33,0x33,0x33,0x33,0x33,0x3F,0x1D,0x00,", - "и": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "й": "0x00,0xF0,0xF0,0x00,0x04,0x08,0x88,0xC4,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "к": "0x00,0xF0,0xF0,0x80,0x80,0xC0,0xE0,0x70,0x30,0x10,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x07,0x0E,0x1C,0x38,0x30,0x20,0x00,", - "л": "0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "м": "0x00,0xF0,0xF0,0xE0,0xC0,0x80,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "н": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,", - "о": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,", - "п": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,", - "р": "0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,", - "с": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x18,0x08,0x00,", - "т": "0x00,0x30,0x30,0x30,0x30,0xF0,0xF0,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,", - "у": "0x00,0x30,0xF0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xF0,0x30,0x00,0x00,0x60,0xE0,0xC3,0xE7,0x7C,0x3C,0x0F,0x03,0x00,0x00,0x00,", - "ф": "0x00,0x80,0xC0,0x60,0x60,0xF0,0xF0,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x30,0x30,0xFF,0xFF,0x30,0x30,0x1F,0x0F,0x00,", - "х": "0x00,0x30,0x70,0xC0,0x80,0x00,0x00,0x80,0xC0,0x70,0x30,0x00,0x00,0x30,0x38,0x0C,0x07,0x03,0x03,0x07,0x0C,0x38,0x30,0x00,", - "ц": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x3F,0xFF,0xF0,0x00,", - "ч": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,", - "ш": "0x00,0xF0,0xF0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,", - "щ": "0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0xFF,0xE0,", - "ъ": "0x30,0x30,0xF0,0xF0,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "ы": "0x00,0xF0,0xF0,0x80,0x80,0x80,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x31,0x31,0x3B,0x1F,0x0E,0x00,0x3F,0x3F,0x00,", - "ь": "0x00,0xF0,0xF0,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,", - "э": "0x00,0x40,0x60,0x70,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x08,0x18,0x38,0x30,0x33,0x33,0x33,0x3B,0x1F,0x0F,0x00,", - "ю": "0x00,0xF0,0xF0,0x00,0xE0,0xF0,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x3F,0x3F,0x03,0x1F,0x3F,0x30,0x30,0x30,0x3F,0x1F,0x00,", - "я": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x21,0x33,0x3B,0x1E,0x0E,0x06,0x06,0x06,0x3F,0x3F,0x00,", - "ѐ": "0x00,0xE0,0xF0,0x32,0x36,0x36,0x34,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", - "ё": "0x00,0xE0,0xF0,0x34,0x34,0x30,0x30,0x34,0x34,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,", - "ђ": "0x00,0x30,0xFC,0xFC,0x30,0xB0,0xB0,0xB0,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x07,0x03,0x01,0x01,0xC1,0xFF,0x3F,0x00,", - "ѓ": "0x00,0xF0,0xF0,0x30,0x30,0x34,0x36,0x32,0x30,0x30,0x30,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,", - "є": "0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x30,0x38,0x18,0x08,0x00,", - "ѕ": "0x00,0xE0,0xF0,0xB0,0xB0,0x30,0x30,0x30,0x30,0x70,0x60,0x00,0x00,0x18,0x39,0x31,0x33,0x33,0x33,0x37,0x36,0x3E,0x1C,0x00,", - "і": "0x00,0x00,0x00,0x00,0x30,0xF6,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ї": "0x00,0x00,0x00,0x04,0x34,0xF0,0xF4,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,", - "ј": "0x00,0x00,0x00,0x00,0x00,0x30,0x30,0xF6,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xE0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00,", - "љ": "0x00,0x00,0xE0,0xF0,0x30,0x30,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x3F,0x3F,0x33,0x33,0x1E,0x0C,", - "њ": "0x00,0xF0,0xF0,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x03,0x3F,0x3F,0x33,0x33,0x1E,0x0C,", - "ћ": "0x00,0x30,0xFC,0xFC,0xB0,0xB0,0xB0,0xB0,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x3F,0x3F,0x00,", - "ќ": "0x00,0xF0,0xF0,0x80,0x88,0xCC,0xE4,0x70,0x30,0x10,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x07,0x0E,0x1C,0x38,0x30,0x20,0x00,", - "ѝ": "0x00,0xF0,0xF0,0x00,0x06,0x0C,0x88,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,", - "ў": "0x00,0x30,0xF0,0xC0,0x04,0x08,0x08,0x04,0xC0,0xF0,0x30,0x00,0x00,0x60,0xE0,0xC3,0xE7,0x7C,0x3C,0x0F,0x03,0x00,0x00,0x00,", - "џ": "0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0xF0,0xF0,0x30,0x30,0x3F,0x3F,0x00,", + "Ѐ": b"\x00\xFC\xFC\x8D\x8F\x8E\x8C\x8C\x8C\x0C\x0C\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x31\x30\x30\x00", + "Ё": b"\x00\xFE\xFE\xC7\xC7\xC6\xC6\xC7\xC7\x06\x06\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "Ђ": b"\x00\x03\xFF\xFF\x83\xC3\xC3\xC3\xC0\x80\x00\x00\x00\x00\x3F\x3F\x01\x00\x30\x30\x39\x1F\x0F\x00", + "Ѓ": b"\x00\xFC\xFC\x0C\x0C\x0C\x0E\x0F\x0D\x0C\x0C\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "Є": b"\x00\xF8\xFC\xCE\xC7\xC3\xC3\xC3\x07\x0E\x0C\x00\x00\x07\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "Ѕ": b"\x00\x3C\x7E\x67\xE3\xC3\xC3\xC3\x87\x8E\x0C\x00\x00\x0C\x1C\x38\x30\x30\x30\x31\x39\x1F\x0F\x00", + "І": b"\x00\x00\x00\x03\x03\xFF\xFF\x03\x03\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ї": b"\x00\x00\x00\x0D\x0D\xFC\xFC\x0D\x0D\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "Ј": b"\x00\x00\x00\x00\x00\x00\x03\x03\x03\xFF\xFF\x00\x00\x0E\x1E\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "Љ": b"\x00\x00\xFE\xFF\x03\x03\xFF\xFF\xC0\xC0\x80\x00\x00\x30\x3F\x1F\x00\x00\x3F\x3F\x30\x39\x1F\x0F", + "Њ": b"\x00\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xC0\xC0\x80\x00\x00\x3F\x3F\x00\x00\x00\x3F\x3F\x30\x39\x1F\x0F", + "Ћ": b"\x00\x03\xFF\xFF\xC3\xC3\xC3\xC3\xC0\x80\x00\x00\x00\x00\x3F\x3F\x01\x00\x00\x00\x01\x3F\x3F\x00", + "Ќ": b"\x00\xFF\xFF\xC0\xE2\xF3\x39\x1C\x0E\x07\x03\x00\x00\x3F\x3F\x00\x01\x03\x07\x0E\x1C\x38\x30\x00", + "Ѝ": b"\x00\xFF\xFF\x00\x01\xC3\xF2\x38\x0E\xFF\xFF\x00\x00\x3F\x3F\x1C\x07\x03\x00\x00\x00\x3F\x3F\x00", + "Ў": b"\x00\x07\x1F\x7C\xF1\xC1\xC1\xF1\x7C\x1F\x07\x00\x00\x00\x30\x30\x3C\x0F\x07\x01\x00\x00\x00\x00", + "Џ": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x1F\x1F\x18\x18\x78\x78\x18\x18\x1F\x1F\x00", + "А": b"\x00\x00\x00\xE0\xFC\x1F\x1F\xFC\xE0\x00\x00\x00\x00\x38\x3F\x07\x06\x06\x06\x06\x07\x3F\x38\x00", + "Б": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xC3\xC3\x83\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x39\x1F\x0F\x00", + "В": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xE7\xFE\xBC\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x39\x1F\x0F\x00", + "Г": b"\x00\xFF\xFF\x03\x03\x03\x03\x03\x03\x03\x03\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "Ґ": b"\x00\xFC\xFC\x0C\x0C\x0C\x0C\x0C\x0C\x0F\x0F\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "Д": b"\x00\x00\xF8\xFE\x0F\x03\x03\x03\xFF\xFF\x00\x00\x00\x70\x7F\x1F\x18\x18\x18\x18\x1F\x7F\x70\x00", + "Е": b"\x00\xFF\xFF\xC3\xC3\xC3\xC3\xC3\xC3\x03\x03\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x30\x30\x30\x00", + "Ж": b"\x00\x03\x0F\xFC\xE0\xFF\xFF\xE0\xFC\x0F\x03\x00\x00\x38\x3F\x07\x00\x3F\x3F\x00\x07\x3F\x38\x00", + "З": b"\x0C\x0E\x07\x03\xC3\xC3\xC3\xC3\xC3\xE7\x7E\x3C\x0C\x1C\x38\x30\x30\x30\x30\x30\x30\x39\x1F\x0E", + "И": b"\x00\xFF\xFF\x00\x00\xC0\xF0\x38\x0E\xFF\xFF\x00\x00\x3F\x3F\x1C\x07\x03\x00\x00\x00\x3F\x3F\x00", + "Й": b"\x00\xFF\xFF\x00\x02\xC3\xF1\x38\x0E\xFF\xFF\x00\x00\x3F\x3F\x1C\x07\x03\x00\x00\x00\x3F\x3F\x00", + "К": b"\x00\xFF\xFF\xC0\xE0\xF0\x38\x1C\x0E\x07\x03\x00\x00\x3F\x3F\x00\x01\x03\x07\x0E\x1C\x38\x30\x00", + "Л": b"\x00\x00\xF0\xFC\x1E\x07\x03\x03\x03\xFF\xFF\x00\x00\x30\x3F\x1F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "М": b"\x00\xFF\xFF\x1E\x78\xE0\xE0\x78\x1E\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x01\x01\x00\x00\x3F\x3F\x00", + "Н": b"\x00\xFF\xFF\xC0\xC0\xC0\xC0\xC0\xC0\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "О": b"\x00\xF0\xFC\x0E\x07\x03\x03\x07\x0E\xFC\xF0\x00\x00\x03\x0F\x1C\x38\x30\x30\x38\x1C\x0F\x03\x00", + "П": b"\x00\xFF\xFF\x03\x03\x03\x03\x03\x03\xFF\xFF\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "Р": b"\x00\xFF\xFF\x83\x83\x83\x83\x83\xC7\xFE\x7C\x00\x00\x3F\x3F\x01\x01\x01\x01\x01\x01\x00\x00\x00", + "С": b"\x00\xF0\xFC\x0E\x07\x03\x03\x03\x07\x0E\x0C\x00\x00\x03\x0F\x1C\x38\x30\x30\x30\x38\x1C\x0C\x00", + "Т": b"\x00\x03\x03\x03\x03\xFF\xFF\x03\x03\x03\x03\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "У": b"\x00\x07\x1F\x7C\xF0\xC0\xC0\xF0\x7C\x1F\x07\x00\x00\x00\x30\x30\x3C\x0F\x07\x01\x00\x00\x00\x00", + "Ф": b"\x00\xF8\xFC\x0E\x06\xFF\xFF\x06\x0E\xFC\xF8\x00\x00\x03\x07\x0E\x0C\x3F\x3F\x0C\x0E\x07\x03\x00", + "Х": b"\x00\x03\x0F\x3C\xF0\xC0\xC0\xF0\x3C\x0F\x03\x00\x00\x30\x3C\x0F\x03\x00\x00\x03\x0F\x3C\x30\x00", + "Ц": b"\x00\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x1F\x1F\x18\x18\x18\x18\x18\x1F\x7F\x78\x00", + "Ч": b"\x00\x7F\xFF\xC0\xC0\xC0\xC0\xC0\xC0\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "Ш": b"\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x3F\x3F\x30\x30\x3F\x3F\x30\x30\x3F\x3F\x00", + "Щ": b"\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x1F\x1F\x18\x18\x1F\x1F\x18\x18\x1F\x7F\x70", + "Ъ": b"\x03\x03\xFF\xFF\xC0\xC0\xC0\xC0\xC0\x80\x00\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x39\x1F\x0F\x00", + "Ы": b"\x00\xFF\xFF\xC0\xC0\xC0\xC0\x80\x00\x00\xFF\xFF\x00\x3F\x3F\x30\x30\x30\x39\x1F\x0F\x00\x3F\x3F", + "Ь": b"\x00\xFF\xFF\xC0\xC0\xC0\xC0\xC0\xC0\x80\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x39\x1F\x0F\x00", + "Э": b"\x00\x0C\x0E\x07\xC3\xC3\xC3\xC7\xCE\xFC\xF8\x00\x00\x0C\x1C\x38\x30\x30\x30\x38\x1C\x0F\x07\x00", + "Ю": b"\x00\xFF\xFF\xC0\xFC\xFE\x07\x03\x07\xFE\xFC\x00\x00\x3F\x3F\x00\x0F\x1F\x38\x30\x38\x1F\x0F\x00", + "Я": b"\x00\x7C\xFE\xC7\x83\x83\x83\x83\x83\xFF\xFF\x00\x00\x30\x38\x1D\x0F\x07\x03\x01\x01\x3F\x3F\x00", + "а": b"\x00\x00\x30\x30\x30\x30\x30\x30\x30\xF0\xE0\x00\x00\x1E\x3F\x33\x33\x33\x33\x33\x33\x3F\x3F\x00", + "б": b"\x00\xE0\xF0\x30\x30\x30\x30\x30\x30\x30\x00\x00\x00\x1F\x3F\x33\x33\x33\x33\x33\x33\x3F\x1E\x00", + "в": b"\x00\xF0\xF0\x30\x30\x30\x30\x30\xF0\xE0\x00\x00\x00\x3F\x3F\x33\x33\x33\x33\x33\x33\x3F\x1E\x00", + "г": b"\x00\xF0\xF0\x30\x30\x30\x30\x30\x30\x30\x30\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "ґ": b"\x00\xF0\xF0\x30\x30\x30\x30\x30\x30\x3C\x3C\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "д": b"\x00\x00\xC0\xE0\x70\x30\x30\x30\xF0\xF0\x00\x00\x00\x60\x7F\x3F\x30\x30\x30\x30\x3F\x7F\x60\x00", + "е": b"\x00\xE0\xF0\x30\x30\x30\x30\x30\x30\xF0\xE0\x00\x00\x1F\x3F\x33\x33\x33\x33\x33\x33\x33\x33\x00", + "ж": b"\x00\x30\xF0\xC0\x00\xF0\xF0\x00\xC0\xF0\x30\x00\x00\x30\x3C\x0F\x03\x3F\x3F\x03\x0F\x3C\x30\x00", + "з": b"\x00\x60\x70\x30\x30\x30\x30\x30\x30\xF0\xE0\x00\x00\x18\x38\x30\x33\x33\x33\x33\x33\x3F\x1D\x00", + "и": b"\x00\xF0\xF0\x00\x00\x00\x80\xC0\xE0\xF0\xF0\x00\x00\x3F\x3F\x1C\x0E\x07\x03\x01\x00\x3F\x3F\x00", + "й": b"\x00\xF0\xF0\x00\x04\x08\x88\xC4\xE0\xF0\xF0\x00\x00\x3F\x3F\x1C\x0E\x07\x03\x01\x00\x3F\x3F\x00", + "к": b"\x00\xF0\xF0\x80\x80\xC0\xE0\x70\x30\x10\x00\x00\x00\x3F\x3F\x03\x03\x07\x0E\x1C\x38\x30\x20\x00", + "л": b"\x00\x00\xC0\xE0\x70\x30\x30\x30\x30\xF0\xF0\x00\x00\x30\x3F\x1F\x00\x00\x00\x00\x00\x3F\x3F\x00", + "м": b"\x00\xF0\xF0\xE0\xC0\x80\x80\xC0\xE0\xF0\xF0\x00\x00\x3F\x3F\x00\x01\x03\x03\x01\x00\x3F\x3F\x00", + "н": b"\x00\xF0\xF0\x00\x00\x00\x00\x00\x00\xF0\xF0\x00\x00\x3F\x3F\x03\x03\x03\x03\x03\x03\x3F\x3F\x00", + "о": b"\x00\xC0\xE0\x70\x30\x30\x30\x30\x70\xE0\xC0\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x1F\x0F\x00", + "п": b"\x00\xF0\xF0\x30\x30\x30\x30\x30\x30\xF0\xF0\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x3F\x3F\x00", + "р": b"\x00\xF0\xF0\x30\x30\x30\x30\x30\x70\xE0\xC0\x00\x00\xFF\xFF\x0C\x0C\x0C\x0C\x0C\x0E\x07\x03\x00", + "с": b"\x00\xC0\xE0\x70\x30\x30\x30\x30\x70\x60\x40\x00\x00\x0F\x1F\x38\x30\x30\x30\x30\x38\x18\x08\x00", + "т": b"\x00\x30\x30\x30\x30\xF0\xF0\x30\x30\x30\x30\x00\x00\x00\x00\x00\x00\x3F\x3F\x00\x00\x00\x00\x00", + "у": b"\x00\x30\xF0\xC0\x00\x00\x00\x00\xC0\xF0\x30\x00\x00\x60\xE0\xC3\xE7\x7C\x3C\x0F\x03\x00\x00\x00", + "ф": b"\x00\x80\xC0\x60\x60\xF0\xF0\x60\x60\xC0\x80\x00\x00\x0F\x1F\x30\x30\xFF\xFF\x30\x30\x1F\x0F\x00", + "х": b"\x00\x30\x70\xC0\x80\x00\x00\x80\xC0\x70\x30\x00\x00\x30\x38\x0C\x07\x03\x03\x07\x0C\x38\x30\x00", + "ц": b"\x00\xF0\xF0\x00\x00\x00\x00\x00\xF0\xF0\x00\x00\x00\x3F\x3F\x30\x30\x30\x30\x30\x3F\xFF\xF0\x00", + "ч": b"\x00\xF0\xF0\x00\x00\x00\x00\x00\x00\xF0\xF0\x00\x00\x01\x03\x03\x03\x03\x03\x03\x03\x3F\x3F\x00", + "ш": b"\x00\xF0\xF0\x00\x00\xE0\xE0\x00\x00\xF0\xF0\x00\x00\x3F\x3F\x30\x30\x3F\x3F\x30\x30\x3F\x3F\x00", + "щ": b"\x00\xF0\xF0\x00\x00\xF0\xF0\x00\x00\xF0\xF0\x00\x00\x3F\x3F\x30\x30\x3F\x3F\x30\x30\x3F\xFF\xE0", + "ъ": b"\x30\x30\xF0\xF0\x80\x80\x80\x80\x80\x00\x00\x00\x00\x00\x3F\x3F\x31\x31\x31\x31\x3B\x1F\x0E\x00", + "ы": b"\x00\xF0\xF0\x80\x80\x80\x00\x00\x00\xF0\xF0\x00\x00\x3F\x3F\x31\x31\x3B\x1F\x0E\x00\x3F\x3F\x00", + "ь": b"\x00\xF0\xF0\x80\x80\x80\x80\x80\x80\x00\x00\x00\x00\x3F\x3F\x31\x31\x31\x31\x31\x3B\x1F\x0E\x00", + "э": b"\x00\x40\x60\x70\x30\x30\x30\x30\x70\xE0\xC0\x00\x00\x08\x18\x38\x30\x33\x33\x33\x3B\x1F\x0F\x00", + "ю": b"\x00\xF0\xF0\x00\xE0\xF0\x30\x30\x30\xF0\xE0\x00\x00\x3F\x3F\x03\x1F\x3F\x30\x30\x30\x3F\x1F\x00", + "я": b"\x00\xC0\xE0\x70\x30\x30\x30\x30\x30\xF0\xF0\x00\x00\x21\x33\x3B\x1E\x0E\x06\x06\x06\x3F\x3F\x00", + "ѐ": b"\x00\xE0\xF0\x32\x36\x36\x34\x30\x30\xF0\xE0\x00\x00\x1F\x3F\x33\x33\x33\x33\x33\x33\x33\x33\x00", + "ё": b"\x00\xE0\xF0\x34\x34\x30\x30\x34\x34\xF0\xE0\x00\x00\x1F\x3F\x33\x33\x33\x33\x33\x33\x33\x33\x00", + "ђ": b"\x00\x30\xFC\xFC\x30\xB0\xB0\xB0\x80\x80\x00\x00\x00\x00\x3F\x3F\x07\x03\x01\x01\xC1\xFF\x3F\x00", + "ѓ": b"\x00\xF0\xF0\x30\x30\x34\x36\x32\x30\x30\x30\x00\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "є": b"\x00\xC0\xE0\x70\x30\x30\x30\x30\x70\x60\x40\x00\x00\x0F\x1F\x3B\x33\x33\x33\x30\x38\x18\x08\x00", + "ѕ": b"\x00\xE0\xF0\xB0\xB0\x30\x30\x30\x30\x70\x60\x00\x00\x18\x39\x31\x33\x33\x33\x37\x36\x3E\x1C\x00", + "і": b"\x00\x00\x00\x00\x30\xF6\xF6\x00\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ї": b"\x00\x00\x00\x04\x34\xF0\xF4\x04\x00\x00\x00\x00\x00\x00\x00\x30\x30\x3F\x3F\x30\x30\x00\x00\x00", + "ј": b"\x00\x00\x00\x00\x00\x30\x30\xF6\xF6\x00\x00\x00\x00\x00\x00\x60\xE0\xC0\xC0\xFF\x7F\x00\x00\x00", + "љ": b"\x00\x00\xE0\xF0\x30\x30\xF0\xF0\x00\x00\x00\x00\x00\x30\x3F\x1F\x00\x00\x3F\x3F\x33\x33\x1E\x0C", + "њ": b"\x00\xF0\xF0\x00\x00\x00\xF0\xF0\x00\x00\x00\x00\x00\x3F\x3F\x03\x03\x03\x3F\x3F\x33\x33\x1E\x0C", + "ћ": b"\x00\x30\xFC\xFC\xB0\xB0\xB0\xB0\x80\x80\x00\x00\x00\x00\x3F\x3F\x01\x01\x01\x01\x01\x3F\x3F\x00", + "ќ": b"\x00\xF0\xF0\x80\x88\xCC\xE4\x70\x30\x10\x00\x00\x00\x3F\x3F\x03\x03\x07\x0E\x1C\x38\x30\x20\x00", + "ѝ": b"\x00\xF0\xF0\x00\x06\x0C\x88\xC0\xE0\xF0\xF0\x00\x00\x3F\x3F\x1C\x0E\x07\x03\x01\x00\x3F\x3F\x00", + "ў": b"\x00\x30\xF0\xC0\x04\x08\x08\x04\xC0\xF0\x30\x00\x00\x60\xE0\xC3\xE7\x7C\x3C\x0F\x03\x00\x00\x00", + "џ": b"\x00\xF0\xF0\x00\x00\x00\x00\x00\x00\xF0\xF0\x00\x00\x3F\x3F\x30\x30\xF0\xF0\x30\x30\x3F\x3F\x00", } return font -def get_small_font_map_ascii_basic(): +def get_small_font_map_ascii_basic() -> Dict[str, bytes]: font = { # U+0000..U+007F Basic Latin - " ": "0x00, 0x00, 0x00, 0x00, 0x00, 0x00,", - "!": "0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,", - '"': "0x00, 0x07, 0x00, 0x07, 0x00, 0x00,", - "#": "0x14, 0x7f, 0x14, 0x7f, 0x14, 0x00,", - "$": "0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x00,", - "%": "0x23, 0x13, 0x08, 0x64, 0x62, 0x00,", - "&": "0x36, 0x49, 0x56, 0x20, 0x58, 0x00,", - "'": "0x00, 0x05, 0x03, 0x00, 0x00, 0x00,", - "(": "0x00, 0x1c, 0x22, 0x41, 0x00, 0x00,", - ")": "0x00, 0x41, 0x22, 0x1c, 0x00, 0x00,", - "*": "0x14, 0x08, 0x3e, 0x08, 0x14, 0x00,", - "+": "0x08, 0x08, 0x3e, 0x08, 0x08, 0x00,", - ",": "0x00, 0x50, 0x30, 0x00, 0x00, 0x00,", - "-": "0x08, 0x08, 0x08, 0x08, 0x08, 0x00,", - ".": "0x00, 0x60, 0x60, 0x00, 0x00, 0x00,", - "/": "0x20, 0x10, 0x08, 0x04, 0x02, 0x00,", - "0": "0x3e, 0x51, 0x49, 0x45, 0x3e, 0x00,", - "1": "0x00, 0x42, 0x7f, 0x40, 0x00, 0x00,", - "2": "0x42, 0x61, 0x51, 0x49, 0x46, 0x00,", - "3": "0x21, 0x41, 0x45, 0x4b, 0x31, 0x00,", - "4": "0x18, 0x14, 0x12, 0x7f, 0x10, 0x00,", - "5": "0x27, 0x45, 0x45, 0x45, 0x39, 0x00,", - "6": "0x3c, 0x4a, 0x49, 0x49, 0x30, 0x00,", - "7": "0x01, 0x71, 0x09, 0x05, 0x03, 0x00,", - "8": "0x36, 0x49, 0x49, 0x49, 0x36, 0x00,", - "9": "0x06, 0x49, 0x49, 0x29, 0x1e, 0x00,", - ":": "0x00, 0x36, 0x36, 0x00, 0x00, 0x00,", - ";": "0x00, 0x56, 0x36, 0x00, 0x00, 0x00,", - "<": "0x08, 0x14, 0x22, 0x41, 0x00, 0x00,", - "=": "0x14, 0x14, 0x14, 0x14, 0x14, 0x00,", - ">": "0x00, 0x41, 0x22, 0x14, 0x08, 0x00,", - "?": "0x02, 0x01, 0x51, 0x09, 0x06, 0x00,", - "@": "0x32, 0x49, 0x79, 0x41, 0x3e, 0x00,", - "A": "0x7e, 0x09, 0x09, 0x09, 0x7e, 0x00,", - "B": "0x7f, 0x49, 0x49, 0x49, 0x36, 0x00,", - "C": "0x3e, 0x41, 0x41, 0x41, 0x22, 0x00,", - "D": "0x7f, 0x41, 0x41, 0x22, 0x1c, 0x00,", - "E": "0x7f, 0x49, 0x49, 0x49, 0x41, 0x00,", - "F": "0x7f, 0x09, 0x09, 0x09, 0x01, 0x00,", - "G": "0x3e, 0x41, 0x41, 0x49, 0x7a, 0x00,", - "H": "0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00,", - "I": "0x00, 0x41, 0x7f, 0x41, 0x00, 0x00,", - "J": "0x20, 0x40, 0x41, 0x3f, 0x01, 0x00,", - "K": "0x7f, 0x08, 0x14, 0x22, 0x41, 0x00,", - "L": "0x7f, 0x40, 0x40, 0x40, 0x40, 0x00,", - "M": "0x7f, 0x02, 0x0c, 0x02, 0x7f, 0x00,", - "N": "0x7f, 0x04, 0x08, 0x10, 0x7f, 0x00,", - "O": "0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00,", - "P": "0x7f, 0x09, 0x09, 0x09, 0x06, 0x00,", - "Q": "0x3e, 0x41, 0x51, 0x21, 0x5e, 0x00,", - "R": "0x7f, 0x09, 0x19, 0x29, 0x46, 0x00,", - "S": "0x26, 0x49, 0x49, 0x49, 0x32, 0x00,", - "T": "0x01, 0x01, 0x7f, 0x01, 0x01, 0x00,", - "U": "0x3f, 0x40, 0x40, 0x40, 0x3f, 0x00,", - "V": "0x1f, 0x20, 0x40, 0x20, 0x1f, 0x00,", - "W": "0x3f, 0x40, 0x38, 0x40, 0x3f, 0x00,", - "X": "0x63, 0x14, 0x08, 0x14, 0x63, 0x00,", - "Y": "0x07, 0x08, 0x70, 0x08, 0x07, 0x00,", - "Z": "0x61, 0x51, 0x49, 0x45, 0x43, 0x00,", - "[": "0x00, 0x7f, 0x41, 0x41, 0x00, 0x00,", - "\\": "0x02, 0x04, 0x08, 0x10, 0x20, 0x00,", - "]": "0x00, 0x41, 0x41, 0x7f, 0x00, 0x00,", - "^": "0x04, 0x02, 0x01, 0x02, 0x04, 0x00,", - "_": "0x40, 0x40, 0x40, 0x40, 0x40, 0x00,", - "`": "0x00, 0x03, 0x05, 0x00, 0x00, 0x00,", - "a": "0x20, 0x54, 0x54, 0x54, 0x78, 0x00,", - "b": "0x7f, 0x48, 0x44, 0x44, 0x38, 0x00,", - "c": "0x38, 0x44, 0x44, 0x44, 0x20, 0x00,", - "d": "0x38, 0x44, 0x44, 0x48, 0x7f, 0x00,", - "e": "0x38, 0x54, 0x54, 0x54, 0x18, 0x00,", - "f": "0x00, 0x04, 0x7e, 0x05, 0x01, 0x00,", - "g": "0x08, 0x54, 0x54, 0x54, 0x3c, 0x00,", - "h": "0x7f, 0x08, 0x04, 0x04, 0x78, 0x00,", - "i": "0x00, 0x44, 0x7d, 0x40, 0x00, 0x00,", - "j": "0x20, 0x40, 0x44, 0x3d, 0x00, 0x00,", - "k": "0x00, 0x7f, 0x10, 0x28, 0x44, 0x00,", - "l": "0x00, 0x41, 0x7f, 0x40, 0x00, 0x00,", - "m": "0x7c, 0x04, 0x78, 0x04, 0x78, 0x00,", - "n": "0x7c, 0x08, 0x04, 0x04, 0x78, 0x00,", - "o": "0x38, 0x44, 0x44, 0x44, 0x38, 0x00,", - "p": "0x7c, 0x14, 0x14, 0x14, 0x08, 0x00,", - "q": "0x08, 0x14, 0x14, 0x14, 0x7c, 0x00,", - "r": "0x7c, 0x08, 0x04, 0x04, 0x08, 0x00,", - "s": "0x48, 0x54, 0x54, 0x54, 0x24, 0x00,", - "t": "0x04, 0x3e, 0x44, 0x40, 0x20, 0x00,", - "u": "0x3c, 0x40, 0x40, 0x20, 0x7c, 0x00,", - "v": "0x0c, 0x30, 0x40, 0x30, 0x0c, 0x00,", - "w": "0x3c, 0x40, 0x30, 0x40, 0x3c, 0x00,", - "x": "0x44, 0x24, 0x38, 0x48, 0x44, 0x00,", - "y": "0x44, 0x48, 0x30, 0x10, 0x0c, 0x00,", - "z": "0x44, 0x64, 0x54, 0x4c, 0x44, 0x00,", - "{": "0x08, 0x36, 0x41, 0x00, 0x00, 0x00,", - "|": "0x00, 0x00, 0x77, 0x00, 0x00, 0x00,", - "}": "0x00, 0x00, 0x41, 0x36, 0x08, 0x00,", - "~": "0x02, 0x01, 0x02, 0x04, 0x02, 0x00,", + " ": b"\x00\x00\x00\x00\x00\x00", + "!": b"\x00\x00\x4f\x00\x00\x00", + '"': b"\x00\x07\x00\x07\x00\x00", + "#": b"\x14\x7f\x14\x7f\x14\x00", + "$": b"\x24\x2a\x7f\x2a\x12\x00", + "%": b"\x23\x13\x08\x64\x62\x00", + "&": b"\x36\x49\x56\x20\x58\x00", + "'": b"\x00\x05\x03\x00\x00\x00", + "(": b"\x00\x1c\x22\x41\x00\x00", + ")": b"\x00\x41\x22\x1c\x00\x00", + "*": b"\x14\x08\x3e\x08\x14\x00", + "+": b"\x08\x08\x3e\x08\x08\x00", + ",": b"\x00\x50\x30\x00\x00\x00", + "-": b"\x08\x08\x08\x08\x08\x00", + ".": b"\x00\x60\x60\x00\x00\x00", + "/": b"\x20\x10\x08\x04\x02\x00", + "0": b"\x3e\x51\x49\x45\x3e\x00", + "1": b"\x00\x42\x7f\x40\x00\x00", + "2": b"\x42\x61\x51\x49\x46\x00", + "3": b"\x21\x41\x45\x4b\x31\x00", + "4": b"\x18\x14\x12\x7f\x10\x00", + "5": b"\x27\x45\x45\x45\x39\x00", + "6": b"\x3c\x4a\x49\x49\x30\x00", + "7": b"\x01\x71\x09\x05\x03\x00", + "8": b"\x36\x49\x49\x49\x36\x00", + "9": b"\x06\x49\x49\x29\x1e\x00", + ":": b"\x00\x36\x36\x00\x00\x00", + ";": b"\x00\x56\x36\x00\x00\x00", + "<": b"\x08\x14\x22\x41\x00\x00", + "=": b"\x14\x14\x14\x14\x14\x00", + ">": b"\x00\x41\x22\x14\x08\x00", + "?": b"\x02\x01\x51\x09\x06\x00", + "@": b"\x32\x49\x79\x41\x3e\x00", + "A": b"\x7e\x09\x09\x09\x7e\x00", + "B": b"\x7f\x49\x49\x49\x36\x00", + "C": b"\x3e\x41\x41\x41\x22\x00", + "D": b"\x7f\x41\x41\x22\x1c\x00", + "E": b"\x7f\x49\x49\x49\x41\x00", + "F": b"\x7f\x09\x09\x09\x01\x00", + "G": b"\x3e\x41\x41\x49\x7a\x00", + "H": b"\x7f\x08\x08\x08\x7f\x00", + "I": b"\x00\x41\x7f\x41\x00\x00", + "J": b"\x20\x40\x41\x3f\x01\x00", + "K": b"\x7f\x08\x14\x22\x41\x00", + "L": b"\x7f\x40\x40\x40\x40\x00", + "M": b"\x7f\x02\x0c\x02\x7f\x00", + "N": b"\x7f\x04\x08\x10\x7f\x00", + "O": b"\x3e\x41\x41\x41\x3e\x00", + "P": b"\x7f\x09\x09\x09\x06\x00", + "Q": b"\x3e\x41\x51\x21\x5e\x00", + "R": b"\x7f\x09\x19\x29\x46\x00", + "S": b"\x26\x49\x49\x49\x32\x00", + "T": b"\x01\x01\x7f\x01\x01\x00", + "U": b"\x3f\x40\x40\x40\x3f\x00", + "V": b"\x1f\x20\x40\x20\x1f\x00", + "W": b"\x3f\x40\x38\x40\x3f\x00", + "X": b"\x63\x14\x08\x14\x63\x00", + "Y": b"\x07\x08\x70\x08\x07\x00", + "Z": b"\x61\x51\x49\x45\x43\x00", + "[": b"\x00\x7f\x41\x41\x00\x00", + "\\": b"\x02\x04\x08\x10\x20\x00", + "]": b"\x00\x41\x41\x7f\x00\x00", + "^": b"\x04\x02\x01\x02\x04\x00", + "_": b"\x40\x40\x40\x40\x40\x00", + "`": b"\x00\x03\x05\x00\x00\x00", + "a": b"\x20\x54\x54\x54\x78\x00", + "b": b"\x7f\x48\x44\x44\x38\x00", + "c": b"\x38\x44\x44\x44\x20\x00", + "d": b"\x38\x44\x44\x48\x7f\x00", + "e": b"\x38\x54\x54\x54\x18\x00", + "f": b"\x00\x04\x7e\x05\x01\x00", + "g": b"\x08\x54\x54\x54\x3c\x00", + "h": b"\x7f\x08\x04\x04\x78\x00", + "i": b"\x00\x44\x7d\x40\x00\x00", + "j": b"\x20\x40\x44\x3d\x00\x00", + "k": b"\x00\x7f\x10\x28\x44\x00", + "l": b"\x00\x41\x7f\x40\x00\x00", + "m": b"\x7c\x04\x78\x04\x78\x00", + "n": b"\x7c\x08\x04\x04\x78\x00", + "o": b"\x38\x44\x44\x44\x38\x00", + "p": b"\x7c\x14\x14\x14\x08\x00", + "q": b"\x08\x14\x14\x14\x7c\x00", + "r": b"\x7c\x08\x04\x04\x08\x00", + "s": b"\x48\x54\x54\x54\x24\x00", + "t": b"\x04\x3e\x44\x40\x20\x00", + "u": b"\x3c\x40\x40\x20\x7c\x00", + "v": b"\x0c\x30\x40\x30\x0c\x00", + "w": b"\x3c\x40\x30\x40\x3c\x00", + "x": b"\x44\x24\x38\x48\x44\x00", + "y": b"\x44\x48\x30\x10\x0c\x00", + "z": b"\x44\x64\x54\x4c\x44\x00", + "{": b"\x08\x36\x41\x00\x00\x00", + "|": b"\x00\x00\x77\x00\x00\x00", + "}": b"\x00\x00\x41\x36\x08\x00", + "~": b"\x02\x01\x02\x04\x02\x00", } return font -def get_small_font_map_latin_extended(): +def get_small_font_map_latin_extended() -> Dict[str, bytes]: font = { # U+0080..U+00FF Latin-1 Supplement - "¡": "0x00, 0x00, 0x79, 0x00, 0x00, 0x00,", - "¢": "0x1c, 0x22, 0x7f, 0x22, 0x10, 0x00,", - "£": "0x50, 0x7e, 0x51, 0x41, 0x42, 0x00,", - "¤": "0x22, 0x1c, 0x14, 0x1c, 0x22, 0x00,", - "¥": "0x15, 0x16, 0x7c, 0x16, 0x15, 0x00,", - "¦": "0x00, 0x00, 0x77, 0x00, 0x00, 0x00,", - "§": "0x4a, 0x55, 0x55, 0x55, 0x29, 0x00,", - "¨": "0x00, 0x01, 0x00, 0x01, 0x00, 0x00,", - "©": "0x00, 0x18, 0x24, 0x24, 0x00, 0x00,", - "«": "0x08, 0x14, 0x00, 0x08, 0x14, 0x00,", - "¬": "0x08, 0x08, 0x08, 0x08, 0x38, 0x00,", - "­": "0x08, 0x08, 0x08, 0x08, 0x08, 0x00,", - "¯": "0x00, 0x01, 0x01, 0x01, 0x00, 0x00,", - "°": "0x00, 0x00, 0x07, 0x05, 0x07, 0x00,", - "±": "0x44, 0x44, 0x5f, 0x44, 0x44, 0x00,", - "²": "0x1d, 0x15, 0x17, 0x00, 0x00, 0x00,", - "³": "0x15, 0x15, 0x1f, 0x00, 0x00, 0x00,", - "´": "0x00, 0x04, 0x02, 0x01, 0x00, 0x00,", - "µ": "0x7c, 0x10, 0x10, 0x0c, 0x10, 0x00,", - "¶": "0x02, 0x07, 0x7f, 0x01, 0x7f, 0x00,", - "·": "0x00, 0x00, 0x08, 0x00, 0x00, 0x00,", - "¸": "0x00, 0x40, 0x60, 0x00, 0x00, 0x00,", - "¹": "0x12, 0x1f, 0x10, 0x00, 0x00, 0x00,", - "º": "0x07, 0x05, 0x07, 0x00, 0x00, 0x00,", - "»": "0x14, 0x08, 0x00, 0x14, 0x08, 0x00,", - "¼": "0x21, 0x17, 0x38, 0x24, 0x72, 0x00,", - "½": "0x21, 0x17, 0x78, 0x54, 0x5e, 0x00,", - "¿": "0x30, 0x48, 0x45, 0x40, 0x20, 0x00,", - "À": "0x78, 0x15, 0x16, 0x14, 0x78, 0x00,", - "Á": "0x78, 0x14, 0x16, 0x15, 0x78, 0x00,", - "Â": "0x78, 0x16, 0x15, 0x16, 0x78, 0x00,", - "Ã": "0x7a, 0x29, 0x2a, 0x79, 0x00, 0x00,", - "Ä": "0x78, 0x15, 0x14, 0x15, 0x78, 0x00,", - "Å": "0x78, 0x14, 0x15, 0x14, 0x78, 0x00,", - "Æ": "0x7e, 0x09, 0x7f, 0x49, 0x49, 0x00,", - "Ç": "0x0e, 0x51, 0x71, 0x11, 0x08, 0x00,", - "È": "0x7c, 0x55, 0x56, 0x44, 0x44, 0x00,", - "É": "0x7c, 0x54, 0x56, 0x45, 0x44, 0x00,", - "Ê": "0x7c, 0x56, 0x55, 0x46, 0x44, 0x00,", - "Ë": "0x7c, 0x55, 0x54, 0x45, 0x44, 0x00,", - "Ì": "0x00, 0x49, 0x7a, 0x48, 0x00, 0x00,", - "Í": "0x00, 0x48, 0x7a, 0x49, 0x00, 0x00,", - "Î": "0x00, 0x4a, 0x79, 0x4a, 0x00, 0x00,", - "Ï": "0x44, 0x45, 0x7c, 0x45, 0x44, 0x00,", - "Ð": "0x08, 0x7f, 0x49, 0x22, 0x1c, 0x00,", - "Ñ": "0x7a, 0x11, 0x22, 0x79, 0x00, 0x00,", - "Ò": "0x38, 0x45, 0x46, 0x44, 0x38, 0x00,", - "Ó": "0x38, 0x44, 0x46, 0x45, 0x38, 0x00,", - "Ô": "0x38, 0x46, 0x45, 0x46, 0x38, 0x00,", - "Õ": "0x32, 0x49, 0x4a, 0x31, 0x00, 0x00,", - "Ö": "0x38, 0x45, 0x44, 0x45, 0x38, 0x00,", - "×": "0x22, 0x14, 0x08, 0x14, 0x22, 0x00,", - "Ø": "0x58, 0x24, 0x54, 0x48, 0x34, 0x00,", - "Ù": "0x38, 0x41, 0x42, 0x40, 0x38, 0x00,", - "Ú": "0x38, 0x40, 0x42, 0x41, 0x38, 0x00,", - "Û": "0x38, 0x42, 0x41, 0x42, 0x38, 0x00,", - "Ü": "0x3c, 0x41, 0x40, 0x41, 0x3c, 0x00,", - "Ý": "0x04, 0x08, 0x72, 0x09, 0x04, 0x00,", - "Þ": "0x7f, 0x22, 0x22, 0x22, 0x1c, 0x00,", - "ß": "0x7e, 0x11, 0x25, 0x25, 0x1a, 0x00,", - "à": "0x20, 0x55, 0x56, 0x54, 0x78, 0x00,", - "á": "0x20, 0x54, 0x56, 0x55, 0x78, 0x00,", - "â": "0x20, 0x56, 0x55, 0x56, 0x78, 0x00,", - "ã": "0x22, 0x55, 0x56, 0x55, 0x78, 0x00,", - "ä": "0x20, 0x55, 0x54, 0x55, 0x78, 0x00,", - "å": "0x20, 0x54, 0x55, 0x54, 0x78, 0x00,", - "æ": "0x24, 0x54, 0x7c, 0x54, 0x48, 0x00,", - "ç": "0x1c, 0x22, 0x62, 0x22, 0x10, 0x00,", - "è": "0x38, 0x55, 0x56, 0x54, 0x08, 0x00,", - "é": "0x38, 0x54, 0x56, 0x55, 0x08, 0x00,", - "ê": "0x38, 0x56, 0x55, 0x56, 0x08, 0x00,", - "ë": "0x38, 0x55, 0x54, 0x55, 0x08, 0x00,", - "ì": "0x00, 0x45, 0x7e, 0x40, 0x00, 0x00,", - "í": "0x00, 0x44, 0x7e, 0x41, 0x00, 0x00,", - "î": "0x00, 0x46, 0x7d, 0x42, 0x00, 0x00,", - "ï": "0x00, 0x45, 0x7c, 0x41, 0x00, 0x00,", - "ñ": "0x78, 0x12, 0x09, 0x0a, 0x71, 0x00,", - "ò": "0x38, 0x45, 0x46, 0x44, 0x38, 0x00,", - "ó": "0x38, 0x44, 0x46, 0x45, 0x38, 0x00,", - "ô": "0x38, 0x46, 0x45, 0x46, 0x38, 0x00,", - "õ": "0x32, 0x49, 0x4a, 0x31, 0x00, 0x00,", - "ö": "0x38, 0x45, 0x44, 0x45, 0x38, 0x00,", - "÷": "0x08, 0x08, 0x2a, 0x08, 0x08, 0x00,", - "ø": "0x58, 0x24, 0x54, 0x48, 0x34, 0x00,", - "ù": "0x3c, 0x41, 0x42, 0x20, 0x7c, 0x00,", - "ú": "0x3c, 0x40, 0x42, 0x21, 0x7c, 0x00,", - "û": "0x3c, 0x42, 0x41, 0x22, 0x7c, 0x00,", - "ü": "0x3c, 0x41, 0x40, 0x21, 0x5c, 0x00,", - "ű": "0x3c, 0x41, 0x40, 0x21, 0x5c, 0x00,", - "ų": "0x3C, 0x40, 0x40, 0x20, 0xDC, 0x80,", - "ý": "0x44, 0x48, 0x32, 0x11, 0x0c, 0x00,", - "þ": "0x7c, 0x28, 0x28, 0x10, 0x00, 0x00,", - "ÿ": "0x44, 0x49, 0x30, 0x11, 0x0c, 0x00,", + "¡": b"\x00\x00\x79\x00\x00\x00", + "¢": b"\x1c\x22\x7f\x22\x10\x00", + "£": b"\x50\x7e\x51\x41\x42\x00", + "¤": b"\x22\x1c\x14\x1c\x22\x00", + "¥": b"\x15\x16\x7c\x16\x15\x00", + "¦": b"\x00\x00\x77\x00\x00\x00", + "§": b"\x4a\x55\x55\x55\x29\x00", + "¨": b"\x00\x01\x00\x01\x00\x00", + "©": b"\x00\x18\x24\x24\x00\x00", + "«": b"\x08\x14\x00\x08\x14\x00", + "¬": b"\x08\x08\x08\x08\x38\x00", + "­": b"\x08\x08\x08\x08\x08\x00", + "¯": b"\x00\x01\x01\x01\x00\x00", + "°": b"\x00\x00\x07\x05\x07\x00", + "±": b"\x44\x44\x5f\x44\x44\x00", + "²": b"\x1d\x15\x17\x00\x00\x00", + "³": b"\x15\x15\x1f\x00\x00\x00", + "´": b"\x00\x04\x02\x01\x00\x00", + "µ": b"\x7c\x10\x10\x0c\x10\x00", + "¶": b"\x02\x07\x7f\x01\x7f\x00", + "·": b"\x00\x00\x08\x00\x00\x00", + "¸": b"\x00\x40\x60\x00\x00\x00", + "¹": b"\x12\x1f\x10\x00\x00\x00", + "º": b"\x07\x05\x07\x00\x00\x00", + "»": b"\x14\x08\x00\x14\x08\x00", + "¼": b"\x21\x17\x38\x24\x72\x00", + "½": b"\x21\x17\x78\x54\x5e\x00", + "¿": b"\x30\x48\x45\x40\x20\x00", + "À": b"\x78\x15\x16\x14\x78\x00", + "Á": b"\x78\x14\x16\x15\x78\x00", + "Â": b"\x78\x16\x15\x16\x78\x00", + "Ã": b"\x7a\x29\x2a\x79\x00\x00", + "Ä": b"\x78\x15\x14\x15\x78\x00", + "Å": b"\x78\x14\x15\x14\x78\x00", + "Æ": b"\x7e\x09\x7f\x49\x49\x00", + "Ç": b"\x0e\x51\x71\x11\x08\x00", + "È": b"\x7c\x55\x56\x44\x44\x00", + "É": b"\x7c\x54\x56\x45\x44\x00", + "Ê": b"\x7c\x56\x55\x46\x44\x00", + "Ë": b"\x7c\x55\x54\x45\x44\x00", + "Ì": b"\x00\x49\x7a\x48\x00\x00", + "Í": b"\x00\x48\x7a\x49\x00\x00", + "Î": b"\x00\x4a\x79\x4a\x00\x00", + "Ï": b"\x44\x45\x7c\x45\x44\x00", + "Ð": b"\x08\x7f\x49\x22\x1c\x00", + "Ñ": b"\x7a\x11\x22\x79\x00\x00", + "Ò": b"\x38\x45\x46\x44\x38\x00", + "Ó": b"\x38\x44\x46\x45\x38\x00", + "Ô": b"\x38\x46\x45\x46\x38\x00", + "Õ": b"\x32\x49\x4a\x31\x00\x00", + "Ö": b"\x38\x45\x44\x45\x38\x00", + "×": b"\x22\x14\x08\x14\x22\x00", + "Ø": b"\x58\x24\x54\x48\x34\x00", + "Ù": b"\x38\x41\x42\x40\x38\x00", + "Ú": b"\x38\x40\x42\x41\x38\x00", + "Û": b"\x38\x42\x41\x42\x38\x00", + "Ü": b"\x3c\x41\x40\x41\x3c\x00", + "Ý": b"\x04\x08\x72\x09\x04\x00", + "Þ": b"\x7f\x22\x22\x22\x1c\x00", + "ß": b"\x7e\x11\x25\x25\x1a\x00", + "à": b"\x20\x55\x56\x54\x78\x00", + "á": b"\x20\x54\x56\x55\x78\x00", + "â": b"\x20\x56\x55\x56\x78\x00", + "ã": b"\x22\x55\x56\x55\x78\x00", + "ä": b"\x20\x55\x54\x55\x78\x00", + "å": b"\x20\x54\x55\x54\x78\x00", + "æ": b"\x24\x54\x7c\x54\x48\x00", + "ç": b"\x1c\x22\x62\x22\x10\x00", + "è": b"\x38\x55\x56\x54\x08\x00", + "é": b"\x38\x54\x56\x55\x08\x00", + "ê": b"\x38\x56\x55\x56\x08\x00", + "ë": b"\x38\x55\x54\x55\x08\x00", + "ì": b"\x00\x45\x7e\x40\x00\x00", + "í": b"\x00\x44\x7e\x41\x00\x00", + "î": b"\x00\x46\x7d\x42\x00\x00", + "ï": b"\x00\x45\x7c\x41\x00\x00", + "ñ": b"\x78\x12\x09\x0a\x71\x00", + "ò": b"\x38\x45\x46\x44\x38\x00", + "ó": b"\x38\x44\x46\x45\x38\x00", + "ô": b"\x38\x46\x45\x46\x38\x00", + "õ": b"\x32\x49\x4a\x31\x00\x00", + "ö": b"\x38\x45\x44\x45\x38\x00", + "÷": b"\x08\x08\x2a\x08\x08\x00", + "ø": b"\x58\x24\x54\x48\x34\x00", + "ù": b"\x3c\x41\x42\x20\x7c\x00", + "ú": b"\x3c\x40\x42\x21\x7c\x00", + "û": b"\x3c\x42\x41\x22\x7c\x00", + "ü": b"\x3c\x41\x40\x21\x5c\x00", + "ű": b"\x3c\x41\x40\x21\x5c\x00", + "ų": b"\x3C\x40\x40\x20\xDC\x80", + "ý": b"\x44\x48\x32\x11\x0c\x00", + "þ": b"\x7c\x28\x28\x10\x00\x00", + "ÿ": b"\x44\x49\x30\x11\x0c\x00", # U+0100..U+017F Latin Extended A - "Ā": "0x78, 0x15, 0x15, 0x15, 0x78, 0x00,", - "ā": "0x20, 0x55, 0x55, 0x55, 0x78, 0x00,", - "Ă": "0x78, 0x15, 0x16, 0x15, 0x78, 0x00,", - "ă": "0x20, 0x55, 0x56, 0x55, 0x78, 0x00,", - "Ą": "0x7e, 0x09, 0x09, 0x49, 0xbe, 0x00,", - "ą": "0x20, 0x54, 0x54, 0xd4, 0x78, 0x00,", - "Ć": "0x38, 0x44, 0x46, 0x45, 0x28, 0x00,", - "ć": "0x38, 0x44, 0x46, 0x45, 0x20, 0x00,", - "Ĉ": "0x38, 0x46, 0x45, 0x46, 0x28, 0x00,", - "ĉ": "0x38, 0x46, 0x45, 0x46, 0x20, 0x00,", - "Ċ": "0x38, 0x44, 0x45, 0x44, 0x28, 0x00,", - "ċ": "0x38, 0x44, 0x45, 0x44, 0x20, 0x00,", - "Č": "0x38, 0x45, 0x46, 0x45, 0x28, 0x00,", - "č": "0x38, 0x45, 0x46, 0x45, 0x20, 0x00,", - "Ď": "0x7c, 0x45, 0x46, 0x29, 0x10, 0x00,", - "ď": "0x38, 0x44, 0x44, 0x4A, 0x7F, 0x00,", - "Đ": "0x08, 0x7f, 0x49, 0x22, 0x1c, 0x00,", - "đ": "0x38, 0x44, 0x44, 0x4A, 0x7F, 0x00,", - "Ē": "0x7c, 0x55, 0x55, 0x55, 0x44, 0x00,", - "ē": "0x38, 0x55, 0x55, 0x55, 0x08, 0x00,", - "Ĕ": "0x7c, 0x55, 0x56, 0x55, 0x44, 0x00,", - "ĕ": "0x38, 0x55, 0x56, 0x55, 0x08, 0x00,", - "Ė": "0x7c, 0x54, 0x55, 0x54, 0x44, 0x00,", - "ė": "0x38, 0x54, 0x55, 0x54, 0x08, 0x00,", - "Ę": "0x7f, 0x49, 0x49, 0xc9, 0x41, 0x00,", - "ę": "0x38, 0x54, 0x54, 0xd4, 0x18, 0x00,", - "Ě": "0x7c, 0x55, 0x56, 0x55, 0x44, 0x00,", - "ě": "0x38, 0x55, 0x56, 0x55, 0x08, 0x00,", - "Ĝ": "0x38, 0x46, 0x55, 0x56, 0x70, 0x00,", - "ĝ": "0x08, 0x56, 0x55, 0x56, 0x3c, 0x00,", - "Ğ": "0x38, 0x45, 0x56, 0x55, 0x30, 0x00,", - "ğ": "0x08, 0x55, 0x56, 0x55, 0x3c, 0x00,", - "Ġ": "0x38, 0x44, 0x55, 0x54, 0x30, 0x00,", - "ġ": "0x08, 0x54, 0x55, 0x54, 0x3c, 0x00,", - "Ģ": "0x0e, 0x51, 0x35, 0x15, 0x1c, 0x00,", - "Ĥ": "0x7c, 0x12, 0x11, 0x12, 0x7c, 0x00,", - "ĥ": "0x02, 0x79, 0x22, 0x10, 0x60, 0x00,", - "Ħ": "0x02, 0x7f, 0x0a, 0x7f, 0x02, 0x00,", - "ħ": "0x02, 0x7f, 0x12, 0x08, 0x70, 0x00,", - "Ĩ": "0x4a, 0x49, 0x7a, 0x49, 0x48, 0x00,", - "ĩ": "0x02, 0x49, 0x7a, 0x41, 0x00, 0x00,", - "Ī": "0x44, 0x45, 0x7d, 0x45, 0x44, 0x00,", - "ī": "0x00, 0x45, 0x7d, 0x41, 0x00, 0x00,", - "Ĭ": "0x44, 0x45, 0x7e, 0x45, 0x44, 0x00,", - "ĭ": "0x00, 0x45, 0x7e, 0x41, 0x00, 0x00,", - "Į": "0x00, 0x41, 0x7f, 0xc1, 0x00, 0x00,", - "į": "0x00, 0x44, 0x7d, 0xc0, 0x00, 0x00,", - "İ": "0x44, 0x44, 0x7d, 0x44, 0x44, 0x00,", - "ı": "0x00, 0x44, 0x7c, 0x40, 0x00, 0x00,", - "ij": "0x44, 0x7d, 0x40, 0x44, 0x3d, 0x00,", - "Ĵ": "0x20, 0x40, 0x46, 0x3d, 0x06, 0x00,", - "ĵ": "0x00, 0x20, 0x46, 0x3d, 0x02, 0x00,", - "Ķ": "0x1f, 0x44, 0x2a, 0x11, 0x00, 0x00,", - "ķ": "0x1f, 0x44, 0x2a, 0x11, 0x00, 0x00,", - "ĸ": "0x7c, 0x10, 0x28, 0x44, 0x00, 0x00,", - "Ĺ": "0x7c, 0x40, 0x42, 0x41, 0x40, 0x00,", - "Ľ": "0x7c, 0x40, 0x42, 0x41, 0x40, 0x00,", - "ĺ": "0x00, 0x44, 0x7e, 0x41, 0x00, 0x00,", - "Ļ": "0x1f, 0x50, 0x30, 0x10, 0x10, 0x00,", - "ļ": "0x00, 0x51, 0x3f, 0x10, 0x00, 0x00,", - "ľ": "0x00, 0x41, 0x7f, 0x40, 0x03, 0x00,", - "Ŀ": "0x7f, 0x40, 0x40, 0x48, 0x40, 0x00,", - "ŀ": "0x00, 0x41, 0x7f, 0x40, 0x08, 0x00,", - "Ł": "0x10, 0x7F, 0x48, 0x44, 0x40, 0x00,", - "ł": "0x00, 0x49, 0x7F, 0x44, 0x00, 0x00,", - "Ń": "0x7c, 0x08, 0x12, 0x21, 0x7c, 0x00,", - "ń": "0x7c, 0x08, 0x06, 0x05, 0x78, 0x00,", - "Ņ": "0x1f, 0x42, 0x24, 0x08, 0x1f, 0x00,", - "ņ": "0x1f, 0x42, 0x21, 0x01, 0x1e, 0x00,", - "Ň": "0x7c, 0x09, 0x12, 0x21, 0x7c, 0x00,", - "ň": "0x7c, 0x09, 0x06, 0x05, 0x78, 0x00,", - "Ō": "0x38, 0x45, 0x45, 0x45, 0x38, 0x00,", - "ō": "0x38, 0x45, 0x45, 0x45, 0x38, 0x00,", - "Ŏ": "0x38, 0x45, 0x46, 0x45, 0x38, 0x00,", - "ŏ": "0x38, 0x45, 0x46, 0x45, 0x38, 0x00,", - "ő": "0x38, 0x45, 0x44, 0x45, 0x38, 0x00,", - "Œ": "0x3e, 0x41, 0x7f, 0x49, 0x49, 0x00,", - "œ": "0x38, 0x44, 0x7c, 0x54, 0x58, 0x00,", - "Ŕ": "0x7c, 0x14, 0x16, 0x15, 0x68, 0x00,", - "ŕ": "0x7c, 0x08, 0x06, 0x05, 0x08, 0x00,", - "Ŗ": "0x1f, 0x45, 0x25, 0x05, 0x1a, 0x00,", - "ŗ": "0x1f, 0x42, 0x21, 0x01, 0x02, 0x00,", - "Ř": "0x7c, 0x15, 0x16, 0x15, 0x68, 0x00,", - "ř": "0x7c, 0x09, 0x06, 0x05, 0x08, 0x00,", - "Ś": "0x08, 0x54, 0x56, 0x55, 0x20, 0x00,", - "ś": "0x48, 0x54, 0x56, 0x55, 0x24, 0x00,", - "Ŝ": "0x08, 0x56, 0x55, 0x56, 0x20, 0x00,", - "ŝ": "0x48, 0x56, 0x55, 0x56, 0x24, 0x00,", - "Ş": "0x02, 0x55, 0x35, 0x15, 0x08, 0x00,", - "ş": "0x12, 0x55, 0x35, 0x15, 0x09, 0x00,", - "Š": "0x08, 0x55, 0x56, 0x55, 0x20, 0x00,", - "š": "0x48, 0x55, 0x56, 0x55, 0x24, 0x00,", - "Ţ": "0x01, 0x41, 0x3f, 0x01, 0x01, 0x00,", - "ţ": "0x02, 0x4f, 0x32, 0x10, 0x08, 0x00,", - "Ť": "0x04, 0x05, 0x7e, 0x05, 0x04, 0x00,", - "ť": "0x04, 0x3e, 0x44, 0x40, 0x23, 0x00,", - "Ŧ": "0x01, 0x09, 0x7f, 0x09, 0x01, 0x00,", - "ŧ": "0x14, 0x3e, 0x54, 0x40, 0x20, 0x00,", - "Ū": "0x3c, 0x41, 0x41, 0x41, 0x3c, 0x00,", - "ū": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", - "Ŭ": "0x3c, 0x41, 0x42, 0x41, 0x3c, 0x00,", - "ŭ": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", - "Ů": "0x3c, 0x40, 0x41, 0x40, 0x3c, 0x00,", - "ů": "0x3c, 0x41, 0x41, 0x21, 0x7c, 0x00,", - "Ŵ": "0x3c, 0x42, 0x39, 0x42, 0x3c, 0x00,", - "ŵ": "0x3c, 0x42, 0x31, 0x42, 0x3c, 0x00,", - "Ŷ": "0x04, 0x0a, 0x71, 0x0a, 0x04, 0x00,", - "ŷ": "0x04, 0x4a, 0x31, 0x12, 0x0c, 0x00,", - "Ÿ": "0x04, 0x09, 0x70, 0x09, 0x04, 0x00,", - "Ź": "0x44, 0x64, 0x56, 0x4d, 0x44, 0x00,", - "ź": "0x44, 0x64, 0x56, 0x4d, 0x44, 0x00,", - "Ż": "0x44, 0x64, 0x55, 0x4c, 0x44, 0x00,", - "ż": "0x44, 0x64, 0x55, 0x4c, 0x44, 0x00,", - "Ž": "0x44, 0x65, 0x56, 0x4d, 0x44, 0x00,", - "ž": "0x44, 0x65, 0x56, 0x4d, 0x44, 0x00,", - "ſ": "0x00, 0x04, 0x7e, 0x01, 0x01, 0x00,", + "Ā": b"\x78\x15\x15\x15\x78\x00", + "ā": b"\x20\x55\x55\x55\x78\x00", + "Ă": b"\x78\x15\x16\x15\x78\x00", + "ă": b"\x20\x55\x56\x55\x78\x00", + "Ą": b"\x7e\x09\x09\x49\xbe\x00", + "ą": b"\x20\x54\x54\xd4\x78\x00", + "Ć": b"\x38\x44\x46\x45\x28\x00", + "ć": b"\x38\x44\x46\x45\x20\x00", + "Ĉ": b"\x38\x46\x45\x46\x28\x00", + "ĉ": b"\x38\x46\x45\x46\x20\x00", + "Ċ": b"\x38\x44\x45\x44\x28\x00", + "ċ": b"\x38\x44\x45\x44\x20\x00", + "Č": b"\x38\x45\x46\x45\x28\x00", + "č": b"\x38\x45\x46\x45\x20\x00", + "Ď": b"\x7c\x45\x46\x29\x10\x00", + "ď": b"\x38\x44\x44\x4A\x7F\x00", + "Đ": b"\x08\x7f\x49\x22\x1c\x00", + "đ": b"\x38\x44\x44\x4A\x7F\x00", + "Ē": b"\x7c\x55\x55\x55\x44\x00", + "ē": b"\x38\x55\x55\x55\x08\x00", + "Ĕ": b"\x7c\x55\x56\x55\x44\x00", + "ĕ": b"\x38\x55\x56\x55\x08\x00", + "Ė": b"\x7c\x54\x55\x54\x44\x00", + "ė": b"\x38\x54\x55\x54\x08\x00", + "Ę": b"\x7f\x49\x49\xc9\x41\x00", + "ę": b"\x38\x54\x54\xd4\x18\x00", + "Ě": b"\x7c\x55\x56\x55\x44\x00", + "ě": b"\x38\x55\x56\x55\x08\x00", + "Ĝ": b"\x38\x46\x55\x56\x70\x00", + "ĝ": b"\x08\x56\x55\x56\x3c\x00", + "Ğ": b"\x38\x45\x56\x55\x30\x00", + "ğ": b"\x08\x55\x56\x55\x3c\x00", + "Ġ": b"\x38\x44\x55\x54\x30\x00", + "ġ": b"\x08\x54\x55\x54\x3c\x00", + "Ģ": b"\x0e\x51\x35\x15\x1c\x00", + "Ĥ": b"\x7c\x12\x11\x12\x7c\x00", + "ĥ": b"\x02\x79\x22\x10\x60\x00", + "Ħ": b"\x02\x7f\x0a\x7f\x02\x00", + "ħ": b"\x02\x7f\x12\x08\x70\x00", + "Ĩ": b"\x4a\x49\x7a\x49\x48\x00", + "ĩ": b"\x02\x49\x7a\x41\x00\x00", + "Ī": b"\x44\x45\x7d\x45\x44\x00", + "ī": b"\x00\x45\x7d\x41\x00\x00", + "Ĭ": b"\x44\x45\x7e\x45\x44\x00", + "ĭ": b"\x00\x45\x7e\x41\x00\x00", + "Į": b"\x00\x41\x7f\xc1\x00\x00", + "į": b"\x00\x44\x7d\xc0\x00\x00", + "İ": b"\x44\x44\x7d\x44\x44\x00", + "ı": b"\x00\x44\x7c\x40\x00\x00", + "ij": b"\x44\x7d\x40\x44\x3d\x00", + "Ĵ": b"\x20\x40\x46\x3d\x06\x00", + "ĵ": b"\x00\x20\x46\x3d\x02\x00", + "Ķ": b"\x1f\x44\x2a\x11\x00\x00", + "ķ": b"\x1f\x44\x2a\x11\x00\x00", + "ĸ": b"\x7c\x10\x28\x44\x00\x00", + "Ĺ": b"\x7c\x40\x42\x41\x40\x00", + "Ľ": b"\x7c\x40\x42\x41\x40\x00", + "ĺ": b"\x00\x44\x7e\x41\x00\x00", + "Ļ": b"\x1f\x50\x30\x10\x10\x00", + "ļ": b"\x00\x51\x3f\x10\x00\x00", + "ľ": b"\x00\x41\x7f\x40\x03\x00", + "Ŀ": b"\x7f\x40\x40\x48\x40\x00", + "ŀ": b"\x00\x41\x7f\x40\x08\x00", + "Ł": b"\x10\x7F\x48\x44\x40\x00", + "ł": b"\x00\x49\x7F\x44\x00\x00", + "Ń": b"\x7c\x08\x12\x21\x7c\x00", + "ń": b"\x7c\x08\x06\x05\x78\x00", + "Ņ": b"\x1f\x42\x24\x08\x1f\x00", + "ņ": b"\x1f\x42\x21\x01\x1e\x00", + "Ň": b"\x7c\x09\x12\x21\x7c\x00", + "ň": b"\x7c\x09\x06\x05\x78\x00", + "Ō": b"\x38\x45\x45\x45\x38\x00", + "ō": b"\x38\x45\x45\x45\x38\x00", + "Ŏ": b"\x38\x45\x46\x45\x38\x00", + "ŏ": b"\x38\x45\x46\x45\x38\x00", + "ő": b"\x38\x45\x44\x45\x38\x00", + "Œ": b"\x3e\x41\x7f\x49\x49\x00", + "œ": b"\x38\x44\x7c\x54\x58\x00", + "Ŕ": b"\x7c\x14\x16\x15\x68\x00", + "ŕ": b"\x7c\x08\x06\x05\x08\x00", + "Ŗ": b"\x1f\x45\x25\x05\x1a\x00", + "ŗ": b"\x1f\x42\x21\x01\x02\x00", + "Ř": b"\x7c\x15\x16\x15\x68\x00", + "ř": b"\x7c\x09\x06\x05\x08\x00", + "Ś": b"\x08\x54\x56\x55\x20\x00", + "ś": b"\x48\x54\x56\x55\x24\x00", + "Ŝ": b"\x08\x56\x55\x56\x20\x00", + "ŝ": b"\x48\x56\x55\x56\x24\x00", + "Ş": b"\x02\x55\x35\x15\x08\x00", + "ş": b"\x12\x55\x35\x15\x09\x00", + "Š": b"\x08\x55\x56\x55\x20\x00", + "š": b"\x48\x55\x56\x55\x24\x00", + "Ţ": b"\x01\x41\x3f\x01\x01\x00", + "ţ": b"\x02\x4f\x32\x10\x08\x00", + "Ť": b"\x04\x05\x7e\x05\x04\x00", + "ť": b"\x04\x3e\x44\x40\x23\x00", + "Ŧ": b"\x01\x09\x7f\x09\x01\x00", + "ŧ": b"\x14\x3e\x54\x40\x20\x00", + "Ū": b"\x3c\x41\x41\x41\x3c\x00", + "ū": b"\x3c\x41\x41\x21\x7c\x00", + "Ŭ": b"\x3c\x41\x42\x41\x3c\x00", + "ŭ": b"\x3c\x41\x41\x21\x7c\x00", + "Ů": b"\x3c\x40\x41\x40\x3c\x00", + "ů": b"\x3c\x41\x41\x21\x7c\x00", + "Ŵ": b"\x3c\x42\x39\x42\x3c\x00", + "ŵ": b"\x3c\x42\x31\x42\x3c\x00", + "Ŷ": b"\x04\x0a\x71\x0a\x04\x00", + "ŷ": b"\x04\x4a\x31\x12\x0c\x00", + "Ÿ": b"\x04\x09\x70\x09\x04\x00", + "Ź": b"\x44\x64\x56\x4d\x44\x00", + "ź": b"\x44\x64\x56\x4d\x44\x00", + "Ż": b"\x44\x64\x55\x4c\x44\x00", + "ż": b"\x44\x64\x55\x4c\x44\x00", + "Ž": b"\x44\x65\x56\x4d\x44\x00", + "ž": b"\x44\x65\x56\x4d\x44\x00", + "ſ": b"\x00\x04\x7e\x01\x01\x00", } return font -def get_small_font_map_cyrillic(): +def get_small_font_map_cyrillic() -> Dict[str, bytes]: font = { # U+0400..U+04FF Cyrillic - "Ѐ": "0x7c, 0x55, 0x56, 0x44, 0x44, 0x00,", - "Ё": "0x7c, 0x55, 0x54, 0x45, 0x44, 0x00,", - "Ђ": "0x01, 0x7f, 0x09, 0x49, 0x31, 0x00,", - "Ѓ": "0x7c, 0x04, 0x06, 0x05, 0x04, 0x00,", - "Є": "0x3e, 0x49, 0x49, 0x41, 0x00, 0x00,", - "Ѕ": "0x06, 0x49, 0x49, 0x49, 0x30, 0x00,", - "І": "0x41, 0x41, 0x7f, 0x41, 0x41, 0x00,", - "Ї": "0x44, 0x45, 0x7c, 0x45, 0x44, 0x00,", - "Ј": "0x20, 0x40, 0x41, 0x3f, 0x01, 0x00,", - "Љ": "0x7f, 0x01, 0x7f, 0x48, 0x30, 0x00,", - "Њ": "0x7f, 0x08, 0x7f, 0x48, 0x30, 0x00,", - "Ћ": "0x01, 0x01, 0x7f, 0x09, 0x71, 0x00,", - "Ќ": "0x7c, 0x12, 0x29, 0x44, 0x00, 0x00,", - "Ѝ": "0x7c, 0x21, 0x12, 0x08, 0x7c, 0x00,", - "Ў": "0x44, 0x49, 0x32, 0x09, 0x04, 0x00,", - "Џ": "0x3f, 0x20, 0x60, 0x20, 0x3f, 0x00,", - "А": "0x7e, 0x09, 0x09, 0x09, 0x7e, 0x00,", - "Б": "0x7f, 0x49, 0x49, 0x49, 0x31, 0x00,", - "В": "0x7f, 0x49, 0x49, 0x49, 0x36, 0x00,", - "Г": "0x7f, 0x01, 0x01, 0x01, 0x01, 0x00,", - "Ґ": "0x7E, 0x02, 0x02, 0x02, 0x03, 0x00,", - "Д": "0x60, 0x3f, 0x21, 0x3f, 0x60, 0x00,", - "Е": "0x7f, 0x49, 0x49, 0x49, 0x41, 0x00,", - "Ж": "0x77, 0x08, 0x7f, 0x08, 0x77, 0x00,", - "З": "0x00, 0x41, 0x49, 0x49, 0x36, 0x00,", - "И": "0x7f, 0x10, 0x08, 0x04, 0x7f, 0x00,", - "Й": "0x7c, 0x21, 0x12, 0x09, 0x7c, 0x00,", - "К": "0x7f, 0x08, 0x14, 0x22, 0x41, 0x00,", - "Л": "0x40, 0x3f, 0x01, 0x01, 0x7f, 0x00,", - "М": "0x7f, 0x02, 0x04, 0x02, 0x7f, 0x00,", - "Н": "0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00,", - "О": "0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00,", - "П": "0x7f, 0x01, 0x01, 0x01, 0x7f, 0x00,", - "Р": "0x7f, 0x09, 0x09, 0x09, 0x06, 0x00,", - "С": "0x3e, 0x41, 0x41, 0x41, 0x22, 0x00,", - "Т": "0x01, 0x01, 0x7f, 0x01, 0x01, 0x00,", - "У": "0x47, 0x48, 0x30, 0x08, 0x07, 0x00,", - "Ф": "0x0c, 0x12, 0x7f, 0x12, 0x0c, 0x00,", - "Х": "0x63, 0x14, 0x08, 0x14, 0x63, 0x00,", - "Ц": "0x3f, 0x20, 0x20, 0x3f, 0x60, 0x00,", - "Ч": "0x07, 0x08, 0x08, 0x08, 0x7f, 0x00,", - "Ш": "0x7F, 0x40, 0x7F, 0x40, 0x7F, 0x00,", - "Щ": "0x7F, 0x40, 0x7F, 0x40, 0x7F, 0xC0,", - "Ъ": "0x01, 0x7f, 0x48, 0x48, 0x30, 0x00,", - "Ы": "0x7f, 0x48, 0x30, 0x00, 0x7f, 0x00,", - "Ь": "0x00, 0x7f, 0x48, 0x48, 0x30, 0x00,", - "Э": "0x22, 0x49, 0x49, 0x2a, 0x1c, 0x00,", - "Ю": "0x7f, 0x08, 0x3e, 0x41, 0x3e, 0x00,", - "Я": "0x46, 0x29, 0x19, 0x09, 0x7f, 0x00,", - "а": "0x20, 0x54, 0x54, 0x54, 0x78, 0x00,", - "б": "0x3c, 0x4a, 0x4a, 0x4a, 0x30, 0x00,", - "в": "0x7c, 0x54, 0x54, 0x54, 0x28, 0x00,", - "г": "0x7c, 0x04, 0x04, 0x04, 0x04, 0x00,", - "ґ": "0x7C, 0x04, 0x04, 0x04, 0x06, 0x00,", - "д": "0x40, 0x3c, 0x24, 0x3c, 0x60, 0x00,", - "е": "0x38, 0x54, 0x54, 0x54, 0x18, 0x00,", - "ж": "0x6c, 0x10, 0x7c, 0x10, 0x6c, 0x00,", - "з": "0x28, 0x44, 0x54, 0x54, 0x28, 0x00,", - "и": "0x7c, 0x20, 0x10, 0x08, 0x7c, 0x00,", - "й": "0x7c, 0x21, 0x12, 0x09, 0x7c, 0x00,", - "к": "0x7c, 0x10, 0x28, 0x44, 0x00, 0x00,", - "л": "0x40, 0x3c, 0x04, 0x04, 0x7c, 0x00,", - "м": "0x7c, 0x08, 0x10, 0x08, 0x7c, 0x00,", - "н": "0x7c, 0x10, 0x10, 0x10, 0x7c, 0x00,", - "о": "0x38, 0x44, 0x44, 0x44, 0x38, 0x00,", - "п": "0x7c, 0x04, 0x04, 0x04, 0x7c, 0x00,", - "р": "0x7c, 0x14, 0x14, 0x14, 0x08, 0x00,", - "с": "0x38, 0x44, 0x44, 0x44, 0x20, 0x00,", - "т": "0x04, 0x04, 0x7c, 0x04, 0x04, 0x00,", - "у": "0x4c, 0x50, 0x20, 0x10, 0x0c, 0x00,", - "ф": "0x18, 0x24, 0x7e, 0x24, 0x18, 0x00,", - "х": "0x44, 0x28, 0x10, 0x28, 0x44, 0x00,", - "ц": "0x3c, 0x20, 0x20, 0x3c, 0x60, 0x00,", - "ч": "0x0c, 0x10, 0x10, 0x10, 0x7c, 0x00,", - "ш": "0x7C, 0x40, 0x7C, 0x40, 0x7C, 0x00,", - "щ": "0x7C, 0x40, 0x7C, 0x40, 0xFC, 0x00,", - "ъ": "0x04, 0x7c, 0x50, 0x20, 0x00, 0x00,", - "ы": "0x7c, 0x50, 0x20, 0x00, 0x7c, 0x00,", - "ь": "0x00, 0x7c, 0x50, 0x20, 0x00, 0x00,", - "э": "0x28, 0x44, 0x54, 0x54, 0x28, 0x00,", - "ю": "0x7c, 0x10, 0x38, 0x44, 0x38, 0x00,", - "я": "0x48, 0x34, 0x14, 0x14, 0x7c, 0x00,", - "ѐ": "0x38, 0x55, 0x56, 0x54, 0x08, 0x00,", - "ё": "0x38, 0x55, 0x54, 0x55, 0x08, 0x00,", - "ђ": "0x02, 0x3f, 0x12, 0x48, 0x30, 0x00,", - "ѓ": "0x7c, 0x04, 0x06, 0x05, 0x04, 0x00,", - "є": "0x38, 0x54, 0x54, 0x44, 0x28, 0x00,", - "ѕ": "0x08, 0x54, 0x54, 0x54, 0x20, 0x00,", - "і": "0x00, 0x44, 0x7d, 0x40, 0x00, 0x00,", - "ї": "0x00, 0x45, 0x7c, 0x41, 0x00, 0x00,", - "ј": "0x20, 0x40, 0x44, 0x3d, 0x00, 0x00,", - "љ": "0x7c, 0x04, 0x7c, 0x50, 0x20, 0x00,", - "њ": "0x7c, 0x10, 0x7c, 0x50, 0x20, 0x00,", - "ћ": "0x04, 0x7e, 0x14, 0x10, 0x60, 0x00,", - "ќ": "0x7c, 0x12, 0x29, 0x44, 0x00, 0x00,", - "ѝ": "0x7c, 0x21, 0x12, 0x08, 0x7c, 0x00,", - "ў": "0x4c, 0x51, 0x22, 0x11, 0x0c, 0x00,", - "џ": "0x3c, 0x20, 0x60, 0x20, 0x3c, 0x00,", + "Ѐ": b"\x7c\x55\x56\x44\x44\x00", + "Ё": b"\x7c\x55\x54\x45\x44\x00", + "Ђ": b"\x01\x7f\x09\x49\x31\x00", + "Ѓ": b"\x7c\x04\x06\x05\x04\x00", + "Є": b"\x3e\x49\x49\x41\x00\x00", + "Ѕ": b"\x06\x49\x49\x49\x30\x00", + "І": b"\x41\x41\x7f\x41\x41\x00", + "Ї": b"\x44\x45\x7c\x45\x44\x00", + "Ј": b"\x20\x40\x41\x3f\x01\x00", + "Љ": b"\x7f\x01\x7f\x48\x30\x00", + "Њ": b"\x7f\x08\x7f\x48\x30\x00", + "Ћ": b"\x01\x01\x7f\x09\x71\x00", + "Ќ": b"\x7c\x12\x29\x44\x00\x00", + "Ѝ": b"\x7c\x21\x12\x08\x7c\x00", + "Ў": b"\x44\x49\x32\x09\x04\x00", + "Џ": b"\x3f\x20\x60\x20\x3f\x00", + "А": b"\x7e\x09\x09\x09\x7e\x00", + "Б": b"\x7f\x49\x49\x49\x31\x00", + "В": b"\x7f\x49\x49\x49\x36\x00", + "Г": b"\x7f\x01\x01\x01\x01\x00", + "Ґ": b"\x7E\x02\x02\x02\x03\x00", + "Д": b"\x60\x3f\x21\x3f\x60\x00", + "Е": b"\x7f\x49\x49\x49\x41\x00", + "Ж": b"\x77\x08\x7f\x08\x77\x00", + "З": b"\x00\x41\x49\x49\x36\x00", + "И": b"\x7f\x10\x08\x04\x7f\x00", + "Й": b"\x7c\x21\x12\x09\x7c\x00", + "К": b"\x7f\x08\x14\x22\x41\x00", + "Л": b"\x40\x3f\x01\x01\x7f\x00", + "М": b"\x7f\x02\x04\x02\x7f\x00", + "Н": b"\x7f\x08\x08\x08\x7f\x00", + "О": b"\x3e\x41\x41\x41\x3e\x00", + "П": b"\x7f\x01\x01\x01\x7f\x00", + "Р": b"\x7f\x09\x09\x09\x06\x00", + "С": b"\x3e\x41\x41\x41\x22\x00", + "Т": b"\x01\x01\x7f\x01\x01\x00", + "У": b"\x47\x48\x30\x08\x07\x00", + "Ф": b"\x0c\x12\x7f\x12\x0c\x00", + "Х": b"\x63\x14\x08\x14\x63\x00", + "Ц": b"\x3f\x20\x20\x3f\x60\x00", + "Ч": b"\x07\x08\x08\x08\x7f\x00", + "Ш": b"\x7F\x40\x7F\x40\x7F\x00", + "Щ": b"\x7F\x40\x7F\x40\x7F\xC0", + "Ъ": b"\x01\x7f\x48\x48\x30\x00", + "Ы": b"\x7f\x48\x30\x00\x7f\x00", + "Ь": b"\x00\x7f\x48\x48\x30\x00", + "Э": b"\x22\x49\x49\x2a\x1c\x00", + "Ю": b"\x7f\x08\x3e\x41\x3e\x00", + "Я": b"\x46\x29\x19\x09\x7f\x00", + "а": b"\x20\x54\x54\x54\x78\x00", + "б": b"\x3c\x4a\x4a\x4a\x30\x00", + "в": b"\x7c\x54\x54\x54\x28\x00", + "г": b"\x7c\x04\x04\x04\x04\x00", + "ґ": b"\x7C\x04\x04\x04\x06\x00", + "д": b"\x40\x3c\x24\x3c\x60\x00", + "е": b"\x38\x54\x54\x54\x18\x00", + "ж": b"\x6c\x10\x7c\x10\x6c\x00", + "з": b"\x28\x44\x54\x54\x28\x00", + "и": b"\x7c\x20\x10\x08\x7c\x00", + "й": b"\x7c\x21\x12\x09\x7c\x00", + "к": b"\x7c\x10\x28\x44\x00\x00", + "л": b"\x40\x3c\x04\x04\x7c\x00", + "м": b"\x7c\x08\x10\x08\x7c\x00", + "н": b"\x7c\x10\x10\x10\x7c\x00", + "о": b"\x38\x44\x44\x44\x38\x00", + "п": b"\x7c\x04\x04\x04\x7c\x00", + "р": b"\x7c\x14\x14\x14\x08\x00", + "с": b"\x38\x44\x44\x44\x20\x00", + "т": b"\x04\x04\x7c\x04\x04\x00", + "у": b"\x4c\x50\x20\x10\x0c\x00", + "ф": b"\x18\x24\x7e\x24\x18\x00", + "х": b"\x44\x28\x10\x28\x44\x00", + "ц": b"\x3c\x20\x20\x3c\x60\x00", + "ч": b"\x0c\x10\x10\x10\x7c\x00", + "ш": b"\x7C\x40\x7C\x40\x7C\x00", + "щ": b"\x7C\x40\x7C\x40\xFC\x00", + "ъ": b"\x04\x7c\x50\x20\x00\x00", + "ы": b"\x7c\x50\x20\x00\x7c\x00", + "ь": b"\x00\x7c\x50\x20\x00\x00", + "э": b"\x28\x44\x54\x54\x28\x00", + "ю": b"\x7c\x10\x38\x44\x38\x00", + "я": b"\x48\x34\x14\x14\x7c\x00", + "ѐ": b"\x38\x55\x56\x54\x08\x00", + "ё": b"\x38\x55\x54\x55\x08\x00", + "ђ": b"\x02\x3f\x12\x48\x30\x00", + "ѓ": b"\x7c\x04\x06\x05\x04\x00", + "є": b"\x38\x54\x54\x44\x28\x00", + "ѕ": b"\x08\x54\x54\x54\x20\x00", + "і": b"\x00\x44\x7d\x40\x00\x00", + "ї": b"\x00\x45\x7c\x41\x00\x00", + "ј": b"\x20\x40\x44\x3d\x00\x00", + "љ": b"\x7c\x04\x7c\x50\x20\x00", + "њ": b"\x7c\x10\x7c\x50\x20\x00", + "ћ": b"\x04\x7e\x14\x10\x60\x00", + "ќ": b"\x7c\x12\x29\x44\x00\x00", + "ѝ": b"\x7c\x21\x12\x08\x7c\x00", + "ў": b"\x4c\x51\x22\x11\x0c\x00", + "џ": b"\x3c\x20\x60\x20\x3c\x00", } return font @functools.lru_cache(maxsize=None) -def get_font_map(): +def get_font_map() -> Dict[str, bytes]: return { **get_font_map_ascii_basic(), **get_font_map_latin_extended(), @@ -865,7 +866,7 @@ def get_font_map(): @functools.lru_cache(maxsize=None) -def get_small_font_map(): +def get_small_font_map() -> Dict[str, bytes]: return { **get_small_font_map_ascii_basic(), **get_small_font_map_latin_extended(), diff --git a/Translations/make_translation.py b/Translations/make_translation.py index 4aad6fc5..c7e43782 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -192,7 +192,7 @@ def get_letter_counts(defs: dict, lang: dict, build_version: str) -> List[str]: return symbols_by_occurrence -def get_cjk_glyph(sym: str) -> str: +def get_cjk_glyph(sym: str) -> bytes: glyph: Glyph = cjk_font()[ord(sym)] data = glyph.data @@ -225,15 +225,15 @@ def get_cjk_glyph(sym: str) -> str: # top-most pixel. The data goes from the left-most to the right-most column # of the top half, then from the left-most to the right-most column of the # bottom half. - s = "" + bs = bytearray() for block in range(2): for c in range(dst_w): b = 0 for r in range(8): if get_cell(c, r + 8 * block): b |= 0x01 << r - s += f"0x{b:02X}," - return s + bs.append(b) + return bytes(bs) def get_bytes_from_font_index(index: int) -> bytes: @@ -291,10 +291,14 @@ def bytes_to_escaped(b: bytes) -> str: return "".join((f"\\x{i:02X}" for i in b)) +def bytes_to_c_hex(b: bytes) -> str: + return ", ".join((f"0x{i:02X}" for i in b)) + "," + + @dataclass class FontMap: - font12: Dict[str, str] - font06: Dict[str, str] + font12: Dict[str, bytes] + font06: Dict[str, Optional[bytes]] def get_font_map_and_table( @@ -307,8 +311,8 @@ def get_font_map_and_table( forced_first_symbols = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] # Get the font table, which does not include CJK chars - font_table = font_tables.get_font_map() - font_small_table = font_tables.get_small_font_map() + font_table: Dict[str, bytes] = font_tables.get_font_map() + font_small_table: Dict[str, bytes] = font_tables.get_small_font_map() # We want to put all CJK chars after non-CJK ones so that the CJK chars # do not need to be in the small font table to save space. @@ -340,8 +344,8 @@ def get_font_map_and_table( symbol_map[sym] = get_bytes_from_font_index(index) index += 1 - font12_map: Dict[str, str] = {} - font06_map: Dict[str, str] = {} + font12_map: Dict[str, bytes] = {} + font06_map: Dict[str, Optional[bytes]] = {} for sym in ordered_normal_sym_list: if sym not in font_table: logging.error(f"Missing Large font element for {sym}") @@ -355,13 +359,13 @@ def get_font_map_and_table( for sym in ordered_cjk_sym_list: if sym in font_table: raise ValueError("Symbol already exists in font_table") - font_line: str = get_cjk_glyph(sym) + font_line = get_cjk_glyph(sym) if font_line is None: logging.error(f"Missing Large font element for {sym}") sys.exit(1) font12_map[sym] = font_line # No data to add to the small font table - font06_map[sym] = "// " # placeholder + font06_map[sym] = None return sym_list, FontMap(font12_map, font06_map), symbol_map @@ -371,16 +375,17 @@ def make_font_table_cpp( ) -> str: output_table = "const uint8_t USER_FONT_12[] = {\n" for sym in sym_list: - output_table += ( - f"{font_map.font12[sym]}//{bytes_to_escaped(symbol_map[sym])} -> {sym}\n" - ) + output_table += f"{bytes_to_c_hex(font_map.font12[sym])}//{bytes_to_escaped(symbol_map[sym])} -> {sym}\n" output_table += "};\n" output_table += "const uint8_t USER_FONT_6x8[] = {\n" for sym in sym_list: - output_table += ( - f"{font_map.font06[sym]}//{bytes_to_escaped(symbol_map[sym])} -> {sym}\n" - ) + font_bytes = font_map.font06[sym] + if font_bytes: + font_line = bytes_to_c_hex(font_bytes) + else: + font_line = "// " # placeholder + output_table += f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}\n" output_table += "};\n" return output_table diff --git a/Translations/make_translation_test.py b/Translations/make_translation_test.py index 39b6f83b..9b2d1ba4 100644 --- a/Translations/make_translation_test.py +++ b/Translations/make_translation_test.py @@ -24,6 +24,12 @@ class TestMakeTranslation(unittest.TestCase): self.assertEqual(bytes_to_escaped(b"\x00"), "\\x00") self.assertEqual(bytes_to_escaped(b"\xF1\xAB"), "\\xF1\\xAB") + def test_bytes_to_c_hex(self): + from make_translation import bytes_to_c_hex + + self.assertEqual(bytes_to_c_hex(b"\x00"), "0x00,") + self.assertEqual(bytes_to_c_hex(b"\xF1\xAB"), "0xF1, 0xAB,") + if __name__ == "__main__": unittest.main() From 9f179f2371fafcd8b8380f4621d52a5c64309623 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Thu, 15 Apr 2021 14:32:09 +0800 Subject: [PATCH 13/19] Make BitmapEditor work with hex escape literals --- Translations/BitmapEditor.html | 47 ++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/Translations/BitmapEditor.html b/Translations/BitmapEditor.html index 4da92db4..b35d3af1 100644 --- a/Translations/BitmapEditor.html +++ b/Translations/BitmapEditor.html @@ -141,10 +141,36 @@ } } } + stringFromMatrix(true, false); + } + + function escapedToMatrix(str) { + app.encodedEscapeSequence = str; + clearMatrix(); + var strs = str.split("\\x"); + var c = 0; + var rs = 7; + for (var i = 0; i 0) { + v = parseInt(d, 16); + sv = padLeft(v.toString(2), "0", 8); + for (r = 0; r < 8; r++) { + paint(getCell(rs - r, c), sv.charAt(r) == '1'); + } + c++; + if (c >= app.matrix.cols) { + c = 0; + rs += 8; + } + } + } + stringFromMatrix(false, true); } - function stringFromMatrix() { + function stringFromMatrix(skipEncodedData, skipEncodedEscapeSequence) { var str = ""; + var strEscaped = ""; var delim = ""; var blocks = app.matrix.rows / 8; var rs = 7; @@ -158,11 +184,17 @@ } } str += delim + "0x" + padLeft(b.toString(16).toUpperCase(), "0", 2); + strEscaped += "\\x" + padLeft(b.toString(16).toUpperCase(), "0", 2); delim = ","; } rs += 8; } - app.encodedData = str; + if (!skipEncodedData) { + app.encodedData = str; + } + if (!skipEncodedEscapeSequence) { + app.encodedEscapeSequence = strEscaped; + } return str; } @@ -175,12 +207,16 @@ rows: 16 }, type: "big", - encodedData: "" + encodedData: "", + encodedEscapeSequence: "", }, methods : { VtoMatrix : function(val) { toMatrix(val); }, + escapedToMatrix : function(val) { + escapedToMatrix(val); + }, VchangeSize : function() { if (app.type == "big") { @@ -236,10 +272,11 @@
- +
- \ No newline at end of file + From cf154114d7deb2efc22617090e7396859bce5c16 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Thu, 15 Apr 2021 14:32:09 +0800 Subject: [PATCH 14/19] Change translation defs to specify fonts to use --- Translations/font_tables.py | 32 ++--- Translations/make_translation.py | 166 ++++++++++++++++++-------- Translations/translation_BG.json | 5 +- Translations/translation_CS.json | 5 +- Translations/translation_DA.json | 5 +- Translations/translation_DE.json | 5 +- Translations/translation_EN.json | 4 +- Translations/translation_ES.json | 5 +- Translations/translation_FI.json | 7 +- Translations/translation_FR.json | 5 +- Translations/translation_HR.json | 5 +- Translations/translation_HU.json | 5 +- Translations/translation_IT.json | 5 +- Translations/translation_JA_JP.json | 7 +- Translations/translation_LT.json | 5 +- Translations/translation_NL.json | 5 +- Translations/translation_NL_BE.json | 5 +- Translations/translation_NO.json | 5 +- Translations/translation_PL.json | 5 +- Translations/translation_PT.json | 5 +- Translations/translation_RU.json | 6 +- Translations/translation_SK.json | 5 +- Translations/translation_SL.json | 5 +- Translations/translation_SR_CYRL.json | 5 +- Translations/translation_SR_LATN.json | 5 +- Translations/translation_SV.json | 5 +- Translations/translation_TR.json | 5 +- Translations/translation_UK.json | 6 +- Translations/translation_YUE_HK.json | 5 +- Translations/translation_ZH_CN.json | 5 +- Translations/translation_ZH_TW.json | 5 +- 31 files changed, 248 insertions(+), 100 deletions(-) diff --git a/Translations/font_tables.py b/Translations/font_tables.py index 4d2068d0..e2f8cff9 100755 --- a/Translations/font_tables.py +++ b/Translations/font_tables.py @@ -1,5 +1,4 @@ -import functools -from typing import Dict +from typing import Dict, Final, Tuple def get_font_map_ascii_basic() -> Dict[str, bytes]: @@ -856,19 +855,20 @@ def get_small_font_map_cyrillic() -> Dict[str, bytes]: return font -@functools.lru_cache(maxsize=None) -def get_font_map() -> Dict[str, bytes]: - return { - **get_font_map_ascii_basic(), - **get_font_map_latin_extended(), - **get_font_map_cyrillic(), - } +NAME_ASCII_BASIC: Final = "ascii_basic" +NAME_LATIN_EXTENDED: Final = "latin_extended" +NAME_CYRILLIC: Final = "cyrillic" +NAME_CJK: Final = "cjk" -@functools.lru_cache(maxsize=None) -def get_small_font_map() -> Dict[str, bytes]: - return { - **get_small_font_map_ascii_basic(), - **get_small_font_map_latin_extended(), - **get_small_font_map_cyrillic(), - } +def get_font_maps_for_name( + font_name: str, +) -> Tuple[Dict[str, bytes], Dict[str, bytes]]: + if font_name == NAME_ASCII_BASIC: + return get_font_map_ascii_basic(), get_small_font_map_ascii_basic() + elif font_name == NAME_LATIN_EXTENDED: + return get_font_map_latin_extended(), get_small_font_map_latin_extended() + elif font_name == NAME_CYRILLIC: + return get_font_map_cyrillic(), get_small_font_map_cyrillic() + else: + raise ValueError("Invalid font name") diff --git a/Translations/make_translation.py b/Translations/make_translation.py index c7e43782..4e25ee71 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -301,8 +301,89 @@ class FontMap: font06: Dict[str, Optional[bytes]] +@dataclass +class FontMapsPerFont: + font12_maps: Dict[str, Dict[str, bytes]] + font06_maps: Dict[str, Dict[str, Optional[bytes]]] + sym_lists: Dict[str, List[str]] + + +def get_font_map_per_font(text_list: List[str], fonts: List[str]) -> FontMapsPerFont: + pending_sym_set = set(text_list) + if len(pending_sym_set) != len(text_list): + raise ValueError("`text_list` contains duplicated symbols") + + if fonts[0] != font_tables.NAME_ASCII_BASIC: + raise ValueError( + f'First item in `fonts` must be "{font_tables.NAME_ASCII_BASIC}"' + ) + + total_symbol_count = len(text_list) + # \x00 is for NULL termination and \x01 is for newline, so the maximum + # number of symbols allowed is as follow (see also the comments in + # `get_bytes_from_font_index`): + if total_symbol_count > (0x10 * 0xFF - 15) - 2: # 4063 + raise ValueError( + f"Error, too many used symbols for this version (total {total_symbol_count})" + ) + + logging.info(f"Generating fonts for {total_symbol_count} symbols") + + # Collect font bitmaps by the defined font order: + font12_maps: Dict[str, Dict[str, bytes]] = {} + font06_maps: Dict[str, Dict[str, Optional[bytes]]] = {} + sym_lists: Dict[str, List[str]] = {} + for font in fonts: + font12_maps[font] = {} + font12_map = font12_maps[font] + font06_maps[font] = {} + font06_map = font06_maps[font] + sym_lists[font] = [] + sym_list = sym_lists[font] + + if len(pending_sym_set) == 0: + logging.warning( + f"Font {font} not used because all symbols already have font bitmaps" + ) + continue + + if font == font_tables.NAME_CJK: + is_cjk = True + else: + is_cjk = False + font12: Dict[str, bytes] + font06: Dict[str, bytes] + font12, font06 = font_tables.get_font_maps_for_name(font) + + for sym in text_list: + if sym not in pending_sym_set: + continue + if is_cjk: + font12_line = get_cjk_glyph(sym) + if font12_line is None: + continue + font06_line = None + else: + try: + font12_line = font12[sym] + font06_line = font06[sym] + except KeyError: + continue + font12_map[sym] = font12_line + font06_map[sym] = font06_line + sym_list.append(sym) + pending_sym_set.remove(sym) + + if len(sym_list) == 0: + logging.warning(f"Font {font} not used by any symbols on the list") + if len(pending_sym_set) > 0: + raise KeyError(f"Symbols not found in specified fonts: {pending_sym_set}") + + return FontMapsPerFont(font12_maps, font06_maps, sym_lists) + + def get_font_map_and_table( - text_list: List[str], + text_list: List[str], fonts: List[str] ) -> Tuple[List[str], FontMap, Dict[str, bytes]]: # the text list is sorted # allocate out these in their order as number codes @@ -310,62 +391,38 @@ def get_font_map_and_table( index = 2 # start at 2, as 0= null terminator,1 = new line forced_first_symbols = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] - # Get the font table, which does not include CJK chars - font_table: Dict[str, bytes] = font_tables.get_font_map() - font_small_table: Dict[str, bytes] = font_tables.get_small_font_map() - - # We want to put all CJK chars after non-CJK ones so that the CJK chars - # do not need to be in the small font table to save space. - # We assume all symbols not in the font table to be a CJK char. - # We also enforce that numbers are first. - ordered_normal_sym_list: List[str] = forced_first_symbols + [ - x for x in text_list if x not in forced_first_symbols and x in font_table - ] - ordered_cjk_sym_list: List[str] = [ - x for x in text_list if x not in forced_first_symbols and x not in font_table + # We enforce that numbers come first. + text_list = forced_first_symbols + [ + x for x in text_list if x not in forced_first_symbols ] - total_symbol_count = len(ordered_normal_sym_list) + len(ordered_cjk_sym_list) - # \x00 is for NULL termination and \x01 is for newline, so the maximum - # number of symbols allowed is as follow (see also the comments in - # `get_bytes_from_font_index`): - if total_symbol_count > (0x10 * 0xFF - 15) - 2: # 4063 - logging.error( - f"Error, too many used symbols for this version (total {total_symbol_count})" - ) - sys.exit(1) + font_maps = get_font_map_per_font(text_list, fonts) + font12_maps = font_maps.font12_maps + font06_maps = font_maps.font06_maps - logging.info(f"Generating fonts for {total_symbol_count} symbols") + # Build the full font maps + font12_map = {} + font06_map = {} + for font in fonts: + font12_map.update(font12_maps[font]) + font06_map.update(font06_maps[font]) - sym_list = ordered_normal_sym_list + ordered_cjk_sym_list - for sym in sym_list: - if sym in symbol_map: - raise ValueError("Symbol not found in symbol map") + # Collect all symbols by the original symbol order, but also making sure + # all symbols with only large font must be placed after all symbols with + # both small and large fonts + sym_list_both_fonts = [] + sym_list_large_only = [] + for sym in text_list: + if font06_map[sym] is None: + sym_list_large_only.append(sym) + else: + sym_list_both_fonts.append(sym) + sym_list = sym_list_both_fonts + sym_list_large_only + + # Assign symbol bytes by font index + for index, sym in enumerate(sym_list, index): + assert sym not in symbol_map symbol_map[sym] = get_bytes_from_font_index(index) - index += 1 - - font12_map: Dict[str, bytes] = {} - font06_map: Dict[str, Optional[bytes]] = {} - for sym in ordered_normal_sym_list: - if sym not in font_table: - logging.error(f"Missing Large font element for {sym}") - sys.exit(1) - font12_map[sym] = font_table[sym] - if sym not in font_small_table: - logging.error(f"Missing Small font element for {sym}") - sys.exit(1) - font06_map[sym] = font_small_table[sym] - - for sym in ordered_cjk_sym_list: - if sym in font_table: - raise ValueError("Symbol already exists in font_table") - font_line = get_cjk_glyph(sym) - if font_line is None: - logging.error(f"Missing Large font element for {sym}") - sys.exit(1) - font12_map[sym] = font_line - # No data to add to the small font table - font06_map[sym] = None return sym_list, FontMap(font12_map, font06_map), symbol_map @@ -438,7 +495,10 @@ def prepare_language(lang: dict, defs: dict, build_version: str) -> LanguageData # Iterate over all of the text to build up the symbols & counts text_list = get_letter_counts(defs, lang, build_version) # From the letter counts, need to make a symbol translator & write out the font - sym_list, font_map, symbol_conversion_table = get_font_map_and_table(text_list) + fonts = lang["fonts"] + sym_list, font_map, symbol_conversion_table = get_font_map_and_table( + text_list, fonts + ) return LanguageData( lang, defs, build_version, sym_list, font_map, symbol_conversion_table ) diff --git a/Translations/translation_BG.json b/Translations/translation_BG.json index 6b5e3a35..5c285352 100644 --- a/Translations/translation_BG.json +++ b/Translations/translation_BG.json @@ -1,7 +1,10 @@ { "languageCode": "BG", "languageLocalName": "Български", - "cyrillicGlyphs": true, + "fonts": [ + "ascii_basic", + "cyrillic" + ], "messages": { "SettingsCalibrationDone": "Калибрацията завършена!", "SettingsCalibrationWarning": "Уверете се, че върха на поялника е със стайна температура преди да продължите!", diff --git a/Translations/translation_CS.json b/Translations/translation_CS.json index 8aed567d..645994f8 100644 --- a/Translations/translation_CS.json +++ b/Translations/translation_CS.json @@ -1,7 +1,10 @@ { "languageCode": "CS", "languageLocalName": "Český", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibrace dokončena!", "SettingsCalibrationWarning": "Ujistěte se, že hrot má pokojovou teplotu!", diff --git a/Translations/translation_DA.json b/Translations/translation_DA.json index ea13608b..1541e74b 100644 --- a/Translations/translation_DA.json +++ b/Translations/translation_DA.json @@ -1,7 +1,10 @@ { "languageCode": "DA", "languageLocalName": "Dansk", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibration done!", "SettingsCalibrationWarning": "Sørg for at loddespidsen er ved stuetemperatur, inden du fortsætter!", diff --git a/Translations/translation_DE.json b/Translations/translation_DE.json index 691b13a1..efd46499 100644 --- a/Translations/translation_DE.json +++ b/Translations/translation_DE.json @@ -1,7 +1,10 @@ { "languageCode": "DE", "languageLocalName": "Deutsch", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "tempUnitFahrenheit": false, "messages": { "SettingsCalibrationDone": "Kalibrierung abgeschlossen!", diff --git a/Translations/translation_EN.json b/Translations/translation_EN.json index 51d79ea0..351577f2 100644 --- a/Translations/translation_EN.json +++ b/Translations/translation_EN.json @@ -1,7 +1,9 @@ { "languageCode": "EN", "languageLocalName": "English", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic" + ], "tempUnitFahrenheit": true, "messages": { "SettingsCalibrationDone": "Calibration done!", diff --git a/Translations/translation_ES.json b/Translations/translation_ES.json index f4ff297e..117ed864 100644 --- a/Translations/translation_ES.json +++ b/Translations/translation_ES.json @@ -1,7 +1,10 @@ { "languageCode": "ES", "languageLocalName": "Castellano", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "¡Calibrada!", "SettingsCalibrationWarning": "¡Asegúrate que la punta esté a temperatura ambiente antes de empezar!", diff --git a/Translations/translation_FI.json b/Translations/translation_FI.json index 8346f7ee..f4ebef8f 100644 --- a/Translations/translation_FI.json +++ b/Translations/translation_FI.json @@ -1,7 +1,10 @@ { "languageCode": "FI", "languageLocalName": "Suomi", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationWarning": "Varmista että kärki on huoneenlämpöinen ennen jatkamista!", "SettingsResetWarning": "Haluatko varmasti palauttaa oletusarvot?", @@ -301,4 +304,4 @@ "desc": "Herätyspulssin kesto (x 250ms)" } } -} \ No newline at end of file +} diff --git a/Translations/translation_FR.json b/Translations/translation_FR.json index 3d171913..ebde1196 100644 --- a/Translations/translation_FR.json +++ b/Translations/translation_FR.json @@ -1,7 +1,10 @@ { "languageCode": "FR", "languageLocalName": "Français", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibration effectuée !", "SettingsCalibrationWarning": "Assurez-vous que la panne soit à température ambiante avant de continuer !", diff --git a/Translations/translation_HR.json b/Translations/translation_HR.json index 28816082..a488a994 100644 --- a/Translations/translation_HR.json +++ b/Translations/translation_HR.json @@ -1,7 +1,10 @@ { "languageCode": "HR", "languageLocalName": "Hrvatski", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibracija gotova!", "SettingsCalibrationWarning": "Provjerite da je vršak ohlađen na sobnu temperaturu prije nego što nastavite!", diff --git a/Translations/translation_HU.json b/Translations/translation_HU.json index 26f2e21d..13d2e0ed 100644 --- a/Translations/translation_HU.json +++ b/Translations/translation_HU.json @@ -1,7 +1,10 @@ { "languageCode": "HU", "languageLocalName": "Magyar", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibráció befejezve!", "SettingsCalibrationWarning": "Folytatás előtt győződjön meg róla, hogy a páka szobahőmérsékletű!", diff --git a/Translations/translation_IT.json b/Translations/translation_IT.json index af7db547..dfcebc61 100644 --- a/Translations/translation_IT.json +++ b/Translations/translation_IT.json @@ -1,7 +1,10 @@ { "languageCode": "IT", "languageLocalName": "Italiano", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibrazione effettuata", "SettingsCalibrationWarning": "Assicurati che la punta si trovi a temperatura ambiente prima di continuare!", diff --git a/Translations/translation_JA_JP.json b/Translations/translation_JA_JP.json index f5e95fa8..7404d2da 100644 --- a/Translations/translation_JA_JP.json +++ b/Translations/translation_JA_JP.json @@ -1,7 +1,10 @@ { "languageCode": "JA_JP", "languageLocalName": "日本語", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "cjk" + ], "tempUnitFahrenheit": true, "messages": { "SettingsCalibrationDone": "校正完了", @@ -200,4 +203,4 @@ "desc": "電源供給元をオンに保つために使用される、電力パルスの時間長 " } } -} \ No newline at end of file +} diff --git a/Translations/translation_LT.json b/Translations/translation_LT.json index ae84c9d3..aba3520d 100644 --- a/Translations/translation_LT.json +++ b/Translations/translation_LT.json @@ -1,7 +1,10 @@ { "languageCode": "LT", "languageLocalName": "Lietuvių", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibravimas atliktas!", "SettingsCalibrationWarning": "Prieš tęsdami įsitikinkite, kad antgalis yra kambario temperatūros!", diff --git a/Translations/translation_NL.json b/Translations/translation_NL.json index 72f34da5..5d4d5f6a 100644 --- a/Translations/translation_NL.json +++ b/Translations/translation_NL.json @@ -1,7 +1,10 @@ { "languageCode": "NL", "languageLocalName": "Nederlands", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibratie klaar!", "SettingsCalibrationWarning": "Zorg ervoor dat te punt op kamertemperatuur is voor je verder gaat!", diff --git a/Translations/translation_NL_BE.json b/Translations/translation_NL_BE.json index e4c0c10c..00ae61bf 100644 --- a/Translations/translation_NL_BE.json +++ b/Translations/translation_NL_BE.json @@ -1,7 +1,10 @@ { "languageCode": "NL_BE", "languageLocalName": "Vlaams", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Gecalibreerd!", "SettingsCalibrationWarning": "Zorg vooraf dat de punt op kamertemperatuur is!", diff --git a/Translations/translation_NO.json b/Translations/translation_NO.json index 6f5ef113..90401145 100644 --- a/Translations/translation_NO.json +++ b/Translations/translation_NO.json @@ -1,7 +1,10 @@ { "languageCode": "NO", "languageLocalName": "Norsk", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibration done!", "SettingsCalibrationWarning": "Sørg for at loddespissen har romtemperatur før du fortsetter!", diff --git a/Translations/translation_PL.json b/Translations/translation_PL.json index 7a0ccb1f..4159e226 100644 --- a/Translations/translation_PL.json +++ b/Translations/translation_PL.json @@ -1,7 +1,10 @@ { "languageCode": "PL", "languageLocalName": "Polski", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "tempUnitFahrenheit": false, "messages": { "SettingsCalibrationDone": "Kalibracja udana!", diff --git a/Translations/translation_PT.json b/Translations/translation_PT.json index 7d7c541b..06b51d37 100644 --- a/Translations/translation_PT.json +++ b/Translations/translation_PT.json @@ -1,7 +1,10 @@ { "languageCode": "PT", "languageLocalName": "Português", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibração terminada!", "SettingsCalibrationWarning": "A ponta deve estar à temperatura ambiente antes de continuar!", diff --git a/Translations/translation_RU.json b/Translations/translation_RU.json index b6746b86..b3de0c81 100644 --- a/Translations/translation_RU.json +++ b/Translations/translation_RU.json @@ -1,7 +1,11 @@ { "languageCode": "RU", "languageLocalName": "Русский", - "cyrillicGlyphs": true, + "fonts": [ + "ascii_basic", + "latin_extended", + "cyrillic" + ], "messages": { "SettingsCalibrationDone": "Калибровка завершена!", "SettingsCalibrationWarning": "Прежде чем продолжить, пожалуйста, убедитесь, что жало имеет комнатную температуру!", diff --git a/Translations/translation_SK.json b/Translations/translation_SK.json index 6423287a..56e9e19d 100644 --- a/Translations/translation_SK.json +++ b/Translations/translation_SK.json @@ -1,7 +1,10 @@ { "languageCode": "SK", "languageLocalName": "Slovenčina", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibrácia hotová!", "SettingsCalibrationWarning": "Najprv sa prosím uistite, že hrot má izbovú teplotu!", diff --git a/Translations/translation_SL.json b/Translations/translation_SL.json index 52e4bf44..622fb026 100644 --- a/Translations/translation_SL.json +++ b/Translations/translation_SL.json @@ -1,7 +1,10 @@ { "languageCode": "SL", "languageLocalName": "Slovenščina", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibracija opravljena!", "SettingsCalibrationWarning": "Pred nadaljevanjem mora biti konica segreta na sobno temperaturo!", diff --git a/Translations/translation_SR_CYRL.json b/Translations/translation_SR_CYRL.json index 69620f63..4c0eb951 100644 --- a/Translations/translation_SR_CYRL.json +++ b/Translations/translation_SR_CYRL.json @@ -1,7 +1,10 @@ { "languageCode": "SR_CYRL", "languageLocalName": "Српски", - "cyrillicGlyphs": true, + "fonts": [ + "ascii_basic", + "cyrillic" + ], "messages": { "SettingsCalibrationDone": "Калибрација готова", "SettingsCalibrationWarning": "Проверите да ли је врх охлађен на собну температуру пре него што наставите", diff --git a/Translations/translation_SR_LATN.json b/Translations/translation_SR_LATN.json index 573e99fa..d5192fe7 100644 --- a/Translations/translation_SR_LATN.json +++ b/Translations/translation_SR_LATN.json @@ -1,7 +1,10 @@ { "languageCode": "SR_LATN", "languageLocalName": "Srpski", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibracija gotova", "SettingsCalibrationWarning": "Proverite da li je vrh ohlađen na sobnu temperaturu pre nego što nastavite", diff --git a/Translations/translation_SV.json b/Translations/translation_SV.json index da04a036..b30449c2 100644 --- a/Translations/translation_SV.json +++ b/Translations/translation_SV.json @@ -1,7 +1,10 @@ { "languageCode": "SV", "languageLocalName": "Svenska", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Calibration done!", "SettingsCalibrationWarning": "Please ensure the tip is at room temperature before continuing!", diff --git a/Translations/translation_TR.json b/Translations/translation_TR.json index 7092bc70..50c3a01f 100644 --- a/Translations/translation_TR.json +++ b/Translations/translation_TR.json @@ -1,7 +1,10 @@ { "languageCode": "TR", "languageLocalName": "Türkçe", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "latin_extended" + ], "messages": { "SettingsCalibrationDone": "Kalibrasyon tamamlandı!", "SettingsCalibrationWarning": "Lütfen devam etmeden önce ucun oda sıcaklığında olduğunu garantiye alın!", diff --git a/Translations/translation_UK.json b/Translations/translation_UK.json index 94959c8a..fbd44a3a 100644 --- a/Translations/translation_UK.json +++ b/Translations/translation_UK.json @@ -1,7 +1,11 @@ { "languageCode": "UK", "languageLocalName": "Українська", - "cyrillicGlyphs": true, + "fonts": [ + "ascii_basic", + "latin_extended", + "cyrillic" + ], "messages": { "SettingsCalibrationDone": "Калібрування виконане!", "SettingsCalibrationWarning": "Переконайтеся, що жало охололо до кімнатної температури, перш ніж продовжувати!", diff --git a/Translations/translation_YUE_HK.json b/Translations/translation_YUE_HK.json index 23ab1a0e..2a257742 100644 --- a/Translations/translation_YUE_HK.json +++ b/Translations/translation_YUE_HK.json @@ -1,7 +1,10 @@ { "languageCode": "YUE_HK", "languageLocalName": "廣東話 (香港)", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "cjk" + ], "tempUnitFahrenheit": true, "messages": { "SettingsCalibrationDone": "校正完成!", diff --git a/Translations/translation_ZH_CN.json b/Translations/translation_ZH_CN.json index 898e1263..fd191a6a 100644 --- a/Translations/translation_ZH_CN.json +++ b/Translations/translation_ZH_CN.json @@ -1,7 +1,10 @@ { "languageCode": "ZH_CN", "languageLocalName": "简体中文", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "cjk" + ], "tempUnitFahrenheit": true, "messages": { "SettingsCalibrationDone": "校正完成!", diff --git a/Translations/translation_ZH_TW.json b/Translations/translation_ZH_TW.json index 2dc083a6..2133d8f3 100644 --- a/Translations/translation_ZH_TW.json +++ b/Translations/translation_ZH_TW.json @@ -1,7 +1,10 @@ { "languageCode": "ZH_TW", "languageLocalName": "正體中文", - "cyrillicGlyphs": false, + "fonts": [ + "ascii_basic", + "cjk" + ], "tempUnitFahrenheit": true, "messages": { "SettingsCalibrationDone": "校正完成!", From 90426b2b22f1e4bd262b65c9e9fca5e4b2deb25d Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Thu, 15 Apr 2021 14:32:09 +0800 Subject: [PATCH 15/19] Change TranslationEditor to handle fonts spec --- Translations/TranslationEditor.html | 31 ++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/Translations/TranslationEditor.html b/Translations/TranslationEditor.html index 6f0ee320..91b982b7 100644 --- a/Translations/TranslationEditor.html +++ b/Translations/TranslationEditor.html @@ -48,8 +48,8 @@ } else if (id == "current-lang-file") { if (checkTranslationFile(file.name)) { app.current = json; - if (!app.current.cyrillicGlyphs){ - app.current.cyrillicGlyphs = false; + if (!app.current.fonts){ + app.current.fonts = ["ascii_basic"]; } app.meta.currentLoaded = true; } @@ -137,6 +137,7 @@ loaded: false, }, obsolete : {}, + fontToAdd: "latin_extended", }, methods : { validateInput: function(valMap, id, mode) { @@ -246,7 +247,15 @@ } else { valMap[id] = message; } - } + }, + + removeFont: function(i) { + this.current.fonts.splice(i, 1); + }, + + addFont: function() { + this.current.fonts.push(this.fontToAdd); + }, } }); app.def = def; @@ -289,12 +298,20 @@ - Font table to use + Font tables to use
("ascii_basic" must be first) - + + + + + From d661e0eb911670f44e90e27a01cd5c98ad8f9fbe Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Fri, 16 Apr 2021 01:01:13 +0800 Subject: [PATCH 16/19] Update Chinese and Japanese translations --- Translations/translation_JA_JP.json | 2 +- Translations/translation_YUE_HK.json | 2 +- Translations/translation_ZH_CN.json | 2 +- Translations/translation_ZH_TW.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Translations/translation_JA_JP.json b/Translations/translation_JA_JP.json index f5e95fa8..c595912f 100644 --- a/Translations/translation_JA_JP.json +++ b/Translations/translation_JA_JP.json @@ -113,7 +113,7 @@ }, "DisplayRotation": { "text2": "画面の向き", - "desc": "A=自動 | L=左利き | R=右利き" + "desc": "自=自動 | 左=左利き | 右=右利き" }, "BoostTemperature": { "text2": "ブースト温度", diff --git a/Translations/translation_YUE_HK.json b/Translations/translation_YUE_HK.json index 23ab1a0e..63db0e00 100644 --- a/Translations/translation_YUE_HK.json +++ b/Translations/translation_YUE_HK.json @@ -113,7 +113,7 @@ }, "DisplayRotation": { "text2": "畫面方向", - "desc": "A=自動 | L=使用左手 | R=使用右手" + "desc": "自=自動 | 左=使用左手 | 右=使用右手" }, "BoostTemperature": { "text2": "增熱温度", diff --git a/Translations/translation_ZH_CN.json b/Translations/translation_ZH_CN.json index 898e1263..2a840bc8 100644 --- a/Translations/translation_ZH_CN.json +++ b/Translations/translation_ZH_CN.json @@ -113,7 +113,7 @@ }, "DisplayRotation": { "text2": "画面方向", - "desc": "A=自动 | L=使用左手 | R=使用右手" + "desc": "自=自动 | 左=使用左手 | 右=使用右手" }, "BoostTemperature": { "text2": "增热温度", diff --git a/Translations/translation_ZH_TW.json b/Translations/translation_ZH_TW.json index 2dc083a6..f1e19136 100644 --- a/Translations/translation_ZH_TW.json +++ b/Translations/translation_ZH_TW.json @@ -113,7 +113,7 @@ }, "DisplayRotation": { "text2": "畫面方向", - "desc": "A=自動 | L=使用左手 | R=使用右手" + "desc": "自=自動 | 左=使用左手 | 右=使用右手" }, "BoostTemperature": { "text2": "增熱溫度", From 6f4f4d9733ddfdeef76ecd96e555b065ec493d93 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Fri, 16 Apr 2021 17:55:30 +0800 Subject: [PATCH 17/19] Move string compression to Python ... so that the script can know its uncompressed size and calculate the appropriate buffer size. --- Translations/lzfx.py | 91 +++++++++++++++++++++++++++ Translations/make_translation.py | 25 +++++--- source/Core/lzfx/lzfx-host-compress.c | 48 -------------- source/Makefile | 15 ++--- 4 files changed, 111 insertions(+), 68 deletions(-) create mode 100644 Translations/lzfx.py delete mode 100644 source/Core/lzfx/lzfx-host-compress.c diff --git a/Translations/lzfx.py b/Translations/lzfx.py new file mode 100644 index 00000000..9f389673 --- /dev/null +++ b/Translations/lzfx.py @@ -0,0 +1,91 @@ +import ctypes +import functools +import os +from pathlib import Path + +HERE = Path(__file__).resolve().parent + + +@functools.lru_cache(maxsize=None) +def _liblzfx(): + so_path = os.path.join(HERE, "../source/Objects/host/lzfx/liblzfx.so") + liblzfx = ctypes.cdll.LoadLibrary(so_path) + return liblzfx + + +@functools.lru_cache(maxsize=None) +def _fn_lzfx_compress(): + """Returns the lzfx_compress C function. + :: + + /* Buffer-to buffer compression. + + Supply pre-allocated input and output buffers via ibuf and obuf, and + their size in bytes via ilen and olen. Buffers may not overlap. + + On success, the function returns a non-negative value and the argument + olen contains the compressed size in bytes. On failure, a negative + value is returned and olen is not modified. + */ + int lzfx_compress(const void* ibuf, unsigned int ilen, + void* obuf, unsigned int *olen); + """ + + fn = _liblzfx().lzfx_compress + fn.argtype = [ + ctypes.c_char_p, + ctypes.c_uint, + ctypes.c_char_p, + ctypes.POINTER(ctypes.c_uint), + ] + fn.restype = ctypes.c_int + return fn + + +def compress(data: bytes) -> bytes: + """Returns a bytes object of the lzfx-compressed data.""" + + fn_compress = _fn_lzfx_compress() + + output_buffer_len = len(data) + 8 + + ibuf = data + ilen = len(ibuf) + obuf = ctypes.create_string_buffer(output_buffer_len) + olen = ctypes.c_uint(output_buffer_len) + + res = fn_compress(ibuf, ilen, obuf, ctypes.byref(olen)) + + if res < 0: + raise LzfxError(res) + else: + return bytes(obuf[: olen.value]) # type: ignore + + +class LzfxError(Exception): + """Exception raised for lzfx compression or decompression error. + + Attributes: + error_code -- The source error code, which is a negative integer + error_name -- The constant name of the error + message -- explanation of the error + """ + + # define LZFX_ESIZE -1 /* Output buffer too small */ + # define LZFX_ECORRUPT -2 /* Invalid data for decompression */ + # define LZFX_EARGS -3 /* Arguments invalid (NULL) */ + + def __init__(self, error_code): + self.error_code = error_code + if error_code == -1: + self.error_name = "LZFX_ESIZE" + self.message = "Output buffer too small" + elif error_code == -2: + self.error_name = "LZFX_ECORRUPT" + self.message = "Invalid data for decompression" + elif error_code == -3: + self.error_name = "LZFX_EARGS" + self.message = "Arguments invalid (NULL)" + else: + self.error_name = "UNKNOWN" + self.message = "Unknown error" diff --git a/Translations/make_translation.py b/Translations/make_translation.py index 4e25ee71..c4a2c60d 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -19,6 +19,7 @@ from bdflib import reader as bdfreader from bdflib.model import Font, Glyph import font_tables +import lzfx logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) @@ -505,7 +506,7 @@ def prepare_language(lang: dict, defs: dict, build_version: str) -> LanguageData def write_language( - data: LanguageData, f: TextIO, lzfx_strings: Optional[bytes] = None + data: LanguageData, f: TextIO, strings_bin: Optional[bytes] = None ) -> None: lang = data.lang defs = data.defs @@ -523,7 +524,7 @@ def write_language( except KeyError: lang_name = language_code - if lzfx_strings: + if strings_bin: f.write('#include "lzfx.h"\n') f.write(f"\n// ---- {lang_name} ----\n\n") @@ -540,7 +541,7 @@ def write_language( "extern const uint8_t *const Font_6x8 = USER_FONT_6x8;\n\n" ) - if not lzfx_strings: + if not strings_bin: translation_strings_and_indices_text = get_translation_strings_and_indices_text( lang, defs, symbol_conversion_table ) @@ -551,9 +552,13 @@ def write_language( "void prepareTranslations() {}\n\n" ) else: - write_bytes_as_c_array(f, "translation_data_lzfx", lzfx_strings) + compressed = lzfx.compress(strings_bin) + logging.info( + f"Strings compressed from {len(strings_bin)} to {len(compressed)} bytes (ratio {len(compressed) / len(strings_bin):.3})" + ) + write_bytes_as_c_array(f, "translation_data_lzfx", compressed) f.write( - "static uint8_t translation_data_out_buffer[4096] __attribute__((__aligned__(2)));\n\n" + f"static uint8_t translation_data_out_buffer[{len(strings_bin)}] __attribute__((__aligned__(2)));\n\n" "const TranslationIndexTable *const Tr = reinterpret_cast(translation_data_out_buffer);\n" "const char *const TranslationStrings = reinterpret_cast(translation_data_out_buffer) + sizeof(TranslationIndexTable);\n\n" "void prepareTranslations() {\n" @@ -847,11 +852,11 @@ def parse_args() -> argparse.Namespace: dest="input_pickled", ) parser.add_argument( - "--lzfx-strings", - help="Use compressed TranslationIndices + TranslationStrings data", + "--strings-bin", + help="Use generated TranslationIndices + TranslationStrings data and compress them", type=argparse.FileType("rb"), required=False, - dest="lzfx_strings", + dest="strings_bin", ) parser.add_argument( "--output", "-o", help="Target file", type=argparse.FileType("w"), required=True @@ -895,8 +900,8 @@ def main() -> None: out_ = args.output write_start(out_) - if args.lzfx_strings: - write_language(language_data, out_, args.lzfx_strings.read()) + if args.strings_bin: + write_language(language_data, out_, args.strings_bin.read()) else: write_language(language_data, out_) diff --git a/source/Core/lzfx/lzfx-host-compress.c b/source/Core/lzfx/lzfx-host-compress.c deleted file mode 100644 index b135b975..00000000 --- a/source/Core/lzfx/lzfx-host-compress.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include - -#include "lzfx.h" - -/* Program to demonstrate file compression. Don't use it in the real world! */ - -int main(int argc, char **argv) { - if (argc == 3) { - /* open input */ - FILE *f = fopen(argv[1], "rb"); - if (!f) { - printf("Error: %s\n", argv[1]); - return 1; - } - - /* get size */ - fseek(f, 0, SEEK_END); - int inputsize = ftell(f); - fseek(f, 0, SEEK_SET); - - /* read */ - char *input = malloc(inputsize); - fread(input, inputsize, 1, f); - fclose(f); - - /* compress */ - int outputsize = inputsize + 1; /* buffer overflow */ - char *output = malloc(outputsize); - lzfx_compress(input, inputsize, output, &outputsize); - - /* open output */ - f = fopen(argv[2], "wb"); - if (!f) { - printf("Error: %s\n", argv[1]); - return 1; - } - - /* write */ - fwrite(output, outputsize, 1, f); - fclose(f); - - return 0; - } else { - printf("Compresses a file.\n\nUsage: lzfx-raw input output\n"); - return 1; - } -} diff --git a/source/Makefile b/source/Makefile index dcd94972..0bca7726 100644 --- a/source/Makefile +++ b/source/Makefile @@ -364,10 +364,10 @@ $(OUTPUT_DIR)/Core/Gen/translation.files/%.o: Core/Gen/Translation.%.cpp @echo Generating $@ @$(CPP) -c $(filter-out -flto -g3,$(CXXFLAGS)) $< -o $@ -$(HOST_OUTPUT_DIR)/lzfx/lzfx-host-compress: Core/lzfx/lzfx-host-compress.c Core/lzfx/lzfx.c +$(HOST_OUTPUT_DIR)/lzfx/liblzfx.so: Core/lzfx/lzfx.c @test -d $(@D) || mkdir -p $(@D) - @echo Building host lzfx tool $@ - @$(HOST_CC) -Wno-unused-result -O $^ -o $@ + @echo Building host lzfx shared library $@ + @$(HOST_CC) -Wno-unused-result -fPIC -shared -O $^ -o $@ $(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.bin: $(OUTPUT_DIR)/Core/Gen/translation.files/%.o @echo Dumping translation strings data from $< @@ -378,18 +378,13 @@ $(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.bin: $(OUTPUT_DIR)/Core/Gen/t @test -s $(@D)/$*.data.TranslationStrings.bin || (rm $(@D)/$*.data.TranslationStrings.bin; echo 'ERROR: Output for .rodata._ZL22TranslationStringsData is empty!' >&2; false) @cat $(@D)/$*.data.TranslationIndices.bin $(@D)/$*.data.TranslationStrings.bin > $@ -$(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.lzfx: $(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.bin $(HOST_OUTPUT_DIR)/lzfx/lzfx-host-compress - @echo Compressing translation strings data for $* - @$(HOST_OUTPUT_DIR)/lzfx/lzfx-host-compress $< $@ - @echo Compressed from $$(stat --printf="%s" $<) to $$(stat --printf="%s" $@) bytes - -Core/Gen/Translation_lzfx.%.cpp: $(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.lzfx $(OUTPUT_DIR)/Core/Gen/translation.files/%.pickle +Core/Gen/Translation_lzfx.%.cpp: $(OUTPUT_DIR)/Core/Gen/translation.files/%.strings.bin $(OUTPUT_DIR)/Core/Gen/translation.files/%.pickle $(HOST_OUTPUT_DIR)/lzfx/liblzfx.so @test -d $(@D) || mkdir -p $(@D) @echo Generating lzfx compressed translation for $* @python3 ../Translations/make_translation.py \ -o $(PWD)/Core/Gen/Translation_lzfx.$*.cpp \ --input-pickled $(OUTPUT_DIR)/Core/Gen/translation.files/$*.pickle \ - --lzfx-strings $(OUTPUT_DIR)/Core/Gen/translation.files/$*.strings.lzfx \ + --strings-bin $(OUTPUT_DIR)/Core/Gen/translation.files/$*.strings.bin \ $* From 9da3c0c6e7e2d41f2c656dcda20a447fe2fb5283 Mon Sep 17 00:00:00 2001 From: HanaO00 <17810985+HanaO00@users.noreply.github.com> Date: Fri, 16 Apr 2021 22:59:41 +0200 Subject: [PATCH 18/19] Update translation_FR.json --- Translations/translation_FR.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Translations/translation_FR.json b/Translations/translation_FR.json index 3d171913..671d78e1 100644 --- a/Translations/translation_FR.json +++ b/Translations/translation_FR.json @@ -277,31 +277,31 @@ }, "AnimLoop": { "text2": [ - "Anim.", - "loop" + "Icônes", + "animées" ], - "desc": "Loop icon animations in root menu" + "desc": "Animations des icônes dans le menu principal" }, "AnimSpeed": { "text2": [ - "Anim.", - "speed" + "Vitesse", + "d'animations" ], - "desc": "Speed of icon animations in menu " + "desc": "Vitesse des animations des icônes dans le menu " }, "PowerPulseWait": { "text2": [ - "Power pulse", - "wait time" + "Délai entre", + "les impulsions" ], - "desc": "Time to wait before triggering every keep-awake pulse (x 2.5s)" + "desc": "Délai entre chaque impulsions pour empêcher la mise en veille (x 2.5s)" }, "PowerPulseDuration": { "text2": [ - "Power pulse", - "duration" + "Durée des", + "impulsions" ], - "desc": "Keep-awake-pulse duration (x 250ms)" + "desc": "Durée des impulsions pour empêcher la mise en veille (x 250ms)" } } } From fadb25273e33356e1a9c4269c5606b174164dab7 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Sat, 17 Apr 2021 05:18:19 +0800 Subject: [PATCH 19/19] Impl. font compression demo --- Translations/make_translation.py | 92 +++++++++++++++++++++++++++----- source/Makefile | 19 +++++++ 2 files changed, 97 insertions(+), 14 deletions(-) diff --git a/Translations/make_translation.py b/Translations/make_translation.py index c4a2c60d..4eb7a3b7 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -430,13 +430,26 @@ def get_font_map_and_table( def make_font_table_cpp( sym_list: List[str], font_map: FontMap, symbol_map: Dict[str, bytes] +) -> str: + output_table = make_font_table_12_cpp(sym_list, font_map, symbol_map) + output_table += make_font_table_06_cpp(sym_list, font_map, symbol_map) + return output_table + + +def make_font_table_12_cpp( + sym_list: List[str], font_map: FontMap, symbol_map: Dict[str, bytes] ) -> str: output_table = "const uint8_t USER_FONT_12[] = {\n" for sym in sym_list: output_table += f"{bytes_to_c_hex(font_map.font12[sym])}//{bytes_to_escaped(symbol_map[sym])} -> {sym}\n" output_table += "};\n" + return output_table - output_table += "const uint8_t USER_FONT_6x8[] = {\n" + +def make_font_table_06_cpp( + sym_list: List[str], font_map: FontMap, symbol_map: Dict[str, bytes] +) -> str: + output_table = "const uint8_t USER_FONT_6x8[] = {\n" for sym in sym_list: font_bytes = font_map.font06[sym] if font_bytes: @@ -506,7 +519,10 @@ def prepare_language(lang: dict, defs: dict, build_version: str) -> LanguageData def write_language( - data: LanguageData, f: TextIO, strings_bin: Optional[bytes] = None + data: LanguageData, + f: TextIO, + strings_bin: Optional[bytes] = None, + compress_font: bool = False, ) -> None: lang = data.lang defs = data.defs @@ -517,18 +533,36 @@ def write_language( language_code: str = lang["languageCode"] logging.info(f"Generating block for {language_code}") - font_table_text = make_font_table_cpp(sym_list, font_map, symbol_conversion_table) try: lang_name = lang["languageLocalName"] except KeyError: lang_name = language_code - if strings_bin: + if strings_bin or compress_font: f.write('#include "lzfx.h"\n') f.write(f"\n// ---- {lang_name} ----\n\n") - f.write(font_table_text) + + if not compress_font: + font_table_text = make_font_table_cpp( + sym_list, font_map, symbol_conversion_table + ) + f.write(font_table_text) + else: + font12_uncompressed = bytearray() + for sym in sym_list: + font12_uncompressed.extend(font_map.font12[sym]) + font12_compressed = lzfx.compress(bytes(font12_uncompressed)) + logging.info( + f"Font table 12x16 compressed from {len(font12_uncompressed)} to {len(font12_compressed)} bytes (ratio {len(font12_compressed) / len(font12_uncompressed):.3})" + ) + write_bytes_as_c_array(f, "font_12x16_lzfx", font12_compressed) + font_table_text = make_font_table_06_cpp( + sym_list, font_map, symbol_conversion_table + ) + f.write(font_table_text) + f.write(f"\n// ---- {lang_name} ----\n\n") translation_common_text = get_translation_common_text( @@ -537,10 +571,17 @@ def write_language( f.write(translation_common_text) f.write( f"const bool HasFahrenheit = {('true' if lang.get('tempUnitFahrenheit', True) else 'false')};\n\n" - "extern const uint8_t *const Font_12x16 = USER_FONT_12;\n" - "extern const uint8_t *const Font_6x8 = USER_FONT_6x8;\n\n" ) + if not compress_font: + f.write("extern const uint8_t *const Font_12x16 = USER_FONT_12;\n") + else: + f.write( + f"static uint8_t font_out_buffer[{len(font12_uncompressed)}];\n\n" + "extern const uint8_t *const Font_12x16 = font_out_buffer;\n" + ) + f.write("extern const uint8_t *const Font_6x8 = USER_FONT_6x8;\n\n") + if not strings_bin: translation_strings_and_indices_text = get_translation_strings_and_indices_text( lang, defs, symbol_conversion_table @@ -549,7 +590,6 @@ def write_language( f.write( "const TranslationIndexTable *const Tr = &TranslationIndices;\n" "const char *const TranslationStrings = TranslationStringsData;\n\n" - "void prepareTranslations() {}\n\n" ) else: compressed = lzfx.compress(strings_bin) @@ -561,12 +601,24 @@ def write_language( f"static uint8_t translation_data_out_buffer[{len(strings_bin)}] __attribute__((__aligned__(2)));\n\n" "const TranslationIndexTable *const Tr = reinterpret_cast(translation_data_out_buffer);\n" "const char *const TranslationStrings = reinterpret_cast(translation_data_out_buffer) + sizeof(TranslationIndexTable);\n\n" - "void prepareTranslations() {\n" - " unsigned int outsize = sizeof(translation_data_out_buffer);\n" - " lzfx_decompress(translation_data_lzfx, sizeof(translation_data_lzfx), translation_data_out_buffer, &outsize);\n" - "}\n\n" ) + if not strings_bin and not compress_font: + f.write("void prepareTranslations() {}\n\n") + else: + f.write("void prepareTranslations() {\n" " unsigned int outsize;\n") + if compress_font: + f.write( + " outsize = sizeof(font_out_buffer);\n" + " lzfx_decompress(font_12x16_lzfx, sizeof(font_12x16_lzfx), font_out_buffer, &outsize);\n" + ) + if strings_bin: + f.write( + " outsize = sizeof(translation_data_out_buffer);\n" + " lzfx_decompress(translation_data_lzfx, sizeof(translation_data_lzfx), translation_data_out_buffer, &outsize);\n" + ) + f.write("}\n\n") + sanity_checks_text = get_translation_sanity_checks_text(defs) f.write(sanity_checks_text) @@ -858,6 +910,13 @@ def parse_args() -> argparse.Namespace: required=False, dest="strings_bin", ) + parser.add_argument( + "--compress-font", + help="Compress the font table", + action="store_true", + required=False, + dest="compress_font", + ) parser.add_argument( "--output", "-o", help="Target file", type=argparse.FileType("w"), required=True ) @@ -901,9 +960,14 @@ def main() -> None: out_ = args.output write_start(out_) if args.strings_bin: - write_language(language_data, out_, args.strings_bin.read()) + write_language( + language_data, + out_, + args.strings_bin.read(), + compress_font=args.compress_font, + ) else: - write_language(language_data, out_) + write_language(language_data, out_, compress_font=args.compress_font) if args.output_pickled: logging.info(f"Writing pickled data to {args.output_pickled.name}") diff --git a/source/Makefile b/source/Makefile index 0bca7726..b86c3c88 100644 --- a/source/Makefile +++ b/source/Makefile @@ -327,6 +327,16 @@ $(HEXFILE_DIR)/$(model)_string_compressed_%.elf : \ $(OUTPUT_DIR)/Core/Gen/Translation_lzfx.$*.o \ $(LIBS) $(LINKER_FLAGS) -o$@ -Wl,-Map=$@.map +$(HEXFILE_DIR)/$(model)_font_compressed_%.elf : \ + $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation_lzfx_font.%.o \ + Makefile $(LDSCRIPT) + @test -d $(@D) || mkdir -p $(@D) + @echo Linking $@ + @$(CPP) $(CXXFLAGS) $(OUT_OBJS_S) $(OUT_OBJS) $(OUT_OBJS_CPP) \ + $(OUTPUT_DIR)/Core/Gen/Translation_lzfx_font.$*.o \ + $(LIBS) $(LINKER_FLAGS) -o$@ -Wl,-Map=$@.map + $(OUT_OBJS): $(OUTPUT_DIR)/%.o : %.c Makefile @test -d $(@D) || mkdir -p $(@D) @echo Compiling ${<} @@ -387,6 +397,15 @@ Core/Gen/Translation_lzfx.%.cpp: $(OUTPUT_DIR)/Core/Gen/translation.files/%.stri --strings-bin $(OUTPUT_DIR)/Core/Gen/translation.files/$*.strings.bin \ $* +Core/Gen/Translation_lzfx_font.%.cpp: $(OUTPUT_DIR)/Core/Gen/translation.files/%.pickle $(HOST_OUTPUT_DIR)/lzfx/liblzfx.so + @test -d $(@D) || mkdir -p $(@D) + @echo Generating lzfx compressed translation for $* + @python3 ../Translations/make_translation.py \ + -o $(PWD)/Core/Gen/Translation_lzfx_font.$*.cpp \ + --input-pickled $(OUTPUT_DIR)/Core/Gen/translation.files/$*.pickle \ + --compress-font \ + $* + clean :