What changed, and why it matters
This is a large firmware update that replaces the device's font system and, as a consequence, loosens text validation from 'printable ASCII only' to 'valid UTF-8 that the new font can render'. The change is primarily a feature/UX improvement (support for accented European characters and the Euro sign), but it also adds new input-validation checks to make sure unsupported characters cannot be shown on screen. There is no direct evidence in the commit that this fixes an active security bug, but the new validation is defensive: it prevents a user from being shown misleading or truncated text on the small OLED screen.
Treat as a significant feature/refactoring commit with defensive security improvements. Reviewers should verify that every user-controlled string path that reaches the display is covered by a `has_glyph` check, that the LVGL font subset and uGUI compatibility layer do not introduce buffer-overread or integer-overflow bugs, and that the new `ttf2lvgl` tool and generated fonts are reproducible. No immediate incident response is indicated by the diff alone.
Security signals we found
Input validation now depends on font glyph coverage rather than a fixed printable-ASCII check
New `has_glyph` API added to the UI abstraction to reject unsupported display characters
Fallback to hex display for messages containing unsupported glyphs
Device-name validation moved from pure ASCII to UTF-8 plus per-font glyph check
Backup/restore names sanitized against the active font instead of ASCII
Payment-request text memos and EIP-712 string fields validated for renderability
Large surface-area change: 99 files, new external LVGL dependency, font toolchain change
Evidence from the diff
The commit migrates BitBox02 fonts from a custom uGUI/ttf2ugui ASCII-only format to LVGL-format fonts generated by a new ttf2lvgl tool. It adds 162-character coverage for English, German, Spanish, Italian and French (printable ASCII plus selected Latin-1/extended characters and the Euro sign). To avoid silent omission of unsupported glyphs, the code introduces a has_glyph UI trait and uses it to validate device names, backup names, payment-request memos, Ethereum EIP-712 string values, signed messages, registered script-config names and U2F confirmation strings before display. Where text cannot be rendered, the firmware either rejects the input or falls back to hex display. Several C UI components are updated to use the renamed fonts and to handle UTF-8 strings instead of printable ASCII.
Changed components
src/ui/fonts/*src/ui/ugui/ugui.csrc/ui/components/label.csrc/ui/components/confirm.csrc/ui/components/lockscreen.csrc/ui/components/button.csrc/ui/components/trinary_input_char.csrc/ui/components/trinary_input_string.csrc/rust/bitbox02/src/ui/ui.rssrc/rust/bitbox02/src/ui/types.rssrc/rust/bitbox02/src/memory.rssrc/rust/bitbox02-rust/src/hww/api/set_device_name.rssrc/rust/bitbox02-rust/src/hww/api/backup.rssrc/rust/bitbox02-rust/src/hww/api/restore.rssrc/rust/bitbox02-rust/src/hww/api/bitcoin/registration.rssrc/rust/bitbox02-rust/src/hww/api/payment_request.rssrc/rust/bitbox02-rust/src/hww/api/ethereum/sign_typed_msg.rssrc/rust/bitbox02-rust/src/workflow/verify_message.rssrc/rust/bitbox02-rust-c/src/u2f_c_api.rstools/ttf2lvgl/*Inspect captured patch +6688 / −1499
### .clang-tidy
@@ -24,7 +24,7 @@ Checks: >-
-clang-analyzer-core.FixedAddressDereference,
-clang-diagnostic-cast-qual
HeaderFilterRegex: '.*'
-ExcludeHeaderFilterRegex: '.*/external/asf4-drivers/.*'
+ExcludeHeaderFilterRegex: '.*/external/(asf4-drivers|lvgl)/.*'
ExtraArgs:
- -Wno-unknown-warning-option
- -Qunused-arguments
### .containerversion
@@ -1 +1 @@
-56
+57
### .gitmodules
@@ -1,9 +1,6 @@
[submodule "external/cryptoauthlib"]
path = external/cryptoauthlib
url = https://github.com/BitBoxSwiss/cryptoauthlib.git
-[submodule "tools/ttf2ugui"]
- path = tools/ttf2ugui
- url = https://github.com/BitBoxSwiss/ttf2ugui
[submodule "external/optiga-trust-m"]
path = external/optiga-trust-m
url = https://github.com/BitBoxSwiss/optiga-trust-m.git
### Dockerfile
@@ -47,6 +47,8 @@ RUN apt-get update && apt-get install -y \
libtool \
pkg-config \
libcmocka-dev \
+ libfreetype6-dev \
+ libicu-dev \
libusb-1.0-0-dev \
libudev-dev \
libhidapi-dev
### src/CMakeLists.txt
@@ -37,15 +37,13 @@ set(DBB-FIRMWARE-UI-SOURCES
${CMAKE_SOURCE_DIR}/src/screen.c
${CMAKE_SOURCE_DIR}/src/ui/graphics/graphics.c
${CMAKE_SOURCE_DIR}/src/ui/ugui/ugui.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_9X9.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_11X10.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_11X12.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_13X14.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_15X16.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_17X18.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/monogram_5X9.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/password_9X9.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/password_11X12.c
+ ${CMAKE_SOURCE_DIR}/src/ui/fonts/regular_11.c
+ ${CMAKE_SOURCE_DIR}/src/ui/fonts/regular_12.c
+ ${CMAKE_SOURCE_DIR}/src/ui/fonts/regular_9.c
+ ${CMAKE_SOURCE_DIR}/src/ui/fonts/lvgl_font_compat.c
+ ${CMAKE_SOURCE_DIR}/src/ui/fonts/monogram_16.c
+ ${CMAKE_SOURCE_DIR}/src/ui/fonts/password_9.c
+ ${CMAKE_SOURCE_DIR}/src/ui/fonts/password_12.c
${CMAKE_SOURCE_DIR}/src/ui/screen_saver.c
${CMAKE_SOURCE_DIR}/src/ui/screen_stack.c
${CMAKE_SOURCE_DIR}/src/ui/screen_process.c
@@ -97,9 +95,9 @@ set(DBB-BOOTLOADER-SOURCES
${CMAKE_SOURCE_DIR}/src/memory/memory_spi.c
${CMAKE_SOURCE_DIR}/src/usb/usb_processing.c
${CMAKE_SOURCE_DIR}/src/ui/ugui/ugui.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_9X9.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_11X10.c
- ${CMAKE_SOURCE_DIR}/src/ui/fonts/monogram_5X9.c
+ ${CMAKE_SOURCE_DIR}/src/ui/fonts/regular_9_bootloader.c
+ ${CMAKE_SOURCE_DIR}/src/ui/fonts/lvgl_font_compat.c
+ ${CMAKE_SOURCE_DIR}/src/ui/fonts/monogram_16_bootloader.c
${CMAKE_SOURCE_DIR}/src/ui/graphics/graphics.c
${CMAKE_SOURCE_DIR}/src/screen.c
${CMAKE_SOURCE_DIR}/src/hardfault.c
@@ -181,9 +179,17 @@ set(INCLUDES
${CMAKE_SOURCE_DIR}/src/usb/class/hid
${CMAKE_SOURCE_DIR}/src/usb/class/hid/hww
${CMAKE_SOURCE_DIR}/src/usb/class/hid/u2f
+ ${CMAKE_SOURCE_DIR}/external/lvgl
)
set(INCLUDES ${INCLUDES} PARENT_SCOPE)
+set(LVGL_DEFINITIONS
+ LV_KCONFIG_IGNORE
+ LV_LVGL_H_INCLUDE_SIMPLE
+ LV_CONF_PATH="${CMAKE_SOURCE_DIR}/src/rust/bitbox-lvgl-sys/lv_conf.h"
+ LV_CONF_INCLUDE_SIMPLE
+)
+
#-----------------------------------------------------------------------------
# Build embedded firmware
@@ -379,6 +385,7 @@ foreach(type ${RUST_LIBS})
_UNIT_TEST_
PRODUCT_BITBOX_MULTI=1
APP_U2F=1
+ ${LVGL_DEFINITIONS}
)
# For tests all C-files are built into the rust lib.
target_include_directories(${type}_rust_c INTERFACE
@@ -429,6 +436,7 @@ if(CMAKE_CROSSCOMPILING)
asf4-drivers
-Wl,-u,exception_table)
target_include_directories(${elf} PRIVATE ${INCLUDES})
+ target_compile_definitions(${elf} PRIVATE ${LVGL_DEFINITIONS})
# needed to find version.h
target_include_directories(${elf} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
@@ -548,6 +556,7 @@ if(CMAKE_CROSSCOMPILING)
${bootloader_type}
${product}
"APP_U2F=0"
+ ${LVGL_DEFINITIONS}
)
target_compile_options(${target}.elf PRIVATE --specs=nano.specs --specs=nosys.specs)
if(is_plus)
@@ -1021,6 +1030,7 @@ if(CMAKE_CROSSCOMPILING)
"APP_U2F=${app_u2f}"
BB02_STAGE1_TARGET_PRODUCT_ID=${target_product_id}
${blupgrade_compile_definitions}
+ ${LVGL_DEFINITIONS}
OPTIGA_LIB_EXTERNAL="optiga_config.h"
)
target_sources(${target}.elf PRIVATE ${PLATFORM-BITBOX02-SOURCES})
### src/bootloader/bootloader.c
@@ -19,7 +19,7 @@
#include <stdint.h>
#include <string.h>
#include <ui/components/ui_images.h>
-#include <ui/fonts/arial_fonts.h>
+#include <ui/fonts/regular_fonts.h>
#include <ui/graphics/graphics.h>
#include <ui/oled/oled.h>
#include <ui/ugui/ugui.h>
@@ -300,9 +300,9 @@ void bootloader_render_ble_confirm_screen(bool confirmed)
image_cross(SCREEN_WIDTH / 16, 0, IMAGE_DEFAULT_CROSS_HEIGHT);
image_checkmark(SCREEN_WIDTH * 15 / 16 - check_width, 0, IMAGE_DEFAULT_CHECKMARK_HEIGHT);
}
- UG_FontSelect(&font_monogram_5X9);
+ UG_FontSelect(&font_monogram_16);
UG_PutString(45, SCREEN_HEIGHT / 2 - 9, code_str);
- UG_FontSelect(&font_font_a_9X9);
+ UG_FontSelect(&font_regular_9);
UG_SendBuffer();
}
#endif
@@ -332,8 +332,8 @@ static void _render_hash(const char* title, const uint8_t* hash)
// If you change this, check the timer_buf size below.
const uint8_t seconds = 10; // how many seconds to show screen
const UG_S16 title_margin = 7; // Margin between title and hash
- const UG_FONT* f_mono = &font_monogram_5X9; // monospaced font
- const UG_FONT* f_regular = &font_font_a_9X9; // regular font
+ const UG_FONT* f_mono = &font_monogram_16; // monospaced font
+ const UG_FONT* f_regular = &font_regular_9; // regular font
// Convert hash to ascii hex
char hash_hex[2 * SHA256_DIGEST_LENGTH + 1];
@@ -355,10 +355,10 @@ static void _render_hash(const char* title, const uint8_t* hash)
bootloader_format_timer(timer_buf, sizeof(timer_buf), seconds - i);
UG_MeasureString(&timer_str_width, NULL, timer_buf);
UG_PutString(
- SCREEN_WIDTH - timer_str_width, SCREEN_HEIGHT - f_regular->char_height, timer_buf);
+ SCREEN_WIDTH - timer_str_width, SCREEN_HEIGHT - f_regular->line_height, timer_buf);
UG_FontSelect(f_mono);
- UG_PutString(0, title_margin + f_regular->char_height, hash_multiline);
+ UG_PutString(0, title_margin + f_regular->line_height, hash_multiline);
UG_FontSelect(f_regular);
@@ -1020,7 +1020,7 @@ void bootloader_jump(void)
boot_args_clear_command();
}
- UG_FontSelect(&font_font_a_9X9);
+ UG_FontSelect(&font_regular_9);
if (!bootloader_wait && shared_data.fields.auto_enter != sectrue_u8) {
#ifdef BOOTLOADER_DEVDEVICE
### src/da14531/da14531_handler.c
@@ -15,7 +15,7 @@
#include <rust/rust.h>
#include <ui/components/confirm.h>
#include <ui/components/ui_images.h>
-#include <ui/fonts/monogram_5X9.h>
+#include <ui/fonts/monogram_16.h>
#include <utils_assert.h>
const uint8_t* da14531_handler_current_product = NULL;
@@ -189,7 +189,7 @@ static void _ctrl_handler(const struct da14531_ctrl_frame* frame, struct RustByt
const confirm_params_t confirm_params = {
.title = "Pairing code",
.body = pairing_code,
- .font = &font_monogram_5X9,
+ .font = &font_monogram_16,
};
_ble_pairing_component = confirm_create(
&confirm_params, _ble_pairing_callback, (void*)&_ble_pairing_callback_data);
### src/memory/memory.h
@@ -69,9 +69,9 @@ USE_RESULT bool memory_cleanup_smarteeprom(void);
extern const char* MEMORY_DEFAULT_DEVICE_NAME;
// Set device name. `name` is null terminated and `name_len` is its length excluding the null
-// terminator. The name must be larger than 0 in size, consist of printable ASCII characters only
-// (and space), not start or end with whitespace, and contain no whitespace other than space. Names
-// longer than MEMORY_DEVICE_MAX_LEN_WITH_NULL - 1 are truncated.
+// terminator. The name must be larger than 0 in size, consist only of safe display characters, not
+// start or end with whitespace, and contain no whitespace other than space. Names longer than
+// MEMORY_DEVICE_MAX_LEN_WITH_NULL - 1 bytes are truncated without splitting a UTF-8 code point.
USE_RESULT bool memory_set_device_name(const char* name, size_t name_len);
// name_out must have MEMORY_DEVICE_MAX_LEN_WITH_NULL bytes in size. If no device name is set, or if
### src/rust/bitbox-hal/src/ui.rs
@@ -24,9 +24,9 @@ pub enum WordlistEntryAbort {
#[derive(Copy, Clone, Default)]
pub enum Font {
#[default]
- Default,
- Password11X12,
- Monogram5X9,
+ Regular11,
+ Password12,
+ Monogram16,
}
#[derive(Default)]
@@ -101,6 +101,12 @@ pub trait Ui {
/// Returns `Ok(())` if the user accepts, `Err(UserAbort)` if the user rejects.
async fn confirm(&mut self, params: &ConfirmParams<'_>) -> Result<(), UserAbort>;
+ /// Returns true if `font` can render `c`.
+ ///
+ /// Control characters such as newlines are workflow-specific layout markers and are not
+ /// considered font glyphs here.
+ fn has_glyph(&self, font: Font, c: char) -> bool;
+
/// Returns `Ok(())` if the user accepts the swap, `Err(UserAbort)` if the user rejects it.
async fn confirm_swap(&mut self, title: &str, from: &str, to: &str) -> Result<(), UserAbort>;
### src/rust/bitbox02-rust-c/src/u2f_c_api.rs
@@ -8,7 +8,7 @@ extern crate alloc;
use alloc::boxed::Box;
use alloc::string::String;
-use bitbox_hal::ui::{ConfirmParams, UserAbort};
+use bitbox_hal::ui::{ConfirmParams, Font, UserAbort};
use bitbox_hal::{Hal, Ui};
use core::ffi::CStr;
use core::sync::atomic::{AtomicU32, Ordering};
@@ -151,9 +151,14 @@ pub unsafe extern "C" fn rust_workflow_spawn_confirm(
) else {
return false;
};
- if !util::ascii::is_printable_ascii(title, util::ascii::Charset::AllNewline)
- || !util::ascii::is_printable_ascii(body, util::ascii::Charset::AllNewline)
- {
+ let has_all_glyphs = {
+ let ui = unsafe { BITBOX02_HAL.get().as_mut().unwrap() }.ui();
+ title
+ .chars()
+ .chain(body.chars())
+ .all(|c| c == '\n' || ui.has_glyph(Font::Regular11, c))
+ };
+ if !has_all_glyphs {
return false;
}
let title: String = title.into();
### src/rust/bitbox02-rust/src/backup.rs
@@ -61,16 +61,14 @@ pub fn id(seed: &[u8]) -> String {
hex::encode(mac.finalize_reset().into_bytes())
}
-/// Replaces non-printable-ASCII characters in legacy backup names with `?`.
-pub(crate) fn sanitize_name(name: &str) -> String {
+/// Replaces characters that cannot be displayed safely in legacy backup names with `?`.
+pub(crate) fn sanitize_name(name: &str, mut has_glyph: impl FnMut(char) -> bool) -> String {
name.chars()
- .map(|character| {
- if util::ascii::Charset::All.contains(character) {
- character
- } else {
- '?'
- }
- })
+ .map(
+ |character| {
+ if has_glyph(character) { character } else { '?' }
+ },
+ )
.collect()
}
@@ -558,6 +556,16 @@ mod tests {
.await;
}
+ #[test]
+ fn test_sanitize_name() {
+ assert_eq!(
+ sanitize_name("Bït\nBox\t東京", |c| matches!(c, ' '..='~' | 'ï')),
+ "Bït?Box???"
+ );
+ assert_eq!(sanitize_name("東京", |_| true), "東京");
+ assert_eq!(sanitize_name("BïtBox", |c| c != 'ï'), "B?tBox");
+ }
+
#[test]
fn test_bitwise_recovery() {
assert!(bitwise_recovery(&[1], &[], &[]).is_err());
### src/rust/bitbox02-rust/src/hal/testing/ui.rs
@@ -2,7 +2,7 @@
use crate::hal::Ui;
use crate::hal::ui::{
- CanCancel, ConfirmParams, Empty, EnterStringParams, Progress, TrinaryChoice, UserAbort,
+ CanCancel, ConfirmParams, Empty, EnterStringParams, Font, Progress, TrinaryChoice, UserAbort,
WordlistEntryAbort,
};
@@ -72,6 +72,7 @@ type EnterStringAsyncCb<'a> = Box<
>;
type EnterWordlistWordCb<'a> =
Box<dyn FnMut(&EnterStringParams<'_>) -> Result<String, WordlistEntryAbort> + 'a>;
+type HasGlyphCb<'a> = Box<dyn Fn(Font, char) -> bool + 'a>;
type MenuCb<'a> = Box<dyn FnMut(&[&str], Option<&str>) -> Result<u8, UserAbort> + 'a>;
type TrinaryChoiceCb<'a> =
Box<dyn FnMut(&str, Option<&str>, Option<&str>, Option<&str>) -> TrinaryChoice + 'a>;
@@ -86,6 +87,7 @@ pub struct TestingUi<'a> {
progress_screens: Rc<RefCell<Vec<ProgressScreen>>>,
_enter_string_async: Option<EnterStringAsyncCb<'a>>,
_enter_wordlist_word: Option<EnterWordlistWordCb<'a>>,
+ _has_glyph: Option<HasGlyphCb<'a>>,
_menu: Option<MenuCb<'a>>,
_trinary_choice: Option<TrinaryChoiceCb<'a>>,
_quiz_choices: VecDeque<u8>,
@@ -161,6 +163,13 @@ impl Ui for TestingUi<'_> {
Ok(())
}
+ fn has_glyph(&self, font: Font, c: char) -> bool {
+ if let Some(has_glyph) = self._has_glyph.as_ref() {
+ return has_glyph(font, c);
+ }
+ matches!(c, '\u{20}'..='\u{7e}' | '\u{a0}'..='\u{17f}')
+ }
+
async fn confirm_swap(&mut self, title: &str, from: &str, to: &str) -> Result<(), UserAbort> {
self.screens.push(Screen::Swap {
title: title.into(),
@@ -350,6 +359,7 @@ impl<'a> TestingUi<'a> {
_abort_nth: None,
_enter_string_async: None,
_enter_wordlist_word: None,
+ _has_glyph: None,
_menu: None,
_trinary_choice: None,
_quiz_choices: VecDeque::new(),
@@ -391,6 +401,10 @@ impl<'a> TestingUi<'a> {
self._enter_string_async = None;
}
+ pub fn set_has_glyph(&mut self, cb: Box<dyn Fn(Font, char) -> bool + 'a>) {
+ self._has_glyph = Some(cb);
+ }
+
pub fn set_menu(&mut self, cb: MenuCb<'a>) {
self._menu = Some(cb);
}
### src/rust/bitbox02-rust/src/hww/api/backup.rs
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
use super::Error;
-use crate::hal::ui::{CanCancel, ConfirmParams};
+use crate::hal::ui::{CanCancel, ConfirmParams, Font};
use crate::pb;
use alloc::vec::Vec;
@@ -29,7 +29,10 @@ pub async fn check(
return Err(Error::Generic);
}
if !silent {
- let name = backup::sanitize_name(&metadata.name);
+ let name = {
+ let ui = hal.ui();
+ backup::sanitize_name(&metadata.name, |c| ui.has_glyph(Font::Regular11, c))
+ };
hal.ui()
.confirm(&ConfirmParams {
title: "Name?",
### src/rust/bitbox02-rust/src/hww/api/bitcoin/registration.rs
@@ -3,7 +3,7 @@
use super::Error;
use super::params;
use super::pb;
-use crate::hal::ui::ConfirmParams;
+use crate::hal::ui::{ConfirmParams, Font};
use alloc::string::String;
@@ -93,7 +93,11 @@ async fn get_name(
} else {
request.name.clone()
};
- if !util::name::validate(&name, bitbox_hal::memory::MULTISIG_NAME_MAX_LEN) {
+ let has_all_glyphs = {
+ let ui = hal.ui();
+ name.chars().all(|c| ui.has_glyph(Font::Regular11, c))
+ };
+ if !util::name::validate(&name, bitbox_hal::memory::MULTISIG_NAME_MAX_LEN) || !has_all_glyphs {
return Err(Error::InvalidInput);
}
Ok(name)
@@ -174,6 +178,24 @@ mod tests {
use crate::hal::testing::TestingHal;
+ #[async_test::test]
+ async fn test_get_name_utf8() {
+ let request = pb::BtcRegisterScriptConfigRequest {
+ name: "Müller".into(),
+ ..Default::default()
+ };
+ let mut mock_hal = TestingHal::new();
+ assert_eq!(get_name(&mut mock_hal, &request).await.unwrap(), "Müller");
+
+ mock_hal
+ .ui
+ .set_has_glyph(alloc::boxed::Box::new(|_, character| character != 'ü'));
+ assert!(matches!(
+ get_name(&mut mock_hal, &request).await,
+ Err(Error::InvalidInput)
+ ));
+ }
+
use pb::btc_script_config::{Multisig, multisig::ScriptType};
#[test]
### src/rust/bitbox02-rust/src/hww/api/ethereum/sign_typed_msg.rs
@@ -13,7 +13,7 @@ use super::sighash::DataProducer;
use super::truncating_hex_preview_byte_cap;
use crate::hal::Ui;
-use crate::hal::ui::ConfirmParams;
+use crate::hal::ui::{ConfirmParams, Font};
use crate::keystore;
use crate::workflow::confirm;
@@ -297,7 +297,11 @@ async fn get_value_from_host(
///
/// Returns the 32 byte encoded value as well as a human readable representation that can be used
/// for user verification.
-fn encode_value(typ: &MemberType, value: Vec<u8>) -> Result<(Vec<u8>, String), Error> {
+fn encode_value(
+ ui: &impl Ui,
+ typ: &MemberType,
+ value: Vec<u8>,
+) -> Result<(Vec<u8>, String), Error> {
let result = match DataType::try_from(typ.r#type)? {
DataType::Unknown => return Err(Error::InvalidInput),
DataType::Bytes => {
@@ -358,12 +362,18 @@ fn encode_value(typ: &MemberType, value: Vec<u8>) -> Result<(Vec<u8>, String), E
(encoded, super::address::format_display_address(&value_str))
}
DataType::String => {
- if !util::ascii::is_printable_ascii(&value, util::ascii::Charset::AllNewline) {
+ let value_str = String::from_utf8(value).or(Err(Error::InvalidInput))?;
+ if !value_str
+ .chars()
+ .all(|c| c == '\n' || ui.has_glyph(Font::Regular11, c))
+ {
return Err(Error::InvalidInput);
}
(
- sha3::Keccak256::digest(&value).as_slice().to_vec(),
- String::from_utf8(value).or(Err(Error::InvalidInput))?,
+ sha3::Keccak256::digest(value_str.as_bytes())
+ .as_slice()
+ .to_vec(),
+ value_str,
)
}
DataType::Array | DataType::Struct => panic!("encode_value"),
@@ -473,7 +483,7 @@ async fn encode_member<U: sha3::digest::Update>(
format!("0x{}", hex::encode(producer.preview()))
} else {
let value_len = req.value.len();
- let (value_encoded, fmt) = encode_value(member_type, req.value)?;
+ let (value_encoded, fmt) = encode_value(&*hal.ui(), member_type, req.value)?;
hasher.update(&value_encoded);
if data_type == DataType::Bytes {
display_size = value_len;
@@ -1233,16 +1243,79 @@ mod tests {
#[test]
fn test_encode_value_address() {
+ let mock_hal = TestingHal::new();
let value = |len: usize| {
let mut value = b"0x".to_vec();
value.resize(2 + len * 2, b'1');
value
};
let typ = mk_type(DataType::Address);
- assert_eq!(encode_value(&typ, value(19)), Err(Error::InvalidInput));
- assert!(encode_value(&typ, value(20)).is_ok());
- assert_eq!(encode_value(&typ, value(21)), Err(Error::InvalidInput));
+ assert_eq!(
+ encode_value(&mock_hal.ui, &typ, value(19)),
+ Err(Error::InvalidInput)
+ );
+ assert!(encode_value(&mock_hal.ui, &typ, value(20)).is_ok());
+ assert_eq!(
+ encode_value(&mock_hal.ui, &typ, value(21)),
+ Err(Error::InvalidInput)
+ );
+ }
+
+ #[test]
+ fn test_encode_value_string() {
+ let mut mock_hal = TestingHal::new();
+ mock_hal
+ .ui
+ .set_has_glyph(Box::new(|_, c| matches!(c, ' '..='~' | 'ü' | '€')));
+ let typ = mk_type(DataType::String);
+ let value = "Zürich\n10 €";
+ let (encoded, formatted) =
+ encode_value(&mock_hal.ui, &typ, value.as_bytes().to_vec()).unwrap();
+ assert_eq!(
+ encoded,
+ sha3::Keccak256::digest(value.as_bytes()).as_slice()
+ );
+ assert_eq!(formatted, value);
+
+ assert_eq!(
+ encode_value(&mock_hal.ui, &typ, "tab\t".as_bytes().to_vec()),
+ Err(Error::InvalidInput)
+ );
+ assert_eq!(
+ encode_value(&mock_hal.ui, &typ, "東京".as_bytes().to_vec()),
+ Err(Error::InvalidInput)
+ );
+ assert_eq!(
+ encode_value(&mock_hal.ui, &typ, "µ".as_bytes().to_vec()),
+ Err(Error::InvalidInput)
+ );
+ for value in ["non\u{a0}breaking space", "soft\u{ad}hyphen"] {
+ assert_eq!(
+ encode_value(&mock_hal.ui, &typ, value.as_bytes().to_vec()),
+ Err(Error::InvalidInput)
+ );
+ }
+ assert_eq!(
+ encode_value(&mock_hal.ui, &typ, vec![0xff]),
+ Err(Error::InvalidInput)
+ );
+
+ mock_hal.ui.set_has_glyph(Box::new(|_, _| true));
+ let value = "東京 µ";
+ let (encoded, formatted) =
+ encode_value(&mock_hal.ui, &typ, value.as_bytes().to_vec()).unwrap();
+ assert_eq!(
+ encoded,
+ sha3::Keccak256::digest(value.as_bytes()).as_slice()
+ );
+ assert_eq!(formatted, value);
+
+ mock_hal.ui.set_has_glyph(Box::new(|_, c| c != 'ü'));
+ assert_eq!(
+ encode_value(&mock_hal.ui, &typ, "Zürich".as_bytes().to_vec()),
+ Err(Error::InvalidInput)
+ );
}
#[test]
### src/rust/bitbox02-rust/src/hww/api/payment_request.rs
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
use super::Error;
-use crate::hal::ui::ConfirmParams;
+use crate::hal::ui::{ConfirmParams, Font};
use crate::pb;
use alloc::vec::Vec;
@@ -148,10 +148,14 @@ pub async fn user_verify(
Memo {
memo: Some(memo::Memo::TextMemo(text_memo)),
} => {
- if !util::ascii::is_printable_ascii(
- &text_memo.note,
- util::ascii::Charset::AllNewline,
- ) {
+ let has_all_glyphs = {
+ let ui = hal.ui();
+ text_memo
+ .note
+ .chars()
+ .all(|c| c == '\n' || ui.has_glyph(Font::Regular11, c))
+ };
+ if !has_all_glyphs {
return Err(Error::InvalidInput);
}
hal.ui()
@@ -1573,7 +1577,7 @@ mod tests {
&mut mock_hal,
&pb::BtcPaymentRequestRequest {
recipient_name: "POCKET".into(),
- memos: vec![make_text_memo("Pocket memo")],
+ memos: vec![make_text_memo("Pöcket memo")],
nonce: vec![],
total_amount: 1234567890,
signature: vec![],
@@ -1597,14 +1601,46 @@ mod tests {
},
Screen::Confirm {
title: "Memo".into(),
- body: "Pocket memo".into(),
+ body: "Pöcket memo".into(),
longtouch: false,
},
]
);
assert_eq!(mock_hal.ui.confirm_scrollable, vec![true, true]);
}
+ #[async_test::test]
+ async fn test_user_verify_text_memo_glyphs() {
+ for (note, valid) in [("Pöcket memo", false), ("東京\nµ", true)] {
+ let mut mock_hal = TestingHal::new();
+ mock_hal.ui.set_has_glyph(alloc::boxed::Box::new(|font, c| {
+ assert!(matches!(font, Font::Regular11));
+ c != 'ö' && !c.is_control()
+ }));
+ let result = user_verify(
+ &mut mock_hal,
+ &pb::BtcPaymentRequestRequest {
+ recipient_name: "POCKET".into(),
+ memos: vec![make_text_memo(note)],
+ ..Default::default()
+ },
+ "0.25 BTC",
+ )
+ .await;
+ if valid {
+ result.unwrap();
+ assert_eq!(mock_hal.ui.screens.len(), 4);
+ assert!(matches!(
+ &mock_hal.ui.screens[2],
+ Screen::Confirm { title, body, .. } if title == "Memo 1/2" && body == "東京"
+ ));
+ } else {
+ assert_eq!(result, Err(Error::InvalidInput));
+ assert_eq!(mock_hal.ui.screens.len(), 1);
+ }
+ }
+ }
+
#[async_test::test]
async fn test_user_verify_long_recipient_name_scrollable() {
let recipient_name = format!("SWAPKIT ({})", "a".repeat(200));
### src/rust/bitbox02-rust/src/hww/api/restore.rs
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
use super::Error;
-use crate::hal::ui::ConfirmParams;
+use crate::hal::ui::{ConfirmParams, Font};
use crate::pb;
use pb::response::Response;
@@ -32,7 +32,10 @@ pub async fn from_file(
}
};
- let device_name = crate::backup::sanitize_name(&metadata.name);
+ let device_name = {
+ let ui = hal.ui();
+ crate::backup::sanitize_name(&metadata.name, |c| ui.has_glyph(Font::Regular11, c))
+ };
hal.ui()
.confirm(&ConfirmParams {
body: &format!("Name: {}. ID: {}", &device_name, &request.id),
@@ -208,11 +211,11 @@ mod tests {
mock_hal.ui.screens[1],
Screen::Confirm {
title: "".into(),
- body: format!("Name: B?t?Box?. ID: {id}"),
+ body: format!("Name: Bït?Box?. ID: {id}"),
longtouch: false,
}
);
- assert_eq!(mock_hal.memory.get_device_name(), "B?t?Box?");
+ assert_eq!(mock_hal.memory.get_device_name(), "Bït?Box?");
}
#[async_test::test]
### src/rust/bitbox02-rust/src/hww/api/set_device_name.rs
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
use super::Error;
-use crate::hal::ui::ConfirmParams;
+use crate::hal::ui::{ConfirmParams, Font};
use crate::pb;
use pb::response::Response;
@@ -20,7 +20,11 @@ pub async fn process(
return Ok(Response::Success(pb::Success {}));
}
- if !util::name::validate(name, bitbox_hal::memory::DEVICE_NAME_MAX_LEN) {
+ let has_all_glyphs = {
+ let ui = hal.ui();
+ name.chars().all(|c| ui.has_glyph(Font::Regular11, c))
+ };
+ if !util::name::validate(name, bitbox_hal::memory::DEVICE_NAME_MAX_LEN) || !has_all_glyphs {
return Err(Error::InvalidInput);
}
@@ -48,7 +52,7 @@ mod tests {
#[async_test::test]
pub async fn test_set_device_name() {
- const SOME_NAME: &str = "foo";
+ const SOME_NAME: &str = "BïtBöx";
// All good.
let mut mock_hal = TestingHal::new();
@@ -94,7 +98,7 @@ mod tests {
}]
);
- // Non-ascii character.
+ // Unsupported character.
assert_eq!(
process(
&mut TestingHal::new(),
@@ -106,6 +110,35 @@ mod tests {
Err(Error::InvalidInput)
);
+ // A character that is unavailable in the active font is rejected.
+ let mut mock_hal = TestingHal::new();
+ mock_hal
+ .ui
+ .set_has_glyph(Box::new(|_, character| character != 'ï'));
+ assert_eq!(
+ process(
+ &mut mock_hal,
+ &pb::SetDeviceNameRequest {
+ name: SOME_NAME.into()
+ }
+ )
+ .await,
+ Err(Error::InvalidInput)
+ );
+
+ mock_hal.ui.set_has_glyph(Box::new(|_, _| true));
+ assert_eq!(
+ process(
+ &mut mock_hal,
+ &pb::SetDeviceNameRequest {
+ name: "東京".into()
+ }
+ )
+ .await,
+ Ok(Response::Success(pb::Success {}))
+ );
+ assert_eq!(mock_hal.memory.get_device_name(), "東京");
+
// Non-printable character.
assert_eq!(
process(
### src/rust/bitbox02-rust/src/workflow/pairing.rs
@@ -24,7 +24,7 @@ pub async fn confirm(hal: &mut impl crate::hal::Hal, hash: &[u8; 32]) -> Result<
let params = ConfirmParams {
title: "Pairing code",
body: &format_hash(hash),
- font: Font::Monogram5X9,
+ font: Font::Monogram16,
..Default::default()
};
### src/rust/bitbox02-rust/src/workflow/unlock.rs
@@ -44,7 +44,7 @@ pub(crate) async fn confirm_mnemonic_passphrase(
let params = ConfirmParams {
title: "Confirm",
body: passphrase,
- font: crate::hal::ui::Font::Password11X12,
+ font: crate::hal::ui::Font::Password12,
scrollable: true,
longtouch: true,
..Default::default()
### src/rust/bitbox02-rust/src/workflow/verify_message.rs
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: Apache-2.0
-use crate::hal::ui::ConfirmParams;
+use crate::hal::ui::{ConfirmParams, Font};
use alloc::vec::Vec;
-use util::ascii;
+use crate::hal::Ui;
pub enum Error {
InvalidInput,
@@ -16,10 +16,18 @@ impl core::convert::From<crate::hal::ui::UserAbort> for Error {
}
}
+fn is_displayable_with_regular11_font(ui: &impl Ui, bytes: &[u8]) -> bool {
+ let Ok(msg) = core::str::from_utf8(bytes) else {
+ return false;
+ };
+ msg.chars()
+ .all(|c| c == '\n' || ui.has_glyph(Font::Regular11, c))
+}
+
/// Verify a message.
///
-/// If the bytes are all printable ascii chars, the message is
-/// confirmed one line at a time (the str is split into lines).
+/// If the bytes are valid UTF-8 and all codepoints are newlines or covered by the Regular11 display
+/// font, the message is confirmed one line at a time (the str is split into lines).
///
/// Otherwise, it is displayed as hex.
///
@@ -34,10 +42,13 @@ pub async fn verify(
msg: &[u8],
is_final: bool,
) -> Result<(), Error> {
- if ascii::is_printable_ascii(msg, ascii::Charset::AllNewline) {
- // The message is all ascii and printable.
- // SAFETY: `is_printable_ascii()` accepted every byte above.
- let msg = unsafe { core::str::from_utf8_unchecked(msg) };
+ let is_displayable = {
+ let ui = hal.ui();
+ is_displayable_with_regular11_font(&*ui, msg)
+ };
+
+ if is_displayable {
+ let msg = core::str::from_utf8(msg).unwrap();
if msg.is_empty() {
return Err(Error::InvalidInput);
}
@@ -84,6 +95,8 @@ pub async fn verify(
mod tests {
use super::*;
+ use alloc::boxed::Box;
+
use crate::hal::testing::TestingHal;
use crate::hal::testing::ui::Screen;
use crate::workflow::confirm::{MAX_CONFIRM_BODY_SIZE, TRUNCATION_WARNING_BODY};
@@ -297,21 +310,136 @@ mod tests {
}
}
+ #[test]
+ fn test_is_displayable_with_regular11_font() {
+ let mut mock_hal = TestingHal::new();
+ mock_hal
+ .ui
+ .set_has_glyph(Box::new(|_, c| matches!(c, ' '..='~' | 'ü' | '€')));
+ assert!(is_displayable_with_regular11_font(
+ &mock_hal.ui,
+ "Zürich".as_bytes()
+ ));
+ assert!(is_displayable_with_regular11_font(
+ &mock_hal.ui,
+ "€\nA".as_bytes()
+ ));
+ assert!(!is_displayable_with_regular11_font(
+ &mock_hal.ui,
+ "Aȑ".as_bytes()
+ ));
+ assert!(!is_displayable_with_regular11_font(
+ &mock_hal.ui,
+ "東京".as_bytes()
+ ));
+ assert!(!is_displayable_with_regular11_font(
+ &mock_hal.ui,
+ "tab\t".as_bytes()
+ ));
+ assert!(!is_displayable_with_regular11_font(
+ &mock_hal.ui,
+ "non\u{a0}breaking space".as_bytes()
+ ));
+ assert!(!is_displayable_with_regular11_font(
+ &mock_hal.ui,
+ "µ".as_bytes()
+ ));
+ assert!(!is_displayable_with_regular11_font(
+ &mock_hal.ui,
+ "soft\u{ad}hyphen".as_bytes()
+ ));
+ assert!(!is_displayable_with_regular11_font(&mock_hal.ui, &[0xff]));
+
+ mock_hal.ui.set_has_glyph(Box::new(|_, _| true));
+ assert!(is_displayable_with_regular11_font(
+ &mock_hal.ui,
+ "東京 µ".as_bytes()
+ ));
+
+ mock_hal.ui.set_has_glyph(Box::new(|_, c| c != 'ü'));
+ assert!(!is_displayable_with_regular11_font(
+ &mock_hal.ui,
+ "Zürich".as_bytes()
+ ));
+ }
+
#[async_test::test]
- async fn test_verify_non_ascii_utf8_as_hex() {
- let mut hal = TestingHal::new();
- assert!(
- verify(&mut hal, "Sign message", "Sign", "tä".as_bytes(), true)
- .await
- .is_ok()
+ async fn test_verify_displayable_with_regular11_font() {
+ let mut mock_hal = TestingHal::new();
+ let result = verify(
+ &mut mock_hal,
+ "Sign message",
+ "Sign",
+ "Zürich\n§".as_bytes(),
+ true,
+ )
+ .await;
+ assert!(matches!(result, Ok(())));
+
+ assert_eq!(
+ mock_hal.ui.screens,
+ vec![
+ Screen::Confirm {
+ title: "Sign 1/2".into(),
+ body: "Zürich".into(),
+ longtouch: false,
+ },
+ Screen::Confirm {
+ title: "Sign 2/2".into(),
+ body: "§".into(),
+ longtouch: true,
+ },
+ ]
);
+ assert_eq!(mock_hal.ui.confirm_display_sizes, vec![0, 0]);
+ }
+
+ #[async_test::test]
+ async fn test_verify_hex_if_not_displayable_with_regular11_font() {
+ let mut mock_hal = TestingHal::new();
+ let result = verify(
+ &mut mock_hal,
+ "Sign message",
+ "Sign",
+ "東京".as_bytes(),
+ true,
+ )
+ .await;
+ assert!(matches!(result, Ok(())));
+
assert_eq!(
- hal.ui.screens,
+ mock_hal.ui.screens,
+ vec![Screen::Confirm {
+ title: "Sign message\ndata (hex)".into(),
+ body: "e69db1e4baac".into(),
+ longtouch: true,
+ }]
+ );
+ assert_eq!(mock_hal.ui.confirm_display_sizes, vec![6]);
+ }
+
+ #[async_test::test]
+ async fn test_verify_hex_if_glyph_missing_from_regular11_font() {
+ let checked_glyphs = core::cell::RefCell::new(Vec::new());
+ let mut mock_hal = TestingHal::new();
+ mock_hal.ui.set_has_glyph(Box::new(|font, c| {
+ assert!(matches!(font, Font::Regular11));
+ checked_glyphs.borrow_mut().push(c);
+ c != 'ü'
+ }));
+
+ let result = verify(&mut mock_hal, "Sign message", "Sign", "Aü".as_bytes(), true).await;
+ assert!(matches!(result, Ok(())));
+ assert_eq!(checked_glyphs.borrow().as_slice(), &['A', 'ü']);
+
+ assert_eq!(
+ mock_hal.ui.screens,
vec![Screen::Confirm {
title: "Sign message\ndata (hex)".into(),
- body: "74c3a4".into(),
+ body: "41c3bc".into(),
longtouch: true,
}]
);
+ assert_eq!(mock_hal.ui.confirm_display_sizes, vec![3]);
}
}
### src/rust/bitbox02-sys/build.rs
@@ -13,10 +13,10 @@ const ALLOWLIST_VARS: &[&str] = &[
"da14531_handler_current_product_len",
"BITBOX02_FLASH_BOOT_LEN",
"BITBOX02_FLASH_BOOT_START",
- "font_font_a_11X10",
- "font_font_a_9X9",
- "font_monogram_5X9",
- "font_password_11X12",
+ "font_regular_11",
+ "font_regular_9",
+ "font_monogram_16",
+ "font_password_12",
"INPUT_STRING_MAX_SIZE",
"MAX_LABEL_SIZE",
"MAX_PK_SCRIPT_SIZE",
@@ -54,6 +54,8 @@ const ALLOWLIST_TYPES: &[&str] = &[
const OPAQUE_TYPES: &[&str] = &[
"da14531_protocol_frame",
+ "_lv_font_t",
+ "lv_font_t",
"RustByteQueue",
"RustUsbReportQueue",
];
@@ -180,6 +182,7 @@ const ALLOWLIST_FNS: &[&str] = &[
"uart_poll",
"UG_ClearBuffer",
"UG_FontSelect",
+ "UG_GetCharWidth",
"UG_PutString",
"UG_SendBuffer",
"ui_screen_stack_pop_all",
@@ -261,15 +264,13 @@ const BITBOX02_SOURCES: &[&str] = &[
"src/ui/components/ui_images.c",
"src/ui/components/waiting.c",
"src/ui/event_handler.c",
- "src/ui/fonts/font_a_11X10.c",
- "src/ui/fonts/font_a_11X12.c",
- "src/ui/fonts/font_a_13X14.c",
- "src/ui/fonts/font_a_15X16.c",
- "src/ui/fonts/font_a_17X18.c",
- "src/ui/fonts/font_a_9X9.c",
- "src/ui/fonts/monogram_5X9.c",
- "src/ui/fonts/password_11X12.c",
- "src/ui/fonts/password_9X9.c",
+ "src/ui/fonts/regular_11.c",
+ "src/ui/fonts/regular_12.c",
+ "src/ui/fonts/regular_9.c",
+ "src/ui/fonts/lvgl_font_compat.c",
+ "src/ui/fonts/monogram_16.c",
+ "src/ui/fonts/password_12.c",
+ "src/ui/fonts/password_9.c",
"src/ui/graphics/graphics.c",
"src/ui/oled/sh1107.c",
"src/ui/oled/ssd1312.c",
@@ -327,6 +328,44 @@ pub fn main() -> BuildResult<()> {
emit_rerun_if_changed("../../../src/bootloader/stage0/stage0_version.h.tmpl");
emit_rerun_if_changed("../../../scripts/generate_version_headers.py");
emit_rerun_if_changed("../../../scripts/generate_rust_header.sh");
+ emit_rerun_if_changed("../bitbox-lvgl-sys/lv_conf.h");
+
+ // Watch C headers and their subdirectories without watching src/rust and its build outputs.
+ for path in [
+ "../../../src/atecc",
+ "../../../src/bootloader",
+ "../../../src/bootloader_upgrade",
+ "../../../src/common_main.h",
+ "../../../src/compiler_util.h",
+ "../../../src/da14531",
+ "../../../src/delay.h",
+ "../../../src/flags.h",
+ "../../../src/hardfault.h",
+ "../../../src/hww.h",
+ "../../../src/i2c_ecc.h",
+ "../../../src/memory",
+ "../../../src/optiga",
+ "../../../src/pac_ext.h",
+ "../../../src/platform",
+ "../../../src/pukcc",
+ "../../../src/qtouch",
+ "../../../src/random.h",
+ "../../../src/reset.h",
+ "../../../src/screen.h",
+ "../../../src/sd.h",
+ "../../../src/sd_mmc",
+ "../../../src/securechip",
+ "../../../src/system.h",
+ "../../../src/touch",
+ "../../../src/u2f",
+ "../../../src/u2f.h",
+ "../../../src/uart.h",
+ "../../../src/ui",
+ "../../../src/usb",
+ "../../../src/util.h",
+ ] {
+ emit_rerun_if_changed(path);
+ }
// Generating version headers depends on the current state of the git repo.
emit_git_rerun_if_changed(&repo_root);
@@ -337,11 +376,22 @@ pub fn main() -> BuildResult<()> {
emit_bindgen_env_rerun_if_changed(&target);
let cross_compiling = target.starts_with("thumb");
- let target_definitions = if cross_compiling {
- vec!["-D__SAMD51J20A__"]
+ let lv_conf = manifest_dir.join("../bitbox-lvgl-sys/lv_conf.h");
+ let mut target_definitions = if cross_compiling {
+ vec!["-D__SAMD51J20A__".to_owned()]
} else {
- vec!["-DTESTING", "-D_UNIT_TEST_", "-DPRODUCT_BITBOX_MULTI=1"]
+ vec![
+ "-DTESTING".to_owned(),
+ "-D_UNIT_TEST_".to_owned(),
+ "-DPRODUCT_BITBOX_MULTI=1".to_owned(),
+ ]
};
+ target_definitions.extend([
+ "-DLV_KCONFIG_IGNORE".to_owned(),
+ "-DLV_LVGL_H_INCLUDE_SIMPLE".to_owned(),
+ format!("-DLV_CONF_PATH=\"{}\"", lv_conf.display()),
+ "-DLV_CONF_INCLUDE_SIMPLE".to_owned(),
+ ]);
// If user enables -Dwarnings for Rust we also want to enable -Werror for C.
let warnings_as_errors = std::env::var("CARGO_ENCODED_RUSTFLAGS")
@@ -354,6 +404,7 @@ pub fn main() -> BuildResult<()> {
// $INCLUDES
"../..".to_owned(),
"../../ui/ugui".to_owned(),
+ "../../../external/lvgl".to_owned(),
"../../platform".to_owned(),
"../../qtouch".to_owned(),
"../../usb/class".to_owned(),
@@ -411,15 +462,23 @@ pub fn main() -> BuildResult<()> {
includes.push("../../../test/hardware-fakes/include".to_owned());
}
+ // Track included headers, including LVGL, ASF4 and hardware fakes. The src root is covered
+ // above. Avoid watching the generated output directory itself.
+ for include in &includes {
+ if include != "../.." && Path::new(include) != generated_headers_dir.as_path() {
+ emit_rerun_if_changed(include);
+ }
+ }
+
let out_path = out_dir.join("bindings.rs");
let out_path = out_path.into_os_string().into_string().unwrap();
// Needs to match the definitions in `CMakeList.txt' files (unit tests, hardware fakes and
// simulator)
- let mut definitions = vec!["-DAPP_U2F=1"];
+ let mut definitions = vec!["-DAPP_U2F=1".to_owned()];
definitions.extend(target_definitions);
if warnings_as_errors {
- definitions.push("-Werror");
+ definitions.push("-Werror".to_owned());
}
let mut bindgen = Command::new("bindgen");
### src/rust/bitbox02-sys/wrapper.h
@@ -39,10 +39,10 @@
#include <ui/components/trinary_choice.h>
#include <ui/components/trinary_input_string.h>
#include <ui/components/unlock_animation.h>
-#include <ui/fonts/font_a_11X10.h>
-#include <ui/fonts/font_a_9X9.h>
-#include <ui/fonts/monogram_5X9.h>
-#include <ui/fonts/password_11X12.h>
+#include <ui/fonts/monogram_16.h>
+#include <ui/fonts/password_12.h>
+#include <ui/fonts/regular_11.h>
+#include <ui/fonts/regular_9.h>
#include <ui/oled/oled.h>
#include <ui/screen_process.h>
#include <ui/screen_saver.h>
### src/rust/bitbox02/src/hal/ui.rs
@@ -33,9 +33,9 @@ impl HalEmpty for BitBox02Empty {}
fn to_bitbox02_font(font: Font) -> crate::ui::Font {
match font {
- Font::Default => crate::ui::Font::Default,
- Font::Password11X12 => crate::ui::Font::Password11X12,
- Font::Monogram5X9 => crate::ui::Font::Monogram5X9,
+ Font::Regular11 => crate::ui::Font::Regular11,
+ Font::Password12 => crate::ui::Font::Password12,
+ Font::Monogram16 => crate::ui::Font::Monogram16,
}
}
@@ -145,6 +145,10 @@ impl<Timer: bitbox_hal::timer::Timer> Ui for BitBox02Ui<Timer> {
}
}
+ fn has_glyph(&self, font: Font, c: char) -> bool {
+ to_bitbox02_font(font).has_glyph(c)
+ }
+
#[inline(always)]
async fn confirm_swap(&mut self, title: &str, from: &str, to: &str) -> Result<(), UserAbort> {
if !crate::ui::transaction_amount_fits(from) || !crate::ui::transaction_amount_fits(to) {
@@ -315,21 +319,29 @@ mod tests {
#[test]
fn test_to_bitbox02_font() {
let cases = [
- (Font::Default, crate::ui::Font::Default),
- (Font::Password11X12, crate::ui::Font::Password11X12),
- (Font::Monogram5X9, crate::ui::Font::Monogram5X9),
+ (Font::Regular11, crate::ui::Font::Regular11),
+ (Font::Password12, crate::ui::Font::Password12),
+ (Font::Monogram16, crate::ui::Font::Monogram16),
];
for (input, expected) in cases {
assert_eq!(to_bitbox02_font(input) as i32, expected as i32);
}
}
+ #[test]
+ fn test_has_glyph_uses_actual_bitbox02_font() {
+ assert!(to_bitbox02_font(Font::Regular11).has_glyph('A'));
+ assert!(to_bitbox02_font(Font::Regular11).has_glyph('ü'));
+ assert!(!to_bitbox02_font(Font::Regular11).has_glyph('ȑ'));
+ assert!(!to_bitbox02_font(Font::Regular11).has_glyph('\t'));
+ }
+
#[test]
fn test_to_bitbox02_confirm_params() {
let fonts = [
- (Font::Default, crate::ui::Font::Default),
- (Font::Password11X12, crate::ui::Font::Password11X12),
- (Font::Monogram5X9, crate::ui::Font::Monogram5X9),
+ (Font::Regular11, crate::ui::Font::Regular11),
+ (Font::Password12, crate::ui::Font::Password12),
+ (Font::Monogram16, crate::ui::Font::Monogram16),
];
for (font, expected_font) in fonts {
let input = ConfirmParams {
### src/rust/bitbox02/src/lib.rs
@@ -71,11 +71,11 @@ pub fn ug_send_buffer() {
}
pub fn ug_font_select_9x9() {
- unsafe { bitbox02_sys::UG_FontSelect(&bitbox02_sys::font_font_a_9X9) }
+ unsafe { bitbox02_sys::UG_FontSelect(&bitbox02_sys::font_regular_9) }
}
pub fn ug_font_select_11x10() {
- unsafe { bitbox02_sys::UG_FontSelect(&bitbox02_sys::font_font_a_11X10) }
+ unsafe { bitbox02_sys::UG_FontSelect(&bitbox02_sys::font_regular_11) }
}
pub fn screen_rotate() {
### src/rust/bitbox02/src/memory.rs
@@ -11,6 +11,29 @@ pub use bitbox02_sys::memory_optiga_config_version_t as OptigaConfigVersion;
pub use bitbox02_sys::memory_password_stretch_algo_t as PasswordStretchAlgo;
pub use bitbox02_sys::memory_result_t as MemoryError;
+/// Calls `util::name::validate()` on the provided C string and checks glyph availability.
+///
+/// # Safety
+///
+/// `buf` must point to a valid buffer of size `max_len`.
+#[unsafe(no_mangle)]
+pub unsafe extern "C" fn rust_util_is_name_valid(buf: *const u8, max_len: usize) -> bool {
+ if max_len == 0 {
+ return false;
+ }
+ let slice = unsafe { core::slice::from_raw_parts(buf, max_len) };
+ match core::ffi::CStr::from_bytes_until_nul(slice) {
+ Ok(cstr) => match cstr.to_str() {
+ Ok(s) => {
+ util::name::validate(s, max_len - 1)
+ && s.chars().all(|c| crate::ui::Font::Regular11.has_glyph(c))
+ }
+ Err(_) => false,
+ },
+ Err(_) => false,
+ }
+}
+
pub fn get_device_name() -> String {
let mut name = [0u8; DEVICE_NAME_MAX_LEN + 1];
unsafe { bitbox02_sys::memory_get_device_name(name.as_mut_ptr().cast()) }
@@ -417,6 +440,10 @@ mod tests {
set_device_name(new_name).unwrap();
assert_eq!(get_device_name(), new_name);
+ let utf8_name = "BïtBöx Zürich";
+ set_device_name(utf8_name).unwrap();
+ assert_eq!(get_device_name(), utf8_name);
+
// A name with the maximum allowed length is accepted.
let max_len_name = "DeviceName_ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxy";
assert_eq!(max_len_name.len(), DEVICE_NAME_MAX_LEN);
@@ -435,8 +462,8 @@ mod tests {
" name", // leading space
"name ", // trailing space
"foo\nbar", // control character
- "Ä", // non-ASCII
- "漢字", // non-ASCII
+ "漢字", // unsupported character
+ "emoji 😃", // unsupported character
];
for invalid in invalid_names {
@@ -851,4 +878,25 @@ mod tests {
Ok(OptigaConfigVersion::MEMORY_OPTIGA_CONFIG_V1),
));
}
+
+ #[test]
+ // For clarity we want explicit null terminators in the strings below, not CStr literals
+ // `c"..."`.
+ #[allow(clippy::manual_c_str_literals)]
+ fn test_rust_util_is_name_valid() {
+ unsafe {
+ // Valid
+ assert!(rust_util_is_name_valid("foo\0".as_ptr(), 4));
+ assert!(rust_util_is_name_valid("foo\0........".as_ptr(), 12));
+ assert!(rust_util_is_name_valid("BïtBöx\0".as_ptr(), 10));
+
+ // Invalid
+ assert!(!rust_util_is_name_valid("fo\no\0".as_ptr(), 5));
+ assert!(!rust_util_is_name_valid("".as_ptr(), 0));
+ assert!(!rust_util_is_name_valid("foo\0".as_ptr(), 3));
+ assert!(!rust_util_is_name_valid("foo".as_ptr(), 3));
+ assert!(!rust_util_is_name_valid("東京\0".as_ptr(), 7));
+ assert!(!rust_util_is_name_valid("ȑ\0".as_ptr(), 3));
+ }
+ }
}
### src/rust/bitbox02/src/ui/types.rs
@@ -13,20 +13,31 @@ const _: () = assert!(MAX_LABEL_SIZE == bitbox02_sys::MAX_LABEL_SIZE as usize);
#[derive(Default)]
pub enum Font {
#[default]
- Default,
- Password11X12,
- Monogram5X9,
+ Regular11,
+ Password12,
+ Monogram16,
+ Regular9,
}
impl Font {
#[cfg_attr(any(feature = "testing", feature = "c-unit-testing"), allow(dead_code))]
pub(crate) fn as_ptr(&self) -> *const bitbox02_sys::UG_FONT {
match self {
- Font::Default => core::ptr::null() as *const _,
- Font::Password11X12 => unsafe { &bitbox02_sys::font_password_11X12 },
- Font::Monogram5X9 => unsafe { &bitbox02_sys::font_monogram_5X9 },
+ Font::Regular11 => unsafe { &bitbox02_sys::font_regular_11 },
+ Font::Password12 => unsafe { &bitbox02_sys::font_password_12 },
+ Font::Monogram16 => unsafe { &bitbox02_sys::font_monogram_16 },
+ Font::Regular9 => unsafe { &bitbox02_sys::font_regular_9 },
}
}
+
+ #[cfg_attr(any(feature = "testing", feature = "c-unit-testing"), allow(dead_code))]
+ pub(crate) fn has_glyph(&self, c: char) -> bool {
+ if c.is_control() {
+ return false;
+ }
+ let mut width = 0u16;
+ unsafe { bitbox02_sys::UG_GetCharWidth(self.as_ptr(), c as u32, &mut width) }
+ }
}
pub enum SdcardResponse {
### src/rust/bitbox02/src/ui/ui.rs
@@ -20,36 +20,51 @@ use zeroize::Zeroizing;
// Rust-side cut moves back to a UTF-8 boundary.
const LABEL_TRUNCATE_SIZE: usize = super::types::MAX_LABEL_SIZE + 4;
-/// BitBox02 fonts contain glyphs for printable ASCII only. Keep this check at the common UI
-/// boundary so unsupported text cannot be silently omitted by the renderer.
-/// The returned buffer is wiped on drop.
-fn display_str_to_cstr_vec(text: &str) -> Zeroizing<Vec<c_char>> {
+/// Keep this check at the common UI boundary so unsupported text cannot be silently omitted by
+/// the renderer. The returned buffer is wiped on drop.
+fn display_str_to_cstr_vec(text: &str, font: &Font) -> Zeroizing<Vec<c_char>> {
assert!(
- util::ascii::is_printable_ascii(text, util::ascii::Charset::AllNewline),
+ text.chars().all(|c| c == '\n' || font.has_glyph(c)),
"BitBox02 UI text contains unsupported characters"
);
// UI strings can contain passphrases or mnemonic words. Include the NUL in the initial
// allocation so growing the buffer cannot leave a discarded copy of the secret.
util::strings::str_to_cstr_vec_zeroizing(text).unwrap()
}
-fn label_fits_width(text: &str, font: *const bitbox02_sys::UG_FONT) -> bool {
- let text = display_str_to_cstr_vec(text);
- unsafe { bitbox02_sys::label_fits_width(text.as_ptr(), font, bitbox02_sys::SCREEN_WIDTH as _) }
+/// The C function retains the selected font, so every `Font` refers to static font data.
+fn label_fits_width(text: &str, font: &Font) -> bool {
+ let text = display_str_to_cstr_vec(text, font);
+ unsafe {
+ bitbox02_sys::label_fits_width(
+ text.as_ptr(),
+ font.as_ptr(),
+ bitbox02_sys::SCREEN_WIDTH as _,
+ )
+ }
+}
+
+/// Mirrors the amount font selection in the C transaction and swap components.
+fn transaction_amount_font(amount: &str) -> Font {
+ if label_fits_width(amount, &Font::Regular11) {
+ Font::Regular11
+ } else {
+ Font::Regular9
+ }
}
/// Returns true if the amount fits the transaction screen, using the smaller font if necessary.
pub fn transaction_amount_fits(amount: &str) -> bool {
- if label_fits_width(amount, unsafe { &bitbox02_sys::font_font_a_11X10 }) {
+ if label_fits_width(amount, &Font::Regular11) {
true
} else {
- label_fits_width(amount, unsafe { &bitbox02_sys::font_font_a_9X9 })
+ label_fits_width(amount, &Font::Regular9)
}
}
/// Returns true if the fee fits the transaction screen's smaller fee font.
pub fn transaction_fee_fits(fee: &str) -> bool {
- label_fits_width(fee, unsafe { &bitbox02_sys::font_font_a_9X9 })
+ label_fits_width(fee, &Font::Regular9)
}
/// Wraps the C component_t to be used in Rust.
@@ -168,10 +183,10 @@ pub async fn trinary_input_string(
(None, core::ptr::null_mut())
};
- let title = display_str_to_cstr_vec(util::strings::truncate_str(
- params.title,
- LABEL_TRUNCATE_SIZE,
- ));
+ let title = display_str_to_cstr_vec(
+ util::strings::truncate_str(params.title, LABEL_TRUNCATE_SIZE),
+ &Font::Regular11,
+ );
let c_params = bitbox02_sys::trinary_input_string_params_t {
title: title.as_ptr().cast(),
wordlist: match params.wordlist {
@@ -201,7 +216,7 @@ pub async fn trinary_input_string(
unsafe {
bitbox02_sys::trinary_input_string_set_input(
component,
- display_str_to_cstr_vec(preset).as_ptr(),
+ display_str_to_cstr_vec(preset, &Font::Password12).as_ptr(),
)
}
}
@@ -260,14 +275,14 @@ pub async fn confirm(params: &ConfirmParams<'_>) -> ConfirmResponse {
}
}
- let title = display_str_to_cstr_vec(util::strings::truncate_str(
- params.title,
- LABEL_TRUNCATE_SIZE,
- ));
- let body = display_str_to_cstr_vec(util::strings::truncate_str(
- params.body,
- LABEL_TRUNCATE_SIZE,
- ));
+ let title = display_str_to_cstr_vec(
+ util::strings::truncate_str(params.title, LABEL_TRUNCATE_SIZE),
+ &Font::Regular11,
+ );
+ let body = display_str_to_cstr_vec(
+ util::strings::truncate_str(params.body, LABEL_TRUNCATE_SIZE),
+ ¶ms.font,
+ );
let c_params = bitbox02_sys::confirm_params_t {
title: title.as_ptr().cast(),
title_autowrap: params.title_autowrap,
@@ -319,7 +334,7 @@ pub fn screen_process() {
pub fn status_create(text: &str, status_success: bool) -> Component {
let component = unsafe {
bitbox02_sys::status_create(
- display_str_to_cstr_vec(text).as_ptr(), // copied in C
+ display_str_to_cstr_vec(text, &Font::Regular11).as_ptr(), // copied in C
status_success,
)
};
@@ -333,7 +348,7 @@ pub fn info_centered_create(text: &str) -> Component {
Component {
component: unsafe {
bitbox02_sys::info_centered_create(
- display_str_to_cstr_vec(text).as_ptr(), // copied in C
+ display_str_to_cstr_vec(text, &Font::Regular11).as_ptr(), // copied in C
None,
)
},
@@ -456,7 +471,7 @@ pub async fn menu(params: MenuParams<'_>) -> MenuResponse {
let words: Vec<_> = params
.words
.iter()
- .map(|word| display_str_to_cstr_vec(word))
+ .map(|word| display_str_to_cstr_vec(word, &Font::Regular11))
.collect();
// Step two: collect pointers. This var also has to be valid until menu() finishes, or
// the pointer will be invalid.
@@ -478,7 +493,9 @@ pub async fn menu(params: MenuParams<'_>) -> MenuResponse {
shared_state_ptr, // passed to continue_on_last_cb as `user_data`.
),
};
- let title = params.title.map(display_str_to_cstr_vec);
+ let title = params
+ .title
+ .map(|title| display_str_to_cstr_vec(title, &Font::Regular11));
let component = unsafe {
bitbox02_sys::menu_create(
c_words.as_ptr(),
@@ -572,13 +589,13 @@ pub async fn trinary_choice(
}
}
- let label_left = label_left.map(display_str_to_cstr_vec);
- let label_middle = label_middle.map(display_str_to_cstr_vec);
- let label_right = label_right.map(display_str_to_cstr_vec);
+ let label_left = label_left.map(|label| display_str_to_cstr_vec(label, &Font::Regular11));
+ let label_middle = label_middle.map(|label| display_str_to_cstr_vec(label, &Font::Regular11));
+ let label_right = label_right.map(|label| display_str_to_cstr_vec(label, &Font::Regular11));
let component = unsafe {
bitbox02_sys::trinary_choice_create(
- display_str_to_cstr_vec(message).as_ptr(), // copied in C
+ display_str_to_cstr_vec(message, &Font::Regular11).as_ptr(), // copied in C
// copied in C
label_left
.as_ref()
@@ -651,8 +668,8 @@ pub async fn confirm_transaction_address(amount: &str, address: &str) -> Confirm
let component = unsafe {
bitbox02_sys::confirm_transaction_address_create(
- display_str_to_cstr_vec(amount).as_ptr(), // copied in C
- display_str_to_cstr_vec(address).as_ptr(), // copied in C
+ display_str_to_cstr_vec(amount, &transaction_amount_font(amount)).as_ptr(), // copied in C
+ display_str_to_cstr_vec(address, &Font::Regular11).as_ptr(), // copied in C
Some(callback),
shared_state_ptr, // passed to callback as `user_data`.
)
@@ -712,9 +729,9 @@ pub async fn confirm_swap(title: &str, from: &str, to: &str) -> ConfirmResponse
let component = unsafe {
bitbox02_sys::confirm_swap_create(
- display_str_to_cstr_vec(title).as_ptr(), // copied in C
- display_str_to_cstr_vec(from).as_ptr(), // copied in C
- display_str_to_cstr_vec(to).as_ptr(), // copied in C
+ display_str_to_cstr_vec(title, &Font::Regular11).as_ptr(), // copied in C
+ display_str_to_cstr_vec(from, &transaction_amount_font(from)).as_ptr(), // copied in C
+ display_str_to_cstr_vec(to, &transaction_amount_font(to)).as_ptr(), // copied in C
Some(callback),
shared_state_ptr, // passed to callback as `user_data`.
)
@@ -774,8 +791,8 @@ pub async fn confirm_transaction_fee(amount: &str, fee: &str, longtouch: bool) -
let component = unsafe {
bitbox02_sys::confirm_transaction_fee_create(
- display_str_to_cstr_vec(amount).as_ptr(), // copied in C
- display_str_to_cstr_vec(fee).as_ptr(), // copied in C
+ display_str_to_cstr_vec(amount, &transaction_amount_font(amount)).as_ptr(), // copied in C
+ display_str_to_cstr_vec(fee, &Font::Regular9).as_ptr(), // copied in C
longtouch,
Some(callback),
shared_state_ptr, // passed to callback as `user_data`.
@@ -814,7 +831,7 @@ pub fn screen_stack_pop_all() {
pub fn progress_create(title: &str) -> Component {
let component = unsafe {
bitbox02_sys::progress_create(
- display_str_to_cstr_vec(title).as_ptr(), // copied in C
+ display_str_to_cstr_vec(title, &Font::Regular11).as_ptr(), // copied in C
)
};
@@ -923,3 +940,52 @@ pub async fn choose_orientation() -> bool {
})
.await
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_display_str_to_cstr_vec() {
+ for (font, text) in [
+ (Font::Regular11, "Café\nZürich"),
+ (Font::Regular9, "Café\nZürich"),
+ (Font::Password12, "Café\nZürich"),
+ (Font::Monogram16, "ABCD 1234\nEFGH 5678"),
+ ] {
+ let encoded = display_str_to_cstr_vec(text, &font);
+ let decoded = unsafe { core::ffi::CStr::from_ptr(encoded.as_ptr()) };
+ assert_eq!(decoded.to_str().unwrap(), text);
+ }
+ }
+
+ #[async_test::test]
+ #[should_panic(expected = "BitBox02 UI text contains unsupported characters")]
+ async fn test_confirm_rejects_missing_body_glyph() {
+ confirm(&ConfirmParams {
+ title: "Confirm",
+ body: "Café",
+ font: Font::Monogram16,
+ ..Default::default()
+ })
+ .await;
+ }
+
+ #[async_test::test]
+ async fn test_confirm_uses_regular11_font_for_title() {
+ crate::screen::init(|_, _, _| {}, |_| {}, || {});
+ let params = ConfirmParams {
+ title: "Café",
+ body: "ABCD 1234",
+ font: Font::Monogram16,
+ ..Default::default()
+ };
+ assert!(
+ futures_lite::future::poll_once(confirm(¶ms))
+ .await
+ .is_none()
+ );
+ // Dropping the pending confirmation queues its C component for cleanup.
+ crate::screen::process(true);
+ }
+}
### src/rust/bitbox03/src/ui.rs
@@ -71,6 +71,10 @@ impl<Timer: bitbox_hal::timer::Timer> hal::ui::Ui for BitBox03Ui<Timer> {
self.with_result_screen(demo::build_demo_screen).await
}
+ fn has_glyph(&self, _font: bitbox_hal::ui::Font, c: char) -> bool {
+ matches!(c, ' '..='~')
+ }
+
async fn confirm_swap(
&mut self,
title: &str,
### src/rust/util/src/name.rs
@@ -1,49 +1,26 @@
// SPDX-License-Identifier: Apache-2.0
-use super::ascii;
-
/// Validate a user given name. The name must be smaller or equal to `max_len` and larger than 0 in
-/// size, consist of printable ASCII characters only (and space), not
-/// start or end with whitespace, and contain no whitespace other than space.
+/// size, contain no control characters, not start or end with whitespace, and contain no
+/// whitespace other than space.
+/// Callers must check glyph availability before displaying the name.
pub fn validate(name: &str, max_len: usize) -> bool {
if name.is_empty() || name.len() > max_len {
return false;
}
- if !ascii::is_printable_ascii(name, ascii::Charset::All) {
+ if name
+ .chars()
+ .any(|c| c.is_control() || (c.is_whitespace() && c != ' '))
+ {
return false;
}
- // Safe because all_ascii passed.
let bytes = name.as_bytes();
if bytes[0] == b' ' || bytes[bytes.len() - 1] == b' ' {
return false;
}
true
}
-//
-// C interface
-//
-
-/// Calls `util::name::validate()` on the provided C string.
-///
-/// # Safety
-///
-/// `buf` must point to a valid buffer of size `max_len`.
-#[unsafe(no_mangle)]
-pub unsafe extern "C" fn rust_util_is_name_valid(buf: *const u8, max_len: usize) -> bool {
- if max_len == 0 {
- return false;
- }
- let slice = unsafe { core::slice::from_raw_parts(buf, max_len) };
- match core::ffi::CStr::from_bytes_until_nul(slice) {
- Ok(cstr) => match cstr.to_str() {
- Ok(s) => validate(s, max_len - 1),
- Err(_) => false,
- },
- Err(_) => false,
- }
-}
-
#[cfg(test)]
mod tests {
extern crate std;
@@ -56,34 +33,21 @@ mod tests {
assert!(validate("foo", 4));
assert!(validate("foo", 3));
assert!(!validate("foo", 2));
+ assert!(validate("ä", 2));
+ assert!(!validate("ä", 1));
// Min len.
assert!(!validate("", 100));
- // Ascii.
+ // Name characters.
assert!(validate("some name", 100));
+ assert!(validate("BïtBöx Zürich", 100));
assert!(!validate("\n", 100));
assert!(!validate("\t", 100));
+ assert!(validate("東京", 100));
+ assert!(!validate("non\u{a0}breaking", 100));
// Starts / ends with space.
assert!(!validate(" foo", 100));
assert!(!validate("foo ", 100));
}
-
- #[test]
- // For clarity we want explicit null terminators in the strings below, not CStr literals
- // `c"..."`.
- #[allow(clippy::manual_c_str_literals)]
- fn test_rust_util_is_name_valid() {
- unsafe {
- // Valid
- assert!(rust_util_is_name_valid("foo\0".as_ptr(), 4));
- assert!(rust_util_is_name_valid("foo\0........".as_ptr(), 12));
-
- // Invalid
- assert!(!rust_util_is_name_valid("fo\no\0".as_ptr(), 5));
- assert!(!rust_util_is_name_valid("".as_ptr(), 0));
- assert!(!rust_util_is_name_valid("foo\0".as_ptr(), 3));
- assert!(!rust_util_is_name_valid("foo".as_ptr(), 3));
- }
- }
}
### src/screen.c
@@ -7,7 +7,7 @@
#include <stdint.h>
#include <string.h>
#include <ui/components/ui_images.h>
-#include <ui/fonts/arial_fonts.h>
+#include <ui/fonts/regular_fonts.h>
#include <ui/oled/oled.h>
#include <ui/ugui/ugui.h>
#include <util.h>
@@ -55,7 +55,7 @@ void screen_print_debug(const char* message, int duration)
char print[100] = {0};
_escape_debug_string(print, sizeof(print), message);
screen_clear();
- UG_FontSelect(&font_font_a_9X9);
+ UG_FontSelect(&font_regular_9);
UG_PutString(0, 0, print);
UG_SendBuffer();
#ifndef TESTING
@@ -124,9 +124,9 @@ void screen_init(
_mirror_fn = mirror_fn;
_clear_fn = clear_fn;
#ifdef BOOTLOADER
- UG_Init(&guioled, pixel_fn, &font_font_a_9X9, SCREEN_WIDTH, SCREEN_HEIGHT);
+ UG_Init(&guioled, pixel_fn, &font_regular_9, SCREEN_WIDTH, SCREEN_HEIGHT);
#else
- UG_Init(&guioled, pixel_fn, &font_font_a_11X10, SCREEN_WIDTH, SCREEN_HEIGHT);
+ UG_Init(&guioled, pixel_fn, &font_regular_11, SCREEN_WIDTH, SCREEN_HEIGHT);
#endif
}
### src/ui/components/button.c
@@ -6,7 +6,7 @@
#include <hardfault.h>
#include <screen.h>
#include <touch/gestures.h>
-#include <ui/fonts/arial_fonts.h>
+#include <ui/fonts/regular_fonts.h>
#include <ui/ui_util.h>
#include <stdbool.h>
@@ -32,7 +32,7 @@ typedef struct {
static void _render(component_t* component)
{
button_data_t* data = (button_data_t*)component->data;
- UG_FontSelect(&font_font_a_11X10);
+ UG_FontSelect(&font_regular_11);
UG_FontSetHSpace(0);
UG_PutStringCentered(
component->position.left,
@@ -163,13 +163,10 @@ void button_update(component_t* button, const char* text, void (*callback)(compo
{
button_data_t* data = (button_data_t*)button->data;
data->callback = callback;
- if (!util_is_printable_ascii(text, true)) {
- Abort("Unsupported button character");
- }
if (util_utf8_strlcpy(data->text, text, sizeof(data->text)) < 0) {
Abort("Invalid UTF-8 button");
}
- UG_FontSelect(&font_font_a_11X10);
+ UG_FontSelect(&font_regular_11);
UG_FontSetHSpace(0);
UG_MeasureString(&(button->dimension.width), &(button->dimension.height), data->text);
if (button->dimension.width < MIN_BUTTON_WIDTH) {
### src/ui/components/confirm.c
@@ -9,7 +9,7 @@
#include <hardfault.h>
#include <screen.h>
-#include <ui/fonts/arial_fonts.h>
+#include <ui/fonts/regular_fonts.h>
#include <ui/ugui/ugui.h>
#include <string.h>
@@ -96,7 +96,7 @@ component_t* confirm_create(
// Create labels. We nest them in a body component that covers the screen minus the title bar,
// so that the CENTER positioning starts below the title bar.
- const UG_FONT* font = &font_font_a_11X10;
+ const UG_FONT* font = &font_regular_11;
const char* title = params->title;
// Arbitrary size big enough to fit all wrapped titles. Increase if needed.
char wrapped_title[128] = {0};
### src/ui/components/confirm.h
@@ -16,6 +16,8 @@ typedef struct {
bool title_autowrap;
// The confirmation body of the screen.
const char* body;
+ // Font retained by the created labels, or NULL for the default font. Must have static lifetime
+ // if non-NULL.
const UG_FONT* font;
// If true, the body is horizontally scrollable.
bool scrollable;
@@ -32,7 +34,8 @@ typedef struct {
/**
* Creates a confirm screen.
- * @param[in] params see confirm_params_t for details.
+ * @param[in] params see confirm_params_t for details. A non-NULL params->font must have static
+ * lifetime because the created labels retain it.
* @param[in] callback The callback triggered when the user accepts or rejects. Will be called at
* most once.
* @param[in] user_data passed through to the callback.
### src/ui/components/confirm_swap.c
@@ -8,7 +8,7 @@
#include <hardfault.h>
#include <screen.h>
#include <string.h>
-#include <ui/fonts/arial_fonts.h>
+#include <ui/fonts/regular_fonts.h>
#include <util.h>
typedef struct {
@@ -93,11 +93,11 @@ component_t* confirm_swap_create(
ui_util_add_sub_component(
confirm, icon_button_create(top_slider, ICON_BUTTON_NEXT, _confirm_cb, confirm));
- component_t* title_component = label_create(title, &font_font_a_11X10, CENTER_TOP, confirm);
+ component_t* title_component = label_create(title, &font_regular_11, CENTER_TOP, confirm);
ui_util_add_sub_component(confirm, title_component);
- const UG_FONT* from_font = label_fits_width(from, NULL, SCREEN_WIDTH) ? NULL : &font_font_a_9X9;
- const UG_FONT* to_font = label_fits_width(to, NULL, SCREEN_WIDTH) ? NULL : &font_font_a_9X9;
+ const UG_FONT* from_font = label_fits_width(from, NULL, SCREEN_WIDTH) ? NULL : &font_regular_9;
+ const UG_FONT* to_font = label_fits_width(to, NULL, SCREEN_WIDTH) ? NULL : &font_regular_9;
ui_util_add_sub_component(
confirm, label_create_offset(from, from_font, CENTER_TOP, 0, 17, confirm));
### src/ui/components/confirm_transaction.c
@@ -10,7 +10,7 @@
#include <screen.h>
#include <stdbool.h>
#include <string.h>
-#include <ui/fonts/arial_fonts.h>
+#include <ui/fonts/regular_fonts.h>
#include <util.h>
typedef struct {
@@ -117,13 +117,13 @@ static component_t* _confirm_transaction_create(
}
if (strlens(fee)) {
ui_util_add_sub_component(
- confirm, label_create_offset("Fee", &font_font_a_9X9, CENTER_TOP, 0, 38, confirm));
+ confirm, label_create_offset("Fee", &font_regular_9, CENTER_TOP, 0, 38, confirm));
ui_util_add_sub_component(
- confirm, label_create_offset(fee, &font_font_a_9X9, CENTER_TOP, 0, 50, confirm));
+ confirm, label_create_offset(fee, &font_regular_9, CENTER_TOP, 0, 50, confirm));
}
const UG_FONT* amount_font =
- label_fits_width(amount, NULL, SCREEN_WIDTH) ? NULL : &font_font_a_9X9;
+ label_fits_width(amount, NULL, SCREEN_WIDTH) ? NULL : &font_regular_9;
if (verify_total) {
ui_util_add_sub_component(
confirm, label_create_offset("Total", NULL, CENTER_TOP, 0, 8, confirm));
### src/ui/components/keyboard_switch.c
@@ -7,7 +7,7 @@
#include <hardfault.h>
#include <screen.h>
#include <touch/gestures.h>
-#include <ui/fonts/arial_fonts.h>
+#include <ui/fonts/regular_fonts.h>
#include <ui/ui_util.h>
#include <stdbool.h>
@@ -32,7 +32,7 @@ typedef struct {
static void _render(component_t* component)
{
keyboard_switch_data_t* ks_data = (keyboard_switch_data_t*)component->data;
- UG_FontSelect(&font_font_a_11X10);
+ UG_FontSelect(&font_regular_11);
UG_S16 w = 0, h = 0;
switch (ks_data->mode) {
case LOWER_CASE:
### src/ui/components/label.c
@@ -7,7 +7,7 @@
#include <screen.h>
#include <string.h>
#include <touch/gestures.h>
-#include <ui/fonts/arial_fonts.h>
+#include <ui/fonts/regular_fonts.h>
#include <ui/ugui/ugui.h>
#include <ui/ui_util.h>
#include <util.h>
@@ -34,17 +34,14 @@ bool label_fits_width(const char* text, const UG_FONT* font, uint16_t max_width)
{
UG_S16 width;
UG_S16 height;
- UG_FontSelect(font != NULL ? font : &font_font_a_11X10);
+ UG_FontSelect(font != NULL ? font : &font_regular_11);
UG_MeasureStringNoBreak(&width, &height, text);
return width <= max_width;
}
void label_update(component_t* component, const char* text)
{
data_t* data = (data_t*)component->data;
- if (!util_is_printable_ascii(text, true)) {
- Abort("Unsupported label character");
- }
const intptr_t result = util_utf8_strlcpy(data->text, text, MAX_LABEL_SIZE + 1);
if (result < 0) {
Abort("Invalid UTF-8 label");
@@ -211,6 +208,7 @@ static const component_functions_t _component_functions = {
/********************************** Create Instance **********************************/
+// A non-NULL `font` must have static lifetime: the label and current GUI retain it.
static component_t* _label_create(
const char* text,
const UG_FONT* font,
@@ -231,7 +229,7 @@ static component_t* _label_create(
memset(data, 0, sizeof(data_t));
memset(label, 0, sizeof(component_t));
- data->font = font != NULL ? font : &font_font_a_11X10;
+ data->font = font != NULL ? font : &font_regular_11;
data->scrollable = scrollable;
data->position = position;
data->xoffset = xoffset;
### src/ui/components/label.h
@@ -16,7 +16,8 @@
/**
* Returns true if the text fits within max_width without wrapping using the given font.
* @param[in] text The text to measure.
- * @param[in] font The font to use. If NULL, the default 11x10 font is used.
+ * @param[in] font The font to use. If NULL, the default 11x10 font is used. A non-NULL font
+ * must have static lifetime: it remains selected in the current GUI after this call.
* @param[in] max_width The available width in pixels.
*/
bool label_fits_width(const char* text, const UG_FONT* font, uint16_t max_width);
@@ -32,7 +33,8 @@ void label_update(component_t* component, const char* text);
* Creates a label with the given font. If the text is longer than MAX_LABEL_SIZE, it is truncated
* and suffixed with '...'.
* @param[in] text The text of the label.
- * @param[in] font The font of the label.
+ * @param[in] font The font retained by the label, or NULL for the default font. A non-NULL font
+ * must have static lifetime.
* @param[in] position The position of the label.
* @param[in] parent The parent component.
*/
@@ -45,7 +47,8 @@ component_t* label_create(
/**
* Creates a label with the given font.
* @param[in] text The text of the label.
- * @param[in] font The font of the label.
+ * @param[in] font The font retained by the label, or NULL for the default font. A non-NULL font
+ * must have static lifetime.
* @param[in] position The position of the label.
* @param[in] xoffset The horizontal offset.
* @param[in] yoffset The vertical offset.
@@ -62,7 +65,8 @@ component_t* label_create_offset(
/**
* Creates a label with the given font that can be scrolled.
* @param[in] text The text of the label.
- * @param[in] font The font of the label.
+ * @param[in] font The font retained by the label, or NULL for the default font. A non-NULL font
+ * must have static lifetime.
* @param[in] position The position of the label.
* @param[in] parent The parent component.
*/
@@ -75,7 +79,8 @@ component_t* label_create_scrollable(
/**
* Creates a label with the given font that can be scrolled.
* @param[in] text The text of the label.
- * @param[in] font The font of the label.
+ * @param[in] font The font retained by the label, or NULL for the default font. A non-NULL font
+ * must have static lifetime.
* @param[in] position The position of the label.
* @param[in] xoffset The horizontal offset.
* @param[in] yoffset The vertical offset.
### src/ui/components/lockscreen.c
@@ -10,7 +10,7 @@
#include <screen.h>
#include <string.h>
#include <touch/gestures.h>
-#include <ui/fonts/arial_fonts.h>
+#include <ui/fonts/regular_fonts.h>
#include <util.h>
/********************************** Component Functions **********************************/
@@ -28,6 +28,7 @@ static const component_functions_t _component_functions = {
// Outputs `in` as is if it can be rendered to fit in `max_width`.
// If it can't, it is truncated (with appended "...") to a size where it fits.
+// `font` must have static lifetime because it remains selected in the current GUI.
static void _truncate_to_fit(
const char* in,
char* out,
@@ -46,37 +47,37 @@ static void _truncate_to_fit(
out[0] = 0;
return;
}
- if (!util_is_printable_ascii(in, false)) {
- out[0] = 0;
- return;
- }
UG_S16 width = 0;
UG_S16 height = 0;
UG_FontSelect(font);
UG_MeasureStringCentered(&width, &height, in);
// Name fits without truncation.
if (width <= max_width) {
- util_utf8_strlcpy(out, in, out_len);
+ if (util_utf8_strlcpy(out, in, out_len) < 0) {
+ out[0] = 0;
+ }
return;
}
// Truncate if too long to a size where "<name>..." fits.
const size_t text_capacity = out_len - 4;
- size_t truncate_len = MIN(strlen(in), text_capacity);
+ const size_t in_len = strlen(in);
+ size_t truncate_len = MIN(in_len, text_capacity);
do {
- const intptr_t result = util_utf8_copy(out, out_len, in, truncate_len);
+ // Limit the copied prefix while validating the complete UTF-8 input.
+ const intptr_t result = util_utf8_copy(out, truncate_len + 1, in, in_len);
if (result < 0) {
out[0] = 0;
return;
}
const size_t copied_len = (size_t)result;
memcpy(&out[copied_len], "...", 4);
UG_MeasureStringCentered(&width, &height, out);
- if (truncate_len == 0) {
+ if (copied_len == 0) {
break;
}
- truncate_len--;
+ truncate_len = copied_len - 1;
} while (width >= max_width);
}
@@ -92,7 +93,7 @@ component_t* lockscreen_create(void)
component->dimension.width = SCREEN_WIDTH;
component->dimension.height = SCREEN_HEIGHT;
- const UG_FONT* device_name_font = &font_font_a_9X9;
+ const UG_FONT* device_name_font = &font_regular_9;
char device_name[MEMORY_DEVICE_MAX_LEN_WITH_NULL] = {0};
memory_get_device_name(device_name);
### src/ui/components/trinary_input_char.c
@@ -6,10 +6,11 @@
#include <hardfault.h>
#include <touch/gestures.h>
-#include <ui/fonts/password_11X12.h>
-#include <ui/fonts/password_9X9.h>
+#include <ui/fonts/password_12.h>
+#include <ui/fonts/password_9.h>
#include <ui/ui_util.h>
#include <util.h>
+#include <utils_assert.h>
#include <string.h>
@@ -34,6 +35,15 @@ typedef struct {
// Each of the three groups can occupy roughly a third of the width.
static const UG_S16 _group_width = SCREEN_WIDTH / 3;
+static UG_U16 _char_width(const UG_FONT* font, char chr)
+{
+ UG_U16 width = 0;
+ const bool found = UG_GetCharWidth(font, (uint8_t)chr, &width);
+ ASSERT(found);
+ (void)found;
+ return width;
+}
+
// Stack entry for navigation history
typedef struct {
char alphabet[MAX_CHARS + 1];
@@ -256,15 +266,15 @@ static void _put_string(
UG_S16 total_width = 0;
for (size_t idx = 0; idx < elements_size; idx++) {
char c = elements[idx]->character;
- total_width += font->widths[c - font->start_char];
+ total_width += _char_width(font, c);
total_width += horiz_space;
}
// Split into two rows of roughly equal size by number of elements if too big.
if (elements_size > 6) {
// split in two halfs; size/2 rounded up
const size_t half = (elements_size + 1) / 2;
- _put_string(font, x_offset, y_offset - font->char_height - 1, horiz_space, elements, half);
+ _put_string(font, x_offset, y_offset - font->line_height - 1, horiz_space, elements, half);
_put_string(font, x_offset, y_offset, horiz_space, elements + half, elements_size - half);
return;
}
@@ -275,8 +285,7 @@ static void _put_string(
char c = elements[idx]->character;
bool update_position = !element->newly_born;
element->target_x = x;
- x += c == ' ' ? UI_UTIL_VISIBLE_SPACE_WIDTH
- : font->widths[element->character - font->start_char];
+ x += c == ' ' ? UI_UTIL_VISIBLE_SPACE_WIDTH : _char_width(font, element->character);
x += horiz_space;
element->target_y = y_offset;
if (!update_position) {
@@ -301,9 +310,9 @@ static void _set_alphabet_internal(
// Switch to larger font for fewer characters
if (len < 12) {
- data->font = &font_password_11X12;
+ data->font = &font_password_12;
} else {
- data->font = &font_password_9X9;
+ data->font = &font_password_9;
}
size_t a = 0;
@@ -354,7 +363,7 @@ static void _set_alphabet_internal(
element->character = alphabet[char_idx];
}
- UG_S16 y_offset = SCREEN_HEIGHT - data->font->char_height;
+ UG_S16 y_offset = SCREEN_HEIGHT - data->font->line_height;
{ // left
_put_string(data->font, 0, y_offset, data->horiz_space, elements_lookup, left_size);
}
@@ -425,7 +434,7 @@ component_t* trinary_input_char_create(
}
memset(component, 0, sizeof(component_t));
- data->font = &font_password_9X9;
+ data->font = &font_password_9;
component->data = data;
component->parent = parent;
component->f = &_component_functions;
### src/ui/components/trinary_input_string.c
@@ -14,7 +14,7 @@
#include <touch/gestures.h>
#include <ui/event.h>
#include <ui/event_handler.h>
-#include <ui/fonts/password_11X12.h>
+#include <ui/fonts/password_12.h>
#include <ui/ugui/ugui.h>
#include <ui/ui_util.h>
#include <util.h>
@@ -43,12 +43,19 @@
static char _alphabet_uppercase[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static char _alphabet_lowercase[] = "abcdefghijklmnopqrstuvwxyz";
static char _digits[] = "0123456789";
-// ` and ~ are missing here as they don't legible on the device with arial 9x9. Can add them back
+// ` and ~ are missing here as they don't legible on the device with regular 9x9. Can add them back
// after tuning the font.
// Keep in sync with SPECIAL in src/rust/bitbox02-rust/src/hww/api/unlock.rs.
static char _special_chars[] = " !\"#$%&'()*+,-./:;<=>?^[\\]@_{|}";
-static const UG_FONT* _font = &font_password_11X12;
+static const UG_FONT* _font = &font_password_12;
+
+static UG_U16 _char_width(char chr)
+{
+ UG_U16 width = 0;
+ UG_GetCharWidth(_font, (uint8_t)chr, &width);
+ return width;
+}
static void _get_bip39_word_stack(uint16_t idx, char* word_out, size_t word_out_size)
{
@@ -121,10 +128,10 @@ static UG_S16 _constant_string_width(const component_t* component)
for (size_t i = 0; i <= data->string_index; i++) {
if (i == data->string_index) {
char chr = EMPTY_CHAR;
- width += _font->widths[chr - _font->start_char];
+ width += _char_width(chr);
} else if (!data->hide) {
char chr = data->string[i];
- width += _font->widths[chr - _font->start_char];
+ width += _char_width(chr);
} else {
width += MASK_CHAR_WIDTH;
}
@@ -174,14 +181,14 @@ static void _render(component_t* component)
}
char chr;
- uint8_t width;
+ UG_U16 width;
if (i == data->string_index) {
chr = EMPTY_CHAR;
- width = _font->widths[chr - _font->start_char];
+ width = _char_width(chr);
} else if ((data->show_last_character && i == data->string_index - 1) || !data->hide) {
// Show character (or only last entered character in if input is hidden).
chr = data->string[i];
- width = _font->widths[chr - _font->start_char];
+ width = _char_width(chr);
} else {
// ad-hoc encoding of the masked char, which will be drawn as a filled circle below.
chr = '\0';
@@ -204,7 +211,7 @@ static void _render(component_t* component)
// Draw '...' when the left part scrolled out of view.
if (data->target_x < STRING_POS_X_START) {
// HACK: blank out the chars rendered at this position first.
- UG_FillFrame(0, STRING_POS_Y, 11, STRING_POS_Y + _font->char_height, screen_back_color);
+ UG_FillFrame(0, STRING_POS_Y, 11, STRING_POS_Y + _font->line_height, screen_back_color);
UG_PutString(0, STRING_POS_Y, "...");
}
### src/ui/fonts/README.md
@@ -1,27 +1,131 @@
-# ttf2ugui
+# Supported BitBox02 characters
-We have converted the fonts in this directory with the ttf2ugui tool provided in `tools` directory.
+The BitBox02 regular text fonts support English, German, Spanish, Italian, and French,
+among the most widely spoken languages in Europe.
+
+The character set includes printable ASCII and the additional letters needed for these languages.
+The language letters are based on the
+[Unicode CLDR main exemplars](https://www.unicode.org/cldr/charts/48/by_type/core_data.alphabetic_information.main.html),
+with uppercase forms included except capital sharp S (`ẞ`, U+1E9E), whose support varies across
+fonts.
+Non-breaking space (U+00A0) and soft hyphen (U+00AD) are excluded because they can look like an
+ordinary space or hyphen.
+This is a set of precomposed characters: input must use NFC for
+accented letters; decomposed base letters followed by combining accents are not included.
+
+The exact supported set is **162 characters**:
+
+* All 95 printable ASCII characters, U+0020–U+007E, including ordinary space:
+
+ ```text
+ !"#$%&'()*+,-./0123456789:;<=>?@
+ ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`
+ abcdefghijklmnopqrstuvwxyz{|}~
+ ```
+
+* The following additional letters (overlap between languages is intentional):
+
+ | Language | Uppercase | Lowercase |
+ | --- | --- | --- |
+ | English | None beyond ASCII `A–Z` | None beyond ASCII `a–z` |
+ | German | `Ä Ö Ü` | `ä ö ü ß` |
+ | Spanish | `Á É Í Ñ Ó Ú Ü` | `á é í ñ ó ú ü` |
+ | Italian | `À È É Ì Ò Ó Ù` | `à è é ì ò ó ù` |
+ | French | `À Â Æ Ç È É Ê Ë Î Ï Ô Œ Ù Û Ü Ÿ` | `à â æ ç è é ê ë î ï ô œ ù û ü ÿ` |
+
+* Punctuation and symbols: `¡ § ª « ° º » ¿ – — ‚ „ … ‹ › €`.
+
+Coverage by font:
+
+| Fonts | Supported characters |
+| --- | --- |
+| `regular_9`, `regular_11`, `regular_12` | All 162 characters above |
+| `password_9`, `password_12` | Same coverage as the corresponding regular font, with a visible space glyph |
+| `monogram_16`, `regular_9_bootloader` | Printable ASCII only (U+0020–U+007E) |
+| `monogram_16_bootloader` | Space, `0123456789`, and `abcdef` |
+
+Monogram is for technical text; the bundled `monogram.ttf` has no accented letters. The bootloader
+fonts intentionally retain their smaller subsets. Password fonts inherit the regular fonts through
+their fallback pointers and do not need separate regeneration.
+
+## Regenerating the regular text fonts
+
+Use this exact decimal range list with `ttf2lvgl`; do not include whole Latin Unicode blocks:
+
+```sh
+FONT_RANGE='32-126,161,167,170-171,176,186-187,191-194,196,198-207,209-212,214,217-220,223-226,228,230-239,241-244,246,249-252,255,338-339,376,8211-8212,8218,8222,8230,8249-8250,8364'
+```
+
+For BitBox02, build `tools/ttf2lvgl`. Starting at the repository root, with `FONT_RANGE` set as above:
+
+```sh
+./scripts/dev_exec.sh make -C tools/ttf2lvgl
+REGULAR_FONT_PATH=/path/to/regular.ttf
+cd src/ui/fonts
+for size in 9 11 12; do
+ ../../../tools/ttf2lvgl/ttf2lvgl --dump --bpp 1 --size "$size" --dpi 72 \
+ --font "$REGULAR_FONT_PATH" --range "$FONT_RANGE" \
+ --name "regular_$size" --output "regular_$size.c"
+done
+```
+
+After generation, retain these uGUI layout metrics in the public font descriptors:
+
+| Font | `.line_height` | `.base_line` |
+| --- | --- | --- |
+| `regular_9` | 9 | 2 |
+| `regular_11` | 10 | 2 |
+| `regular_12` | 12 | 3 |
+
+Preserve the checked-in ASCII glyph pixels and spacing when regenerating. These glyphs contain
+manual bitmap or metric adjustments that raw FreeType output does not reproduce:
+
+| Font | Adjusted glyphs |
+| --- | --- |
+| `regular_9` | `0 A V j t` |
+| `regular_11` | `B W j t` |
+| `regular_12` | `f` |
+
+The ASCII rendering snapshots in `test/unit-test/test_ugui.c` verify the pixels, placement,
+advance widths, and line heights, including the password-font fallbacks.
+
+# ttf2lvgl
+
+We convert fonts for the BitBox02 OLED with the ttf2lvgl tool provided in the `tools` directory.
Example execution:
```
-./ttf2ugui --dump --font <PATH-TO-FONT> --size <SIZE>
+./ttf2lvgl --dump --font <PATH-TO-FONT> --size <SIZE> --range <RANGES> \
+ --name <FONT_SYMBOL> --output <FONT_SYMBOL>.c
```
+`<RANGES>` is a comma-separated list of individual code points and ranges, for example
+`32-126,161,U+0104-U+0107`.
+Code points in the requested ranges that are not present in the font are omitted from the generated
+LVGL cmaps.
+
To check the conversion of the font to bitmap you can use the `--show <STRING>` parameter. The tool
-will then print out the `<STRING>` with asterixes in the terminal:
+decodes `<STRING>` as UTF-8 and prints it with asterixes in the terminal:
```
-./ttf2ugui --show ABCDEF --font <PATH-TO-FONT> --size <SIZE>
+./ttf2lvgl --show ABCDEF --font <PATH-TO-FONT> --size <SIZE> --range <RANGES>
```
-Once you have `dump`ed the font there will be a `.c` and `.h` file in the current directory named
-somthing like `FontName_<WIDTH>X<HEIGHT>`. Move this file to this directory and make some small
-adjustments to it so that it compiles.
+Once you have `dump`ed the font there will be a `.c` and `.h` file in the current directory. Move
+these files to this directory. BitBox02 OLED fonts are exported directly as `font_*` LVGL font
+objects and the generated headers include `<ugui.h>` and declare `extern const UG_FONT font_*`.
+`UG_FONT` is an alias for `lv_font_t`, so no separate uGUI wrapper is needed.
+
+For BitBox02 uGUI use, keep the generated font in the compact subset consumed by `ugui.c`: 1bpp,
+`stride = 0`, no kerning, and `LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY` cmaps only. The local
+`lv_font_get_glyph_dsc_fmt_txt` and `lv_font_get_bitmap_fmt_txt` callbacks only support this subset.
+If the historical uGUI layout height differs from the generated FreeType line height, set
+`.line_height` to the uGUI layout height.
## libfreetype note
-Since `ttf2ugui` uses `libfreetype` it actually supports the following font types:
+Since `ttf2lvgl` uses `libfreetype` it actually supports the following font types:
* TrueType fonts (TTF) and TrueType collections (TTC)
* CFF fonts
@@ -36,11 +140,10 @@ Since `ttf2ugui` uses `libfreetype` it actually supports the following font type
* PFR fonts
* Type 42 fonts (limited support)
-# ugui font format
+# LVGL font format
-The bitmaps are layed out line by line and every line uses `ceil(width/8)` bytes. A 9 pixel wide
-font will use 16 bits per line (7 bits per line are not used). See for example underscore `_` and
-exclamation mark `!` to get a good understanding of the layout.
+The tool emits LVGL's uncompressed `lv_font_fmt_txt` format with tight glyph bounding boxes. For
+1bpp fonts, pixels are packed in LVGL bit order over the tight glyph bitmap. For 8bpp fonts, each
+pixel stores the same 16x16 downsampled coverage value that the old `ttf2ugui` tool produced.
-Each item in the array is suffixed with a comment that shows which character the bytes correspond
-to.
+Bitmap groups and glyph descriptors are annotated with their Unicode code points.
### src/ui/fonts/arial_fonts.h
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-#ifndef _ARIAL_FONTS_H_
-#define _ARIAL_FONTS_H_
-
-#include "font_a_11X10.h"
-#include "font_a_11X12.h"
-#include "font_a_13X14.h"
-#include "font_a_15X16.h"
-#include "font_a_17X18.h"
-#include "font_a_9X9.h"
-#include "monogram_5X9.h"
-
-#endif
### src/ui/fonts/font_a_11X10.c
@@ -1,107 +0,0 @@
-// Converted from font_a.ttf
-// --size 11
-// --bpp 1
-// For copyright, see original font file.
-
-#include <ugui.h>
-
-static UG_FONT_DATA unsigned char fontBits_font_a_11X10[95][20] = {
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x20 ' '
- {0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x21 '!'
- {0x05,0x00,0x05,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x22 '"'
- {0x14,0x00,0x14,0x00,0x1F,0x00,0x0A,0x00,0x0A,0x00,0x1F,0x00,0x05,0x00,0x05,0x00,0x00,0x00,0x00,0x00 }, // 0x23 '#'
- {0x0E,0x00,0x15,0x00,0x05,0x00,0x0E,0x00,0x14,0x00,0x14,0x00,0x15,0x00,0x0E,0x00,0x04,0x00,0x00,0x00 }, // 0x24 '$'
- {0x46,0x00,0x29,0x00,0x29,0x00,0x16,0x00,0xD0,0x00,0x28,0x01,0x28,0x01,0xC4,0x00,0x00,0x00,0x00,0x00 }, // 0x25 '%'
- {0x0C,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x0A,0x00,0x31,0x00,0x11,0x00,0x2E,0x00,0x00,0x00,0x00,0x00 }, // 0x26 '&'
- {0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x27 '''
- {0x04,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x04,0x00 }, // 0x28 '('
- {0x01,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x01,0x00 }, // 0x29 ')'
- {0x02,0x00,0x07,0x00,0x02,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2A '*'
- {0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1F,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2B '+'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00 }, // 0x2C ','
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2D '-'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x2E '.'
- {0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x2F '/'
- {0x0E,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x30 '0'
- {0x04,0x00,0x06,0x00,0x05,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x31 '1'
- {0x0E,0x00,0x11,0x00,0x10,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x1F,0x00,0x00,0x00,0x00,0x00 }, // 0x32 '2'
- {0x0E,0x00,0x11,0x00,0x10,0x00,0x0C,0x00,0x10,0x00,0x10,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x33 '3'
- {0x08,0x00,0x0C,0x00,0x0A,0x00,0x0A,0x00,0x09,0x00,0x1F,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00 }, // 0x34 '4'
- {0x1E,0x00,0x02,0x00,0x01,0x00,0x0F,0x00,0x10,0x00,0x10,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x35 '5'
- {0x0E,0x00,0x11,0x00,0x01,0x00,0x0F,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x36 '6'
- {0x1F,0x00,0x08,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x37 '7'
- {0x0E,0x00,0x11,0x00,0x11,0x00,0x0E,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x38 '8'
- {0x0E,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x1E,0x00,0x10,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x39 '9'
- {0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x3A ':'
- {0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00 }, // 0x3B ';'
- {0x00,0x00,0x00,0x00,0x10,0x00,0x0E,0x00,0x01,0x00,0x0E,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3C '<'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3D '='
- {0x00,0x00,0x00,0x00,0x01,0x00,0x0E,0x00,0x10,0x00,0x0E,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3E '>'
- {0x0E,0x00,0x11,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x3F '?'
- {0xF8,0x00,0x06,0x01,0xB2,0x02,0xC9,0x02,0x45,0x02,0x45,0x02,0x65,0x01,0xD9,0x00,0x02,0x02,0xFC,0x01 }, // 0x40 '@'
- {0x08,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x22,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00 }, // 0x41 'A'
- {0x1F,0x00,0x21,0x00,0x21,0x00,0x1F,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x1F,0x00,0x00,0x00,0x00,0x00 }, // 0x42 'B'
- {0x1C,0x00,0x22,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x43 'C'
- {0x0F,0x00,0x11,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x11,0x00,0x0F,0x00,0x00,0x00,0x00,0x00 }, // 0x44 'D'
- {0x1F,0x00,0x01,0x00,0x01,0x00,0x1F,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x1F,0x00,0x00,0x00,0x00,0x00 }, // 0x45 'E'
- {0x1F,0x00,0x01,0x00,0x01,0x00,0x0F,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x46 'F'
- {0x1C,0x00,0x22,0x00,0x41,0x00,0x01,0x00,0x71,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x47 'G'
- {0x21,0x00,0x21,0x00,0x21,0x00,0x3F,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x00,0x00,0x00,0x00 }, // 0x48 'H'
- {0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x49 'I'
- {0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x4A 'J'
- {0x21,0x00,0x11,0x00,0x09,0x00,0x0D,0x00,0x0B,0x00,0x11,0x00,0x11,0x00,0x21,0x00,0x00,0x00,0x00,0x00 }, // 0x4B 'K'
- {0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x1F,0x00,0x00,0x00,0x00,0x00 }, // 0x4C 'L'
- {0x41,0x00,0x63,0x00,0x63,0x00,0x55,0x00,0x55,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x00,0x00,0x00,0x00 }, // 0x4D 'M'
- {0x21,0x00,0x23,0x00,0x25,0x00,0x25,0x00,0x29,0x00,0x29,0x00,0x31,0x00,0x21,0x00,0x00,0x00,0x00,0x00 }, // 0x4E 'N'
- {0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x4F 'O'
- {0x0F,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x0F,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x50 'P'
- {0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x59,0x00,0x22,0x00,0x7C,0x00,0x00,0x00,0x00,0x00 }, // 0x51 'Q'
- {0x1F,0x00,0x21,0x00,0x21,0x00,0x1F,0x00,0x09,0x00,0x11,0x00,0x11,0x00,0x21,0x00,0x00,0x00,0x00,0x00 }, // 0x52 'R'
- {0x1E,0x00,0x21,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x20,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00 }, // 0x53 'S'
- {0x1F,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x54 'T'
- {0x21,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00 }, // 0x55 'U'
- {0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00 }, // 0x56 'V'
- {0x21,0x04,0x51,0x04,0x52,0x02,0x52,0x02,0x8a,0x02,0x8a,0x02,0x04,0x01,0x04,0x01,0x00,0x00,0x00,0x00 }, // 0x57 'W'
- {0x21,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x00,0x00,0x00,0x00 }, // 0x58 'X'
- {0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00 }, // 0x59 'Y'
- {0x3E,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x3F,0x00,0x00,0x00,0x00,0x00 }, // 0x5A 'Z'
- {0x03,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x03,0x00 }, // 0x5B '['
- {0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x5C '\'
- {0x03,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x03,0x00 }, // 0x5D ']'
- {0x04,0x00,0x0A,0x00,0x0A,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x5E '^'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00 }, // 0x5F '_'
- {0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x60 '`'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x11,0x00,0x1E,0x00,0x11,0x00,0x19,0x00,0x17,0x00,0x00,0x00,0x00,0x00 }, // 0x61 'a'
- {0x01,0x00,0x01,0x00,0x0D,0x00,0x13,0x00,0x11,0x00,0x11,0x00,0x13,0x00,0x0D,0x00,0x00,0x00,0x00,0x00 }, // 0x62 'b'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x11,0x00,0x01,0x00,0x01,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x63 'c'
- {0x10,0x00,0x10,0x00,0x16,0x00,0x19,0x00,0x11,0x00,0x11,0x00,0x19,0x00,0x16,0x00,0x00,0x00,0x00,0x00 }, // 0x64 'd'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x11,0x00,0x1F,0x00,0x01,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x65 'e'
- {0x04,0x00,0x02,0x00,0x07,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x66 'f'
- {0x00,0x00,0x00,0x00,0x16,0x00,0x19,0x00,0x11,0x00,0x11,0x00,0x19,0x00,0x16,0x00,0x10,0x00,0x0F,0x00 }, // 0x67 'g'
- {0x01,0x00,0x01,0x00,0x0D,0x00,0x13,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00 }, // 0x68 'h'
- {0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x69 'i'
- {0x02,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x00,0x00 }, // 0x6A 'j'
- {0x01,0x00,0x01,0x00,0x09,0x00,0x05,0x00,0x03,0x00,0x07,0x00,0x05,0x00,0x09,0x00,0x00,0x00,0x00,0x00 }, // 0x6B 'k'
- {0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x6C 'l'
- {0x00,0x00,0x00,0x00,0x3D,0x00,0x4B,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x00,0x00,0x00,0x00 }, // 0x6D 'm'
- {0x00,0x00,0x00,0x00,0x0F,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00 }, // 0x6E 'n'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x6F 'o'
- {0x00,0x00,0x00,0x00,0x0D,0x00,0x13,0x00,0x11,0x00,0x11,0x00,0x13,0x00,0x0D,0x00,0x01,0x00,0x01,0x00 }, // 0x70 'p'
- {0x00,0x00,0x00,0x00,0x16,0x00,0x19,0x00,0x11,0x00,0x11,0x00,0x19,0x00,0x16,0x00,0x10,0x00,0x10,0x00 }, // 0x71 'q'
- {0x00,0x00,0x00,0x00,0x05,0x00,0x03,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x72 'r'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x11,0x00,0x06,0x00,0x08,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x73 's'
- {0x02,0x00,0x02,0x00,0x07,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x74 't'
- {0x00,0x00,0x00,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x19,0x00,0x16,0x00,0x00,0x00,0x00,0x00 }, // 0x75 'u'
- {0x00,0x00,0x00,0x00,0x11,0x00,0x11,0x00,0x0A,0x00,0x0A,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x76 'v'
- {0x00,0x00,0x00,0x00,0x11,0x01,0x29,0x01,0xAA,0x00,0xAA,0x00,0x44,0x00,0x44,0x00,0x00,0x00,0x00,0x00 }, // 0x77 'w'
- {0x00,0x00,0x00,0x00,0x11,0x00,0x0A,0x00,0x04,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x00,0x00,0x00,0x00 }, // 0x78 'x'
- {0x00,0x00,0x00,0x00,0x11,0x00,0x11,0x00,0x0A,0x00,0x0A,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00 }, // 0x79 'y'
- {0x00,0x00,0x00,0x00,0x1F,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x1F,0x00,0x00,0x00,0x00,0x00 }, // 0x7A 'z'
- {0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x04,0x00 }, // 0x7B '{'
- {0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00 }, // 0x7C '|'
- {0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00 }, // 0x7D '}'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } // 0x7E '~'
-};
-static UG_U8 fontWidths_font_a_11X10[] = {
-3,2,4,6,6,10,7,2,4,4,4,6,3,4,3,3,6,6,6,6,6,6,6,6,6,6,3,3,6,6,6,6,11,8,7,7,7,6,6,8,7,2,5,7,6,8,7,8,6,8,7,7,6,7,8,11,7,8,7,3,3,3,5,6,4,6,6,6,6,6,4,6,6,2,3,5,2,8,6,6,6,6,4,6,4,6,6,10,6,6,6,4,2,4,6};
-const UG_FONT font_font_a_11X10 = { (unsigned char*)fontBits_font_a_11X10, FONT_TYPE_1BPP, 11, 10, 32, 126, fontWidths_font_a_11X10 };
### src/ui/fonts/font_a_11X10.h
@@ -1,5 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-#include <ugui.h>
-
-extern const UG_FONT font_font_a_11X10;
### src/ui/fonts/font_a_11X12.c
@@ -1,109 +0,0 @@
-// Converted from font_a.ttf
-// --size 12
-// --dpi 72
-// --bpp 1
-// For copyright, see original font file.
-
-#include <ugui.h>
-
-static UG_FONT_DATA unsigned char fontBits_font_a_11X12[95][24] = {
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x20 ' '
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x21 '!'
- {0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x22 '"'
- {0x28, 0x00, 0x28, 0x00, 0x7F, 0x00, 0x14, 0x00, 0x14, 0x00, 0x7F, 0x00, 0x14, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x23 '#'
- {0x1C, 0x00, 0x2A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x1C, 0x00, 0x28, 0x00, 0x2A, 0x00, 0x2A, 0x00, 0x1C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x24 '$'
- {0x8C, 0x00, 0x52, 0x00, 0x52, 0x00, 0x32, 0x00, 0xAC, 0x01, 0x60, 0x02, 0x50, 0x02, 0x50, 0x02, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x25 '%'
- {0x18, 0x00, 0x24, 0x00, 0x24, 0x00, 0x14, 0x00, 0x0C, 0x00, 0x52, 0x00, 0x22, 0x00, 0x62, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x26 '&'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x27 '''
- {0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00 }, // 0x28 '('
- {0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00 }, // 0x29 ')'
- {0x04, 0x00, 0x1F, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2A '*'
- {0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x3E, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2B '+'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x2C ','
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2D '-'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2E '.'
- {0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2F '/'
- {0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x30 '0'
- {0x08, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x31 '1'
- {0x1C, 0x00, 0x22, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x32 '2'
- {0x1C, 0x00, 0x22, 0x00, 0x20, 0x00, 0x20, 0x00, 0x18, 0x00, 0x20, 0x00, 0x20, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x33 '3'
- {0x10, 0x00, 0x18, 0x00, 0x18, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x3E, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x34 '4'
- {0x3C, 0x00, 0x04, 0x00, 0x02, 0x00, 0x1E, 0x00, 0x22, 0x00, 0x20, 0x00, 0x20, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x35 '5'
- {0x1C, 0x00, 0x22, 0x00, 0x02, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x36 '6'
- {0x3E, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x37 '7'
- {0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x38 '8'
- {0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2C, 0x00, 0x20, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x39 '9'
- {0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3A ':'
- {0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x3B ';'
- {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x1C, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3C '<'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3D '='
- {0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x20, 0x00, 0x1C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3E '>'
- {0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3F '?'
- {0xE0, 0x01, 0x18, 0x06, 0x04, 0x04, 0x64, 0x09, 0x92, 0x09, 0x8A, 0x08, 0x8A, 0x08, 0x8A, 0x04, 0xF2, 0x03, 0x04, 0x08, 0x08, 0x06, 0xF0, 0x01 }, // 0x40 '@'
- {0x08, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x22, 0x00, 0x3E, 0x00, 0x22, 0x00, 0x41, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x41 'A'
- {0x3E, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x7E, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x42 'B'
- {0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x43 'C'
- {0x3E, 0x00, 0x42, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x42, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x44 'D'
- {0x7E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x45 'E'
- {0x3E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x1E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x46 'F'
- {0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x02, 0x00, 0xE2, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x47 'G'
- {0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0xFE, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x48 'H'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x49 'I'
- {0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4A 'J'
- {0x82, 0x00, 0x42, 0x00, 0x22, 0x00, 0x12, 0x00, 0x0A, 0x00, 0x16, 0x00, 0x22, 0x00, 0x42, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4B 'K'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4C 'L'
- {0x82, 0x00, 0xC6, 0x00, 0xC6, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x92, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4D 'M'
- {0x82, 0x00, 0x86, 0x00, 0x8A, 0x00, 0x8A, 0x00, 0x92, 0x00, 0xA2, 0x00, 0xA2, 0x00, 0xC2, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4E 'N'
- {0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4F 'O'
- {0x3E, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x50 'P'
- {0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0xB2, 0x00, 0x44, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x51 'Q'
- {0x7E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x7E, 0x00, 0x22, 0x00, 0x42, 0x00, 0x42, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x52 'R'
- {0x3C, 0x00, 0x42, 0x00, 0x42, 0x00, 0x02, 0x00, 0x3C, 0x00, 0x40, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x53 'S'
- {0x7F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x54 'T'
- {0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x55 'U'
- {0x41, 0x00, 0x41, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x56 'V'
- {0x21, 0x04, 0x51, 0x04, 0x51, 0x02, 0x52, 0x02, 0x8A, 0x02, 0x8A, 0x02, 0x8A, 0x02, 0x04, 0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x57 'W'
- {0x41, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x08, 0x00, 0x14, 0x00, 0x22, 0x00, 0x22, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x58 'X'
- {0x41, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x59 'Y'
- {0x7E, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5A 'Z'
- {0x06, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00 }, // 0x5B '['
- {0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5C '\'
- {0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00 }, // 0x5D ']'
- {0x04, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5E '^'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00 }, // 0x5F '_'
- {0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x60 '`'
- {0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x20, 0x00, 0x3C, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x61 'a'
- {0x02, 0x00, 0x02, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x26, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x62 'b'
- {0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x12, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x12, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x63 'c'
- {0x20, 0x00, 0x20, 0x00, 0x2C, 0x00, 0x32, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x64 'd'
- {0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x3E, 0x00, 0x02, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x65 'e'
- {0x0C, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x66 'f'
- {0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x32, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2C, 0x00, 0x20, 0x00, 0x1E, 0x00, 0x00, 0x00 }, // 0x67 'g'
- {0x02, 0x00, 0x02, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x68 'h'
- {0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x69 'i'
- {0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00 }, // 0x6A 'j'
- {0x02, 0x00, 0x02, 0x00, 0x22, 0x00, 0x12, 0x00, 0x0A, 0x00, 0x0E, 0x00, 0x12, 0x00, 0x12, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6B 'k'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6C 'l'
- {0x00, 0x00, 0x00, 0x00, 0x9A, 0x01, 0x66, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6D 'm'
- {0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6E 'n'
- {0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6F 'o'
- {0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x26, 0x00, 0x1A, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x70 'p'
- {0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x32, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2C, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00 }, // 0x71 'q'
- {0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x72 'r'
- {0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x20, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x73 's'
- {0x02, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x74 't'
- {0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x75 'u'
- {0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x76 'v'
- {0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x11, 0x01, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x44, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x77 'w'
- {0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x78 'x'
- {0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x79 'y'
- {0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x7A 'z'
- {0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00 }, // 0x7B '{'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x7C '|'
- {0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x7D '}'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // 0x7E '~'
-};
-static UG_U8 fontWidths_font_a_11X12[] = {
- 3, 3, 4, 7, 7, 11, 8, 2, 4, 4, 5, 7, 3, 4, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 7, 7, 7, 7, 12, 7, 8, 9, 9, 8, 7, 9, 9, 3, 6, 8, 7, 9, 9, 9, 8, 9, 9, 8, 7, 9, 7, 11, 7, 7, 7, 3, 3, 3, 5, 7, 4, 7, 7, 6, 7, 7, 3, 7, 7, 3, 3, 6, 3, 11, 7, 7, 7, 7, 4, 7, 3, 7, 5, 9, 5, 5, 5, 4, 3, 4, 7
-};
-const UG_FONT font_font_a_11X12 = { (unsigned char *)fontBits_font_a_11X12, FONT_TYPE_1BPP, 11, 12, 32, 126, fontWidths_font_a_11X12 };
### src/ui/fonts/font_a_11X12.h
@@ -1,5 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-#include <ugui.h>
-
-extern const UG_FONT font_font_a_11X12;
### src/ui/fonts/font_a_13X14.c
@@ -1,108 +0,0 @@
-// Converted from font_a.ttf
-// --size 14
-// --dpi 72
-// --bpp 1
-// For copyright, see original font file.
-
-#include <ugui.h>
-
-static UG_FONT_DATA unsigned char fontBits_font_a_13X14[95][28] = {
- {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 }, // 0x20 ' '
- {0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x21 '!'
- {0x00,0x00,0x0A,0x00,0x0A,0x00,0x0A,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x22 '"'
- {0x00,0x00,0x48,0x00,0x48,0x00,0x24,0x00,0xFF,0x00,0x24,0x00,0x24,0x00,0xFF,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x23 '#'
- {0x08,0x00,0x3C,0x00,0x4A,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x38,0x00,0x48,0x00,0x48,0x00,0x29,0x00,0x1E,0x00,0x08,0x00,0x00,0x00,0x00,0x00 }, // 0x24 '$'
- {0x00,0x00,0x0C,0x01,0x92,0x00,0x92,0x00,0x52,0x00,0x4C,0x00,0x20,0x03,0xA0,0x04,0x90,0x04,0x90,0x04,0x08,0x03,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x25 '%'
- {0x00,0x00,0x38,0x00,0x44,0x00,0x44,0x00,0x24,0x00,0x18,0x00,0x14,0x00,0xA2,0x00,0x42,0x00,0xC2,0x00,0x3C,0x01,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x26 '&'
- {0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x27 '''
- {0x00,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x08,0x00 }, // 0x28 '('
- {0x00,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00 }, // 0x29 ')'
- {0x00,0x00,0x04,0x00,0x1F,0x00,0x04,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2A '*'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0xFE,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2B '+'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00 }, // 0x2C ','
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2D '-'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2E '.'
- {0x00,0x00,0x08,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2F '/'
- {0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x30 '0'
- {0x00,0x00,0x10,0x00,0x18,0x00,0x14,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x31 '1'
- {0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x32 '2'
- {0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x40,0x00,0x38,0x00,0x40,0x00,0x40,0x00,0x42,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x33 '3'
- {0x00,0x00,0x20,0x00,0x30,0x00,0x28,0x00,0x24,0x00,0x24,0x00,0x22,0x00,0x21,0x00,0x7F,0x00,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x34 '4'
- {0x00,0x00,0x7C,0x00,0x04,0x00,0x02,0x00,0x3E,0x00,0x42,0x00,0x40,0x00,0x40,0x00,0x42,0x00,0x22,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x35 '5'
- {0x00,0x00,0x38,0x00,0x44,0x00,0x02,0x00,0x02,0x00,0x3A,0x00,0x46,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x36 '6'
- {0x00,0x00,0x7E,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x37 '7'
- {0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x38 '8'
- {0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x62,0x00,0x5C,0x00,0x40,0x00,0x40,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x39 '9'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3A ':'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00 }, // 0x3B ';'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x02,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3C '<'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3D '='
- {0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3E '>'
- {0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3F '?'
- {0x00,0x00,0xF0,0x03,0x0C,0x04,0x02,0x08,0xE2,0x12,0x11,0x13,0x09,0x12,0x09,0x11,0x09,0x09,0x89,0x09,0x72,0x07,0x02,0x10,0x0C,0x0C,0xF0,0x03 }, // 0x40 '@'
- {0x00,0x00,0x10,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x44,0x00,0x44,0x00,0xFE,0x00,0x82,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x41 'A'
- {0x00,0x00,0x7E,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x7E,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x42 'B'
- {0x00,0x00,0x78,0x00,0x84,0x00,0x02,0x01,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x01,0x84,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x43 'C'
- {0x00,0x00,0x7E,0x00,0x82,0x00,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x82,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x44 'D'
- {0x00,0x00,0xFE,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0xFE,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x45 'E'
- {0x00,0x00,0xFE,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x7E,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x46 'F'
- {0x00,0x00,0xF8,0x00,0x04,0x01,0x02,0x02,0x02,0x00,0x02,0x00,0xC2,0x03,0x02,0x02,0x02,0x02,0x04,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x47 'G'
- {0x00,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0xFE,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x48 'H'
- {0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x49 'I'
- {0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x11,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x4A 'J'
- {0x00,0x00,0x02,0x01,0x82,0x00,0x42,0x00,0x22,0x00,0x12,0x00,0x2A,0x00,0x46,0x00,0x42,0x00,0x82,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x4B 'K'
- {0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x4C 'L'
- {0x00,0x00,0x02,0x02,0x06,0x03,0x06,0x03,0x8A,0x02,0x8A,0x02,0x52,0x02,0x52,0x02,0x52,0x02,0x22,0x02,0x22,0x02,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x4D 'M'
- {0x00,0x00,0x82,0x00,0x86,0x00,0x8A,0x00,0x8A,0x00,0x92,0x00,0x92,0x00,0xA2,0x00,0xA2,0x00,0xC2,0x00,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x4E 'N'
- {0x00,0x00,0xF8,0x00,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x04,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x4F 'O'
- {0x00,0x00,0x7E,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x7E,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x50 'P'
- {0x00,0x00,0xF8,0x00,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x42,0x01,0x84,0x01,0x78,0x03,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x51 'Q'
- {0x00,0x00,0xFE,0x00,0x02,0x01,0x02,0x01,0x02,0x01,0x02,0x01,0xFE,0x00,0x22,0x00,0x42,0x00,0x82,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x52 'R'
- {0x00,0x00,0x7C,0x00,0x82,0x00,0x82,0x00,0x02,0x00,0x1C,0x00,0xE0,0x00,0x80,0x00,0x82,0x00,0x82,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x53 'S'
- {0x00,0x00,0xFE,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x54 'T'
- {0x00,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x44,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x55 'U'
- {0x00,0x00,0x01,0x01,0x01,0x01,0x82,0x00,0x82,0x00,0x44,0x00,0x44,0x00,0x28,0x00,0x28,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x56 'V'
- {0x00,0x00,0x41,0x10,0xA1,0x10,0xA2,0x08,0xA2,0x08,0xA2,0x08,0x14,0x05,0x14,0x05,0x14,0x05,0x08,0x02,0x08,0x02,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x57 'W'
- {0x00,0x00,0x81,0x00,0x42,0x00,0x42,0x00,0x24,0x00,0x18,0x00,0x18,0x00,0x24,0x00,0x42,0x00,0x42,0x00,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x58 'X'
- {0x00,0x00,0x01,0x01,0x82,0x00,0x44,0x00,0x44,0x00,0x28,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x59 'Y'
- {0x00,0x00,0xFE,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x5A 'Z'
- {0x00,0x00,0x06,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x06,0x00 }, // 0x5B '['
- {0x00,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x5C '\'
- {0x00,0x00,0x06,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x06,0x00 }, // 0x5D ']'
- {0x00,0x00,0x04,0x00,0x0A,0x00,0x0A,0x00,0x0A,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x5E '^'
- {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,0xFF,0x00 }, // 0x5F '_'
- {0x00,0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x60 '`'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x40,0x00,0x78,0x00,0x44,0x00,0x42,0x00,0x62,0x00,0x5C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x61 'a'
- {0x00,0x00,0x02,0x00,0x02,0x00,0x3A,0x00,0x46,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x46,0x00,0x3A,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x62 'b'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x63 'c'
- {0x00,0x00,0x40,0x00,0x40,0x00,0x5C,0x00,0x62,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x62,0x00,0x5C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x64 'd'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x7E,0x00,0x02,0x00,0x02,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x65 'e'
- {0x00,0x00,0x0C,0x00,0x02,0x00,0x0F,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x66 'f'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x00,0x62,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x62,0x00,0x5C,0x00,0x40,0x00,0x42,0x00,0x3C,0x00 }, // 0x67 'g'
- {0x00,0x00,0x02,0x00,0x02,0x00,0x3A,0x00,0x46,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x68 'h'
- {0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x69 'i'
- {0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00 }, // 0x6A 'j'
- {0x00,0x00,0x02,0x00,0x02,0x00,0x42,0x00,0x22,0x00,0x12,0x00,0x0A,0x00,0x16,0x00,0x22,0x00,0x22,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x6B 'k'
- {0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x6C 'l'
- {0x00,0x00,0x00,0x00,0x00,0x00,0xDA,0x01,0x66,0x02,0x22,0x02,0x22,0x02,0x22,0x02,0x22,0x02,0x22,0x02,0x22,0x02,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x6D 'm'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x3A,0x00,0x46,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x6E 'n'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x6F 'o'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x3A,0x00,0x46,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x46,0x00,0x3A,0x00,0x02,0x00,0x02,0x00,0x02,0x00 }, // 0x70 'p'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x00,0x62,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x62,0x00,0x5C,0x00,0x40,0x00,0x40,0x00,0x40,0x00 }, // 0x71 'q'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x1A,0x00,0x06,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x72 'r'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x02,0x00,0x1C,0x00,0x20,0x00,0x20,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x73 's'
- {0x00,0x00,0x02,0x00,0x02,0x00,0x0F,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x74 't'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x62,0x00,0x5C,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x75 'u'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x76 'v'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x01,0x11,0x01,0xAA,0x00,0xAA,0x00,0xAA,0x00,0xAA,0x00,0x44,0x00,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x77 'w'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x78 'x'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x06,0x00 }, // 0x79 'y'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x7A 'z'
- {0x00,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x08,0x00 }, // 0x7B '{'
- {0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00 }, // 0x7C '|'
- {0x00,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00 }, // 0x7D '}'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4E,0x00,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } // 0x7E '~'
-};
-static UG_U8 fontWidths_font_a_13X14[] = {
-4,5,5,8,8,12,9,3,5,5,5,8,4,5,4,4,8,8,8,8,8,8,8,8,8,8,4,4,8,8,8,8,14,9,9,10,10,9,9,11,9,3,6,9,8,11,9,11,9,11,10,9,9,9,9,13,8,9,8,4,4,4,5,8,5,8,8,7,8,8,4,8,8,3,3,7,3,11,8,8,8,8,5,7,4,8,7,9,6,7,6,5,3,5,8};
-const UG_FONT font_font_a_13X14 = { (unsigned char*)fontBits_font_a_13X14, FONT_TYPE_1BPP, 13, 14, 32, 126, fontWidths_font_a_13X14 };
### src/ui/fonts/font_a_13X14.h
@@ -1,5 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-#include <ugui.h>
-
-extern const UG_FONT font_font_a_13X14;
### src/ui/fonts/font_a_15X16.c
@@ -1,109 +0,0 @@
-// Converted from font_a.ttf
-// --size 16
-// --dpi 72
-// --bpp 1
-// For copyright, see original font file.
-
-#include <ugui.h>
-
-static UG_FONT_DATA unsigned char fontBits_font_a_15X16[95][32] = {
- {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, 0x00, 0x00, 0x00, 0x00 }, // 0x20 ' '
- {0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x21 '!'
- {0x00, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x22 '"'
- {0x00, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x44, 0x00, 0xFF, 0x01, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0xFF, 0x01, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x23 '#'
- {0x10, 0x00, 0x78, 0x00, 0x94, 0x00, 0x92, 0x00, 0x12, 0x00, 0x12, 0x00, 0x1C, 0x00, 0x70, 0x00, 0x90, 0x00, 0x90, 0x00, 0x92, 0x00, 0x54, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x24 '$'
- {0x00, 0x00, 0x1C, 0x02, 0x22, 0x01, 0x22, 0x01, 0xA2, 0x00, 0xA2, 0x00, 0x9C, 0x00, 0x40, 0x0E, 0x40, 0x11, 0x20, 0x11, 0x20, 0x11, 0x10, 0x11, 0x10, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x25 '%'
- {0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x28, 0x00, 0x18, 0x00, 0x14, 0x00, 0x22, 0x02, 0x42, 0x01, 0x82, 0x00, 0x44, 0x01, 0x38, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x26 '&'
- {0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x27 '''
- {0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00 }, // 0x28 '('
- {0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00 }, // 0x29 ')'
- {0x00, 0x00, 0x04, 0x00, 0x1F, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2A '*'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2B '+'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00 }, // 0x2C ','
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2D '-'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2E '.'
- {0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2F '/'
- {0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x30 '0'
- {0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x28, 0x00, 0x24, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x31 '1'
- {0x00, 0x00, 0x78, 0x00, 0x44, 0x00, 0x82, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x32 '2'
- {0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x42, 0x00, 0x40, 0x00, 0x60, 0x00, 0x38, 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x00, 0x82, 0x00, 0x46, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x33 '3'
- {0x00, 0x00, 0x40, 0x00, 0x60, 0x00, 0x50, 0x00, 0x48, 0x00, 0x48, 0x00, 0x44, 0x00, 0x42, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x34 '4'
- {0x00, 0x00, 0xFC, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x3E, 0x00, 0x42, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x35 '5'
- {0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x02, 0x00, 0x3A, 0x00, 0x46, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x36 '6'
- {0x00, 0x00, 0xFC, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x37 '7'
- {0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x38 '8'
- {0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0xC4, 0x00, 0xB8, 0x00, 0x80, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x39 '9'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3A ':'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x3B ';'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x70, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3C '<'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3D '='
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x60, 0x00, 0x80, 0x00, 0x60, 0x00, 0x1C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3E '>'
- {0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3F '?'
- {0x00, 0x00, 0xC0, 0x0F, 0x30, 0x30, 0x08, 0x40, 0x84, 0x4B, 0x44, 0x8C, 0x22, 0x88, 0x12, 0x88, 0x12, 0x84, 0x12, 0x84, 0x12, 0x44, 0x22, 0x26, 0xC4, 0x1D, 0x08, 0x80, 0x30, 0x60, 0xC0, 0x1F }, // 0x40 '@'
- {0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xFC, 0x01, 0x04, 0x01, 0x04, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x41 'A'
- {0x00, 0x00, 0xFE, 0x00, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0xFE, 0x00, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x42 'B'
- {0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x04, 0x04, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x04, 0x08, 0x02, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x43 'C'
- {0x00, 0x00, 0xFE, 0x00, 0x02, 0x01, 0x02, 0x02, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x44 'D'
- {0x00, 0x00, 0xFE, 0x03, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0xFE, 0x01, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x45 'E'
- {0x00, 0x00, 0xFE, 0x01, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0xFE, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x46 'F'
- {0x00, 0x00, 0xF0, 0x00, 0x08, 0x01, 0x04, 0x02, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0xC2, 0x07, 0x02, 0x04, 0x02, 0x04, 0x04, 0x02, 0x08, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x47 'G'
- {0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0xFE, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x48 'H'
- {0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x49 'I'
- {0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4A 'J'
- {0x00, 0x00, 0x02, 0x02, 0x02, 0x01, 0x82, 0x00, 0x42, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2A, 0x00, 0x46, 0x00, 0x82, 0x00, 0x82, 0x00, 0x02, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4B 'K'
- {0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4C 'L'
- {0x00, 0x00, 0x02, 0x08, 0x06, 0x0C, 0x06, 0x0C, 0x0A, 0x0A, 0x0A, 0x0A, 0x12, 0x09, 0x12, 0x09, 0xA2, 0x08, 0xA2, 0x08, 0xA2, 0x08, 0x42, 0x08, 0x42, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4D 'M'
- {0x00, 0x00, 0x02, 0x02, 0x06, 0x02, 0x0A, 0x02, 0x0A, 0x02, 0x12, 0x02, 0x22, 0x02, 0x22, 0x02, 0x42, 0x02, 0x82, 0x02, 0x82, 0x02, 0x02, 0x03, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4E 'N'
- {0x00, 0x00, 0xF0, 0x00, 0x08, 0x01, 0x04, 0x02, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x04, 0x02, 0x08, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4F 'O'
- {0x00, 0x00, 0xFE, 0x00, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0xFE, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x50 'P'
- {0x00, 0x00, 0xF0, 0x00, 0x08, 0x01, 0x04, 0x02, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0xC4, 0x06, 0x08, 0x03, 0xF0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x51 'Q'
- {0x00, 0x00, 0xFE, 0x00, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0xFE, 0x00, 0x42, 0x00, 0x82, 0x00, 0x82, 0x00, 0x02, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x52 'R'
- {0x00, 0x00, 0xF8, 0x00, 0x04, 0x01, 0x02, 0x02, 0x02, 0x00, 0x04, 0x00, 0x38, 0x00, 0xC0, 0x01, 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x04, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x53 'S'
- {0x00, 0x00, 0xFF, 0x01, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x54 'T'
- {0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x55 'U'
- {0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x04, 0x01, 0x04, 0x01, 0x04, 0x01, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x50, 0x00, 0x50, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x56 'V'
- {0x00, 0x00, 0x81, 0x40, 0x41, 0x41, 0x42, 0x21, 0x42, 0x21, 0x22, 0x22, 0x22, 0x22, 0x24, 0x12, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x57 'W'
- {0x00, 0x00, 0x02, 0x02, 0x04, 0x01, 0x88, 0x00, 0x88, 0x00, 0x50, 0x00, 0x20, 0x00, 0x50, 0x00, 0x88, 0x00, 0x88, 0x00, 0x04, 0x01, 0x02, 0x02, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x58 'X'
- {0x00, 0x00, 0x01, 0x01, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x28, 0x00, 0x28, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x59 'Y'
- {0x00, 0x00, 0xFE, 0x01, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5A 'Z'
- {0x00, 0x00, 0x0E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x0E, 0x00 }, // 0x5B '['
- {0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5C '\'
- {0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x07, 0x00 }, // 0x5D ']'
- {0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x14, 0x00, 0x22, 0x00, 0x22, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5E '^'
- {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, 0x00, 0x00, 0xFF, 0x01 }, // 0x5F '_'
- {0x00, 0x00, 0x02, 0x00, 0x04, 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 }, // 0x60 '`'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, 0x82, 0x00, 0xE0, 0x00, 0x9C, 0x00, 0x82, 0x00, 0x82, 0x00, 0xC2, 0x00, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x61 'a'
- {0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x3A, 0x00, 0x46, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x46, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x62 'b'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x63 'c'
- {0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xB8, 0x00, 0xC4, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0xC4, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x64 'd'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0xFE, 0x00, 0x02, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x65 'e'
- {0x00, 0x00, 0x0C, 0x00, 0x02, 0x00, 0x02, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x66 'f'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0xC4, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0xC4, 0x00, 0xB8, 0x00, 0x80, 0x00, 0x42, 0x00, 0x3C, 0x00 }, // 0x67 'g'
- {0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x3A, 0x00, 0x46, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x68 'h'
- {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x69 'i'
- {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00 }, // 0x6A 'j'
- {0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x82, 0x00, 0x42, 0x00, 0x22, 0x00, 0x12, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x42, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6B 'k'
- {0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6C 'l'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x07, 0xC6, 0x08, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6D 'm'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x46, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6E 'n'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6F 'o'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x46, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x46, 0x00, 0x3A, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00 }, // 0x70 'p'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0xC4, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0xC4, 0x00, 0xB8, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 }, // 0x71 'q'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x72 'r'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x42, 0x00, 0x02, 0x00, 0x02, 0x00, 0x3C, 0x00, 0x40, 0x00, 0x40, 0x00, 0x42, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x73 's'
- {0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x74 't'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x62, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x75 'u'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x41, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x76 'v'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x04, 0x21, 0x04, 0x52, 0x02, 0x52, 0x02, 0x8A, 0x02, 0x8A, 0x02, 0x8A, 0x02, 0x04, 0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x77 'w'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x22, 0x00, 0x14, 0x00, 0x14, 0x00, 0x08, 0x00, 0x14, 0x00, 0x14, 0x00, 0x22, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x78 'x'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x41, 0x00, 0x21, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x18, 0x00, 0x08, 0x00, 0x08, 0x00, 0x06, 0x00 }, // 0x79 'y'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x7A 'z'
- {0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x18, 0x00 }, // 0x7B '{'
- {0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00 }, // 0x7C '|'
- {0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x18, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00 }, // 0x7D '}'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // 0x7E '~'
-};
-static UG_U8 fontWidths_font_a_15X16[] = {
- 4, 5, 6, 9, 9, 14, 11, 3, 5, 5, 6, 9, 4, 5, 4, 4, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 4, 9, 9, 9, 9, 16, 11, 11, 12, 12, 11, 10, 12, 11, 3, 8, 11, 9, 13, 11, 12, 11, 12, 11, 11, 9, 11, 11, 15, 11, 9, 9, 4, 4, 4, 7, 9, 5, 9, 9, 8, 9, 9, 4, 9, 8, 4, 3, 8, 3, 13, 8, 9, 9, 9, 5, 8, 4, 8, 7, 11, 7, 7, 7, 5, 3, 5, 9
-};
-const UG_FONT font_font_a_15X16 = { (unsigned char *)fontBits_font_a_15X16, FONT_TYPE_1BPP, 15, 16, 32, 126, fontWidths_font_a_15X16 };
### src/ui/fonts/font_a_15X16.h
@@ -1,5 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-#include <ugui.h>
-
-extern const UG_FONT font_font_a_15X16;
### src/ui/fonts/font_a_17X18.c
@@ -1,109 +0,0 @@
-// Converted from font_a.ttf
-// --size 18
-// --dpi 72
-// --bpp 1
-// For copyright, see original font file.
-
-#include <ugui.h>
-
-static UG_FONT_DATA unsigned char fontBits_font_a_17X18[95][54] = {
- {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, 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 }, // 0x20 ' '
- {0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x21 '!'
- {0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x36, 0x00, 0x00, 0x36, 0x00, 0x00, 0x36, 0x00, 0x00, 0x36, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x22 '"'
- {0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x98, 0x01, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x07, 0x00, 0x98, 0x01, 0x00, 0xDC, 0x01, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x07, 0x00, 0xCC, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x23 '#'
- {0x20, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x26, 0x03, 0x00, 0x26, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xE0, 0x03, 0x00, 0x20, 0x03, 0x00, 0x26, 0x03, 0x00, 0xAE, 0x03, 0x00, 0xFC, 0x01, 0x00, 0xF8, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x24 '$'
- {0x00, 0x00, 0x00, 0x3C, 0x0C, 0x00, 0x66, 0x06, 0x00, 0x66, 0x06, 0x00, 0x66, 0x03, 0x00, 0x66, 0x03, 0x00, 0xE6, 0x03, 0x00, 0xBC, 0x3D, 0x00, 0x80, 0x67, 0x00, 0xC0, 0x66, 0x00, 0xC0, 0x66, 0x00, 0x60, 0x66, 0x00, 0x60, 0x66, 0x00, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x25 '%'
- {0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x98, 0x01, 0x00, 0x98, 0x01, 0x00, 0xD8, 0x00, 0x00, 0x70, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x6C, 0x06, 0x00, 0xC6, 0x06, 0x00, 0x86, 0x03, 0x00, 0x8E, 0x03, 0x00, 0xFC, 0x07, 0x00, 0x78, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x26 '&'
- {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x27 '''
- {0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00 }, // 0x28 '('
- {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00 }, // 0x29 ')'
- {0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x14, 0x00, 0x00, 0x14, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2A '*'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x07, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2B '+'
- {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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2C ','
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 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 }, // 0x2D '-'
- {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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2E '.'
- {0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2F '/'
- {0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xCE, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xCE, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x30 '0'
- {0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70, 0x00, 0x00, 0x78, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x64, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x31 '1'
- {0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xCE, 0x01, 0x00, 0x86, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x32 '2'
- {0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xC6, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x33 '3'
- {0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x78, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x66, 0x00, 0x00, 0x63, 0x00, 0x00, 0xFF, 0x01, 0x00, 0xFF, 0x01, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x34 '4'
- {0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x76, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x86, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x35 '5'
- {0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x76, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x8E, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x8C, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x36 '6'
- {0x00, 0x00, 0x00, 0xFE, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x37 '7'
- {0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x38 '8'
- {0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xC6, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xB8, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0xC6, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x39 '9'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3A ':'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3B ';'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x03, 0x00, 0xF0, 0x01, 0x00, 0x3C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x80, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3C '<'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x03, 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 }, // 0x3D '='
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x03, 0x00, 0xE0, 0x01, 0x00, 0x7C, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3E '>'
- {0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xCE, 0x01, 0x00, 0x86, 0x01, 0x00, 0x80, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3F '?'
- {0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x7F, 0x00, 0x70, 0xE0, 0x00, 0x18, 0xF7, 0x01, 0x8C, 0xBF, 0x03, 0xCC, 0x1C, 0x03, 0xE6, 0x18, 0x03, 0x66, 0x18, 0x03, 0x66, 0x08, 0x03, 0x66, 0x8C, 0x01, 0xE6, 0xCC, 0x01, 0xC6, 0xFF, 0x00, 0xCC, 0x3D, 0x00, 0x1C, 0x80, 0x03, 0x78, 0xC0, 0x01, 0xF0, 0xFF, 0x00, 0xC0, 0x3F, 0x00 }, // 0x40 '@'
- {0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0xD8, 0x00, 0x00, 0xD8, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x8C, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xFE, 0x03, 0x00, 0x06, 0x03, 0x00, 0x06, 0x03, 0x00, 0x03, 0x06, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x41 'A'
- {0x00, 0x00, 0x00, 0xFE, 0x01, 0x00, 0xFE, 0x03, 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x03, 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x06, 0x07, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x42 'B'
- {0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF8, 0x07, 0x00, 0x1C, 0x0E, 0x00, 0x0C, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x1C, 0x06, 0x00, 0xF8, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x43 'C'
- {0x00, 0x00, 0x00, 0xFE, 0x01, 0x00, 0xFE, 0x03, 0x00, 0x06, 0x07, 0x00, 0x06, 0x0E, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x06, 0x00, 0x06, 0x07, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x44 'D'
- {0x00, 0x00, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x07, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x03, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x45 'E'
- {0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x03, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0xFE, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x46 'F'
- {0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0xF8, 0x0F, 0x00, 0x1C, 0x0C, 0x00, 0x0C, 0x18, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x86, 0x1F, 0x00, 0x86, 0x1F, 0x00, 0x06, 0x18, 0x00, 0x0C, 0x18, 0x00, 0x1C, 0x1C, 0x00, 0xF8, 0x0F, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x47 'G'
- {0x00, 0x00, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0xFE, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x48 'H'
- {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x49 'I'
- {0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC6, 0x00, 0x00, 0xC6, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4A 'J'
- {0x00, 0x00, 0x00, 0x06, 0x07, 0x00, 0x86, 0x03, 0x00, 0xC6, 0x01, 0x00, 0xE6, 0x00, 0x00, 0x76, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xEE, 0x00, 0x00, 0xC6, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x03, 0x00, 0x06, 0x07, 0x00, 0x06, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4B 'K'
- {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0xFE, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4C 'L'
- {0x00, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x1E, 0x3C, 0x00, 0x1E, 0x3C, 0x00, 0x1E, 0x3C, 0x00, 0x36, 0x36, 0x00, 0x36, 0x36, 0x00, 0x36, 0x36, 0x00, 0x26, 0x32, 0x00, 0x66, 0x33, 0x00, 0x66, 0x33, 0x00, 0x66, 0x33, 0x00, 0xC6, 0x31, 0x00, 0xC6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4D 'M'
- {0x00, 0x00, 0x00, 0x06, 0x0C, 0x00, 0x0E, 0x0C, 0x00, 0x1E, 0x0C, 0x00, 0x1E, 0x0C, 0x00, 0x36, 0x0C, 0x00, 0x66, 0x0C, 0x00, 0xE6, 0x0C, 0x00, 0xC6, 0x0C, 0x00, 0x86, 0x0D, 0x00, 0x06, 0x0F, 0x00, 0x06, 0x0F, 0x00, 0x06, 0x0E, 0x00, 0x06, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4E 'N'
- {0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0xF8, 0x07, 0x00, 0x1C, 0x0E, 0x00, 0x0C, 0x0C, 0x00, 0x06, 0x18, 0x00, 0x06, 0x18, 0x00, 0x06, 0x18, 0x00, 0x06, 0x18, 0x00, 0x06, 0x18, 0x00, 0x0C, 0x0C, 0x00, 0x1C, 0x0E, 0x00, 0xF8, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4F 'O'
- {0x00, 0x00, 0x00, 0xFE, 0x01, 0x00, 0xFE, 0x03, 0x00, 0x06, 0x07, 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x06, 0x07, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x01, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x50 'P'
- {0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0xF8, 0x07, 0x00, 0x1C, 0x0E, 0x00, 0x0C, 0x1C, 0x00, 0x06, 0x18, 0x00, 0x06, 0x18, 0x00, 0x06, 0x18, 0x00, 0x06, 0x18, 0x00, 0x06, 0x18, 0x00, 0x8C, 0x0D, 0x00, 0x1C, 0x07, 0x00, 0xF8, 0x07, 0x00, 0xF0, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x51 'Q'
- {0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x06, 0x0E, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0E, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x03, 0x00, 0x86, 0x01, 0x00, 0x86, 0x03, 0x00, 0x06, 0x07, 0x00, 0x06, 0x06, 0x00, 0x06, 0x0E, 0x00, 0x06, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x52 'R'
- {0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xFC, 0x03, 0x00, 0x0E, 0x07, 0x00, 0x06, 0x06, 0x00, 0x06, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x06, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x53 'S'
- {0x00, 0x00, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x07, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x54 'T'
- {0x00, 0x00, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x0E, 0x06, 0x00, 0xFC, 0x07, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x55 'U'
- {0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x03, 0x06, 0x00, 0x06, 0x03, 0x00, 0x06, 0x03, 0x00, 0x06, 0x03, 0x00, 0x8C, 0x01, 0x00, 0x8C, 0x01, 0x00, 0x8C, 0x01, 0x00, 0xD8, 0x00, 0x00, 0xD8, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x56 'V'
- {0x00, 0x00, 0x00, 0x83, 0x83, 0x01, 0x83, 0x83, 0x01, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0x00, 0x46, 0xC4, 0x00, 0x6C, 0x6C, 0x00, 0x6C, 0x6C, 0x00, 0x6C, 0x6C, 0x00, 0x6C, 0x6C, 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x57 'W'
- {0x00, 0x00, 0x00, 0x8E, 0x03, 0x00, 0x8C, 0x01, 0x00, 0xD8, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0xD8, 0x00, 0x00, 0xD8, 0x00, 0x00, 0xDC, 0x01, 0x00, 0x8C, 0x01, 0x00, 0x06, 0x03, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x58 'X'
- {0x00, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x06, 0x06, 0x00, 0x0C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x98, 0x01, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x59 'Y'
- {0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x03, 0x00, 0x80, 0x01, 0x00, 0xC0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5A 'Z'
- {0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x00, 0x00 }, // 0x5B '['
- {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5C '\'
- {0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00 }, // 0x5D ']'
- {0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x14, 0x00, 0x00, 0x36, 0x00, 0x00, 0x36, 0x00, 0x00, 0x22, 0x00, 0x00, 0x63, 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, 0x00, 0x00, 0x00, 0x00 }, // 0x5E '^'
- {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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x03, 0x00 }, // 0x5F '_'
- {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x60 '`'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x86, 0x01, 0x00, 0xE0, 0x01, 0x00, 0xFC, 0x01, 0x00, 0x9E, 0x01, 0x00, 0x86, 0x01, 0x00, 0xC6, 0x01, 0x00, 0xFE, 0x01, 0x00, 0xBC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x61 'a'
- {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x76, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xCE, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xCE, 0x01, 0x00, 0xFE, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x62 'b'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0xCE, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x63 'c'
- {0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0xB8, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xCE, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xCE, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x64 'd'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x86, 0x01, 0x00, 0xFE, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x06, 0x00, 0x00, 0x8E, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x65 'e'
- {0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x66 'f'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xCE, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xCE, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xB8, 0x01, 0x00, 0x80, 0x01, 0x00, 0xC6, 0x01, 0x00, 0xFE, 0x00, 0x00, 0x7C, 0x00, 0x00 }, // 0x67 'g'
- {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0xF6, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x8E, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x68 'h'
- {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x69 'i'
- {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x00, 0x00 }, // 0x6A 'j'
- {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0xC6, 0x01, 0x00, 0xE6, 0x00, 0x00, 0x76, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x36, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0xC6, 0x00, 0x00, 0xC6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6B 'k'
- {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6C 'l'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x0E, 0x00, 0x7E, 0x1F, 0x00, 0xCE, 0x19, 0x00, 0xC6, 0x18, 0x00, 0xC6, 0x18, 0x00, 0xC6, 0x18, 0x00, 0xC6, 0x18, 0x00, 0xC6, 0x18, 0x00, 0xC6, 0x18, 0x00, 0xC6, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6D 'm'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x8E, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6E 'n'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xCE, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xCE, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6F 'o'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xCE, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xCE, 0x01, 0x00, 0xFE, 0x00, 0x00, 0x76, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00 }, // 0x70 'p'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xCE, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xCE, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xB8, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00 }, // 0x71 'q'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x72 'r'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xC6, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xC6, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x73 's'
- {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x74 't'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0x86, 0x01, 0x00, 0xC6, 0x01, 0x00, 0xFE, 0x01, 0x00, 0xBC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x75 'u'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x01, 0x00, 0x83, 0x01, 0x00, 0xC6, 0x00, 0x00, 0xC6, 0x00, 0x00, 0xC6, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x76 'v'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x18, 0x00, 0xE3, 0x18, 0x00, 0xE3, 0x18, 0x00, 0xA6, 0x0C, 0x00, 0xB6, 0x0D, 0x00, 0xB6, 0x0D, 0x00, 0x14, 0x05, 0x00, 0x1C, 0x07, 0x00, 0x1C, 0x07, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x77 'w'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x78 'x'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x01, 0x00, 0x83, 0x01, 0x00, 0xC6, 0x00, 0x00, 0xC6, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x78, 0x00, 0x00, 0x78, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x0E, 0x00, 0x00 }, // 0x79 'y'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x70, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x7A 'z'
- {0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x38, 0x00, 0x00 }, // 0x7B '{'
- {0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00 }, // 0x7C '|'
- {0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x07, 0x00, 0x00 }, // 0x7D '}'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x3F, 0x02, 0x00, 0xF1, 0x03, 0x00, 0xC0, 0x01, 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 } // 0x7E '~'
-};
-static UG_U8 fontWidths_font_a_17X18[] = {
- 5, 6, 6, 10, 10, 16, 12, 3, 6, 6, 7, 11, 5, 6, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 5, 5, 11, 11, 11, 10, 18, 11, 12, 13, 13, 12, 11, 14, 13, 4, 9, 12, 10, 15, 13, 14, 12, 14, 13, 12, 12, 13, 11, 17, 11, 12, 11, 5, 5, 5, 7, 10, 6, 10, 10, 9, 10, 10, 5, 10, 10, 4, 4, 9, 4, 14, 10, 10, 10, 10, 6, 9, 5, 10, 9, 13, 8, 9, 8, 6, 6, 6, 11
-};
-const UG_FONT font_font_a_17X18 = { (unsigned char *)fontBits_font_a_17X18, FONT_TYPE_1BPP, 17, 18, 32, 126, fontWidths_font_a_17X18 };
### src/ui/fonts/font_a_17X18.h
@@ -1,5 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-#include <ugui.h>
-
-extern const UG_FONT font_font_a_17X18;
### src/ui/fonts/font_a_9X9.c
@@ -1,108 +0,0 @@
-// Converted from font_a.ttf
-// --size 9
-// --dpi 72
-// --bpp 1
-// For copyright, see original font file.
-
-#include <ugui.h>
-
-static UG_FONT_DATA unsigned char fontBits_font_a_9X9[95][18] = {
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x20 ' '
- {0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x21 '!'
- {0x05,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x22 '"'
- {0x0A,0x00,0x0A,0x00,0x0F,0x00,0x0A,0x00,0x0F,0x00,0x05,0x00,0x05,0x00,0x00,0x00,0x00,0x00 }, // 0x23 '#'
- {0x0E,0x00,0x15,0x00,0x05,0x00,0x0E,0x00,0x14,0x00,0x15,0x00,0x0E,0x00,0x04,0x00,0x00,0x00 }, // 0x24 '$'
- {0x24,0x00,0x1A,0x00,0x14,0x00,0x10,0x00,0x28,0x00,0x58,0x00,0x28,0x00,0x00,0x00,0x00,0x00 }, // 0x25 '%'
- {0x0C,0x00,0x12,0x00,0x12,0x00,0x0E,0x00,0x29,0x00,0x11,0x00,0x2E,0x00,0x00,0x00,0x00,0x00 }, // 0x26 '&'
- {0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x27 '''
- {0x04,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x04,0x00 }, // 0x28 '('
- {0x01,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x01,0x00 }, // 0x29 ')'
- {0x07,0x00,0x02,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2A '*'
- {0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1F,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x2B '+'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x00,0x00 }, // 0x2C ','
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2D '-'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x2E '.'
- {0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x2F '/'
- {0x06,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x30 '0'
- {0x04,0x00,0x06,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x31 '1'
- {0x06,0x00,0x09,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x0F,0x00,0x00,0x00,0x00,0x00 }, // 0x32 '2'
- {0x06,0x00,0x09,0x00,0x08,0x00,0x04,0x00,0x08,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x33 '3'
- {0x08,0x00,0x0C,0x00,0x0A,0x00,0x09,0x00,0x1F,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00 }, // 0x34 '4'
- {0x0E,0x00,0x02,0x00,0x07,0x00,0x09,0x00,0x08,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x35 '5'
- {0x06,0x00,0x09,0x00,0x07,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x36 '6'
- {0x0F,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x37 '7'
- {0x06,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x38 '8'
- {0x06,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x39 '9'
- {0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x3A ':'
- {0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x00,0x00 }, // 0x3B ';'
- {0x00,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3C '<'
- {0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3D '='
- {0x00,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3E '>'
- {0x0E,0x00,0x11,0x00,0x10,0x00,0x0C,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x3F '?'
- {0x78,0x00,0x84,0x00,0x52,0x01,0x6A,0x01,0x2A,0x01,0xAA,0x00,0x7A,0x00,0x84,0x01,0x78,0x00 }, // 0x40 '@'
- {0x08,0x00,0x14,0x00,0x22,0x00,0x22,0x00,0x3E,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00 }, // 0x41 'A'
- {0x0E,0x00,0x12,0x00,0x12,0x00,0x1E,0x00,0x12,0x00,0x12,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x42 'B'
- {0x1C,0x00,0x22,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x43 'C'
- {0x1E,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x1E,0x00,0x00,0x00,0x00,0x00 }, // 0x44 'D'
- {0x3E,0x00,0x02,0x00,0x02,0x00,0x3E,0x00,0x02,0x00,0x02,0x00,0x3E,0x00,0x00,0x00,0x00,0x00 }, // 0x45 'E'
- {0x1E,0x00,0x02,0x00,0x02,0x00,0x0E,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x46 'F'
- {0x1C,0x00,0x22,0x00,0x02,0x00,0x32,0x00,0x22,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x47 'G'
- {0x22,0x00,0x22,0x00,0x22,0x00,0x3E,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00 }, // 0x48 'H'
- {0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x49 'I'
- {0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x09,0x00,0x07,0x00,0x00,0x00,0x00,0x00 }, // 0x4A 'J'
- {0x22,0x00,0x12,0x00,0x0A,0x00,0x06,0x00,0x0A,0x00,0x12,0x00,0x22,0x00,0x00,0x00,0x00,0x00 }, // 0x4B 'K'
- {0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x1E,0x00,0x00,0x00,0x00,0x00 }, // 0x4C 'L'
- {0x41,0x00,0x63,0x00,0x63,0x00,0x55,0x00,0x55,0x00,0x55,0x00,0x49,0x00,0x00,0x00,0x00,0x00 }, // 0x4D 'M'
- {0x22,0x00,0x26,0x00,0x26,0x00,0x2A,0x00,0x32,0x00,0x32,0x00,0x22,0x00,0x00,0x00,0x00,0x00 }, // 0x4E 'N'
- {0x1C,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x4F 'O'
- {0x1E,0x00,0x12,0x00,0x12,0x00,0x1E,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x50 'P'
- {0x1C,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x12,0x00,0x3C,0x00,0x00,0x00,0x00,0x00 }, // 0x51 'Q'
- {0x1E,0x00,0x22,0x00,0x22,0x00,0x1E,0x00,0x12,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00 }, // 0x52 'R'
- {0x0C,0x00,0x12,0x00,0x02,0x00,0x0C,0x00,0x10,0x00,0x12,0x00,0x0C,0x00,0x00,0x00,0x00,0x00 }, // 0x53 'S'
- {0x1F,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x54 'T'
- {0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x55 'U'
- {0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x00 }, // 0x56 'V'
- {0x11,0x01,0x29,0x01,0xAA,0x00,0xAA,0x00,0xAA,0x00,0xAA,0x00,0x44,0x00,0x00,0x00,0x00,0x00 }, // 0x57 'W'
- {0x11,0x00,0x0A,0x00,0x0A,0x00,0x04,0x00,0x0A,0x00,0x0A,0x00,0x11,0x00,0x00,0x00,0x00,0x00 }, // 0x58 'X'
- {0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00 }, // 0x59 'Y'
- {0x3F,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x3F,0x00,0x00,0x00,0x00,0x00 }, // 0x5A 'Z'
- {0x06,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x06,0x00 }, // 0x5B '['
- {0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x5C '\'
- {0x03,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x03,0x00 }, // 0x5D ']'
- {0x02,0x00,0x05,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x5E '^'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00 }, // 0x5F '_'
- {0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x60 '`'
- {0x00,0x00,0x00,0x00,0x0F,0x00,0x08,0x00,0x0E,0x00,0x09,0x00,0x0F,0x00,0x00,0x00,0x00,0x00 }, // 0x61 'a'
- {0x01,0x00,0x01,0x00,0x07,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x07,0x00,0x00,0x00,0x00,0x00 }, // 0x62 'b'
- {0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x00,0x01,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x63 'c'
- {0x08,0x00,0x08,0x00,0x0E,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x64 'd'
- {0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x00,0x0F,0x00,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x65 'e'
- {0x04,0x00,0x02,0x00,0x07,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x66 'f'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x09,0x00,0x06,0x00 }, // 0x67 'g'
- {0x01,0x00,0x01,0x00,0x07,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00,0x00,0x00 }, // 0x68 'h'
- {0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x69 'i'
- {0x02,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00 }, // 0x6A 'j'
- {0x01,0x00,0x01,0x00,0x09,0x00,0x05,0x00,0x07,0x00,0x05,0x00,0x09,0x00,0x00,0x00,0x00,0x00 }, // 0x6B 'k'
- {0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x6C 'l'
- {0x00,0x00,0x00,0x00,0x3F,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x00,0x00,0x00,0x00 }, // 0x6D 'm'
- {0x00,0x00,0x00,0x00,0x07,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00,0x00,0x00 }, // 0x6E 'n'
- {0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x6F 'o'
- {0x00,0x00,0x00,0x00,0x07,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x07,0x00,0x01,0x00,0x01,0x00 }, // 0x70 'p'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x08,0x00,0x08,0x00 }, // 0x71 'q'
- {0x00,0x00,0x00,0x00,0x07,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x72 'r'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x01,0x00,0x06,0x00,0x08,0x00,0x07,0x00,0x00,0x00,0x00,0x00 }, // 0x73 's'
- {0x00,0x00,0x01,0x00,0x03,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x03,0x00,0x00,0x00,0x00,0x00 }, // 0x74 't'
- {0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x75 'u'
- {0x00,0x00,0x00,0x00,0x11,0x00,0x0A,0x00,0x0A,0x00,0x0A,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x76 'v'
- {0x00,0x00,0x00,0x00,0x15,0x00,0x15,0x00,0x15,0x00,0x15,0x00,0x0A,0x00,0x00,0x00,0x00,0x00 }, // 0x77 'w'
- {0x00,0x00,0x00,0x00,0x09,0x00,0x06,0x00,0x02,0x00,0x06,0x00,0x09,0x00,0x00,0x00,0x00,0x00 }, // 0x78 'x'
- {0x00,0x00,0x00,0x00,0x11,0x00,0x0A,0x00,0x0A,0x00,0x0A,0x00,0x04,0x00,0x04,0x00,0x02,0x00 }, // 0x79 'y'
- {0x00,0x00,0x00,0x00,0x07,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x07,0x00,0x00,0x00,0x00,0x00 }, // 0x7A 'z'
- {0x06,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x06,0x00 }, // 0x7B '{'
- {0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00 }, // 0x7C '|'
- {0x03,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x03,0x00 }, // 0x7D '}'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } // 0x7E '~'
-};
-static UG_U8 fontWidths_font_a_9X9[] = {
-3,3,3,5,5,8,6,2,3,3,4,5,3,3,3,3,5,5,5,5,5,5,5,5,5,5,3,3,5,5,5,5,9,6,6,7,7,6,6,7,7,3,5,6,5,7,7,7,6,7,7,6,5,7,6,9,5,7,6,3,3,3,3,5,3,5,5,5,5,5,4,5,5,2,3,5,2,8,5,5,5,5,3,5,3,5,6,6,5,6,4,3,3,3,5};
-UG_FONT font_font_a_9X9 = { (unsigned char*)fontBits_font_a_9X9, FONT_TYPE_1BPP, 9, 9, 32, 126, fontWidths_font_a_9X9 };
### src/ui/fonts/font_a_9X9.h
@@ -1,5 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-#include <ugui.h>
-
-extern const UG_FONT font_font_a_9X9;
### src/ui/fonts/lvgl.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef _UI_FONTS_LVGL_H_
+#define _UI_FONTS_LVGL_H_
+
+#include <lv_version.h>
+#include <src/font/lv_font.h>
+#include <src/font/lv_font_fmt_txt.h>
+
+#ifndef LV_VERSION_CHECK
+#define LV_VERSION_CHECK(x, y, z) \
+ ((x) == LVGL_VERSION_MAJOR && \
+ ((y) < LVGL_VERSION_MINOR || ((y) == LVGL_VERSION_MINOR && (z) <= LVGL_VERSION_PATCH)))
+#endif
+
+#endif
### src/ui/fonts/lvgl_font_compat.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: Apache-2.0
+
+#include "lvgl.h"
+
+#include <stdbool.h>
+#include <string.h>
+
+static bool _font_dsc_supported(const lv_font_fmt_txt_dsc_t* font_dsc)
+{
+ if (font_dsc == NULL || font_dsc->glyph_bitmap == NULL || font_dsc->glyph_dsc == NULL ||
+ (font_dsc->cmap_num != 0 && font_dsc->cmaps == NULL) || font_dsc->bpp != 1 ||
+ font_dsc->stride != 0 || font_dsc->bitmap_format != LV_FONT_FMT_TXT_PLAIN ||
+ font_dsc->kern_dsc != NULL || font_dsc->kern_scale != 0 || font_dsc->kern_classes != 0) {
+ return false;
+ }
+
+ for (uint16_t i = 0; i < font_dsc->cmap_num; i++) {
+ const lv_font_fmt_txt_cmap_t* cmap = &font_dsc->cmaps[i];
+ if (cmap->type != LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY || cmap->unicode_list != NULL ||
+ cmap->glyph_id_ofs_list != NULL || cmap->list_length != 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static uint32_t _get_glyph_id(const lv_font_fmt_txt_dsc_t* font_dsc, uint32_t codepoint)
+{
+ if (codepoint == '\0') {
+ return 0;
+ }
+
+ for (uint16_t i = 0; i < font_dsc->cmap_num; i++) {
+ const lv_font_fmt_txt_cmap_t* cmap = &font_dsc->cmaps[i];
+ uint32_t relative_codepoint = codepoint - cmap->range_start;
+ if (relative_codepoint < cmap->range_length) {
+ return cmap->glyph_id_start + relative_codepoint;
+ }
+ }
+ return 0;
+}
+
+__attribute__((weak)) bool lv_font_get_glyph_dsc_fmt_txt(
+ const lv_font_t* font,
+ lv_font_glyph_dsc_t* dsc_out,
+ uint32_t unicode_letter,
+ uint32_t unicode_letter_next)
+{
+ (void)unicode_letter_next;
+ if (font == NULL || font->dsc == NULL || dsc_out == NULL) {
+ return false;
+ }
+
+ bool is_tab = unicode_letter == '\t';
+ if (is_tab) {
+ unicode_letter = ' ';
+ }
+
+ const lv_font_fmt_txt_dsc_t* font_dsc = (const lv_font_fmt_txt_dsc_t*)font->dsc;
+ if (!_font_dsc_supported(font_dsc)) {
+ return false;
+ }
+
+ uint32_t glyph_id = _get_glyph_id(font_dsc, unicode_letter);
+ if (glyph_id == 0) {
+ return false;
+ }
+
+ const lv_font_fmt_txt_glyph_dsc_t* glyph_dsc = &font_dsc->glyph_dsc[glyph_id];
+
+ memset(dsc_out, 0, sizeof(*dsc_out));
+ dsc_out->resolved_font = font;
+ dsc_out->adv_w = (glyph_dsc->adv_w + (1 << 3)) >> 4;
+ dsc_out->box_w = glyph_dsc->box_w;
+ dsc_out->box_h = glyph_dsc->box_h;
+ dsc_out->ofs_x = glyph_dsc->ofs_x;
+ dsc_out->ofs_y = glyph_dsc->ofs_y;
+ dsc_out->stride = 0;
+ dsc_out->format = LV_FONT_GLYPH_FORMAT_A1;
+ dsc_out->is_placeholder = false;
+ dsc_out->gid.index = glyph_id;
+
+ if (is_tab) {
+ dsc_out->adv_w *= 2;
+ }
+
+ return true;
+}
+
+__attribute__((weak)) const void* lv_font_get_bitmap_fmt_txt(
+ lv_font_glyph_dsc_t* glyph_dsc,
+ lv_draw_buf_t* draw_buf)
+{
+ (void)draw_buf;
+ if (glyph_dsc == NULL || glyph_dsc->resolved_font == NULL ||
+ glyph_dsc->resolved_font->dsc == NULL || glyph_dsc->gid.index == 0 ||
+ glyph_dsc->format != LV_FONT_GLYPH_FORMAT_A1 || glyph_dsc->stride != 0) {
+ return NULL;
+ }
+
+ const lv_font_fmt_txt_dsc_t* font_dsc =
+ (const lv_font_fmt_txt_dsc_t*)glyph_dsc->resolved_font->dsc;
+ if (!_font_dsc_supported(font_dsc)) {
+ return NULL;
+ }
+
+ const lv_font_fmt_txt_glyph_dsc_t* font_glyph_dsc =
+ &font_dsc->glyph_dsc[glyph_dsc->gid.index];
+ return &font_dsc->glyph_bitmap[font_glyph_dsc->bitmap_index];
+}
### src/ui/fonts/monogram_16.c
@@ -0,0 +1,448 @@
+/*******************************************************************************
+ * Size: 16 px
+ * Bpp: 1
+ * Opts: --dump --bpp 1 --size 16 --font monogram.ttf --range 32-126 --name monogram_16 --output monogram_16.c
+ ******************************************************************************/
+
+#ifdef __has_include
+ #if __has_include("lvgl.h")
+ #ifndef LV_LVGL_H_INCLUDE_SIMPLE
+ #define LV_LVGL_H_INCLUDE_SIMPLE
+ #endif
+ #endif
+#endif
+
+#ifdef LV_LVGL_H_INCLUDE_SIMPLE
+ #include "lvgl.h"
+#else
+ #include "lvgl/lvgl.h"
+#endif
+
+#include "monogram_16.h"
+
+#ifndef MONOGRAM_16
+#define MONOGRAM_16 1
+#endif
+
+#if MONOGRAM_16
+
+static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
+ /* U+0020 "\u0020" */
+ 0x00,
+
+ /* U+0021 "!" */
+ 0xFA,
+
+ /* U+0022 "\"" */
+ 0xB6, 0x80,
+
+ /* U+0023 "#" */
+ 0x57, 0xD4, 0xAF, 0xA8,
+
+ /* U+0024 "$" */
+ 0x23, 0xE8, 0xE2, 0xF8, 0x80,
+
+ /* U+0025 "%" */
+ 0x8C, 0x44, 0x44, 0x46, 0x20,
+
+ /* U+0026 "&" */
+ 0x64, 0xA4, 0xF9, 0x49, 0xA0,
+
+ /* U+0027 "'" */
+ 0xE0,
+
+ /* U+0028 "(" */
+ 0x6A, 0xA4,
+
+ /* U+0029 ")" */
+ 0x95, 0x58,
+
+ /* U+002A "*" */
+ 0x25, 0x5D, 0x52, 0x00,
+
+ /* U+002B "+" */
+ 0x21, 0x3E, 0x42, 0x00,
+
+ /* U+002C "," */
+ 0x58,
+
+ /* U+002D "-" */
+ 0xF8,
+
+ /* U+002E "." */
+ 0xC0,
+
+ /* U+002F "/" */
+ 0x08, 0x44, 0x44, 0x42, 0x00,
+
+ /* U+0030 "0" */
+ 0x74, 0x67, 0x5C, 0xC5, 0xC0,
+
+ /* U+0031 "1" */
+ 0x23, 0x08, 0x42, 0x13, 0xE0,
+
+ /* U+0032 "2" */
+ 0x74, 0x42, 0x22, 0x23, 0xE0,
+
+ /* U+0033 "3" */
+ 0x74, 0x42, 0x60, 0xC5, 0xC0,
+
+ /* U+0034 "4" */
+ 0x4A, 0x63, 0xF0, 0x84, 0x20,
+
+ /* U+0035 "5" */
+ 0xFC, 0x3C, 0x10, 0xC5, 0xC0,
+
+ /* U+0036 "6" */
+ 0x74, 0x21, 0xE8, 0xC5, 0xC0,
+
+ /* U+0037 "7" */
+ 0xF8, 0x42, 0x22, 0x10, 0x80,
+
+ /* U+0038 "8" */
+ 0x74, 0x62, 0xE8, 0xC5, 0xC0,
+
+ /* U+0039 "9" */
+ 0x74, 0x62, 0xF0, 0xC5, 0xC0,
+
+ /* U+003A ":" */
+ 0xCC,
+
+ /* U+003B ";" */
+ 0x50, 0x58,
+
+ /* U+003C "<" */
+ 0x1B, 0x20, 0xC1, 0x80,
+
+ /* U+003D "=" */
+ 0xF8, 0x3E,
+
+ /* U+003E ">" */
+ 0xC1, 0x82, 0x6C, 0x00,
+
+ /* U+003F "?" */
+ 0x74, 0x42, 0x22, 0x00, 0x80,
+
+ /* U+0040 "@" */
+ 0x74, 0xEB, 0x59, 0xC1, 0xC0,
+
+ /* U+0041 "A" */
+ 0x74, 0x63, 0x1F, 0xC6, 0x20,
+
+ /* U+0042 "B" */
+ 0xF4, 0x63, 0xE8, 0xC7, 0xC0,
+
+ /* U+0043 "C" */
+ 0x74, 0x61, 0x08, 0x45, 0xC0,
+
+ /* U+0044 "D" */
+ 0xF4, 0x63, 0x18, 0xC7, 0xC0,
+
+ /* U+0045 "E" */
+ 0xFC, 0x21, 0xE8, 0x43, 0xE0,
+
+ /* U+0046 "F" */
+ 0xFC, 0x21, 0xE8, 0x42, 0x00,
+
+ /* U+0047 "G" */
+ 0x74, 0x61, 0x78, 0xC5, 0xC0,
+
+ /* U+0048 "H" */
+ 0x8C, 0x63, 0xF8, 0xC6, 0x20,
+
+ /* U+0049 "I" */
+ 0xF9, 0x08, 0x42, 0x13, 0xE0,
+
+ /* U+004A "J" */
+ 0x08, 0x42, 0x18, 0xC5, 0xC0,
+
+ /* U+004B "K" */
+ 0x8C, 0xA9, 0x8A, 0x4A, 0x20,
+
+ /* U+004C "L" */
+ 0x84, 0x21, 0x08, 0x43, 0xE0,
+
+ /* U+004D "M" */
+ 0x8E, 0xEB, 0x18, 0xC6, 0x20,
+
+ /* U+004E "N" */
+ 0x8C, 0x73, 0x59, 0xC6, 0x20,
+
+ /* U+004F "O" */
+ 0x74, 0x63, 0x18, 0xC5, 0xC0,
+
+ /* U+0050 "P" */
+ 0xF4, 0x63, 0xE8, 0x42, 0x00,
+
+ /* U+0051 "Q" */
+ 0x74, 0x63, 0x18, 0xC5, 0xC3,
+
+ /* U+0052 "R" */
+ 0xF4, 0x63, 0xE8, 0xC6, 0x20,
+
+ /* U+0053 "S" */
+ 0x74, 0x60, 0xE0, 0xC5, 0xC0,
+
+ /* U+0054 "T" */
+ 0xF9, 0x08, 0x42, 0x10, 0x80,
+
+ /* U+0055 "U" */
+ 0x8C, 0x63, 0x18, 0xC5, 0xC0,
+
+ /* U+0056 "V" */
+ 0x8C, 0x63, 0x15, 0x28, 0x80,
+
+ /* U+0057 "W" */
+ 0x8C, 0x63, 0x1A, 0xEE, 0x20,
+
+ /* U+0058 "X" */
+ 0x8C, 0x54, 0x45, 0x46, 0x20,
+
+ /* U+0059 "Y" */
+ 0x8C, 0x54, 0x42, 0x10, 0x80,
+
+ /* U+005A "Z" */
+ 0xF8, 0x44, 0x44, 0x43, 0xE0,
+
+ /* U+005B "[" */
+ 0xEA, 0xAC,
+
+ /* U+005C "\\" */
+ 0x84, 0x10, 0x41, 0x04, 0x20,
+
+ /* U+005D "]" */
+ 0xD5, 0x5C,
+
+ /* U+005E "^" */
+ 0x22, 0xA2,
+
+ /* U+005F "_" */
+ 0xF8,
+
+ /* U+0060 "`" */
+ 0x90,
+
+ /* U+0061 "a" */
+ 0x7C, 0x63, 0x17, 0x80,
+
+ /* U+0062 "b" */
+ 0x84, 0x3D, 0x18, 0xC7, 0xC0,
+
+ /* U+0063 "c" */
+ 0x74, 0x61, 0x17, 0x00,
+
+ /* U+0064 "d" */
+ 0x08, 0x5F, 0x18, 0xC5, 0xE0,
+
+ /* U+0065 "e" */
+ 0x74, 0x7F, 0x07, 0x00,
+
+ /* U+0066 "f" */
+ 0x32, 0x51, 0xE4, 0x21, 0x00,
+
+ /* U+0067 "g" */
+ 0x7C, 0x63, 0x17, 0x85, 0xC0,
+
+ /* U+0068 "h" */
+ 0x84, 0x3D, 0x18, 0xC6, 0x20,
+
+ /* U+0069 "i" */
+ 0x20, 0x18, 0x42, 0x13, 0xE0,
+
+ /* U+006A "j" */
+ 0x08, 0x06, 0x10, 0x84, 0x31, 0x70,
+
+ /* U+006B "k" */
+ 0x84, 0x23, 0x2E, 0x4A, 0x20,
+
+ /* U+006C "l" */
+ 0xC2, 0x10, 0x84, 0x20, 0xE0,
+
+ /* U+006D "m" */
+ 0xF5, 0x6B, 0x5A, 0x80,
+
+ /* U+006E "n" */
+ 0xF4, 0x63, 0x18, 0x80,
+
+ /* U+006F "o" */
+ 0x74, 0x63, 0x17, 0x00,
+
+ /* U+0070 "p" */
+ 0xF4, 0x63, 0x1F, 0x42, 0x00,
+
+ /* U+0071 "q" */
+ 0x7C, 0x63, 0x17, 0x84, 0x20,
+
+ /* U+0072 "r" */
+ 0xB6, 0x61, 0x08, 0x00,
+
+ /* U+0073 "s" */
+ 0x7C, 0x1C, 0x1F, 0x00,
+
+ /* U+0074 "t" */
+ 0x42, 0x3C, 0x84, 0x20, 0xE0,
+
+ /* U+0075 "u" */
+ 0x8C, 0x63, 0x17, 0x80,
+
+ /* U+0076 "v" */
+ 0x8C, 0x62, 0xA2, 0x00,
+
+ /* U+0077 "w" */
+ 0x8C, 0x6B, 0x55, 0x00,
+
+ /* U+0078 "x" */
+ 0x8A, 0x88, 0xA8, 0x80,
+
+ /* U+0079 "y" */
+ 0x8C, 0x63, 0x17, 0x85, 0xC0,
+
+ /* U+007A "z" */
+ 0xF8, 0x88, 0x8F, 0x80,
+
+ /* U+007B "{" */
+ 0x29, 0x44, 0x88,
+
+ /* U+007C "|" */
+ 0xFE,
+
+ /* U+007D "}" */
+ 0x89, 0x14, 0xA0,
+
+ /* U+007E "~" */
+ 0x4D, 0x80,
+};
+
+static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 96, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0} /* U+0020 */,
+ {.bitmap_index = 1, .adv_w = 96, .box_w = 1, .box_h = 7, .ofs_x = 2, .ofs_y = 0} /* U+0021 */,
+ {.bitmap_index = 2, .adv_w = 96, .box_w = 3, .box_h = 3, .ofs_x = 1, .ofs_y = 4} /* U+0022 */,
+ {.bitmap_index = 4, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0023 */,
+ {.bitmap_index = 8, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0024 */,
+ {.bitmap_index = 13, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0025 */,
+ {.bitmap_index = 18, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0026 */,
+ {.bitmap_index = 23, .adv_w = 96, .box_w = 1, .box_h = 3, .ofs_x = 2, .ofs_y = 4} /* U+0027 */,
+ {.bitmap_index = 24, .adv_w = 96, .box_w = 2, .box_h = 7, .ofs_x = 2, .ofs_y = 0} /* U+0028 */,
+ {.bitmap_index = 26, .adv_w = 96, .box_w = 2, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0029 */,
+ {.bitmap_index = 28, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 1} /* U+002A */,
+ {.bitmap_index = 32, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 1} /* U+002B */,
+ {.bitmap_index = 36, .adv_w = 96, .box_w = 2, .box_h = 3, .ofs_x = 1, .ofs_y = -1} /* U+002C */,
+ {.bitmap_index = 37, .adv_w = 96, .box_w = 5, .box_h = 1, .ofs_x = 0, .ofs_y = 3} /* U+002D */,
+ {.bitmap_index = 38, .adv_w = 96, .box_w = 1, .box_h = 2, .ofs_x = 2, .ofs_y = 0} /* U+002E */,
+ {.bitmap_index = 39, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+002F */,
+ {.bitmap_index = 44, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0030 */,
+ {.bitmap_index = 49, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0031 */,
+ {.bitmap_index = 54, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0032 */,
+ {.bitmap_index = 59, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0033 */,
+ {.bitmap_index = 64, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0034 */,
+ {.bitmap_index = 69, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0035 */,
+ {.bitmap_index = 74, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0036 */,
+ {.bitmap_index = 79, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0037 */,
+ {.bitmap_index = 84, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0038 */,
+ {.bitmap_index = 89, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0039 */,
+ {.bitmap_index = 94, .adv_w = 96, .box_w = 1, .box_h = 6, .ofs_x = 2, .ofs_y = 0} /* U+003A */,
+ {.bitmap_index = 95, .adv_w = 96, .box_w = 2, .box_h = 7, .ofs_x = 1, .ofs_y = -1} /* U+003B */,
+ {.bitmap_index = 97, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 1} /* U+003C */,
+ {.bitmap_index = 101, .adv_w = 96, .box_w = 5, .box_h = 3, .ofs_x = 0, .ofs_y = 2} /* U+003D */,
+ {.bitmap_index = 103, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 1} /* U+003E */,
+ {.bitmap_index = 107, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+003F */,
+ {.bitmap_index = 112, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0040 */,
+ {.bitmap_index = 117, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0041 */,
+ {.bitmap_index = 122, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0042 */,
+ {.bitmap_index = 127, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0043 */,
+ {.bitmap_index = 132, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0044 */,
+ {.bitmap_index = 137, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0045 */,
+ {.bitmap_index = 142, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0046 */,
+ {.bitmap_index = 147, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0047 */,
+ {.bitmap_index = 152, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0048 */,
+ {.bitmap_index = 157, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0049 */,
+ {.bitmap_index = 162, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+004A */,
+ {.bitmap_index = 167, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+004B */,
+ {.bitmap_index = 172, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+004C */,
+ {.bitmap_index = 177, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+004D */,
+ {.bitmap_index = 182, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+004E */,
+ {.bitmap_index = 187, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+004F */,
+ {.bitmap_index = 192, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0050 */,
+ {.bitmap_index = 197, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -1} /* U+0051 */,
+ {.bitmap_index = 202, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0052 */,
+ {.bitmap_index = 207, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0053 */,
+ {.bitmap_index = 212, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0054 */,
+ {.bitmap_index = 217, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0055 */,
+ {.bitmap_index = 222, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0056 */,
+ {.bitmap_index = 227, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0057 */,
+ {.bitmap_index = 232, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0058 */,
+ {.bitmap_index = 237, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0059 */,
+ {.bitmap_index = 242, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+005A */,
+ {.bitmap_index = 247, .adv_w = 96, .box_w = 2, .box_h = 7, .ofs_x = 2, .ofs_y = 0} /* U+005B */,
+ {.bitmap_index = 249, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+005C */,
+ {.bitmap_index = 254, .adv_w = 96, .box_w = 2, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+005D */,
+ {.bitmap_index = 256, .adv_w = 96, .box_w = 5, .box_h = 3, .ofs_x = 0, .ofs_y = 4} /* U+005E */,
+ {.bitmap_index = 258, .adv_w = 96, .box_w = 5, .box_h = 1, .ofs_x = 0, .ofs_y = 0} /* U+005F */,
+ {.bitmap_index = 259, .adv_w = 96, .box_w = 2, .box_h = 2, .ofs_x = 1, .ofs_y = 5} /* U+0060 */,
+ {.bitmap_index = 260, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0061 */,
+ {.bitmap_index = 264, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0062 */,
+ {.bitmap_index = 269, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0063 */,
+ {.bitmap_index = 273, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0064 */,
+ {.bitmap_index = 278, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0065 */,
+ {.bitmap_index = 282, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0066 */,
+ {.bitmap_index = 287, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0067 */,
+ {.bitmap_index = 292, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0068 */,
+ {.bitmap_index = 297, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0069 */,
+ {.bitmap_index = 302, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+006A */,
+ {.bitmap_index = 308, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+006B */,
+ {.bitmap_index = 313, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+006C */,
+ {.bitmap_index = 318, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+006D */,
+ {.bitmap_index = 322, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+006E */,
+ {.bitmap_index = 326, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+006F */,
+ {.bitmap_index = 330, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0070 */,
+ {.bitmap_index = 335, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0071 */,
+ {.bitmap_index = 340, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0072 */,
+ {.bitmap_index = 344, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0073 */,
+ {.bitmap_index = 348, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0074 */,
+ {.bitmap_index = 353, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0075 */,
+ {.bitmap_index = 357, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0076 */,
+ {.bitmap_index = 361, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0077 */,
+ {.bitmap_index = 365, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0078 */,
+ {.bitmap_index = 369, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0079 */,
+ {.bitmap_index = 374, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+007A */,
+ {.bitmap_index = 378, .adv_w = 96, .box_w = 3, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+007B */,
+ {.bitmap_index = 381, .adv_w = 96, .box_w = 1, .box_h = 7, .ofs_x = 2, .ofs_y = 0} /* U+007C */,
+ {.bitmap_index = 382, .adv_w = 96, .box_w = 3, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+007D */,
+ {.bitmap_index = 385, .adv_w = 96, .box_w = 5, .box_h = 2, .ofs_x = 0, .ofs_y = 5} /* U+007E */
+};
+
+static const lv_font_fmt_txt_cmap_t cmaps[] = {
+ {.range_start = 32, .range_length = 95, .glyph_id_start = 1,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}
+};
+
+static const lv_font_fmt_txt_dsc_t font_dsc = {
+ .glyph_bitmap = glyph_bitmap,
+ .glyph_dsc = glyph_dsc,
+ .cmaps = cmaps,
+ .kern_dsc = NULL,
+ .kern_scale = 0,
+ .cmap_num = 1,
+ .bpp = 1,
+ .kern_classes = 0,
+ .bitmap_format = 0,
+ .stride = 0,
+};
+
+const UG_FONT font_monogram_16 = {
+ .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,
+ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,
+ .line_height = 9,
+ .base_line = 2,
+ .subpx = LV_FONT_SUBPX_NONE,
+ .underline_position = -1,
+ .underline_thickness = 0,
+ .static_bitmap = 0,
+ .dsc = &font_dsc,
+ .fallback = NULL,
+ .user_data = NULL,
+};
+
+#endif /* MONOGRAM_16 */
### src/ui/fonts/monogram_16.h
@@ -0,0 +1,8 @@
+#ifndef TTF2LVGL_MONOGRAM_16_H
+#define TTF2LVGL_MONOGRAM_16_H
+
+#include <ugui.h>
+
+extern const UG_FONT font_monogram_16;
+
+#endif /* TTF2LVGL_MONOGRAM_16_H */
### src/ui/fonts/monogram_16_bootloader.c
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Size: 16 px
+ * Bpp: 1
+ * Opts: --dump --bpp 1 --size 16 --font src/ui/fonts/monogram.ttf --range 32,48-57,97-102 --name monogram_16 --output src/ui/fonts/monogram_16_bootloader.c
+ ******************************************************************************/
+
+#ifdef __has_include
+ #if __has_include("lvgl.h")
+ #ifndef LV_LVGL_H_INCLUDE_SIMPLE
+ #define LV_LVGL_H_INCLUDE_SIMPLE
+ #endif
+ #endif
+#endif
+
+#ifdef LV_LVGL_H_INCLUDE_SIMPLE
+ #include "lvgl.h"
+#else
+ #include "lvgl/lvgl.h"
+#endif
+
+#include "monogram_16_bootloader.h"
+
+#ifndef MONOGRAM_16
+#define MONOGRAM_16 1
+#endif
+
+#if MONOGRAM_16
+
+static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
+ /* U+0020 "\u0020" */
+ 0x00,
+
+ /* U+0030 "0" */
+ 0x74, 0x67, 0x5C, 0xC5, 0xC0,
+
+ /* U+0031 "1" */
+ 0x23, 0x08, 0x42, 0x13, 0xE0,
+
+ /* U+0032 "2" */
+ 0x74, 0x42, 0x22, 0x23, 0xE0,
+
+ /* U+0033 "3" */
+ 0x74, 0x42, 0x60, 0xC5, 0xC0,
+
+ /* U+0034 "4" */
+ 0x4A, 0x63, 0xF0, 0x84, 0x20,
+
+ /* U+0035 "5" */
+ 0xFC, 0x3C, 0x10, 0xC5, 0xC0,
+
+ /* U+0036 "6" */
+ 0x74, 0x21, 0xE8, 0xC5, 0xC0,
+
+ /* U+0037 "7" */
+ 0xF8, 0x42, 0x22, 0x10, 0x80,
+
+ /* U+0038 "8" */
+ 0x74, 0x62, 0xE8, 0xC5, 0xC0,
+
+ /* U+0039 "9" */
+ 0x74, 0x62, 0xF0, 0xC5, 0xC0,
+
+ /* U+0061 "a" */
+ 0x7C, 0x63, 0x17, 0x80,
+
+ /* U+0062 "b" */
+ 0x84, 0x3D, 0x18, 0xC7, 0xC0,
+
+ /* U+0063 "c" */
+ 0x74, 0x61, 0x17, 0x00,
+
+ /* U+0064 "d" */
+ 0x08, 0x5F, 0x18, 0xC5, 0xE0,
+
+ /* U+0065 "e" */
+ 0x74, 0x7F, 0x07, 0x00,
+
+ /* U+0066 "f" */
+ 0x32, 0x51, 0xE4, 0x21, 0x00,
+};
+
+static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 96, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0} /* U+0020 */,
+ {.bitmap_index = 1, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0030 */,
+ {.bitmap_index = 6, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0031 */,
+ {.bitmap_index = 11, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0032 */,
+ {.bitmap_index = 16, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0033 */,
+ {.bitmap_index = 21, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0034 */,
+ {.bitmap_index = 26, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0035 */,
+ {.bitmap_index = 31, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0036 */,
+ {.bitmap_index = 36, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0037 */,
+ {.bitmap_index = 41, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0038 */,
+ {.bitmap_index = 46, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0039 */,
+ {.bitmap_index = 51, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0061 */,
+ {.bitmap_index = 55, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0062 */,
+ {.bitmap_index = 60, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0063 */,
+ {.bitmap_index = 64, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0064 */,
+ {.bitmap_index = 69, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0065 */,
+ {.bitmap_index = 73, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0066 */
+};
+
+static const lv_font_fmt_txt_cmap_t cmaps[] = {
+ {.range_start = 32, .range_length = 1, .glyph_id_start = 1,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 48, .range_length = 10, .glyph_id_start = 2,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 97, .range_length = 6, .glyph_id_start = 12,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}
+};
+
+static const lv_font_fmt_txt_dsc_t font_dsc = {
+ .glyph_bitmap = glyph_bitmap,
+ .glyph_dsc = glyph_dsc,
+ .cmaps = cmaps,
+ .kern_dsc = NULL,
+ .kern_scale = 0,
+ .cmap_num = 3,
+ .bpp = 1,
+ .kern_classes = 0,
+ .bitmap_format = 0,
+ .stride = 0,
+};
+
+const UG_FONT font_monogram_16 = {
+ .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,
+ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,
+ .line_height = 9,
+ .base_line = 2,
+ .subpx = LV_FONT_SUBPX_NONE,
+ .underline_position = -1,
+ .underline_thickness = 0,
+ .static_bitmap = 0,
+ .dsc = &font_dsc,
+ .fallback = NULL,
+ .user_data = NULL,
+};
+
+#endif /* MONOGRAM_16 */
### src/ui/fonts/monogram_16_bootloader.h
@@ -0,0 +1,8 @@
+#ifndef TTF2LVGL_MONOGRAM_16_BOOTLOADER_H
+#define TTF2LVGL_MONOGRAM_16_BOOTLOADER_H
+
+#include <ugui.h>
+
+extern const UG_FONT font_monogram_16;
+
+#endif /* TTF2LVGL_MONOGRAM_16_BOOTLOADER_H */
### src/ui/fonts/monogram_5X9.c
@@ -1,107 +0,0 @@
-// Converted from /home/niklas/.local/share/fonts/monogram.ttf
-// --size 16
-// --bpp 1
-// For copyright, see original font file.
-
-#include <ugui.h>
-
-static UG_FONT_DATA unsigned char fontBits_monogram_5X9[95][9] = {
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x20 ' '
- {0x04,0x04,0x04,0x04,0x04,0x00,0x04,0x00,0x00 }, // 0x21 '!'
- {0x0A,0x0A,0x0A,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x22 '"'
- {0x00,0x0A,0x1F,0x0A,0x0A,0x1F,0x0A,0x00,0x00 }, // 0x23 '#'
- {0x04,0x1E,0x05,0x0E,0x14,0x0F,0x04,0x00,0x00 }, // 0x24 '$'
- {0x11,0x11,0x08,0x04,0x02,0x11,0x11,0x00,0x00 }, // 0x25 '%'
- {0x06,0x09,0x09,0x1E,0x09,0x09,0x16,0x00,0x00 }, // 0x26 '&'
- {0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x27 '''
- {0x08,0x04,0x04,0x04,0x04,0x04,0x08,0x00,0x00 }, // 0x28 '('
- {0x02,0x04,0x04,0x04,0x04,0x04,0x02,0x00,0x00 }, // 0x29 ')'
- {0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00,0x00 }, // 0x2A '*'
- {0x00,0x04,0x04,0x1F,0x04,0x04,0x00,0x00,0x00 }, // 0x2B '+'
- {0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x02,0x00 }, // 0x2C ','
- {0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00 }, // 0x2D '-'
- {0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x00,0x00 }, // 0x2E '.'
- {0x10,0x10,0x08,0x04,0x02,0x01,0x01,0x00,0x00 }, // 0x2F '/'
- {0x0E,0x11,0x19,0x15,0x13,0x11,0x0E,0x00,0x00 }, // 0x30 '0'
- {0x04,0x06,0x04,0x04,0x04,0x04,0x1F,0x00,0x00 }, // 0x31 '1'
- {0x0E,0x11,0x10,0x08,0x04,0x02,0x1F,0x00,0x00 }, // 0x32 '2'
- {0x0E,0x11,0x10,0x0C,0x10,0x11,0x0E,0x00,0x00 }, // 0x33 '3'
- {0x12,0x12,0x11,0x1F,0x10,0x10,0x10,0x00,0x00 }, // 0x34 '4'
- {0x1F,0x01,0x0F,0x10,0x10,0x11,0x0E,0x00,0x00 }, // 0x35 '5'
- {0x0E,0x01,0x01,0x0F,0x11,0x11,0x0E,0x00,0x00 }, // 0x36 '6'
- {0x1F,0x10,0x10,0x08,0x04,0x04,0x04,0x00,0x00 }, // 0x37 '7'
- {0x0E,0x11,0x11,0x0E,0x11,0x11,0x0E,0x00,0x00 }, // 0x38 '8'
- {0x0E,0x11,0x11,0x1E,0x10,0x11,0x0E,0x00,0x00 }, // 0x39 '9'
- {0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x00 }, // 0x3A ':'
- {0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x02,0x00 }, // 0x3B ';'
- {0x00,0x18,0x06,0x01,0x06,0x18,0x00,0x00,0x00 }, // 0x3C '<'
- {0x00,0x00,0x1F,0x00,0x1F,0x00,0x00,0x00,0x00 }, // 0x3D '='
- {0x00,0x03,0x0C,0x10,0x0C,0x03,0x00,0x00,0x00 }, // 0x3E '>'
- {0x0E,0x11,0x10,0x08,0x04,0x00,0x04,0x00,0x00 }, // 0x3F '?'
- {0x0E,0x19,0x15,0x15,0x19,0x01,0x0E,0x00,0x00 }, // 0x40 '@'
- {0x0E,0x11,0x11,0x11,0x1F,0x11,0x11,0x00,0x00 }, // 0x41 'A'
- {0x0F,0x11,0x11,0x0F,0x11,0x11,0x0F,0x00,0x00 }, // 0x42 'B'
- {0x0E,0x11,0x01,0x01,0x01,0x11,0x0E,0x00,0x00 }, // 0x43 'C'
- {0x0F,0x11,0x11,0x11,0x11,0x11,0x0F,0x00,0x00 }, // 0x44 'D'
- {0x1F,0x01,0x01,0x0F,0x01,0x01,0x1F,0x00,0x00 }, // 0x45 'E'
- {0x1F,0x01,0x01,0x0F,0x01,0x01,0x01,0x00,0x00 }, // 0x46 'F'
- {0x0E,0x11,0x01,0x1D,0x11,0x11,0x0E,0x00,0x00 }, // 0x47 'G'
- {0x11,0x11,0x11,0x1F,0x11,0x11,0x11,0x00,0x00 }, // 0x48 'H'
- {0x1F,0x04,0x04,0x04,0x04,0x04,0x1F,0x00,0x00 }, // 0x49 'I'
- {0x10,0x10,0x10,0x10,0x11,0x11,0x0E,0x00,0x00 }, // 0x4A 'J'
- {0x11,0x09,0x05,0x03,0x05,0x09,0x11,0x00,0x00 }, // 0x4B 'K'
- {0x01,0x01,0x01,0x01,0x01,0x01,0x1F,0x00,0x00 }, // 0x4C 'L'
- {0x11,0x1B,0x15,0x11,0x11,0x11,0x11,0x00,0x00 }, // 0x4D 'M'
- {0x11,0x11,0x13,0x15,0x19,0x11,0x11,0x00,0x00 }, // 0x4E 'N'
- {0x0E,0x11,0x11,0x11,0x11,0x11,0x0E,0x00,0x00 }, // 0x4F 'O'
- {0x0F,0x11,0x11,0x0F,0x01,0x01,0x01,0x00,0x00 }, // 0x50 'P'
- {0x0E,0x11,0x11,0x11,0x11,0x11,0x0E,0x18,0x00 }, // 0x51 'Q'
- {0x0F,0x11,0x11,0x0F,0x11,0x11,0x11,0x00,0x00 }, // 0x52 'R'
- {0x0E,0x11,0x01,0x0E,0x10,0x11,0x0E,0x00,0x00 }, // 0x53 'S'
- {0x1F,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x00 }, // 0x54 'T'
- {0x11,0x11,0x11,0x11,0x11,0x11,0x0E,0x00,0x00 }, // 0x55 'U'
- {0x11,0x11,0x11,0x11,0x0A,0x0A,0x04,0x00,0x00 }, // 0x56 'V'
- {0x11,0x11,0x11,0x11,0x15,0x1B,0x11,0x00,0x00 }, // 0x57 'W'
- {0x11,0x11,0x0A,0x04,0x0A,0x11,0x11,0x00,0x00 }, // 0x58 'X'
- {0x11,0x11,0x0A,0x04,0x04,0x04,0x04,0x00,0x00 }, // 0x59 'Y'
- {0x1F,0x10,0x08,0x04,0x02,0x01,0x1F,0x00,0x00 }, // 0x5A 'Z'
- {0x0C,0x04,0x04,0x04,0x04,0x04,0x0C,0x00,0x00 }, // 0x5B '['
- {0x01,0x01,0x02,0x04,0x08,0x10,0x10,0x00,0x00 }, // 0x5C '\'
- {0x06,0x04,0x04,0x04,0x04,0x04,0x06,0x00,0x00 }, // 0x5D ']'
- {0x04,0x0A,0x11,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x5E '^'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00 }, // 0x5F '_'
- {0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x60 '`'
- {0x00,0x00,0x1E,0x11,0x11,0x11,0x1E,0x00,0x00 }, // 0x61 'a'
- {0x01,0x01,0x0F,0x11,0x11,0x11,0x0F,0x00,0x00 }, // 0x62 'b'
- {0x00,0x00,0x0E,0x11,0x01,0x11,0x0E,0x00,0x00 }, // 0x63 'c'
- {0x10,0x10,0x1E,0x11,0x11,0x11,0x1E,0x00,0x00 }, // 0x64 'd'
- {0x00,0x00,0x0E,0x11,0x1F,0x01,0x0E,0x00,0x00 }, // 0x65 'e'
- {0x0C,0x12,0x02,0x0F,0x02,0x02,0x02,0x00,0x00 }, // 0x66 'f'
- {0x00,0x00,0x1E,0x11,0x11,0x11,0x1E,0x10,0x0E }, // 0x67 'g'
- {0x01,0x01,0x0F,0x11,0x11,0x11,0x11,0x00,0x00 }, // 0x68 'h'
- {0x04,0x00,0x06,0x04,0x04,0x04,0x1F,0x00,0x00 }, // 0x69 'i'
- {0x10,0x00,0x18,0x10,0x10,0x10,0x10,0x11,0x0E }, // 0x6A 'j'
- {0x01,0x01,0x11,0x09,0x07,0x09,0x11,0x00,0x00 }, // 0x6B 'k'
- {0x03,0x02,0x02,0x02,0x02,0x02,0x1C,0x00,0x00 }, // 0x6C 'l'
- {0x00,0x00,0x0F,0x15,0x15,0x15,0x15,0x00,0x00 }, // 0x6D 'm'
- {0x00,0x00,0x0F,0x11,0x11,0x11,0x11,0x00,0x00 }, // 0x6E 'n'
- {0x00,0x00,0x0E,0x11,0x11,0x11,0x0E,0x00,0x00 }, // 0x6F 'o'
- {0x00,0x00,0x0F,0x11,0x11,0x11,0x0F,0x01,0x01 }, // 0x70 'p'
- {0x00,0x00,0x1E,0x11,0x11,0x11,0x1E,0x10,0x10 }, // 0x71 'q'
- {0x00,0x00,0x0D,0x13,0x01,0x01,0x01,0x00,0x00 }, // 0x72 'r'
- {0x00,0x00,0x1E,0x01,0x0E,0x10,0x0F,0x00,0x00 }, // 0x73 's'
- {0x02,0x02,0x0F,0x02,0x02,0x02,0x1C,0x00,0x00 }, // 0x74 't'
- {0x00,0x00,0x11,0x11,0x11,0x11,0x1E,0x00,0x00 }, // 0x75 'u'
- {0x00,0x00,0x11,0x11,0x11,0x0A,0x04,0x00,0x00 }, // 0x76 'v'
- {0x00,0x00,0x11,0x11,0x15,0x15,0x0A,0x00,0x00 }, // 0x77 'w'
- {0x00,0x00,0x11,0x0A,0x04,0x0A,0x11,0x00,0x00 }, // 0x78 'x'
- {0x00,0x00,0x11,0x11,0x11,0x11,0x1E,0x10,0x0E }, // 0x79 'y'
- {0x00,0x00,0x1F,0x08,0x04,0x02,0x1F,0x00,0x00 }, // 0x7A 'z'
- {0x08,0x04,0x04,0x02,0x04,0x04,0x08,0x00,0x00 }, // 0x7B '{'
- {0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x00 }, // 0x7C '|'
- {0x02,0x04,0x04,0x08,0x04,0x04,0x02,0x00,0x00 }, // 0x7D '}'
- {0x12,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } // 0x7E '~'
-};
-static UG_U8 fontWidths_monogram_5X9[] = {
-6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6};
-const UG_FONT font_monogram_5X9 = { (unsigned char*)fontBits_monogram_5X9, FONT_TYPE_1BPP, 5, 9, 32, 126, fontWidths_monogram_5X9 };
### src/ui/fonts/monogram_5X9.h
@@ -1,3 +0,0 @@
-#include <ugui.h>
-
-extern const UG_FONT font_monogram_5X9;
### src/ui/fonts/password_11X12.c
@@ -1,105 +0,0 @@
-// This is a copy of font_a_11X12.c with a modified space character
-
-#include <ugui.h>
-
-static UG_FONT_DATA unsigned char fontBits_password_11X12[95][24] = {
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x7F, 0x00, 0x00, 0x00 }, // 0x20 (0x2423) '#'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x21 '!'
- {0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x22 '"'
- {0x28, 0x00, 0x28, 0x00, 0x7F, 0x00, 0x14, 0x00, 0x14, 0x00, 0x7F, 0x00, 0x14, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x23 '#'
- {0x1C, 0x00, 0x2A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x1C, 0x00, 0x28, 0x00, 0x2A, 0x00, 0x2A, 0x00, 0x1C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x24 '$'
- {0x8C, 0x00, 0x52, 0x00, 0x52, 0x00, 0x32, 0x00, 0xAC, 0x01, 0x60, 0x02, 0x50, 0x02, 0x50, 0x02, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x25 '%'
- {0x18, 0x00, 0x24, 0x00, 0x24, 0x00, 0x14, 0x00, 0x0C, 0x00, 0x52, 0x00, 0x22, 0x00, 0x62, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x26 '&'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x27 '''
- {0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00 }, // 0x28 '('
- {0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00 }, // 0x29 ')'
- {0x04, 0x00, 0x1F, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2A '*'
- {0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x3E, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2B '+'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x2C ','
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2D '-'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2E '.'
- {0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x2F '/'
- {0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x30 '0'
- {0x08, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x31 '1'
- {0x1C, 0x00, 0x22, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x32 '2'
- {0x1C, 0x00, 0x22, 0x00, 0x20, 0x00, 0x20, 0x00, 0x18, 0x00, 0x20, 0x00, 0x20, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x33 '3'
- {0x10, 0x00, 0x18, 0x00, 0x18, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x3E, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x34 '4'
- {0x3C, 0x00, 0x04, 0x00, 0x02, 0x00, 0x1E, 0x00, 0x22, 0x00, 0x20, 0x00, 0x20, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x35 '5'
- {0x1C, 0x00, 0x22, 0x00, 0x02, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x36 '6'
- {0x3E, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x37 '7'
- {0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x38 '8'
- {0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2C, 0x00, 0x20, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x39 '9'
- {0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3A ':'
- {0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x3B ';'
- {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x1C, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3C '<'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3D '='
- {0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x20, 0x00, 0x1C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3E '>'
- {0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x3F '?'
- {0xE0, 0x01, 0x18, 0x06, 0x04, 0x04, 0x64, 0x09, 0x92, 0x09, 0x8A, 0x08, 0x8A, 0x08, 0x8A, 0x04, 0xF2, 0x03, 0x04, 0x08, 0x08, 0x06, 0xF0, 0x01 }, // 0x40 '@'
- {0x08, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x22, 0x00, 0x3E, 0x00, 0x22, 0x00, 0x41, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x41 'A'
- {0x3E, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x7E, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x42 'B'
- {0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x43 'C'
- {0x3E, 0x00, 0x42, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x42, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x44 'D'
- {0x7E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x45 'E'
- {0x3E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x1E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x46 'F'
- {0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x02, 0x00, 0xE2, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x47 'G'
- {0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0xFE, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x48 'H'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x49 'I'
- {0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4A 'J'
- {0x82, 0x00, 0x42, 0x00, 0x22, 0x00, 0x12, 0x00, 0x0A, 0x00, 0x16, 0x00, 0x22, 0x00, 0x42, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4B 'K'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4C 'L'
- {0x82, 0x00, 0xC6, 0x00, 0xC6, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x92, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4D 'M'
- {0x82, 0x00, 0x86, 0x00, 0x8A, 0x00, 0x8A, 0x00, 0x92, 0x00, 0xA2, 0x00, 0xA2, 0x00, 0xC2, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4E 'N'
- {0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x4F 'O'
- {0x3E, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x50 'P'
- {0x38, 0x00, 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0xB2, 0x00, 0x44, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x51 'Q'
- {0x7E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x7E, 0x00, 0x22, 0x00, 0x42, 0x00, 0x42, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x52 'R'
- {0x3C, 0x00, 0x42, 0x00, 0x42, 0x00, 0x02, 0x00, 0x3C, 0x00, 0x40, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x53 'S'
- {0x7F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x54 'T'
- {0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x55 'U'
- {0x41, 0x00, 0x41, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x56 'V'
- {0x21, 0x04, 0x51, 0x04, 0x51, 0x02, 0x52, 0x02, 0x8A, 0x02, 0x8A, 0x02, 0x8A, 0x02, 0x04, 0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x57 'W'
- {0x41, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x08, 0x00, 0x14, 0x00, 0x22, 0x00, 0x22, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x58 'X'
- {0x41, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x59 'Y'
- {0x7E, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5A 'Z'
- {0x06, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00 }, // 0x5B '['
- {0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5C '\'
- {0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00 }, // 0x5D ']'
- {0x04, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x5E '^'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00 }, // 0x5F '_'
- {0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x60 '`'
- {0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x20, 0x00, 0x3C, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x61 'a'
- {0x02, 0x00, 0x02, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x26, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x62 'b'
- {0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x12, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x12, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x63 'c'
- {0x20, 0x00, 0x20, 0x00, 0x2C, 0x00, 0x32, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x64 'd'
- {0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x3E, 0x00, 0x02, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x65 'e'
- {0x0C, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x66 'f'
- {0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x32, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2C, 0x00, 0x20, 0x00, 0x1E, 0x00, 0x00, 0x00 }, // 0x67 'g'
- {0x02, 0x00, 0x02, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x68 'h'
- {0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x69 'i'
- {0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00 }, // 0x6A 'j'
- {0x02, 0x00, 0x02, 0x00, 0x22, 0x00, 0x12, 0x00, 0x0A, 0x00, 0x0E, 0x00, 0x12, 0x00, 0x12, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6B 'k'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6C 'l'
- {0x00, 0x00, 0x00, 0x00, 0x9A, 0x01, 0x66, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6D 'm'
- {0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6E 'n'
- {0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x6F 'o'
- {0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x26, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x26, 0x00, 0x1A, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x70 'p'
- {0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x32, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x32, 0x00, 0x2C, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00 }, // 0x71 'q'
- {0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x72 'r'
- {0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x20, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x73 's'
- {0x02, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x74 't'
- {0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x75 'u'
- {0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x76 'v'
- {0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x11, 0x01, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x44, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x77 'w'
- {0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x78 'x'
- {0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x79 'y'
- {0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0x7A 'z'
- {0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00 }, // 0x7B '{'
- {0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x7C '|'
- {0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00 }, // 0x7D '}'
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // 0x7E '~'
-};
-static UG_U8 fontWidths_password_11X12[] = {
- 7, 3, 4, 7, 7, 11, 8, 2, 4, 4, 5, 7, 3, 4, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 7, 7, 7, 7, 12, 7, 8, 9, 9, 8, 7, 9, 9, 3, 6, 8, 7, 9, 9, 9, 8, 9, 9, 8, 7, 9, 7, 11, 7, 7, 7, 3, 3, 3, 5, 7, 4, 7, 7, 6, 7, 7, 3, 7, 7, 3, 3, 6, 3, 11, 7, 7, 7, 7, 4, 7, 3, 7, 5, 9, 5, 5, 5, 4, 3, 4, 7
-};
-const UG_FONT font_password_11X12 = { (unsigned char *)fontBits_password_11X12, FONT_TYPE_1BPP, 11, 12, 32, 126, fontWidths_password_11X12 };
### src/ui/fonts/password_11X12.h
@@ -1,5 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-#include <ugui.h>
-
-extern const UG_FONT font_password_11X12;
### src/ui/fonts/password_12.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: Apache-2.0
+
+#include "regular_12.h"
+#include "lvgl.h"
+#include "password_12.h"
+
+#include <stdint.h>
+
+static const uint8_t glyph_bitmap[] = {
+ /* U+0020 " " rendered as a visible U-shaped space */
+ 0x83, 0x06, 0x0F, 0xF0,
+};
+
+static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 0, .adv_w = 112, .box_w = 7, .box_h = 4, .ofs_x = 0, .ofs_y = -2},
+};
+
+static const lv_font_fmt_txt_cmap_t cmaps[] = {
+ {.range_start = 32,
+ .range_length = 1,
+ .glyph_id_start = 1,
+ .unicode_list = NULL,
+ .glyph_id_ofs_list = NULL,
+ .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+};
+
+static const lv_font_fmt_txt_dsc_t font_dsc = {
+ .glyph_bitmap = glyph_bitmap,
+ .glyph_dsc = glyph_dsc,
+ .cmaps = cmaps,
+ .kern_dsc = NULL,
+ .kern_scale = 0,
+ .cmap_num = 1,
+ .bpp = 1,
+ .kern_classes = 0,
+ .bitmap_format = 0,
+ .stride = 0,
+};
+
+const UG_FONT font_password_12 = {
+ .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,
+ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,
+ .line_height = 12,
+ .base_line = 3,
+ .subpx = LV_FONT_SUBPX_NONE,
+ .underline_position = -1,
+ .underline_thickness = 0,
+ .static_bitmap = 0,
+ .dsc = &font_dsc,
+ .fallback = &font_regular_12,
+ .user_data = NULL,
+};
### src/ui/fonts/password_12.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef UI_FONTS_PASSWORD_12_H
+#define UI_FONTS_PASSWORD_12_H
+
+#include <ugui.h>
+
+extern const UG_FONT font_password_12;
+
+#endif /* UI_FONTS_PASSWORD_12_H */
### src/ui/fonts/password_9.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: Apache-2.0
+
+#include "regular_9.h"
+#include "lvgl.h"
+#include "password_9.h"
+
+#include <stdint.h>
+
+static const uint8_t glyph_bitmap[] = {
+ /* U+0020 " " rendered as a visible U-shaped space */
+ 0x8C, 0x7E,
+};
+
+static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 0, .adv_w = 112, .box_w = 5, .box_h = 3, .ofs_x = 1, .ofs_y = -2},
+};
+
+static const lv_font_fmt_txt_cmap_t cmaps[] = {
+ {.range_start = 32,
+ .range_length = 1,
+ .glyph_id_start = 1,
+ .unicode_list = NULL,
+ .glyph_id_ofs_list = NULL,
+ .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+};
+
+static const lv_font_fmt_txt_dsc_t font_dsc = {
+ .glyph_bitmap = glyph_bitmap,
+ .glyph_dsc = glyph_dsc,
+ .cmaps = cmaps,
+ .kern_dsc = NULL,
+ .kern_scale = 0,
+ .cmap_num = 1,
+ .bpp = 1,
+ .kern_classes = 0,
+ .bitmap_format = 0,
+ .stride = 0,
+};
+
+const UG_FONT font_password_9 = {
+ .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,
+ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,
+ .line_height = 9,
+ .base_line = 2,
+ .subpx = LV_FONT_SUBPX_NONE,
+ .underline_position = -1,
+ .underline_thickness = 0,
+ .static_bitmap = 0,
+ .dsc = &font_dsc,
+ .fallback = &font_regular_9,
+ .user_data = NULL,
+};
### src/ui/fonts/password_9.h
@@ -0,0 +1,8 @@
+#ifndef UI_FONTS_PASSWORD_9_H
+#define UI_FONTS_PASSWORD_9_H
+
+#include <ugui.h>
+
+extern const UG_FONT font_password_9;
+
+#endif /* UI_FONTS_PASSWORD_9_H */
### src/ui/fonts/password_9X9.c
@@ -1,104 +0,0 @@
-// This is a copy of font_a_9X9.c with a modified space character
-
-#include <ugui.h>
-
-static UG_FONT_DATA unsigned char fontBits_password_9X9[95][18] = {
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x00,0x22,0x00,0x3E,0x00 }, // 0x20 (0x2423) '#'
- {0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x21 '!'
- {0x05,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x22 '"'
- {0x0A,0x00,0x0A,0x00,0x0F,0x00,0x0A,0x00,0x0F,0x00,0x05,0x00,0x05,0x00,0x00,0x00,0x00,0x00 }, // 0x23 '#'
- {0x0E,0x00,0x15,0x00,0x05,0x00,0x0E,0x00,0x14,0x00,0x15,0x00,0x0E,0x00,0x04,0x00,0x00,0x00 }, // 0x24 '$'
- {0x24,0x00,0x1A,0x00,0x14,0x00,0x10,0x00,0x28,0x00,0x58,0x00,0x28,0x00,0x00,0x00,0x00,0x00 }, // 0x25 '%'
- {0x0C,0x00,0x12,0x00,0x12,0x00,0x0E,0x00,0x29,0x00,0x11,0x00,0x2E,0x00,0x00,0x00,0x00,0x00 }, // 0x26 '&'
- {0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x27 '''
- {0x04,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x04,0x00 }, // 0x28 '('
- {0x01,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x01,0x00 }, // 0x29 ')'
- {0x07,0x00,0x02,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2A '*'
- {0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1F,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x2B '+'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x00,0x00 }, // 0x2C ','
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x2D '-'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x2E '.'
- {0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x2F '/'
- {0x06,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x30 '0'
- {0x04,0x00,0x06,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x31 '1'
- {0x06,0x00,0x09,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x0F,0x00,0x00,0x00,0x00,0x00 }, // 0x32 '2'
- {0x06,0x00,0x09,0x00,0x08,0x00,0x04,0x00,0x08,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x33 '3'
- {0x08,0x00,0x0C,0x00,0x0A,0x00,0x09,0x00,0x1F,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00 }, // 0x34 '4'
- {0x0E,0x00,0x02,0x00,0x07,0x00,0x09,0x00,0x08,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x35 '5'
- {0x06,0x00,0x09,0x00,0x07,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x36 '6'
- {0x0F,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x37 '7'
- {0x06,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x38 '8'
- {0x06,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x39 '9'
- {0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x3A ':'
- {0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x00,0x00 }, // 0x3B ';'
- {0x00,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3C '<'
- {0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3D '='
- {0x00,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x3E '>'
- {0x0E,0x00,0x11,0x00,0x10,0x00,0x0C,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x3F '?'
- {0x78,0x00,0x84,0x00,0x52,0x01,0x6A,0x01,0x2A,0x01,0xAA,0x00,0x7A,0x00,0x84,0x01,0x78,0x00 }, // 0x40 '@'
- {0x08,0x00,0x14,0x00,0x22,0x00,0x22,0x00,0x3E,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00 }, // 0x41 'A'
- {0x0E,0x00,0x12,0x00,0x12,0x00,0x1E,0x00,0x12,0x00,0x12,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x42 'B'
- {0x1C,0x00,0x22,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x43 'C'
- {0x1E,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x1E,0x00,0x00,0x00,0x00,0x00 }, // 0x44 'D'
- {0x3E,0x00,0x02,0x00,0x02,0x00,0x3E,0x00,0x02,0x00,0x02,0x00,0x3E,0x00,0x00,0x00,0x00,0x00 }, // 0x45 'E'
- {0x1E,0x00,0x02,0x00,0x02,0x00,0x0E,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x46 'F'
- {0x1C,0x00,0x22,0x00,0x02,0x00,0x32,0x00,0x22,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x47 'G'
- {0x22,0x00,0x22,0x00,0x22,0x00,0x3E,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00 }, // 0x48 'H'
- {0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x49 'I'
- {0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x09,0x00,0x07,0x00,0x00,0x00,0x00,0x00 }, // 0x4A 'J'
- {0x22,0x00,0x12,0x00,0x0A,0x00,0x06,0x00,0x0A,0x00,0x12,0x00,0x22,0x00,0x00,0x00,0x00,0x00 }, // 0x4B 'K'
- {0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x1E,0x00,0x00,0x00,0x00,0x00 }, // 0x4C 'L'
- {0x41,0x00,0x63,0x00,0x63,0x00,0x55,0x00,0x55,0x00,0x55,0x00,0x49,0x00,0x00,0x00,0x00,0x00 }, // 0x4D 'M'
- {0x22,0x00,0x26,0x00,0x26,0x00,0x2A,0x00,0x32,0x00,0x32,0x00,0x22,0x00,0x00,0x00,0x00,0x00 }, // 0x4E 'N'
- {0x1C,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x4F 'O'
- {0x1E,0x00,0x12,0x00,0x12,0x00,0x1E,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x50 'P'
- {0x1C,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x12,0x00,0x3C,0x00,0x00,0x00,0x00,0x00 }, // 0x51 'Q'
- {0x1E,0x00,0x22,0x00,0x22,0x00,0x1E,0x00,0x12,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00 }, // 0x52 'R'
- {0x0C,0x00,0x12,0x00,0x02,0x00,0x0C,0x00,0x10,0x00,0x12,0x00,0x0C,0x00,0x00,0x00,0x00,0x00 }, // 0x53 'S'
- {0x1F,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x54 'T'
- {0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00 }, // 0x55 'U'
- {0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x00 }, // 0x56 'V'
- {0x11,0x01,0x29,0x01,0xAA,0x00,0xAA,0x00,0xAA,0x00,0xAA,0x00,0x44,0x00,0x00,0x00,0x00,0x00 }, // 0x57 'W'
- {0x11,0x00,0x0A,0x00,0x0A,0x00,0x04,0x00,0x0A,0x00,0x0A,0x00,0x11,0x00,0x00,0x00,0x00,0x00 }, // 0x58 'X'
- {0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00 }, // 0x59 'Y'
- {0x3F,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x3F,0x00,0x00,0x00,0x00,0x00 }, // 0x5A 'Z'
- {0x06,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x06,0x00 }, // 0x5B '['
- {0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x5C '\'
- {0x03,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x03,0x00 }, // 0x5D ']'
- {0x02,0x00,0x05,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x5E '^'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00 }, // 0x5F '_'
- {0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0x60 '`'
- {0x00,0x00,0x00,0x00,0x0F,0x00,0x08,0x00,0x0E,0x00,0x09,0x00,0x0F,0x00,0x00,0x00,0x00,0x00 }, // 0x61 'a'
- {0x01,0x00,0x01,0x00,0x07,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x07,0x00,0x00,0x00,0x00,0x00 }, // 0x62 'b'
- {0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x00,0x01,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x63 'c'
- {0x08,0x00,0x08,0x00,0x0E,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x64 'd'
- {0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x00,0x0F,0x00,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x65 'e'
- {0x04,0x00,0x02,0x00,0x07,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00 }, // 0x66 'f'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x09,0x00,0x06,0x00 }, // 0x67 'g'
- {0x01,0x00,0x01,0x00,0x07,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00,0x00,0x00 }, // 0x68 'h'
- {0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x69 'i'
- {0x02,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00 }, // 0x6A 'j'
- {0x01,0x00,0x01,0x00,0x09,0x00,0x05,0x00,0x07,0x00,0x05,0x00,0x09,0x00,0x00,0x00,0x00,0x00 }, // 0x6B 'k'
- {0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x6C 'l'
- {0x00,0x00,0x00,0x00,0x3F,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x00,0x00,0x00,0x00 }, // 0x6D 'm'
- {0x00,0x00,0x00,0x00,0x07,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00,0x00,0x00 }, // 0x6E 'n'
- {0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x06,0x00,0x00,0x00,0x00,0x00 }, // 0x6F 'o'
- {0x00,0x00,0x00,0x00,0x07,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x07,0x00,0x01,0x00,0x01,0x00 }, // 0x70 'p'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x08,0x00,0x08,0x00 }, // 0x71 'q'
- {0x00,0x00,0x00,0x00,0x07,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }, // 0x72 'r'
- {0x00,0x00,0x00,0x00,0x0E,0x00,0x01,0x00,0x06,0x00,0x08,0x00,0x07,0x00,0x00,0x00,0x00,0x00 }, // 0x73 's'
- {0x00,0x00,0x01,0x00,0x03,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x03,0x00,0x00,0x00,0x00,0x00 }, // 0x74 't'
- {0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x0E,0x00,0x00,0x00,0x00,0x00 }, // 0x75 'u'
- {0x00,0x00,0x00,0x00,0x11,0x00,0x0A,0x00,0x0A,0x00,0x0A,0x00,0x04,0x00,0x00,0x00,0x00,0x00 }, // 0x76 'v'
- {0x00,0x00,0x00,0x00,0x15,0x00,0x15,0x00,0x15,0x00,0x15,0x00,0x0A,0x00,0x00,0x00,0x00,0x00 }, // 0x77 'w'
- {0x00,0x00,0x00,0x00,0x09,0x00,0x06,0x00,0x02,0x00,0x06,0x00,0x09,0x00,0x00,0x00,0x00,0x00 }, // 0x78 'x'
- {0x00,0x00,0x00,0x00,0x11,0x00,0x0A,0x00,0x0A,0x00,0x0A,0x00,0x04,0x00,0x04,0x00,0x02,0x00 }, // 0x79 'y'
- {0x00,0x00,0x00,0x00,0x07,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x07,0x00,0x00,0x00,0x00,0x00 }, // 0x7A 'z'
- {0x06,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x06,0x00 }, // 0x7B '{'
- {0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00 }, // 0x7C '|'
- {0x03,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x03,0x00 }, // 0x7D '}'
- {0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } // 0x7E '~'
-};
-static UG_U8 fontWidths_password_9X9[] = {
-7,3,3,5,5,8,6,2,3,3,4,5,3,3,3,3,5,5,5,5,5,5,5,5,5,5,3,3,5,5,5,5,9,6,6,7,7,6,6,7,7,3,5,6,5,7,7,7,6,7,7,6,5,7,6,9,5,7,6,3,3,3,3,5,3,5,5,5,5,5,4,5,5,2,3,5,2,8,5,5,5,5,3,5,3,5,6,6,5,6,4,3,3,3,5};
-UG_FONT font_password_9X9 = { (unsigned char*)fontBits_password_9X9, FONT_TYPE_1BPP, 9, 9, 32, 126, fontWidths_password_9X9 };
### src/ui/fonts/password_9X9.h
@@ -1,3 +0,0 @@
-#include <ugui.h>
-
-extern const UG_FONT font_password_9X9;
### src/ui/fonts/regular_11.c
@@ -0,0 +1,795 @@
+/*******************************************************************************
+ * Size: 11 px
+ * Bpp: 1
+ * Opts: --dump --bpp 1 --size 11 --dpi 72 --font /usr/share/fonts/truetype/msttcorefonts/Arial.ttf --range 32-126,161,167,170-171,176,186-187,191-194,196,198-207,209-212,214,217-220,223-226,228,230-239,241-244,246,249-252,255,338-339,376,8211-8212,8218,8222,8230,8249-8250,8364 --name regular_11 --output regular_11.c
+ ******************************************************************************/
+
+#ifdef __has_include
+ #if __has_include("lvgl.h")
+ #ifndef LV_LVGL_H_INCLUDE_SIMPLE
+ #define LV_LVGL_H_INCLUDE_SIMPLE
+ #endif
+ #endif
+#endif
+
+#ifdef LV_LVGL_H_INCLUDE_SIMPLE
+ #include "lvgl.h"
+#else
+ #include "lvgl/lvgl.h"
+#endif
+
+#include "regular_11.h"
+
+#ifndef REGULAR_11
+#define REGULAR_11 1
+#endif
+
+#if REGULAR_11
+
+static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
+ /* U+0020 "\u0020" */
+ 0x00,
+
+ /* U+0021 "!" */
+ 0xFD,
+
+ /* U+0022 "\"" */
+ 0xB6, 0x80,
+
+ /* U+0023 "#" */
+ 0x29, 0x7E, 0xA5, 0x7E, 0x94,
+
+ /* U+0024 "$" */
+ 0x75, 0x68, 0xE2, 0x96, 0xAE, 0x20,
+
+ /* U+0025 "%" */
+ 0x62, 0x4A, 0x25, 0x0D, 0x00, 0xB0, 0xA4, 0x52, 0x46,
+
+ /* U+0026 "&" */
+ 0x31, 0x24, 0x8C, 0x52, 0x38, 0x9D,
+
+ /* U+0027 "'" */
+ 0xE0,
+
+ /* U+0028 "(" */
+ 0x2A, 0x49, 0x24, 0x44,
+
+ /* U+0029 ")" */
+ 0x88, 0x92, 0x49, 0x50,
+
+ /* U+002A "*" */
+ 0x5D, 0x50,
+
+ /* U+002B "+" */
+ 0x21, 0x3E, 0x42, 0x00,
+
+ /* U+002C "," */
+ 0xE0,
+
+ /* U+002D "-" */
+ 0xE0,
+
+ /* U+002E "." */
+ 0x80,
+
+ /* U+002F "/" */
+ 0x25, 0x24, 0xA4,
+
+ /* U+0030 "0" */
+ 0x74, 0x63, 0x18, 0xC6, 0x2E,
+
+ /* U+0031 "1" */
+ 0x2E, 0x92, 0x49,
+
+ /* U+0032 "2" */
+ 0x74, 0x42, 0x11, 0x11, 0x1F,
+
+ /* U+0033 "3" */
+ 0x74, 0x42, 0x60, 0x86, 0x2E,
+
+ /* U+0034 "4" */
+ 0x11, 0x94, 0xA9, 0x7C, 0x42,
+
+ /* U+0035 "5" */
+ 0x7A, 0x21, 0xE0, 0x86, 0x2E,
+
+ /* U+0036 "6" */
+ 0x74, 0x61, 0xE8, 0xC6, 0x2E,
+
+ /* U+0037 "7" */
+ 0xF8, 0x84, 0x42, 0x21, 0x08,
+
+ /* U+0038 "8" */
+ 0x74, 0x62, 0xE8, 0xC6, 0x2E,
+
+ /* U+0039 "9" */
+ 0x74, 0x63, 0x17, 0x86, 0x2E,
+
+ /* U+003A ":" */
+ 0x84,
+
+ /* U+003B ";" */
+ 0x87,
+
+ /* U+003C "<" */
+ 0x0B, 0xA0, 0xE0, 0x80,
+
+ /* U+003D "=" */
+ 0xF8, 0x3E,
+
+ /* U+003E ">" */
+ 0x83, 0x82, 0xE8, 0x00,
+
+ /* U+003F "?" */
+ 0x74, 0x42, 0x22, 0x10, 0x04,
+
+ /* U+0040 "@" */
+ 0x1F, 0x18, 0x24, 0xD6, 0x4D, 0xA2, 0x68, 0x9A, 0x6A, 0x6C, 0x40, 0x4F,
+ 0xE0,
+
+ /* U+0041 "A" */
+ 0x10, 0x50, 0xA1, 0x44, 0x4F, 0xA0, 0xC1,
+
+ /* U+0042 "B" */
+ 0xFA, 0x18, 0x7E, 0x86, 0x18, 0x7E,
+
+ /* U+0043 "C" */
+ 0x39, 0x18, 0x20, 0x82, 0x04, 0x4E,
+
+ /* U+0044 "D" */
+ 0xF2, 0x28, 0x61, 0x86, 0x18, 0xBC,
+
+ /* U+0045 "E" */
+ 0xFC, 0x21, 0xF8, 0x42, 0x1F,
+
+ /* U+0046 "F" */
+ 0xFC, 0x21, 0xE8, 0x42, 0x10,
+
+ /* U+0047 "G" */
+ 0x38, 0x8A, 0x0C, 0x08, 0xF0, 0x51, 0x1C,
+
+ /* U+0048 "H" */
+ 0x86, 0x18, 0x7F, 0x86, 0x18, 0x61,
+
+ /* U+0049 "I" */
+ 0xFF,
+
+ /* U+004A "J" */
+ 0x11, 0x11, 0x19, 0x96,
+
+ /* U+004B "K" */
+ 0x86, 0x29, 0x2C, 0xD2, 0x28, 0xA1,
+
+ /* U+004C "L" */
+ 0x84, 0x21, 0x08, 0x42, 0x1F,
+
+ /* U+004D "M" */
+ 0x83, 0x8F, 0x1D, 0x5A, 0xB5, 0x64, 0xC9,
+
+ /* U+004E "N" */
+ 0x87, 0x1A, 0x69, 0x96, 0x58, 0xE1,
+
+ /* U+004F "O" */
+ 0x38, 0x8A, 0x0C, 0x18, 0x30, 0x51, 0x1C,
+
+ /* U+0050 "P" */
+ 0xF4, 0x63, 0x1F, 0x42, 0x10,
+
+ /* U+0051 "Q" */
+ 0x38, 0x8A, 0x0C, 0x18, 0x33, 0x51, 0x1F,
+
+ /* U+0052 "R" */
+ 0xFA, 0x18, 0x7E, 0x92, 0x28, 0xA1,
+
+ /* U+0053 "S" */
+ 0x7A, 0x18, 0x18, 0x18, 0x18, 0x5E,
+
+ /* U+0054 "T" */
+ 0xF9, 0x08, 0x42, 0x10, 0x84,
+
+ /* U+0055 "U" */
+ 0x86, 0x18, 0x61, 0x86, 0x18, 0x5E,
+
+ /* U+0056 "V" */
+ 0x83, 0x05, 0x12, 0x22, 0x85, 0x04, 0x08,
+
+ /* U+0057 "W" */
+ 0x84, 0x31, 0x45, 0x29, 0x25, 0x25, 0x14, 0xA2, 0x88, 0x21, 0x04,
+
+ /* U+0058 "X" */
+ 0x85, 0x24, 0x8C, 0x31, 0x24, 0xA1,
+
+ /* U+0059 "Y" */
+ 0x82, 0x89, 0x11, 0x41, 0x02, 0x04, 0x08,
+
+ /* U+005A "Z" */
+ 0x7C, 0x21, 0x04, 0x20, 0x84, 0x3F,
+
+ /* U+005B "[" */
+ 0xEA, 0xAA, 0xB0,
+
+ /* U+005C "\\" */
+ 0x91, 0x24, 0x89,
+
+ /* U+005D "]" */
+ 0xD5, 0x55, 0x70,
+
+ /* U+005E "^" */
+ 0x22, 0x95, 0x10,
+
+ /* U+005F "_" */
+ 0xFC,
+
+ /* U+0060 "`" */
+ 0x90,
+
+ /* U+0061 "a" */
+ 0x74, 0x5F, 0x19, 0xF4,
+
+ /* U+0062 "b" */
+ 0x84, 0x2D, 0x98, 0xC7, 0x36,
+
+ /* U+0063 "c" */
+ 0x74, 0x61, 0x08, 0xB8,
+
+ /* U+0064 "d" */
+ 0x08, 0x5B, 0x38, 0xC6, 0x6D,
+
+ /* U+0065 "e" */
+ 0x74, 0x7F, 0x08, 0xB8,
+
+ /* U+0066 "f" */
+ 0x24, 0xE4, 0x44, 0x44,
+
+ /* U+0067 "g" */
+ 0x6C, 0xE3, 0x19, 0xB4, 0x3E,
+
+ /* U+0068 "h" */
+ 0x84, 0x2D, 0x98, 0xC6, 0x31,
+
+ /* U+0069 "i" */
+ 0xBF,
+
+ /* U+006A "j" */
+ 0x45, 0x55, 0xC0,
+
+ /* U+006B "k" */
+ 0x88, 0x9A, 0xCE, 0xA9,
+
+ /* U+006C "l" */
+ 0xFF,
+
+ /* U+006D "m" */
+ 0xBD, 0xA6, 0x4C, 0x99, 0x32, 0x40,
+
+ /* U+006E "n" */
+ 0xF4, 0x63, 0x18, 0xC4,
+
+ /* U+006F "o" */
+ 0x74, 0x63, 0x18, 0xB8,
+
+ /* U+0070 "p" */
+ 0xB6, 0x63, 0x1C, 0xDA, 0x10,
+
+ /* U+0071 "q" */
+ 0x6C, 0xE3, 0x19, 0xB4, 0x21,
+
+ /* U+0072 "r" */
+ 0xBA, 0x49, 0x00,
+
+ /* U+0073 "s" */
+ 0x74, 0x58, 0x28, 0xB8,
+
+ /* U+0074 "t" */
+ 0x4B, 0xA4, 0x93,
+
+ /* U+0075 "u" */
+ 0x8C, 0x63, 0x19, 0xB4,
+
+ /* U+0076 "v" */
+ 0x8C, 0x54, 0xA2, 0x10,
+
+ /* U+0077 "w" */
+ 0x88, 0xCA, 0x55, 0x4A, 0xA2, 0x21, 0x10,
+
+ /* U+0078 "x" */
+ 0x8A, 0x88, 0x45, 0x44,
+
+ /* U+0079 "y" */
+ 0x8C, 0x54, 0xA2, 0x10, 0x88,
+
+ /* U+007A "z" */
+ 0xF8, 0x88, 0x44, 0x7C,
+
+ /* U+007B "{" */
+ 0x29, 0x28, 0x92, 0x44,
+
+ /* U+007C "|" */
+ 0xFF, 0xC0,
+
+ /* U+007D "}" */
+ 0x89, 0x22, 0x92, 0x50,
+
+ /* U+007E "~" */
+ 0x07, 0x6C, 0x00,
+
+ /* U+00A1 "¡" */
+ 0xBF,
+
+ /* U+00A7 "§" */
+ 0x74, 0x51, 0xC9, 0x24, 0xA2, 0x8B, 0x80,
+
+ /* U+00AA "ª" */
+ 0xE7, 0xF0,
+
+ /* U+00AB "«" */
+ 0x2A, 0xA8, 0xA2, 0x80,
+
+ /* U+00B0 "°" */
+ 0xF7, 0x80,
+
+ /* U+00BA "º" */
+ 0x69, 0x96,
+
+ /* U+00BB "»" */
+ 0xA2, 0x8A, 0xAA, 0x00,
+
+ /* U+00BF "¿" */
+ 0x20, 0x08, 0x44, 0x42, 0x2E,
+
+ /* U+00C0 "À" */
+ 0x20, 0x20, 0x00, 0x82, 0x85, 0x0A, 0x22, 0x7D, 0x06, 0x08,
+
+ /* U+00C1 "Á" */
+ 0x08, 0x20, 0x00, 0x82, 0x85, 0x0A, 0x22, 0x7D, 0x06, 0x08,
+
+ /* U+00C2 "Â" */
+ 0x30, 0x50, 0x00, 0x82, 0x85, 0x0A, 0x22, 0x7D, 0x06, 0x08,
+
+ /* U+00C4 "Ä" */
+ 0x28, 0x00, 0x41, 0x42, 0x85, 0x11, 0x3E, 0x83, 0x04,
+
+ /* U+00C6 "Æ" */
+ 0x0F, 0xE1, 0x40, 0x48, 0x09, 0xF2, 0x20, 0x7C, 0x10, 0x82, 0x1F,
+
+ /* U+00C7 "Ç" */
+ 0x39, 0x18, 0x20, 0x82, 0x04, 0x4E, 0x10, 0x21, 0x80,
+
+ /* U+00C8 "È" */
+ 0x41, 0x01, 0xF8, 0x43, 0xF0, 0x84, 0x3E,
+
+ /* U+00C9 "É" */
+ 0x11, 0x01, 0xF8, 0x43, 0xF0, 0x84, 0x3E,
+
+ /* U+00CA "Ê" */
+ 0x22, 0x81, 0xF8, 0x43, 0xF0, 0x84, 0x3E,
+
+ /* U+00CB "Ë" */
+ 0x50, 0x3F, 0x08, 0x7E, 0x10, 0x87, 0xC0,
+
+ /* U+00CC "Ì" */
+ 0x91, 0x55, 0x54,
+
+ /* U+00CD "Í" */
+ 0x62, 0xAA, 0xA8,
+
+ /* U+00CE "Î" */
+ 0x22, 0x80, 0x42, 0x10, 0x84, 0x21, 0x08,
+
+ /* U+00CF "Ï" */
+ 0xA1, 0x24, 0x92, 0x48,
+
+ /* U+00D1 "Ñ" */
+ 0x29, 0x40, 0x21, 0xC6, 0x9A, 0x65, 0x96, 0x38, 0x40,
+
+ /* U+00D2 "Ò" */
+ 0x20, 0x20, 0x01, 0xC4, 0x50, 0x60, 0xC1, 0x82, 0x88, 0xE0,
+
+ /* U+00D3 "Ó" */
+ 0x08, 0x20, 0x01, 0xC4, 0x50, 0x60, 0xC1, 0x82, 0x88, 0xE0,
+
+ /* U+00D4 "Ô" */
+ 0x18, 0x68, 0x01, 0xC4, 0x50, 0x60, 0xC1, 0x82, 0x88, 0xE0,
+
+ /* U+00D6 "Ö" */
+ 0x28, 0x00, 0xE2, 0x28, 0x30, 0x60, 0xC1, 0x44, 0x70,
+
+ /* U+00D9 "Ù" */
+ 0x20, 0x40, 0x21, 0x86, 0x18, 0x61, 0x86, 0x17, 0x80,
+
+ /* U+00DA "Ú" */
+ 0x10, 0x80, 0x21, 0x86, 0x18, 0x61, 0x86, 0x17, 0x80,
+
+ /* U+00DB "Û" */
+ 0x21, 0x40, 0x21, 0x86, 0x18, 0x61, 0x86, 0x17, 0x80,
+
+ /* U+00DC "Ü" */
+ 0x28, 0x08, 0x61, 0x86, 0x18, 0x61, 0x85, 0xE0,
+
+ /* U+00DF "ß" */
+ 0x72, 0x28, 0xA4, 0x9A, 0x1A, 0x66,
+
+ /* U+00E0 "à" */
+ 0x20, 0x80, 0xE8, 0xBE, 0x33, 0xE8,
+
+ /* U+00E1 "á" */
+ 0x11, 0x00, 0xE8, 0xBE, 0x33, 0xE8,
+
+ /* U+00E2 "â" */
+ 0x32, 0x80, 0xE8, 0xBE, 0x33, 0xE8,
+
+ /* U+00E4 "ä" */
+ 0x50, 0x1D, 0x17, 0xC6, 0x7D,
+
+ /* U+00E6 "æ" */
+ 0x77, 0x44, 0x5F, 0xF1, 0x08, 0x8B, 0xB8,
+
+ /* U+00E7 "ç" */
+ 0x74, 0x61, 0x08, 0xB8, 0x82, 0x30,
+
+ /* U+00E8 "è" */
+ 0x41, 0x00, 0xE8, 0xFE, 0x11, 0x70,
+
+ /* U+00E9 "é" */
+ 0x11, 0x00, 0xE8, 0xFE, 0x11, 0x70,
+
+ /* U+00EA "ê" */
+ 0x32, 0x80, 0xE8, 0xFE, 0x11, 0x70,
+
+ /* U+00EB "ë" */
+ 0x50, 0x1D, 0x1F, 0xC2, 0x2E,
+
+ /* U+00EC "ì" */
+ 0x91, 0x55, 0x40,
+
+ /* U+00ED "í" */
+ 0x62, 0xAA, 0x80,
+
+ /* U+00EE "î" */
+ 0x65, 0x04, 0x44, 0x44, 0x40,
+
+ /* U+00EF "ï" */
+ 0xA1, 0x24, 0x92,
+
+ /* U+00F1 "ñ" */
+ 0x2A, 0x81, 0xE8, 0xC6, 0x31, 0x88,
+
+ /* U+00F2 "ò" */
+ 0x41, 0x00, 0xE8, 0xC6, 0x31, 0x70,
+
+ /* U+00F3 "ó" */
+ 0x11, 0x00, 0xE8, 0xC6, 0x31, 0x70,
+
+ /* U+00F4 "ô" */
+ 0x32, 0x80, 0xE8, 0xC6, 0x31, 0x70,
+
+ /* U+00F6 "ö" */
+ 0x50, 0x1D, 0x18, 0xC6, 0x2E,
+
+ /* U+00F9 "ù" */
+ 0x41, 0x01, 0x18, 0xC6, 0x33, 0x68,
+
+ /* U+00FA "ú" */
+ 0x11, 0x01, 0x18, 0xC6, 0x33, 0x68,
+
+ /* U+00FB "û" */
+ 0x22, 0x81, 0x18, 0xC6, 0x33, 0x68,
+
+ /* U+00FC "ü" */
+ 0x50, 0x23, 0x18, 0xC6, 0x6D,
+
+ /* U+00FF "ÿ" */
+ 0x50, 0x23, 0x15, 0x28, 0x84, 0x22, 0x00,
+
+ /* U+0152 "Œ" */
+ 0x77, 0xE3, 0x08, 0x42, 0x1F, 0x84, 0x21, 0x08, 0xC1, 0xDF,
+
+ /* U+0153 "œ" */
+ 0x77, 0x44, 0x63, 0xF1, 0x08, 0x8B, 0xB8,
+
+ /* U+0178 "Ÿ" */
+ 0x28, 0x02, 0x0A, 0x24, 0x45, 0x04, 0x08, 0x10, 0x20,
+
+ /* U+2013 "–" */
+ 0xFE,
+
+ /* U+2014 "—" */
+ 0xFF, 0xF0,
+
+ /* U+201A "‚" */
+ 0xE0,
+
+ /* U+201E "„" */
+ 0xB6, 0x80,
+
+ /* U+2026 "…" */
+ 0x92,
+
+ /* U+2039 "‹" */
+ 0x2A, 0x22,
+
+ /* U+203A "›" */
+ 0x88, 0xA8,
+
+ /* U+20AC "€" */
+ 0x3D, 0x0F, 0xD0, 0xFD, 0x02, 0x07,
+};
+
+static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 48, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0} /* U+0020 */,
+ {.bitmap_index = 1, .adv_w = 32, .box_w = 1, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0021 */,
+ {.bitmap_index = 2, .adv_w = 64, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 5} /* U+0022 */,
+ {.bitmap_index = 4, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0023 */,
+ {.bitmap_index = 9, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = -1} /* U+0024 */,
+ {.bitmap_index = 15, .adv_w = 160, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0025 */,
+ {.bitmap_index = 24, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0026 */,
+ {.bitmap_index = 30, .adv_w = 32, .box_w = 1, .box_h = 3, .ofs_x = 0, .ofs_y = 5} /* U+0027 */,
+ {.bitmap_index = 31, .adv_w = 64, .box_w = 3, .box_h = 10, .ofs_x = 0, .ofs_y = -2} /* U+0028 */,
+ {.bitmap_index = 35, .adv_w = 64, .box_w = 3, .box_h = 10, .ofs_x = 0, .ofs_y = -2} /* U+0029 */,
+ {.bitmap_index = 39, .adv_w = 64, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = 4} /* U+002A */,
+ {.bitmap_index = 41, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 1} /* U+002B */,
+ {.bitmap_index = 45, .adv_w = 48, .box_w = 1, .box_h = 3, .ofs_x = 1, .ofs_y = -2} /* U+002C */,
+ {.bitmap_index = 46, .adv_w = 64, .box_w = 3, .box_h = 1, .ofs_x = 0, .ofs_y = 2} /* U+002D */,
+ {.bitmap_index = 47, .adv_w = 48, .box_w = 1, .box_h = 1, .ofs_x = 1, .ofs_y = 0} /* U+002E */,
+ {.bitmap_index = 48, .adv_w = 48, .box_w = 3, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+002F */,
+ {.bitmap_index = 51, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0030 */,
+ {.bitmap_index = 56, .adv_w = 96, .box_w = 3, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0031 */,
+ {.bitmap_index = 59, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0032 */,
+ {.bitmap_index = 64, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0033 */,
+ {.bitmap_index = 69, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0034 */,
+ {.bitmap_index = 74, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0035 */,
+ {.bitmap_index = 79, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0036 */,
+ {.bitmap_index = 84, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0037 */,
+ {.bitmap_index = 89, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0038 */,
+ {.bitmap_index = 94, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0039 */,
+ {.bitmap_index = 99, .adv_w = 48, .box_w = 1, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+003A */,
+ {.bitmap_index = 100, .adv_w = 48, .box_w = 1, .box_h = 8, .ofs_x = 0, .ofs_y = -2} /* U+003B */,
+ {.bitmap_index = 101, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 1} /* U+003C */,
+ {.bitmap_index = 105, .adv_w = 96, .box_w = 5, .box_h = 3, .ofs_x = 0, .ofs_y = 2} /* U+003D */,
+ {.bitmap_index = 107, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 1} /* U+003E */,
+ {.bitmap_index = 111, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+003F */,
+ {.bitmap_index = 116, .adv_w = 176, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -2} /* U+0040 */,
+ {.bitmap_index = 129, .adv_w = 128, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0041 */,
+ {.bitmap_index = 136, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0042 */,
+ {.bitmap_index = 142, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0043 */,
+ {.bitmap_index = 148, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0044 */,
+ {.bitmap_index = 154, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0045 */,
+ {.bitmap_index = 159, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0046 */,
+ {.bitmap_index = 164, .adv_w = 128, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0047 */,
+ {.bitmap_index = 171, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0048 */,
+ {.bitmap_index = 177, .adv_w = 32, .box_w = 1, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0049 */,
+ {.bitmap_index = 178, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+004A */,
+ {.bitmap_index = 182, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+004B */,
+ {.bitmap_index = 188, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+004C */,
+ {.bitmap_index = 193, .adv_w = 128, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+004D */,
+ {.bitmap_index = 200, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+004E */,
+ {.bitmap_index = 206, .adv_w = 128, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+004F */,
+ {.bitmap_index = 213, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0050 */,
+ {.bitmap_index = 218, .adv_w = 128, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0051 */,
+ {.bitmap_index = 225, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0052 */,
+ {.bitmap_index = 231, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0053 */,
+ {.bitmap_index = 237, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0054 */,
+ {.bitmap_index = 242, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0055 */,
+ {.bitmap_index = 248, .adv_w = 128, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0056 */,
+ {.bitmap_index = 255, .adv_w = 176, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0057 */,
+ {.bitmap_index = 266, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0058 */,
+ {.bitmap_index = 272, .adv_w = 128, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0059 */,
+ {.bitmap_index = 279, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+005A */,
+ {.bitmap_index = 285, .adv_w = 48, .box_w = 2, .box_h = 10, .ofs_x = 0, .ofs_y = -2} /* U+005B */,
+ {.bitmap_index = 288, .adv_w = 48, .box_w = 3, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+005C */,
+ {.bitmap_index = 291, .adv_w = 48, .box_w = 2, .box_h = 10, .ofs_x = 0, .ofs_y = -2} /* U+005D */,
+ {.bitmap_index = 294, .adv_w = 80, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 4} /* U+005E */,
+ {.bitmap_index = 297, .adv_w = 96, .box_w = 6, .box_h = 1, .ofs_x = 0, .ofs_y = -2} /* U+005F */,
+ {.bitmap_index = 298, .adv_w = 64, .box_w = 2, .box_h = 2, .ofs_x = 0, .ofs_y = 6} /* U+0060 */,
+ {.bitmap_index = 299, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0061 */,
+ {.bitmap_index = 303, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0062 */,
+ {.bitmap_index = 308, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0063 */,
+ {.bitmap_index = 312, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0064 */,
+ {.bitmap_index = 317, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0065 */,
+ {.bitmap_index = 321, .adv_w = 64, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0066 */,
+ {.bitmap_index = 325, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -2} /* U+0067 */,
+ {.bitmap_index = 330, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0068 */,
+ {.bitmap_index = 335, .adv_w = 32, .box_w = 1, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0069 */,
+ {.bitmap_index = 336, .adv_w = 48, .box_w = 2, .box_h = 9, .ofs_x = 0, .ofs_y = -1} /* U+006A */,
+ {.bitmap_index = 339, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+006B */,
+ {.bitmap_index = 343, .adv_w = 32, .box_w = 1, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+006C */,
+ {.bitmap_index = 344, .adv_w = 128, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+006D */,
+ {.bitmap_index = 350, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+006E */,
+ {.bitmap_index = 354, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+006F */,
+ {.bitmap_index = 358, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -2} /* U+0070 */,
+ {.bitmap_index = 363, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -2} /* U+0071 */,
+ {.bitmap_index = 368, .adv_w = 64, .box_w = 3, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0072 */,
+ {.bitmap_index = 371, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0073 */,
+ {.bitmap_index = 375, .adv_w = 64, .box_w = 3, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0074 */,
+ {.bitmap_index = 378, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0075 */,
+ {.bitmap_index = 382, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0076 */,
+ {.bitmap_index = 386, .adv_w = 160, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0077 */,
+ {.bitmap_index = 393, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0078 */,
+ {.bitmap_index = 397, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -2} /* U+0079 */,
+ {.bitmap_index = 402, .adv_w = 96, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+007A */,
+ {.bitmap_index = 406, .adv_w = 64, .box_w = 3, .box_h = 10, .ofs_x = 0, .ofs_y = -2} /* U+007B */,
+ {.bitmap_index = 410, .adv_w = 32, .box_w = 1, .box_h = 10, .ofs_x = 0, .ofs_y = -2} /* U+007C */,
+ {.bitmap_index = 412, .adv_w = 64, .box_w = 3, .box_h = 10, .ofs_x = 1, .ofs_y = -2} /* U+007D */,
+ {.bitmap_index = 416, .adv_w = 96, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 2} /* U+007E */,
+ {.bitmap_index = 419, .adv_w = 32, .box_w = 1, .box_h = 8, .ofs_x = 0, .ofs_y = -2} /* U+00A1 */,
+ {.bitmap_index = 420, .adv_w = 96, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = -2} /* U+00A7 */,
+ {.bitmap_index = 427, .adv_w = 64, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = 4} /* U+00AA */,
+ {.bitmap_index = 429, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+00AB */,
+ {.bitmap_index = 433, .adv_w = 64, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 5} /* U+00B0 */,
+ {.bitmap_index = 435, .adv_w = 80, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = 4} /* U+00BA */,
+ {.bitmap_index = 437, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+00BB */,
+ {.bitmap_index = 441, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -2} /* U+00BF */,
+ {.bitmap_index = 446, .adv_w = 128, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00C0 */,
+ {.bitmap_index = 456, .adv_w = 128, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00C1 */,
+ {.bitmap_index = 466, .adv_w = 128, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00C2 */,
+ {.bitmap_index = 476, .adv_w = 128, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0} /* U+00C4 */,
+ {.bitmap_index = 485, .adv_w = 176, .box_w = 11, .box_h = 8, .ofs_x = -1, .ofs_y = 0} /* U+00C6 */,
+ {.bitmap_index = 496, .adv_w = 112, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = -3} /* U+00C7 */,
+ {.bitmap_index = 505, .adv_w = 96, .box_w = 5, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00C8 */,
+ {.bitmap_index = 512, .adv_w = 96, .box_w = 5, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00C9 */,
+ {.bitmap_index = 519, .adv_w = 96, .box_w = 5, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00CA */,
+ {.bitmap_index = 526, .adv_w = 96, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = 0} /* U+00CB */,
+ {.bitmap_index = 533, .adv_w = 32, .box_w = 2, .box_h = 11, .ofs_x = -1, .ofs_y = 0} /* U+00CC */,
+ {.bitmap_index = 536, .adv_w = 32, .box_w = 2, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00CD */,
+ {.bitmap_index = 539, .adv_w = 32, .box_w = 5, .box_h = 11, .ofs_x = -2, .ofs_y = 0} /* U+00CE */,
+ {.bitmap_index = 546, .adv_w = 32, .box_w = 3, .box_h = 10, .ofs_x = -1, .ofs_y = 0} /* U+00CF */,
+ {.bitmap_index = 550, .adv_w = 112, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00D1 */,
+ {.bitmap_index = 559, .adv_w = 128, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00D2 */,
+ {.bitmap_index = 569, .adv_w = 128, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00D3 */,
+ {.bitmap_index = 579, .adv_w = 128, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00D4 */,
+ {.bitmap_index = 589, .adv_w = 128, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0} /* U+00D6 */,
+ {.bitmap_index = 598, .adv_w = 112, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00D9 */,
+ {.bitmap_index = 607, .adv_w = 112, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00DA */,
+ {.bitmap_index = 616, .adv_w = 112, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00DB */,
+ {.bitmap_index = 625, .adv_w = 112, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = 0} /* U+00DC */,
+ {.bitmap_index = 633, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00DF */,
+ {.bitmap_index = 639, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00E0 */,
+ {.bitmap_index = 645, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00E1 */,
+ {.bitmap_index = 651, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00E2 */,
+ {.bitmap_index = 657, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00E4 */,
+ {.bitmap_index = 662, .adv_w = 160, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+00E6 */,
+ {.bitmap_index = 669, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = -3} /* U+00E7 */,
+ {.bitmap_index = 675, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00E8 */,
+ {.bitmap_index = 681, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00E9 */,
+ {.bitmap_index = 687, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00EA */,
+ {.bitmap_index = 693, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00EB */,
+ {.bitmap_index = 698, .adv_w = 32, .box_w = 2, .box_h = 9, .ofs_x = -1, .ofs_y = 0} /* U+00EC */,
+ {.bitmap_index = 701, .adv_w = 32, .box_w = 2, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00ED */,
+ {.bitmap_index = 704, .adv_w = 32, .box_w = 4, .box_h = 9, .ofs_x = -1, .ofs_y = 0} /* U+00EE */,
+ {.bitmap_index = 709, .adv_w = 32, .box_w = 3, .box_h = 8, .ofs_x = -1, .ofs_y = 0} /* U+00EF */,
+ {.bitmap_index = 712, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00F1 */,
+ {.bitmap_index = 718, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00F2 */,
+ {.bitmap_index = 724, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00F3 */,
+ {.bitmap_index = 730, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00F4 */,
+ {.bitmap_index = 736, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00F6 */,
+ {.bitmap_index = 741, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00F9 */,
+ {.bitmap_index = 747, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00FA */,
+ {.bitmap_index = 753, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00FB */,
+ {.bitmap_index = 759, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00FC */,
+ {.bitmap_index = 764, .adv_w = 96, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = -2} /* U+00FF */,
+ {.bitmap_index = 771, .adv_w = 176, .box_w = 10, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+0152 */,
+ {.bitmap_index = 781, .adv_w = 160, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0} /* U+0153 */,
+ {.bitmap_index = 788, .adv_w = 128, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0} /* U+0178 */,
+ {.bitmap_index = 797, .adv_w = 96, .box_w = 7, .box_h = 1, .ofs_x = -1, .ofs_y = 2} /* U+2013 */,
+ {.bitmap_index = 798, .adv_w = 176, .box_w = 12, .box_h = 1, .ofs_x = -1, .ofs_y = 2} /* U+2014 */,
+ {.bitmap_index = 800, .adv_w = 32, .box_w = 1, .box_h = 3, .ofs_x = 0, .ofs_y = -2} /* U+201A */,
+ {.bitmap_index = 801, .adv_w = 64, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = -2} /* U+201E */,
+ {.bitmap_index = 803, .adv_w = 176, .box_w = 7, .box_h = 1, .ofs_x = 1, .ofs_y = 0} /* U+2026 */,
+ {.bitmap_index = 804, .adv_w = 64, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+2039 */,
+ {.bitmap_index = 806, .adv_w = 64, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+203A */,
+ {.bitmap_index = 808, .adv_w = 96, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+20AC */
+};
+
+static const lv_font_fmt_txt_cmap_t cmaps[] = {
+ {.range_start = 32, .range_length = 95, .glyph_id_start = 1,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 161, .range_length = 1, .glyph_id_start = 96,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 167, .range_length = 1, .glyph_id_start = 97,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 170, .range_length = 2, .glyph_id_start = 98,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 176, .range_length = 1, .glyph_id_start = 100,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 186, .range_length = 2, .glyph_id_start = 101,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 191, .range_length = 4, .glyph_id_start = 103,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 196, .range_length = 1, .glyph_id_start = 107,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 198, .range_length = 10, .glyph_id_start = 108,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 209, .range_length = 4, .glyph_id_start = 118,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 214, .range_length = 1, .glyph_id_start = 122,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 217, .range_length = 4, .glyph_id_start = 123,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 223, .range_length = 4, .glyph_id_start = 127,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 228, .range_length = 1, .glyph_id_start = 131,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 230, .range_length = 10, .glyph_id_start = 132,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 241, .range_length = 4, .glyph_id_start = 142,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 246, .range_length = 1, .glyph_id_start = 146,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 249, .range_length = 4, .glyph_id_start = 147,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 255, .range_length = 1, .glyph_id_start = 151,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 338, .range_length = 2, .glyph_id_start = 152,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 376, .range_length = 1, .glyph_id_start = 154,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8211, .range_length = 2, .glyph_id_start = 155,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8218, .range_length = 1, .glyph_id_start = 157,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8222, .range_length = 1, .glyph_id_start = 158,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8230, .range_length = 1, .glyph_id_start = 159,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8249, .range_length = 2, .glyph_id_start = 160,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8364, .range_length = 1, .glyph_id_start = 162,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}
+};
+
+static const lv_font_fmt_txt_dsc_t font_dsc = {
+ .glyph_bitmap = glyph_bitmap,
+ .glyph_dsc = glyph_dsc,
+ .cmaps = cmaps,
+ .kern_dsc = NULL,
+ .kern_scale = 0,
+ .cmap_num = 27,
+ .bpp = 1,
+ .kern_classes = 0,
+ .bitmap_format = 0,
+ .stride = 0,
+};
+
+const UG_FONT font_regular_11 = {
+ .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,
+ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,
+ .line_height = 10,
+ .base_line = 2,
+ .subpx = LV_FONT_SUBPX_NONE,
+ .underline_position = -1,
+ .underline_thickness = 0,
+ .static_bitmap = 0,
+ .dsc = &font_dsc,
+ .fallback = NULL,
+ .user_data = NULL,
+};
+
+#endif /* REGULAR_11 */
### src/ui/fonts/regular_11.h
@@ -0,0 +1,8 @@
+#ifndef TTF2LVGL_REGULAR_11_H
+#define TTF2LVGL_REGULAR_11_H
+
+#include <ugui.h>
+
+extern const UG_FONT font_regular_11;
+
+#endif /* TTF2LVGL_REGULAR_11_H */
### src/ui/fonts/regular_12.c
@@ -0,0 +1,797 @@
+/*******************************************************************************
+ * Size: 12 px
+ * Bpp: 1
+ * Opts: --dump --bpp 1 --size 12 --dpi 72 --font /usr/share/fonts/truetype/msttcorefonts/Arial.ttf --range 32-126,161,167,170-171,176,186-187,191-194,196,198-207,209-212,214,217-220,223-226,228,230-239,241-244,246,249-252,255,338-339,376,8211-8212,8218,8222,8230,8249-8250,8364 --name regular_12 --output regular_12.c
+ ******************************************************************************/
+
+#ifdef __has_include
+ #if __has_include("lvgl.h")
+ #ifndef LV_LVGL_H_INCLUDE_SIMPLE
+ #define LV_LVGL_H_INCLUDE_SIMPLE
+ #endif
+ #endif
+#endif
+
+#ifdef LV_LVGL_H_INCLUDE_SIMPLE
+ #include "lvgl.h"
+#else
+ #include "lvgl/lvgl.h"
+#endif
+
+#include "regular_12.h"
+
+#ifndef REGULAR_12
+#define REGULAR_12 1
+#endif
+
+#if REGULAR_12
+
+static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
+ /* U+0020 "\u0020" */
+ 0x00,
+
+ /* U+0021 "!" */
+ 0xFE, 0x80,
+
+ /* U+0022 "\"" */
+ 0xB6, 0x80,
+
+ /* U+0023 "#" */
+ 0x14, 0x2B, 0xF9, 0x42, 0x9F, 0xCA, 0x28, 0x50,
+
+ /* U+0024 "$" */
+ 0x75, 0x69, 0x47, 0x16, 0xB5, 0x71, 0x00,
+
+ /* U+0025 "%" */
+ 0x62, 0x4A, 0x25, 0x13, 0x06, 0xB0, 0x64, 0x52, 0x29, 0x23, 0x00,
+
+ /* U+0026 "&" */
+ 0x30, 0x91, 0x22, 0x86, 0x12, 0xA2, 0x46, 0x72,
+
+ /* U+0027 "'" */
+ 0xE0,
+
+ /* U+0028 "(" */
+ 0x29, 0x49, 0x24, 0x48, 0x80,
+
+ /* U+0029 ")" */
+ 0x89, 0x12, 0x49, 0x4A, 0x00,
+
+ /* U+002A "*" */
+ 0x27, 0xC8, 0xA0,
+
+ /* U+002B "+" */
+ 0x21, 0x3E, 0x42, 0x00,
+
+ /* U+002C "," */
+ 0xE0,
+
+ /* U+002D "-" */
+ 0xE0,
+
+ /* U+002E "." */
+ 0x80,
+
+ /* U+002F "/" */
+ 0x25, 0x24, 0x94, 0x80,
+
+ /* U+0030 "0" */
+ 0x74, 0x63, 0x18, 0xC6, 0x31, 0x70,
+
+ /* U+0031 "1" */
+ 0x2E, 0x92, 0x49, 0x20,
+
+ /* U+0032 "2" */
+ 0x74, 0x42, 0x11, 0x08, 0x88, 0xF8,
+
+ /* U+0033 "3" */
+ 0x74, 0x42, 0x13, 0x04, 0x31, 0x70,
+
+ /* U+0034 "4" */
+ 0x11, 0x8C, 0xA5, 0x4B, 0xE2, 0x10,
+
+ /* U+0035 "5" */
+ 0x7A, 0x21, 0xE8, 0x84, 0x31, 0x70,
+
+ /* U+0036 "6" */
+ 0x74, 0x61, 0x6C, 0xC6, 0x31, 0x70,
+
+ /* U+0037 "7" */
+ 0xF8, 0x84, 0x42, 0x11, 0x08, 0x40,
+
+ /* U+0038 "8" */
+ 0x74, 0x63, 0x17, 0x46, 0x31, 0x70,
+
+ /* U+0039 "9" */
+ 0x74, 0x63, 0x19, 0xB4, 0x31, 0x70,
+
+ /* U+003A ":" */
+ 0x82,
+
+ /* U+003B ";" */
+ 0x83, 0x80,
+
+ /* U+003C "<" */
+ 0x0B, 0xA0, 0xE0, 0x80,
+
+ /* U+003D "=" */
+ 0xFC, 0x00, 0x3F,
+
+ /* U+003E ">" */
+ 0x83, 0x82, 0xE8, 0x00,
+
+ /* U+003F "?" */
+ 0x74, 0x62, 0x11, 0x10, 0x80, 0x20,
+
+ /* U+0040 "@" */
+ 0x0F, 0x06, 0x19, 0x01, 0x26, 0x99, 0x33, 0x44, 0x68, 0x8D, 0x12, 0x9F,
+ 0x88, 0x04, 0x83, 0x0F, 0x80,
+
+ /* U+0041 "A" */
+ 0x10, 0x50, 0xA1, 0x44, 0x4F, 0x91, 0x41, 0x82,
+
+ /* U+0042 "B" */
+ 0xFA, 0x18, 0x61, 0xFE, 0x18, 0x61, 0xF8,
+
+ /* U+0043 "C" */
+ 0x38, 0x8A, 0x0C, 0x08, 0x10, 0x20, 0xA2, 0x38,
+
+ /* U+0044 "D" */
+ 0xF9, 0x0A, 0x0C, 0x18, 0x30, 0x60, 0xC2, 0xF8,
+
+ /* U+0045 "E" */
+ 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC,
+
+ /* U+0046 "F" */
+ 0xFC, 0x21, 0x0F, 0x42, 0x10, 0x80,
+
+ /* U+0047 "G" */
+ 0x38, 0x8A, 0x0C, 0x08, 0xF0, 0x60, 0xA2, 0x38,
+
+ /* U+0048 "H" */
+ 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82,
+
+ /* U+0049 "I" */
+ 0xFF, 0x80,
+
+ /* U+004A "J" */
+ 0x08, 0x42, 0x10, 0x86, 0x31, 0x70,
+
+ /* U+004B "K" */
+ 0x83, 0x0A, 0x24, 0x8A, 0x1A, 0x22, 0x42, 0x82,
+
+ /* U+004C "L" */
+ 0x82, 0x08, 0x20, 0x82, 0x08, 0x20, 0xFC,
+
+ /* U+004D "M" */
+ 0x83, 0x8F, 0x1D, 0x5A, 0xB5, 0x6A, 0xC9, 0x92,
+
+ /* U+004E "N" */
+ 0x83, 0x86, 0x8D, 0x19, 0x31, 0x62, 0xC3, 0x82,
+
+ /* U+004F "O" */
+ 0x38, 0x8A, 0x0C, 0x18, 0x30, 0x60, 0xA2, 0x38,
+
+ /* U+0050 "P" */
+ 0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80,
+
+ /* U+0051 "Q" */
+ 0x38, 0x8A, 0x0C, 0x18, 0x30, 0x66, 0xA2, 0x3A, 0x00,
+
+ /* U+0052 "R" */
+ 0xFD, 0x06, 0x0C, 0x1F, 0xD1, 0x21, 0x42, 0x82,
+
+ /* U+0053 "S" */
+ 0x7A, 0x18, 0x60, 0x78, 0x18, 0x61, 0x78,
+
+ /* U+0054 "T" */
+ 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10,
+
+ /* U+0055 "U" */
+ 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xA2, 0x38,
+
+ /* U+0056 "V" */
+ 0x83, 0x05, 0x12, 0x24, 0x45, 0x0A, 0x08, 0x10,
+
+ /* U+0057 "W" */
+ 0x84, 0x31, 0x46, 0x29, 0x25, 0x25, 0x14, 0xA2, 0x94, 0x51, 0x04, 0x20,
+ 0x80,
+
+ /* U+0058 "X" */
+ 0x82, 0x89, 0x11, 0x41, 0x05, 0x11, 0x22, 0x82,
+
+ /* U+0059 "Y" */
+ 0x82, 0x89, 0x11, 0x41, 0x02, 0x04, 0x08, 0x10,
+
+ /* U+005A "Z" */
+ 0x7E, 0x08, 0x20, 0x41, 0x04, 0x08, 0x20, 0xFE,
+
+ /* U+005B "[" */
+ 0xEA, 0xAA, 0xAC,
+
+ /* U+005C "\\" */
+ 0x91, 0x24, 0x91, 0x20,
+
+ /* U+005D "]" */
+ 0xD5, 0x55, 0x5C,
+
+ /* U+005E "^" */
+ 0x22, 0x94, 0xA8, 0x80,
+
+ /* U+005F "_" */
+ 0xFE,
+
+ /* U+0060 "`" */
+ 0x90,
+
+ /* U+0061 "a" */
+ 0x74, 0x42, 0xF8, 0xCD, 0xA0,
+
+ /* U+0062 "b" */
+ 0x84, 0x2D, 0x98, 0xC6, 0x39, 0xB0,
+
+ /* U+0063 "c" */
+ 0x69, 0x88, 0x89, 0x60,
+
+ /* U+0064 "d" */
+ 0x08, 0x5B, 0x38, 0xC6, 0x33, 0x68,
+
+ /* U+0065 "e" */
+ 0x74, 0x63, 0xF8, 0x45, 0xC0,
+
+ /* U+0066 "f" */
+ 0x24, 0xE4, 0x44, 0x44, 0x40,
+
+ /* U+0067 "g" */
+ 0x6C, 0xE3, 0x18, 0xCD, 0xA1, 0xF0,
+
+ /* U+0068 "h" */
+ 0x84, 0x2D, 0x98, 0xC6, 0x31, 0x88,
+
+ /* U+0069 "i" */
+ 0xBF, 0x80,
+
+ /* U+006A "j" */
+ 0x20, 0x92, 0x49, 0x25, 0x00,
+
+ /* U+006B "k" */
+ 0x84, 0x23, 0x2A, 0x72, 0x52, 0x88,
+
+ /* U+006C "l" */
+ 0xFF, 0x80,
+
+ /* U+006D "m" */
+ 0xB3, 0x66, 0x62, 0x31, 0x18, 0x8C, 0x46, 0x22,
+
+ /* U+006E "n" */
+ 0xB6, 0x63, 0x18, 0xC6, 0x20,
+
+ /* U+006F "o" */
+ 0x74, 0x63, 0x18, 0xC5, 0xC0,
+
+ /* U+0070 "p" */
+ 0xB6, 0x63, 0x18, 0xE6, 0xD0, 0x80,
+
+ /* U+0071 "q" */
+ 0x6C, 0xE3, 0x18, 0xCD, 0xA1, 0x08,
+
+ /* U+0072 "r" */
+ 0xBA, 0x49, 0x20,
+
+ /* U+0073 "s" */
+ 0x74, 0x60, 0xE0, 0xC5, 0xC0,
+
+ /* U+0074 "t" */
+ 0x4B, 0xA4, 0x92, 0x60,
+
+ /* U+0075 "u" */
+ 0x8C, 0x63, 0x18, 0xC5, 0xE0,
+
+ /* U+0076 "v" */
+ 0x8C, 0x54, 0xA5, 0x10, 0x80,
+
+ /* U+0077 "w" */
+ 0x88, 0xC4, 0x55, 0x4A, 0xA5, 0x51, 0x10, 0x88,
+
+ /* U+0078 "x" */
+ 0x8A, 0x94, 0x45, 0x2A, 0x20,
+
+ /* U+0079 "y" */
+ 0x8C, 0x54, 0xA5, 0x10, 0x84, 0x40,
+
+ /* U+007A "z" */
+ 0xF8, 0x84, 0x44, 0x23, 0xE0,
+
+ /* U+007B "{" */
+ 0x29, 0x25, 0x12, 0x48, 0x80,
+
+ /* U+007C "|" */
+ 0xFF, 0xE0,
+
+ /* U+007D "}" */
+ 0x89, 0x24, 0x52, 0x4A, 0x00,
+
+ /* U+007E "~" */
+ 0x01, 0x99, 0x80,
+
+ /* U+00A1 "¡" */
+ 0xBF, 0x80,
+
+ /* U+00A7 "§" */
+ 0x31, 0x24, 0x1C, 0x9A, 0x16, 0x4E, 0x0A, 0x27, 0x00,
+
+ /* U+00AA "ª" */
+ 0x71, 0xFF,
+
+ /* U+00AB "«" */
+ 0x2A, 0xA8, 0xA2, 0x80,
+
+ /* U+00B0 "°" */
+ 0xF7, 0x80,
+
+ /* U+00BA "º" */
+ 0x69, 0x96,
+
+ /* U+00BB "»" */
+ 0xA2, 0x8A, 0xAA, 0x00,
+
+ /* U+00BF "¿" */
+ 0x20, 0x08, 0x44, 0x42, 0x31, 0x70,
+
+ /* U+00C0 "À" */
+ 0x20, 0x20, 0x00, 0x82, 0x85, 0x0A, 0x22, 0x7C, 0x8A, 0x0C, 0x10,
+
+ /* U+00C1 "Á" */
+ 0x08, 0x20, 0x00, 0x82, 0x85, 0x0A, 0x22, 0x7C, 0x8A, 0x0C, 0x10,
+
+ /* U+00C2 "Â" */
+ 0x30, 0x50, 0x00, 0x82, 0x85, 0x0A, 0x22, 0x7C, 0x8A, 0x0C, 0x10,
+
+ /* U+00C4 "Ä" */
+ 0x28, 0x00, 0x41, 0x42, 0x85, 0x11, 0x3E, 0x45, 0x06, 0x08,
+
+ /* U+00C6 "Æ" */
+ 0x07, 0xF0, 0x90, 0x09, 0x01, 0x10, 0x11, 0xF3, 0xF0, 0x21, 0x04, 0x10,
+ 0x41, 0xF0,
+
+ /* U+00C7 "Ç" */
+ 0x38, 0x8A, 0x0C, 0x08, 0x10, 0x20, 0xA2, 0x38, 0x20, 0x21, 0xC0,
+
+ /* U+00C8 "È" */
+ 0x20, 0x40, 0x3F, 0x82, 0x08, 0x3F, 0x82, 0x08, 0x3F,
+
+ /* U+00C9 "É" */
+ 0x10, 0x80, 0x3F, 0x82, 0x08, 0x3F, 0x82, 0x08, 0x3F,
+
+ /* U+00CA "Ê" */
+ 0x21, 0x40, 0x3F, 0x82, 0x08, 0x3F, 0x82, 0x08, 0x3F,
+
+ /* U+00CB "Ë" */
+ 0x28, 0x0F, 0xE0, 0x82, 0x0F, 0xE0, 0x82, 0x0F, 0xC0,
+
+ /* U+00CC "Ì" */
+ 0x91, 0x55, 0x55,
+
+ /* U+00CD "Í" */
+ 0x62, 0xAA, 0xAA,
+
+ /* U+00CE "Î" */
+ 0x22, 0x80, 0x42, 0x10, 0x84, 0x21, 0x08, 0x40,
+
+ /* U+00CF "Ï" */
+ 0xA1, 0x24, 0x92, 0x49, 0x00,
+
+ /* U+00D1 "Ñ" */
+ 0x14, 0x50, 0x04, 0x1C, 0x34, 0x68, 0xC9, 0x8B, 0x16, 0x1C, 0x10,
+
+ /* U+00D2 "Ò" */
+ 0x20, 0x20, 0x01, 0xC4, 0x50, 0x60, 0xC1, 0x83, 0x05, 0x11, 0xC0,
+
+ /* U+00D3 "Ó" */
+ 0x08, 0x20, 0x01, 0xC4, 0x50, 0x60, 0xC1, 0x83, 0x05, 0x11, 0xC0,
+
+ /* U+00D4 "Ô" */
+ 0x18, 0x28, 0x01, 0xC4, 0x50, 0x60, 0xC1, 0x83, 0x05, 0x11, 0xC0,
+
+ /* U+00D6 "Ö" */
+ 0x28, 0x00, 0xE2, 0x28, 0x30, 0x60, 0xC1, 0x82, 0x88, 0xE0,
+
+ /* U+00D9 "Ù" */
+ 0x20, 0x20, 0x04, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x05, 0x11, 0xC0,
+
+ /* U+00DA "Ú" */
+ 0x08, 0x20, 0x04, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x05, 0x11, 0xC0,
+
+ /* U+00DB "Û" */
+ 0x10, 0x50, 0x04, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x05, 0x11, 0xC0,
+
+ /* U+00DC "Ü" */
+ 0x28, 0x02, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x82, 0x88, 0xE0,
+
+ /* U+00DF "ß" */
+ 0x72, 0x28, 0xA4, 0x92, 0x28, 0x69, 0x98,
+
+ /* U+00E0 "à" */
+ 0x20, 0x80, 0xE8, 0x85, 0xF1, 0x9B, 0x40,
+
+ /* U+00E1 "á" */
+ 0x11, 0x00, 0xE8, 0x85, 0xF1, 0x9B, 0x40,
+
+ /* U+00E2 "â" */
+ 0x33, 0x80, 0xE8, 0x85, 0xF1, 0x9B, 0x40,
+
+ /* U+00E4 "ä" */
+ 0x50, 0x1D, 0x10, 0xBE, 0x33, 0x68,
+
+ /* U+00E6 "æ" */
+ 0x77, 0x44, 0x4E, 0x39, 0xF8, 0x84, 0x45, 0xDC,
+
+ /* U+00E7 "ç" */
+ 0x69, 0x88, 0x89, 0x64, 0x2E,
+
+ /* U+00E8 "è" */
+ 0x41, 0x00, 0xE8, 0xC7, 0xF0, 0x8B, 0x80,
+
+ /* U+00E9 "é" */
+ 0x11, 0x00, 0xE8, 0xC7, 0xF0, 0x8B, 0x80,
+
+ /* U+00EA "ê" */
+ 0x33, 0x80, 0xE8, 0xC7, 0xF0, 0x8B, 0x80,
+
+ /* U+00EB "ë" */
+ 0x50, 0x1D, 0x18, 0xFE, 0x11, 0x70,
+
+ /* U+00EC "ì" */
+ 0x91, 0x55, 0x50,
+
+ /* U+00ED "í" */
+ 0x62, 0xAA, 0xA0,
+
+ /* U+00EE "î" */
+ 0x65, 0x02, 0x22, 0x22, 0x22,
+
+ /* U+00EF "ï" */
+ 0xA1, 0x24, 0x92, 0x40,
+
+ /* U+00F1 "ñ" */
+ 0x2A, 0x81, 0x6C, 0xC6, 0x31, 0x8C, 0x40,
+
+ /* U+00F2 "ò" */
+ 0x41, 0x00, 0xE8, 0xC6, 0x31, 0x8B, 0x80,
+
+ /* U+00F3 "ó" */
+ 0x11, 0x00, 0xE8, 0xC6, 0x31, 0x8B, 0x80,
+
+ /* U+00F4 "ô" */
+ 0x33, 0x80, 0xE8, 0xC6, 0x31, 0x8B, 0x80,
+
+ /* U+00F6 "ö" */
+ 0x50, 0x1D, 0x18, 0xC6, 0x31, 0x70,
+
+ /* U+00F9 "ù" */
+ 0x41, 0x01, 0x18, 0xC6, 0x31, 0x8B, 0xC0,
+
+ /* U+00FA "ú" */
+ 0x11, 0x01, 0x18, 0xC6, 0x31, 0x8B, 0xC0,
+
+ /* U+00FB "û" */
+ 0x22, 0x81, 0x18, 0xC6, 0x31, 0x8B, 0xC0,
+
+ /* U+00FC "ü" */
+ 0x50, 0x23, 0x18, 0xC6, 0x31, 0x78,
+
+ /* U+00FF "ÿ" */
+ 0x50, 0x23, 0x15, 0x29, 0x44, 0x21, 0x10,
+
+ /* U+0152 "Œ" */
+ 0x77, 0xE3, 0x08, 0x42, 0x10, 0x87, 0xE1, 0x08, 0x42, 0x30, 0x77, 0xC0,
+
+ /* U+0153 "œ" */
+ 0x77, 0x44, 0x62, 0x31, 0xF8, 0x84, 0x45, 0xDC,
+
+ /* U+0178 "Ÿ" */
+ 0x28, 0x02, 0x0A, 0x24, 0x45, 0x04, 0x08, 0x10, 0x20, 0x40,
+
+ /* U+2013 "–" */
+ 0xFE,
+
+ /* U+2014 "—" */
+ 0xFF, 0xF0,
+
+ /* U+201A "‚" */
+ 0xE0,
+
+ /* U+201E "„" */
+ 0xB6, 0x80,
+
+ /* U+2026 "…" */
+ 0x88, 0x80,
+
+ /* U+2039 "‹" */
+ 0x2A, 0x22,
+
+ /* U+203A "›" */
+ 0x88, 0xA8,
+
+ /* U+20AC "€" */
+ 0x1E, 0x45, 0x07, 0xF4, 0x1F, 0xD0, 0x10, 0x1E,
+};
+
+static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 48, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0} /* U+0020 */,
+ {.bitmap_index = 1, .adv_w = 48, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0021 */,
+ {.bitmap_index = 3, .adv_w = 64, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 6} /* U+0022 */,
+ {.bitmap_index = 5, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+0023 */,
+ {.bitmap_index = 13, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = -1} /* U+0024 */,
+ {.bitmap_index = 20, .adv_w = 176, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0025 */,
+ {.bitmap_index = 31, .adv_w = 128, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0026 */,
+ {.bitmap_index = 39, .adv_w = 32, .box_w = 1, .box_h = 3, .ofs_x = 1, .ofs_y = 6} /* U+0027 */,
+ {.bitmap_index = 40, .adv_w = 64, .box_w = 3, .box_h = 11, .ofs_x = 1, .ofs_y = -2} /* U+0028 */,
+ {.bitmap_index = 45, .adv_w = 64, .box_w = 3, .box_h = 11, .ofs_x = 0, .ofs_y = -2} /* U+0029 */,
+ {.bitmap_index = 50, .adv_w = 80, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 5} /* U+002A */,
+ {.bitmap_index = 53, .adv_w = 112, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 2} /* U+002B */,
+ {.bitmap_index = 57, .adv_w = 48, .box_w = 1, .box_h = 3, .ofs_x = 1, .ofs_y = -2} /* U+002C */,
+ {.bitmap_index = 58, .adv_w = 64, .box_w = 3, .box_h = 1, .ofs_x = 0, .ofs_y = 3} /* U+002D */,
+ {.bitmap_index = 59, .adv_w = 48, .box_w = 1, .box_h = 1, .ofs_x = 1, .ofs_y = 0} /* U+002E */,
+ {.bitmap_index = 60, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+002F */,
+ {.bitmap_index = 64, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0030 */,
+ {.bitmap_index = 70, .adv_w = 112, .box_w = 3, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0031 */,
+ {.bitmap_index = 74, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0032 */,
+ {.bitmap_index = 80, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0033 */,
+ {.bitmap_index = 86, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0034 */,
+ {.bitmap_index = 92, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0035 */,
+ {.bitmap_index = 98, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0036 */,
+ {.bitmap_index = 104, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0037 */,
+ {.bitmap_index = 110, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0038 */,
+ {.bitmap_index = 116, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0039 */,
+ {.bitmap_index = 122, .adv_w = 48, .box_w = 1, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+003A */,
+ {.bitmap_index = 123, .adv_w = 48, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = -2} /* U+003B */,
+ {.bitmap_index = 125, .adv_w = 112, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 2} /* U+003C */,
+ {.bitmap_index = 129, .adv_w = 112, .box_w = 6, .box_h = 4, .ofs_x = 0, .ofs_y = 2} /* U+003D */,
+ {.bitmap_index = 132, .adv_w = 112, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 2} /* U+003E */,
+ {.bitmap_index = 136, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+003F */,
+ {.bitmap_index = 142, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -3} /* U+0040 */,
+ {.bitmap_index = 159, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+0041 */,
+ {.bitmap_index = 167, .adv_w = 128, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0042 */,
+ {.bitmap_index = 174, .adv_w = 144, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0043 */,
+ {.bitmap_index = 182, .adv_w = 144, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0044 */,
+ {.bitmap_index = 190, .adv_w = 128, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0045 */,
+ {.bitmap_index = 197, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0046 */,
+ {.bitmap_index = 203, .adv_w = 144, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0047 */,
+ {.bitmap_index = 211, .adv_w = 144, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0048 */,
+ {.bitmap_index = 219, .adv_w = 48, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0049 */,
+ {.bitmap_index = 221, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+004A */,
+ {.bitmap_index = 227, .adv_w = 128, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+004B */,
+ {.bitmap_index = 235, .adv_w = 112, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+004C */,
+ {.bitmap_index = 242, .adv_w = 144, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+004D */,
+ {.bitmap_index = 250, .adv_w = 144, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+004E */,
+ {.bitmap_index = 258, .adv_w = 144, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+004F */,
+ {.bitmap_index = 266, .adv_w = 128, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0050 */,
+ {.bitmap_index = 273, .adv_w = 144, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = -1} /* U+0051 */,
+ {.bitmap_index = 282, .adv_w = 144, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0052 */,
+ {.bitmap_index = 290, .adv_w = 128, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0053 */,
+ {.bitmap_index = 297, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+0054 */,
+ {.bitmap_index = 305, .adv_w = 144, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0055 */,
+ {.bitmap_index = 313, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+0056 */,
+ {.bitmap_index = 321, .adv_w = 176, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+0057 */,
+ {.bitmap_index = 334, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+0058 */,
+ {.bitmap_index = 342, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+0059 */,
+ {.bitmap_index = 350, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+005A */,
+ {.bitmap_index = 358, .adv_w = 48, .box_w = 2, .box_h = 11, .ofs_x = 1, .ofs_y = -2} /* U+005B */,
+ {.bitmap_index = 361, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+005C */,
+ {.bitmap_index = 365, .adv_w = 48, .box_w = 2, .box_h = 11, .ofs_x = 0, .ofs_y = -2} /* U+005D */,
+ {.bitmap_index = 368, .adv_w = 80, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 4} /* U+005E */,
+ {.bitmap_index = 372, .adv_w = 112, .box_w = 7, .box_h = 1, .ofs_x = 0, .ofs_y = -2} /* U+005F */,
+ {.bitmap_index = 373, .adv_w = 64, .box_w = 2, .box_h = 2, .ofs_x = 1, .ofs_y = 7} /* U+0060 */,
+ {.bitmap_index = 374, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0061 */,
+ {.bitmap_index = 379, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0062 */,
+ {.bitmap_index = 385, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0063 */,
+ {.bitmap_index = 389, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0064 */,
+ {.bitmap_index = 395, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0065 */,
+ {.bitmap_index = 400, .adv_w = 48, .box_w = 4, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+0066 */,
+ {.bitmap_index = 405, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = -2} /* U+0067 */,
+ {.bitmap_index = 411, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0068 */,
+ {.bitmap_index = 417, .adv_w = 48, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0069 */,
+ {.bitmap_index = 419, .adv_w = 48, .box_w = 3, .box_h = 11, .ofs_x = -1, .ofs_y = -2} /* U+006A */,
+ {.bitmap_index = 424, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+006B */,
+ {.bitmap_index = 430, .adv_w = 48, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+006C */,
+ {.bitmap_index = 432, .adv_w = 176, .box_w = 9, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+006D */,
+ {.bitmap_index = 440, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+006E */,
+ {.bitmap_index = 445, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+006F */,
+ {.bitmap_index = 450, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = -2} /* U+0070 */,
+ {.bitmap_index = 456, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = -2} /* U+0071 */,
+ {.bitmap_index = 462, .adv_w = 64, .box_w = 3, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0072 */,
+ {.bitmap_index = 465, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0073 */,
+ {.bitmap_index = 470, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+0074 */,
+ {.bitmap_index = 474, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0075 */,
+ {.bitmap_index = 479, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0076 */,
+ {.bitmap_index = 484, .adv_w = 144, .box_w = 9, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0077 */,
+ {.bitmap_index = 492, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0078 */,
+ {.bitmap_index = 497, .adv_w = 80, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+0079 */,
+ {.bitmap_index = 503, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+007A */,
+ {.bitmap_index = 508, .adv_w = 64, .box_w = 3, .box_h = 11, .ofs_x = 0, .ofs_y = -2} /* U+007B */,
+ {.bitmap_index = 513, .adv_w = 48, .box_w = 1, .box_h = 11, .ofs_x = 1, .ofs_y = -2} /* U+007C */,
+ {.bitmap_index = 515, .adv_w = 64, .box_w = 3, .box_h = 11, .ofs_x = 1, .ofs_y = -2} /* U+007D */,
+ {.bitmap_index = 520, .adv_w = 112, .box_w = 6, .box_h = 4, .ofs_x = 1, .ofs_y = 2} /* U+007E */,
+ {.bitmap_index = 523, .adv_w = 48, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = -2} /* U+00A1 */,
+ {.bitmap_index = 525, .adv_w = 112, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = -2} /* U+00A7 */,
+ {.bitmap_index = 534, .adv_w = 64, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = 5} /* U+00AA */,
+ {.bitmap_index = 536, .adv_w = 112, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 0} /* U+00AB */,
+ {.bitmap_index = 540, .adv_w = 80, .box_w = 3, .box_h = 3, .ofs_x = 1, .ofs_y = 6} /* U+00B0 */,
+ {.bitmap_index = 542, .adv_w = 64, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = 5} /* U+00BA */,
+ {.bitmap_index = 544, .adv_w = 112, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 0} /* U+00BB */,
+ {.bitmap_index = 548, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = -2} /* U+00BF */,
+ {.bitmap_index = 554, .adv_w = 112, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0} /* U+00C0 */,
+ {.bitmap_index = 565, .adv_w = 112, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0} /* U+00C1 */,
+ {.bitmap_index = 576, .adv_w = 112, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0} /* U+00C2 */,
+ {.bitmap_index = 587, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00C4 */,
+ {.bitmap_index = 597, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = -1, .ofs_y = 0} /* U+00C6 */,
+ {.bitmap_index = 611, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = -3} /* U+00C7 */,
+ {.bitmap_index = 622, .adv_w = 128, .box_w = 6, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00C8 */,
+ {.bitmap_index = 631, .adv_w = 128, .box_w = 6, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00C9 */,
+ {.bitmap_index = 640, .adv_w = 128, .box_w = 6, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00CA */,
+ {.bitmap_index = 649, .adv_w = 128, .box_w = 6, .box_h = 11, .ofs_x = 1, .ofs_y = 0} /* U+00CB */,
+ {.bitmap_index = 658, .adv_w = 48, .box_w = 2, .box_h = 12, .ofs_x = 0, .ofs_y = 0} /* U+00CC */,
+ {.bitmap_index = 661, .adv_w = 48, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00CD */,
+ {.bitmap_index = 664, .adv_w = 48, .box_w = 5, .box_h = 12, .ofs_x = -1, .ofs_y = 0} /* U+00CE */,
+ {.bitmap_index = 672, .adv_w = 48, .box_w = 3, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+00CF */,
+ {.bitmap_index = 677, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00D1 */,
+ {.bitmap_index = 688, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00D2 */,
+ {.bitmap_index = 699, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00D3 */,
+ {.bitmap_index = 710, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00D4 */,
+ {.bitmap_index = 721, .adv_w = 144, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = 0} /* U+00D6 */,
+ {.bitmap_index = 731, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00D9 */,
+ {.bitmap_index = 742, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00DA */,
+ {.bitmap_index = 753, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0} /* U+00DB */,
+ {.bitmap_index = 764, .adv_w = 144, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = 0} /* U+00DC */,
+ {.bitmap_index = 774, .adv_w = 128, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00DF */,
+ {.bitmap_index = 781, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00E0 */,
+ {.bitmap_index = 788, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00E1 */,
+ {.bitmap_index = 795, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00E2 */,
+ {.bitmap_index = 802, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00E4 */,
+ {.bitmap_index = 808, .adv_w = 176, .box_w = 9, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+00E6 */,
+ {.bitmap_index = 816, .adv_w = 96, .box_w = 4, .box_h = 10, .ofs_x = 1, .ofs_y = -3} /* U+00E7 */,
+ {.bitmap_index = 821, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00E8 */,
+ {.bitmap_index = 828, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00E9 */,
+ {.bitmap_index = 835, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00EA */,
+ {.bitmap_index = 842, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00EB */,
+ {.bitmap_index = 848, .adv_w = 48, .box_w = 2, .box_h = 10, .ofs_x = 0, .ofs_y = 0} /* U+00EC */,
+ {.bitmap_index = 851, .adv_w = 48, .box_w = 2, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00ED */,
+ {.bitmap_index = 854, .adv_w = 48, .box_w = 4, .box_h = 10, .ofs_x = -1, .ofs_y = 0} /* U+00EE */,
+ {.bitmap_index = 859, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00EF */,
+ {.bitmap_index = 863, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00F1 */,
+ {.bitmap_index = 870, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00F2 */,
+ {.bitmap_index = 877, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00F3 */,
+ {.bitmap_index = 884, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00F4 */,
+ {.bitmap_index = 891, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00F6 */,
+ {.bitmap_index = 897, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00F9 */,
+ {.bitmap_index = 904, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00FA */,
+ {.bitmap_index = 911, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0} /* U+00FB */,
+ {.bitmap_index = 918, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00FC */,
+ {.bitmap_index = 924, .adv_w = 80, .box_w = 5, .box_h = 11, .ofs_x = 0, .ofs_y = -2} /* U+00FF */,
+ {.bitmap_index = 931, .adv_w = 192, .box_w = 10, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+0152 */,
+ {.bitmap_index = 943, .adv_w = 176, .box_w = 9, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0153 */,
+ {.bitmap_index = 951, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0} /* U+0178 */,
+ {.bitmap_index = 961, .adv_w = 112, .box_w = 7, .box_h = 1, .ofs_x = 0, .ofs_y = 3} /* U+2013 */,
+ {.bitmap_index = 962, .adv_w = 192, .box_w = 12, .box_h = 1, .ofs_x = 0, .ofs_y = 3} /* U+2014 */,
+ {.bitmap_index = 964, .adv_w = 48, .box_w = 1, .box_h = 3, .ofs_x = 1, .ofs_y = -2} /* U+201A */,
+ {.bitmap_index = 965, .adv_w = 64, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = -2} /* U+201E */,
+ {.bitmap_index = 967, .adv_w = 192, .box_w = 9, .box_h = 1, .ofs_x = 1, .ofs_y = 0} /* U+2026 */,
+ {.bitmap_index = 969, .adv_w = 64, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+2039 */,
+ {.bitmap_index = 971, .adv_w = 64, .box_w = 3, .box_h = 5, .ofs_x = 1, .ofs_y = 0} /* U+203A */,
+ {.bitmap_index = 973, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+20AC */
+};
+
+static const lv_font_fmt_txt_cmap_t cmaps[] = {
+ {.range_start = 32, .range_length = 95, .glyph_id_start = 1,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 161, .range_length = 1, .glyph_id_start = 96,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 167, .range_length = 1, .glyph_id_start = 97,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 170, .range_length = 2, .glyph_id_start = 98,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 176, .range_length = 1, .glyph_id_start = 100,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 186, .range_length = 2, .glyph_id_start = 101,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 191, .range_length = 4, .glyph_id_start = 103,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 196, .range_length = 1, .glyph_id_start = 107,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 198, .range_length = 10, .glyph_id_start = 108,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 209, .range_length = 4, .glyph_id_start = 118,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 214, .range_length = 1, .glyph_id_start = 122,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 217, .range_length = 4, .glyph_id_start = 123,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 223, .range_length = 4, .glyph_id_start = 127,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 228, .range_length = 1, .glyph_id_start = 131,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 230, .range_length = 10, .glyph_id_start = 132,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 241, .range_length = 4, .glyph_id_start = 142,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 246, .range_length = 1, .glyph_id_start = 146,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 249, .range_length = 4, .glyph_id_start = 147,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 255, .range_length = 1, .glyph_id_start = 151,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 338, .range_length = 2, .glyph_id_start = 152,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 376, .range_length = 1, .glyph_id_start = 154,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8211, .range_length = 2, .glyph_id_start = 155,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8218, .range_length = 1, .glyph_id_start = 157,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8222, .range_length = 1, .glyph_id_start = 158,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8230, .range_length = 1, .glyph_id_start = 159,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8249, .range_length = 2, .glyph_id_start = 160,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8364, .range_length = 1, .glyph_id_start = 162,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}
+};
+
+static const lv_font_fmt_txt_dsc_t font_dsc = {
+ .glyph_bitmap = glyph_bitmap,
+ .glyph_dsc = glyph_dsc,
+ .cmaps = cmaps,
+ .kern_dsc = NULL,
+ .kern_scale = 0,
+ .cmap_num = 27,
+ .bpp = 1,
+ .kern_classes = 0,
+ .bitmap_format = 0,
+ .stride = 0,
+};
+
+const UG_FONT font_regular_12 = {
+ .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,
+ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,
+ .line_height = 12,
+ .base_line = 3,
+ .subpx = LV_FONT_SUBPX_NONE,
+ .underline_position = -1,
+ .underline_thickness = 0,
+ .static_bitmap = 0,
+ .dsc = &font_dsc,
+ .fallback = NULL,
+ .user_data = NULL,
+};
+
+#endif /* REGULAR_12 */
### src/ui/fonts/regular_12.h
@@ -0,0 +1,8 @@
+#ifndef TTF2LVGL_REGULAR_12_H
+#define TTF2LVGL_REGULAR_12_H
+
+#include <ugui.h>
+
+extern const UG_FONT font_regular_12;
+
+#endif /* TTF2LVGL_REGULAR_12_H */
### src/ui/fonts/regular_9.c
@@ -0,0 +1,794 @@
+/*******************************************************************************
+ * Size: 9 px
+ * Bpp: 1
+ * Opts: --dump --bpp 1 --size 9 --dpi 72 --font /usr/share/fonts/truetype/msttcorefonts/Arial.ttf --range 32-126,161,167,170-171,176,186-187,191-194,196,198-207,209-212,214,217-220,223-226,228,230-239,241-244,246,249-252,255,338-339,376,8211-8212,8218,8222,8230,8249-8250,8364 --name regular_9 --output regular_9.c
+ ******************************************************************************/
+
+#ifdef __has_include
+ #if __has_include("lvgl.h")
+ #ifndef LV_LVGL_H_INCLUDE_SIMPLE
+ #define LV_LVGL_H_INCLUDE_SIMPLE
+ #endif
+ #endif
+#endif
+
+#ifdef LV_LVGL_H_INCLUDE_SIMPLE
+ #include "lvgl.h"
+#else
+ #include "lvgl/lvgl.h"
+#endif
+
+#include "regular_9.h"
+
+#ifndef REGULAR_9
+#define REGULAR_9 1
+#endif
+
+#if REGULAR_9
+
+static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
+ /* U+0020 "\u0020" */
+ 0x00,
+
+ /* U+0021 "!" */
+ 0xFA,
+
+ /* U+0022 "\"" */
+ 0xB4,
+
+ /* U+0023 "#" */
+ 0x55, 0xF5, 0xFA, 0xA0,
+
+ /* U+0024 "$" */
+ 0x75, 0x68, 0xE2, 0xD5, 0xC4,
+
+ /* U+0025 "%" */
+ 0x4A, 0xC5, 0x04, 0x28, 0xD2, 0x80,
+
+ /* U+0026 "&" */
+ 0x31, 0x24, 0x9C, 0x96, 0x27, 0x40,
+
+ /* U+0027 "'" */
+ 0xC0,
+
+ /* U+0028 "(" */
+ 0x2A, 0x49, 0x22, 0x20,
+
+ /* U+0029 ")" */
+ 0x88, 0x92, 0x4A, 0x80,
+
+ /* U+002A "*" */
+ 0xEA, 0x80,
+
+ /* U+002B "+" */
+ 0x21, 0x3E, 0x42, 0x00,
+
+ /* U+002C "," */
+ 0xC0,
+
+ /* U+002D "-" */
+ 0xC0,
+
+ /* U+002E "." */
+ 0x80,
+
+ /* U+002F "/" */
+ 0x25, 0x25, 0x20,
+
+ /* U+0030 "0" */
+ 0x69, 0x99, 0x99, 0x60,
+
+ /* U+0031 "1" */
+ 0x75, 0x54,
+
+ /* U+0032 "2" */
+ 0x69, 0x12, 0x24, 0xF0,
+
+ /* U+0033 "3" */
+ 0x69, 0x12, 0x19, 0x60,
+
+ /* U+0034 "4" */
+ 0x11, 0x95, 0x2F, 0x88, 0x40,
+
+ /* U+0035 "5" */
+ 0x74, 0xE9, 0x19, 0x60,
+
+ /* U+0036 "6" */
+ 0x69, 0xE9, 0x99, 0x60,
+
+ /* U+0037 "7" */
+ 0xF1, 0x22, 0x44, 0x40,
+
+ /* U+0038 "8" */
+ 0x69, 0x96, 0x99, 0x60,
+
+ /* U+0039 "9" */
+ 0x69, 0x99, 0x79, 0x60,
+
+ /* U+003A ":" */
+ 0x88,
+
+ /* U+003B ";" */
+ 0x8C,
+
+ /* U+003C "<" */
+ 0x2A, 0x22,
+
+ /* U+003D "=" */
+ 0xF0, 0xF0,
+
+ /* U+003E ">" */
+ 0x88, 0xA8,
+
+ /* U+003F "?" */
+ 0x74, 0x42, 0x62, 0x00, 0x80,
+
+ /* U+0040 "@" */
+ 0x3C, 0x42, 0x95, 0xAD, 0xA9, 0xAA, 0xBC, 0x43, 0x3C,
+
+ /* U+0041 "A" */
+ 0x10, 0x51, 0x12, 0x27, 0xC8, 0x91, 0x00,
+
+ /* U+0042 "B" */
+ 0xE9, 0x9F, 0x99, 0xE0,
+
+ /* U+0043 "C" */
+ 0x74, 0x61, 0x08, 0x45, 0xC0,
+
+ /* U+0044 "D" */
+ 0xF4, 0x63, 0x18, 0xC7, 0xC0,
+
+ /* U+0045 "E" */
+ 0xFC, 0x21, 0xF8, 0x43, 0xE0,
+
+ /* U+0046 "F" */
+ 0xF8, 0x8E, 0x88, 0x80,
+
+ /* U+0047 "G" */
+ 0x74, 0x61, 0x38, 0xC5, 0xC0,
+
+ /* U+0048 "H" */
+ 0x8C, 0x63, 0xF8, 0xC6, 0x20,
+
+ /* U+0049 "I" */
+ 0xFE,
+
+ /* U+004A "J" */
+ 0x11, 0x11, 0x19, 0xE0,
+
+ /* U+004B "K" */
+ 0x8C, 0xA9, 0x8A, 0x4A, 0x20,
+
+ /* U+004C "L" */
+ 0x88, 0x88, 0x88, 0xF0,
+
+ /* U+004D "M" */
+ 0x83, 0x8F, 0x1D, 0x5A, 0xB5, 0x64, 0x80,
+
+ /* U+004E "N" */
+ 0x8E, 0x73, 0x59, 0xCE, 0x20,
+
+ /* U+004F "O" */
+ 0x74, 0x63, 0x18, 0xC5, 0xC0,
+
+ /* U+0050 "P" */
+ 0xF9, 0x9F, 0x88, 0x80,
+
+ /* U+0051 "Q" */
+ 0x74, 0x63, 0x18, 0xC9, 0xE0,
+
+ /* U+0052 "R" */
+ 0xF4, 0x63, 0xE9, 0x46, 0x20,
+
+ /* U+0053 "S" */
+ 0x69, 0x86, 0x19, 0x60,
+
+ /* U+0054 "T" */
+ 0xF9, 0x08, 0x42, 0x10, 0x80,
+
+ /* U+0055 "U" */
+ 0x8C, 0x63, 0x18, 0xC5, 0xC0,
+
+ /* U+0056 "V" */
+ 0x44, 0x89, 0x12, 0x22, 0x85, 0x04, 0x00,
+
+ /* U+0057 "W" */
+ 0x88, 0xCA, 0x55, 0x4A, 0xA5, 0x52, 0xA8, 0x88,
+
+ /* U+0058 "X" */
+ 0x8A, 0x94, 0x45, 0x2A, 0x20,
+
+ /* U+0059 "Y" */
+ 0x8A, 0x94, 0x42, 0x10, 0x80,
+
+ /* U+005A "Z" */
+ 0xFC, 0x21, 0x08, 0x42, 0x0F, 0xC0,
+
+ /* U+005B "[" */
+ 0xEA, 0xAA, 0xC0,
+
+ /* U+005C "\\" */
+ 0x91, 0x24, 0x48,
+
+ /* U+005D "]" */
+ 0xD5, 0x55, 0xC0,
+
+ /* U+005E "^" */
+ 0x56, 0x80,
+
+ /* U+005F "_" */
+ 0xF8,
+
+ /* U+0060 "`" */
+ 0x90,
+
+ /* U+0061 "a" */
+ 0xF1, 0x79, 0xF0,
+
+ /* U+0062 "b" */
+ 0x88, 0xE9, 0x99, 0xE0,
+
+ /* U+0063 "c" */
+ 0x69, 0x89, 0x60,
+
+ /* U+0064 "d" */
+ 0x11, 0x79, 0x99, 0x70,
+
+ /* U+0065 "e" */
+ 0x69, 0xF8, 0x70,
+
+ /* U+0066 "f" */
+ 0x2B, 0xA4, 0x90,
+
+ /* U+0067 "g" */
+ 0x79, 0x99, 0x79, 0x60,
+
+ /* U+0068 "h" */
+ 0x88, 0xE9, 0x99, 0x90,
+
+ /* U+0069 "i" */
+ 0xBE,
+
+ /* U+006A "j" */
+ 0x45, 0x55, 0x80,
+
+ /* U+006B "k" */
+ 0x88, 0x9A, 0xEA, 0x90,
+
+ /* U+006C "l" */
+ 0xFE,
+
+ /* U+006D "m" */
+ 0xFD, 0x26, 0x4C, 0x99, 0x20,
+
+ /* U+006E "n" */
+ 0xE9, 0x99, 0x90,
+
+ /* U+006F "o" */
+ 0x69, 0x99, 0x60,
+
+ /* U+0070 "p" */
+ 0xE9, 0x99, 0xE8, 0x80,
+
+ /* U+0071 "q" */
+ 0x79, 0x99, 0x71, 0x10,
+
+ /* U+0072 "r" */
+ 0xF2, 0x48,
+
+ /* U+0073 "s" */
+ 0x78, 0x61, 0xE0,
+
+ /* U+0074 "t" */
+ 0x09, 0xA4, 0x98,
+
+ /* U+0075 "u" */
+ 0x99, 0x99, 0x70,
+
+ /* U+0076 "v" */
+ 0x8A, 0x94, 0xA2, 0x00,
+
+ /* U+0077 "w" */
+ 0xAD, 0x6B, 0x55, 0x00,
+
+ /* U+0078 "x" */
+ 0x96, 0x46, 0x90,
+
+ /* U+0079 "y" */
+ 0x8A, 0x94, 0xA2, 0x11, 0x00,
+
+ /* U+007A "z" */
+ 0xE5, 0x4E,
+
+ /* U+007B "{" */
+ 0x69, 0x28, 0x92, 0x60,
+
+ /* U+007C "|" */
+ 0xFF,
+
+ /* U+007D "}" */
+ 0xC9, 0x22, 0x92, 0xC0,
+
+ /* U+007E "~" */
+ 0xDB,
+
+ /* U+00A1 "¡" */
+ 0xBE,
+
+ /* U+00A7 "§" */
+ 0xE9, 0x4A, 0x95, 0x29, 0x70,
+
+ /* U+00AA "ª" */
+ 0xEF, 0x80,
+
+ /* U+00AB "«" */
+ 0x2A, 0x94, 0x50,
+
+ /* U+00B0 "°" */
+ 0xF7, 0x80,
+
+ /* U+00BA "º" */
+ 0xF7, 0x80,
+
+ /* U+00BB "»" */
+ 0xA2, 0x95, 0x40,
+
+ /* U+00BF "¿" */
+ 0x20, 0x26, 0x89, 0x60,
+
+ /* U+00C0 "À" */
+ 0x10, 0x10, 0x41, 0x42, 0x88, 0x9F, 0x22, 0x82,
+
+ /* U+00C1 "Á" */
+ 0x08, 0x20, 0x41, 0x42, 0x88, 0x9F, 0x22, 0x82,
+
+ /* U+00C2 "Â" */
+ 0x18, 0x68, 0x41, 0x42, 0x88, 0x9F, 0x22, 0x82,
+
+ /* U+00C4 "Ä" */
+ 0x28, 0x20, 0xA1, 0x44, 0x4F, 0x91, 0x41,
+
+ /* U+00C6 "Æ" */
+ 0x0F, 0xC5, 0x01, 0x40, 0x9F, 0x3C, 0x11, 0x04, 0x7C,
+
+ /* U+00C7 "Ç" */
+ 0x74, 0x61, 0x08, 0x45, 0xC2, 0x11, 0x80,
+
+ /* U+00C8 "È" */
+ 0x20, 0xBF, 0x08, 0x7E, 0x10, 0xF8,
+
+ /* U+00C9 "É" */
+ 0x11, 0x3F, 0x08, 0x7E, 0x10, 0xF8,
+
+ /* U+00CA "Ê" */
+ 0x22, 0xBF, 0x08, 0x7E, 0x10, 0xF8,
+
+ /* U+00CB "Ë" */
+ 0x57, 0xE1, 0x0F, 0xC2, 0x1F,
+
+ /* U+00CC "Ì" */
+ 0x9A, 0xAA, 0x80,
+
+ /* U+00CD "Í" */
+ 0x65, 0x55, 0x40,
+
+ /* U+00CE "Î" */
+ 0x22, 0x84, 0x21, 0x08, 0x42, 0x10,
+
+ /* U+00CF "Ï" */
+ 0xA9, 0x24, 0x92,
+
+ /* U+00D1 "Ñ" */
+ 0x55, 0x23, 0x9C, 0xD6, 0x73, 0x88,
+
+ /* U+00D2 "Ò" */
+ 0x20, 0x9D, 0x18, 0xC6, 0x31, 0x70,
+
+ /* U+00D3 "Ó" */
+ 0x11, 0x1D, 0x18, 0xC6, 0x31, 0x70,
+
+ /* U+00D4 "Ô" */
+ 0x22, 0x9D, 0x18, 0xC6, 0x31, 0x70,
+
+ /* U+00D6 "Ö" */
+ 0x53, 0xA3, 0x18, 0xC6, 0x2E,
+
+ /* U+00D9 "Ù" */
+ 0x41, 0x23, 0x18, 0xC6, 0x31, 0x70,
+
+ /* U+00DA "Ú" */
+ 0x22, 0x23, 0x18, 0xC6, 0x31, 0x70,
+
+ /* U+00DB "Û" */
+ 0x22, 0xA3, 0x18, 0xC6, 0x31, 0x70,
+
+ /* U+00DC "Ü" */
+ 0x54, 0x63, 0x18, 0xC6, 0x2E,
+
+ /* U+00DF "ß" */
+ 0x4A, 0xAC, 0xBD, 0xA0,
+
+ /* U+00E0 "à" */
+ 0x42, 0x0F, 0x17, 0x9F,
+
+ /* U+00E1 "á" */
+ 0x24, 0x0F, 0x17, 0x9F,
+
+ /* U+00E2 "â" */
+ 0x25, 0x0F, 0x17, 0x9F,
+
+ /* U+00E4 "ä" */
+ 0x50, 0xF1, 0x79, 0xF0,
+
+ /* U+00E6 "æ" */
+ 0xEC, 0x25, 0xFC, 0x8E, 0xE0,
+
+ /* U+00E7 "ç" */
+ 0x69, 0x89, 0x62, 0x26,
+
+ /* U+00E8 "è" */
+ 0x42, 0x06, 0x9F, 0x87,
+
+ /* U+00E9 "é" */
+ 0x24, 0x06, 0x9F, 0x87,
+
+ /* U+00EA "ê" */
+ 0x25, 0x06, 0x9F, 0x87,
+
+ /* U+00EB "ë" */
+ 0xA0, 0x69, 0xF8, 0x70,
+
+ /* U+00EC "ì" */
+ 0x92, 0xAA,
+
+ /* U+00ED "í" */
+ 0x61, 0x55,
+
+ /* U+00EE "î" */
+ 0x65, 0x04, 0x44, 0x44,
+
+ /* U+00EF "ï" */
+ 0xA1, 0x24, 0x90,
+
+ /* U+00F1 "ñ" */
+ 0x5A, 0x0E, 0x99, 0x99,
+
+ /* U+00F2 "ò" */
+ 0x42, 0x06, 0x99, 0x96,
+
+ /* U+00F3 "ó" */
+ 0x24, 0x06, 0x99, 0x96,
+
+ /* U+00F4 "ô" */
+ 0x25, 0x06, 0x99, 0x96,
+
+ /* U+00F6 "ö" */
+ 0xA0, 0x69, 0x99, 0x60,
+
+ /* U+00F9 "ù" */
+ 0x42, 0x09, 0x99, 0x97,
+
+ /* U+00FA "ú" */
+ 0x24, 0x09, 0x99, 0x97,
+
+ /* U+00FB "û" */
+ 0x22, 0x80, 0x94, 0xA5, 0x27,
+
+ /* U+00FC "ü" */
+ 0x50, 0x99, 0x99, 0x70,
+
+ /* U+00FF "ÿ" */
+ 0x50, 0x22, 0xA5, 0x28, 0x84, 0x40,
+
+ /* U+0152 "Œ" */
+ 0x7F, 0x88, 0x88, 0x8F, 0x88, 0x88, 0x7F,
+
+ /* U+0153 "œ" */
+ 0x76, 0x89, 0x8F, 0x88, 0x77,
+
+ /* U+0178 "Ÿ" */
+ 0x54, 0x54, 0xA2, 0x10, 0x84,
+
+ /* U+2013 "–" */
+ 0xF8,
+
+ /* U+2014 "—" */
+ 0xFF, 0x80,
+
+ /* U+201A "‚" */
+ 0xC0,
+
+ /* U+201E "„" */
+ 0xB4,
+
+ /* U+2026 "…" */
+ 0x92,
+
+ /* U+2039 "‹" */
+ 0x52, 0x20,
+
+ /* U+203A "›" */
+ 0x89, 0x40,
+
+ /* U+20AC "€" */
+ 0x3D, 0x0F, 0xD0, 0xFD, 0x03, 0xC0,
+};
+
+static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 48, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0} /* U+0020 */,
+ {.bitmap_index = 1, .adv_w = 48, .box_w = 1, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0021 */,
+ {.bitmap_index = 2, .adv_w = 48, .box_w = 3, .box_h = 2, .ofs_x = 0, .ofs_y = 5} /* U+0022 */,
+ {.bitmap_index = 3, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0023 */,
+ {.bitmap_index = 7, .adv_w = 80, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -1} /* U+0024 */,
+ {.bitmap_index = 12, .adv_w = 128, .box_w = 6, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0025 */,
+ {.bitmap_index = 18, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0026 */,
+ {.bitmap_index = 24, .adv_w = 32, .box_w = 1, .box_h = 2, .ofs_x = 0, .ofs_y = 5} /* U+0027 */,
+ {.bitmap_index = 25, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+0028 */,
+ {.bitmap_index = 29, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+0029 */,
+ {.bitmap_index = 33, .adv_w = 64, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 4} /* U+002A */,
+ {.bitmap_index = 35, .adv_w = 80, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+002B */,
+ {.bitmap_index = 39, .adv_w = 48, .box_w = 1, .box_h = 2, .ofs_x = 1, .ofs_y = -1} /* U+002C */,
+ {.bitmap_index = 40, .adv_w = 48, .box_w = 2, .box_h = 1, .ofs_x = 0, .ofs_y = 2} /* U+002D */,
+ {.bitmap_index = 41, .adv_w = 48, .box_w = 1, .box_h = 1, .ofs_x = 1, .ofs_y = 0} /* U+002E */,
+ {.bitmap_index = 42, .adv_w = 48, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+002F */,
+ {.bitmap_index = 45, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0030 */,
+ {.bitmap_index = 49, .adv_w = 80, .box_w = 2, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0031 */,
+ {.bitmap_index = 51, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0032 */,
+ {.bitmap_index = 55, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0033 */,
+ {.bitmap_index = 59, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0034 */,
+ {.bitmap_index = 64, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0035 */,
+ {.bitmap_index = 68, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0036 */,
+ {.bitmap_index = 72, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0037 */,
+ {.bitmap_index = 76, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0038 */,
+ {.bitmap_index = 80, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0039 */,
+ {.bitmap_index = 84, .adv_w = 48, .box_w = 1, .box_h = 5, .ofs_x = 1, .ofs_y = 0} /* U+003A */,
+ {.bitmap_index = 85, .adv_w = 48, .box_w = 1, .box_h = 6, .ofs_x = 1, .ofs_y = -1} /* U+003B */,
+ {.bitmap_index = 86, .adv_w = 80, .box_w = 3, .box_h = 5, .ofs_x = 1, .ofs_y = 1} /* U+003C */,
+ {.bitmap_index = 88, .adv_w = 80, .box_w = 4, .box_h = 3, .ofs_x = 0, .ofs_y = 2} /* U+003D */,
+ {.bitmap_index = 90, .adv_w = 80, .box_w = 3, .box_h = 5, .ofs_x = 1, .ofs_y = 1} /* U+003E */,
+ {.bitmap_index = 92, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+003F */,
+ {.bitmap_index = 97, .adv_w = 144, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = -2} /* U+0040 */,
+ {.bitmap_index = 106, .adv_w = 96, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0041 */,
+ {.bitmap_index = 113, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0042 */,
+ {.bitmap_index = 117, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0043 */,
+ {.bitmap_index = 122, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0044 */,
+ {.bitmap_index = 127, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0045 */,
+ {.bitmap_index = 132, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0046 */,
+ {.bitmap_index = 136, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0047 */,
+ {.bitmap_index = 141, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0048 */,
+ {.bitmap_index = 146, .adv_w = 48, .box_w = 1, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0049 */,
+ {.bitmap_index = 147, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+004A */,
+ {.bitmap_index = 151, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+004B */,
+ {.bitmap_index = 156, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+004C */,
+ {.bitmap_index = 160, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+004D */,
+ {.bitmap_index = 167, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+004E */,
+ {.bitmap_index = 172, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+004F */,
+ {.bitmap_index = 177, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0050 */,
+ {.bitmap_index = 181, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0051 */,
+ {.bitmap_index = 186, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0052 */,
+ {.bitmap_index = 191, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0053 */,
+ {.bitmap_index = 195, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0054 */,
+ {.bitmap_index = 200, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0055 */,
+ {.bitmap_index = 205, .adv_w = 96, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0056 */,
+ {.bitmap_index = 212, .adv_w = 144, .box_w = 9, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0057 */,
+ {.bitmap_index = 220, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0058 */,
+ {.bitmap_index = 225, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0059 */,
+ {.bitmap_index = 230, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+005A */,
+ {.bitmap_index = 236, .adv_w = 48, .box_w = 2, .box_h = 9, .ofs_x = 1, .ofs_y = -2} /* U+005B */,
+ {.bitmap_index = 239, .adv_w = 48, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+005C */,
+ {.bitmap_index = 242, .adv_w = 48, .box_w = 2, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+005D */,
+ {.bitmap_index = 245, .adv_w = 48, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 4} /* U+005E */,
+ {.bitmap_index = 247, .adv_w = 80, .box_w = 5, .box_h = 1, .ofs_x = 0, .ofs_y = -2} /* U+005F */,
+ {.bitmap_index = 248, .adv_w = 48, .box_w = 2, .box_h = 2, .ofs_x = 0, .ofs_y = 5} /* U+0060 */,
+ {.bitmap_index = 249, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0061 */,
+ {.bitmap_index = 252, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0062 */,
+ {.bitmap_index = 256, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0063 */,
+ {.bitmap_index = 259, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0064 */,
+ {.bitmap_index = 263, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0065 */,
+ {.bitmap_index = 266, .adv_w = 64, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0066 */,
+ {.bitmap_index = 269, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0067 */,
+ {.bitmap_index = 273, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0068 */,
+ {.bitmap_index = 277, .adv_w = 32, .box_w = 1, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0069 */,
+ {.bitmap_index = 278, .adv_w = 48, .box_w = 2, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+006A */,
+ {.bitmap_index = 281, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+006B */,
+ {.bitmap_index = 285, .adv_w = 32, .box_w = 1, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+006C */,
+ {.bitmap_index = 286, .adv_w = 128, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+006D */,
+ {.bitmap_index = 291, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+006E */,
+ {.bitmap_index = 294, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+006F */,
+ {.bitmap_index = 297, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0070 */,
+ {.bitmap_index = 301, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0071 */,
+ {.bitmap_index = 305, .adv_w = 48, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0072 */,
+ {.bitmap_index = 307, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0073 */,
+ {.bitmap_index = 310, .adv_w = 48, .box_w = 3, .box_h = 7, .ofs_x = -1, .ofs_y = 0} /* U+0074 */,
+ {.bitmap_index = 313, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0075 */,
+ {.bitmap_index = 316, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0076 */,
+ {.bitmap_index = 320, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0077 */,
+ {.bitmap_index = 324, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0078 */,
+ {.bitmap_index = 327, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0079 */,
+ {.bitmap_index = 332, .adv_w = 64, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+007A */,
+ {.bitmap_index = 334, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+007B */,
+ {.bitmap_index = 338, .adv_w = 48, .box_w = 1, .box_h = 8, .ofs_x = 1, .ofs_y = -1} /* U+007C */,
+ {.bitmap_index = 339, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+007D */,
+ {.bitmap_index = 343, .adv_w = 80, .box_w = 4, .box_h = 2, .ofs_x = 0, .ofs_y = 2} /* U+007E */,
+ {.bitmap_index = 344, .adv_w = 48, .box_w = 1, .box_h = 7, .ofs_x = 1, .ofs_y = -2} /* U+00A1 */,
+ {.bitmap_index = 345, .adv_w = 80, .box_w = 4, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+00A7 */,
+ {.bitmap_index = 350, .adv_w = 48, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 4} /* U+00AA */,
+ {.bitmap_index = 352, .adv_w = 80, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0} /* U+00AB */,
+ {.bitmap_index = 355, .adv_w = 64, .box_w = 3, .box_h = 3, .ofs_x = 1, .ofs_y = 4} /* U+00B0 */,
+ {.bitmap_index = 357, .adv_w = 48, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 4} /* U+00BA */,
+ {.bitmap_index = 359, .adv_w = 80, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0} /* U+00BB */,
+ {.bitmap_index = 362, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = -2} /* U+00BF */,
+ {.bitmap_index = 366, .adv_w = 96, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00C0 */,
+ {.bitmap_index = 374, .adv_w = 96, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00C1 */,
+ {.bitmap_index = 382, .adv_w = 96, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00C2 */,
+ {.bitmap_index = 390, .adv_w = 96, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00C4 */,
+ {.bitmap_index = 397, .adv_w = 144, .box_w = 10, .box_h = 7, .ofs_x = -1, .ofs_y = 0} /* U+00C6 */,
+ {.bitmap_index = 406, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = -3} /* U+00C7 */,
+ {.bitmap_index = 413, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00C8 */,
+ {.bitmap_index = 419, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00C9 */,
+ {.bitmap_index = 425, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00CA */,
+ {.bitmap_index = 431, .adv_w = 96, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0} /* U+00CB */,
+ {.bitmap_index = 436, .adv_w = 48, .box_w = 2, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00CC */,
+ {.bitmap_index = 439, .adv_w = 48, .box_w = 2, .box_h = 9, .ofs_x = 0, .ofs_y = 0} /* U+00CD */,
+ {.bitmap_index = 442, .adv_w = 48, .box_w = 5, .box_h = 9, .ofs_x = -2, .ofs_y = 0} /* U+00CE */,
+ {.bitmap_index = 448, .adv_w = 48, .box_w = 3, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00CF */,
+ {.bitmap_index = 451, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00D1 */,
+ {.bitmap_index = 457, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00D2 */,
+ {.bitmap_index = 463, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00D3 */,
+ {.bitmap_index = 469, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00D4 */,
+ {.bitmap_index = 475, .adv_w = 112, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0} /* U+00D6 */,
+ {.bitmap_index = 480, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00D9 */,
+ {.bitmap_index = 486, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00DA */,
+ {.bitmap_index = 492, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0} /* U+00DB */,
+ {.bitmap_index = 498, .adv_w = 112, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0} /* U+00DC */,
+ {.bitmap_index = 503, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+00DF */,
+ {.bitmap_index = 507, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00E0 */,
+ {.bitmap_index = 511, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00E1 */,
+ {.bitmap_index = 515, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00E2 */,
+ {.bitmap_index = 519, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+00E4 */,
+ {.bitmap_index = 523, .adv_w = 128, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+00E6 */,
+ {.bitmap_index = 528, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = -3} /* U+00E7 */,
+ {.bitmap_index = 532, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00E8 */,
+ {.bitmap_index = 536, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00E9 */,
+ {.bitmap_index = 540, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00EA */,
+ {.bitmap_index = 544, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+00EB */,
+ {.bitmap_index = 548, .adv_w = 32, .box_w = 2, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00EC */,
+ {.bitmap_index = 550, .adv_w = 32, .box_w = 2, .box_h = 8, .ofs_x = -1, .ofs_y = 0} /* U+00ED */,
+ {.bitmap_index = 552, .adv_w = 32, .box_w = 4, .box_h = 8, .ofs_x = -1, .ofs_y = 0} /* U+00EE */,
+ {.bitmap_index = 556, .adv_w = 32, .box_w = 3, .box_h = 7, .ofs_x = -1, .ofs_y = 0} /* U+00EF */,
+ {.bitmap_index = 559, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00F1 */,
+ {.bitmap_index = 563, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00F2 */,
+ {.bitmap_index = 567, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00F3 */,
+ {.bitmap_index = 571, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00F4 */,
+ {.bitmap_index = 575, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+00F6 */,
+ {.bitmap_index = 579, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00F9 */,
+ {.bitmap_index = 583, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0} /* U+00FA */,
+ {.bitmap_index = 587, .adv_w = 80, .box_w = 5, .box_h = 8, .ofs_x = -1, .ofs_y = 0} /* U+00FB */,
+ {.bitmap_index = 592, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+00FC */,
+ {.bitmap_index = 596, .adv_w = 96, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+00FF */,
+ {.bitmap_index = 602, .adv_w = 144, .box_w = 8, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0152 */,
+ {.bitmap_index = 609, .adv_w = 144, .box_w = 8, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0153 */,
+ {.bitmap_index = 614, .adv_w = 112, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0} /* U+0178 */,
+ {.bitmap_index = 619, .adv_w = 80, .box_w = 5, .box_h = 1, .ofs_x = 0, .ofs_y = 2} /* U+2013 */,
+ {.bitmap_index = 620, .adv_w = 144, .box_w = 9, .box_h = 1, .ofs_x = 0, .ofs_y = 2} /* U+2014 */,
+ {.bitmap_index = 622, .adv_w = 32, .box_w = 1, .box_h = 2, .ofs_x = 0, .ofs_y = -1} /* U+201A */,
+ {.bitmap_index = 623, .adv_w = 48, .box_w = 3, .box_h = 2, .ofs_x = 0, .ofs_y = -1} /* U+201E */,
+ {.bitmap_index = 624, .adv_w = 144, .box_w = 7, .box_h = 1, .ofs_x = 1, .ofs_y = 0} /* U+2026 */,
+ {.bitmap_index = 625, .adv_w = 48, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = 0} /* U+2039 */,
+ {.bitmap_index = 627, .adv_w = 48, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = 0} /* U+203A */,
+ {.bitmap_index = 629, .adv_w = 80, .box_w = 6, .box_h = 7, .ofs_x = -1, .ofs_y = 0} /* U+20AC */
+};
+
+static const lv_font_fmt_txt_cmap_t cmaps[] = {
+ {.range_start = 32, .range_length = 95, .glyph_id_start = 1,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 161, .range_length = 1, .glyph_id_start = 96,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 167, .range_length = 1, .glyph_id_start = 97,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 170, .range_length = 2, .glyph_id_start = 98,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 176, .range_length = 1, .glyph_id_start = 100,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 186, .range_length = 2, .glyph_id_start = 101,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 191, .range_length = 4, .glyph_id_start = 103,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 196, .range_length = 1, .glyph_id_start = 107,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 198, .range_length = 10, .glyph_id_start = 108,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 209, .range_length = 4, .glyph_id_start = 118,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 214, .range_length = 1, .glyph_id_start = 122,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 217, .range_length = 4, .glyph_id_start = 123,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 223, .range_length = 4, .glyph_id_start = 127,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 228, .range_length = 1, .glyph_id_start = 131,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 230, .range_length = 10, .glyph_id_start = 132,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 241, .range_length = 4, .glyph_id_start = 142,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 246, .range_length = 1, .glyph_id_start = 146,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 249, .range_length = 4, .glyph_id_start = 147,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 255, .range_length = 1, .glyph_id_start = 151,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 338, .range_length = 2, .glyph_id_start = 152,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 376, .range_length = 1, .glyph_id_start = 154,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8211, .range_length = 2, .glyph_id_start = 155,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8218, .range_length = 1, .glyph_id_start = 157,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8222, .range_length = 1, .glyph_id_start = 158,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8230, .range_length = 1, .glyph_id_start = 159,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8249, .range_length = 2, .glyph_id_start = 160,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY},
+ {.range_start = 8364, .range_length = 1, .glyph_id_start = 162,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}
+};
+
+static const lv_font_fmt_txt_dsc_t font_dsc = {
+ .glyph_bitmap = glyph_bitmap,
+ .glyph_dsc = glyph_dsc,
+ .cmaps = cmaps,
+ .kern_dsc = NULL,
+ .kern_scale = 0,
+ .cmap_num = 27,
+ .bpp = 1,
+ .kern_classes = 0,
+ .bitmap_format = 0,
+ .stride = 0,
+};
+
+const UG_FONT font_regular_9 = {
+ .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,
+ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,
+ .line_height = 9,
+ .base_line = 2,
+ .subpx = LV_FONT_SUBPX_NONE,
+ .underline_position = -1,
+ .underline_thickness = 0,
+ .static_bitmap = 0,
+ .dsc = &font_dsc,
+ .fallback = NULL,
+ .user_data = NULL,
+};
+
+#endif /* REGULAR_9 */
### src/ui/fonts/regular_9.h
@@ -0,0 +1,8 @@
+#ifndef TTF2LVGL_REGULAR_9_H
+#define TTF2LVGL_REGULAR_9_H
+
+#include <ugui.h>
+
+extern const UG_FONT font_regular_9;
+
+#endif /* TTF2LVGL_REGULAR_9_H */
### src/ui/fonts/regular_9_bootloader.c
@@ -0,0 +1,449 @@
+/*******************************************************************************
+ * Size: 9 px
+ * Bpp: 1
+ * Opts: bootloader subset of regular_9.c, range 32-126
+ ******************************************************************************/
+
+#ifdef __has_include
+ #if __has_include("lvgl.h")
+ #ifndef LV_LVGL_H_INCLUDE_SIMPLE
+ #define LV_LVGL_H_INCLUDE_SIMPLE
+ #endif
+ #endif
+#endif
+
+#ifdef LV_LVGL_H_INCLUDE_SIMPLE
+ #include "lvgl.h"
+#else
+ #include "lvgl/lvgl.h"
+#endif
+
+#include "regular_9_bootloader.h"
+
+#ifndef REGULAR_9
+#define REGULAR_9 1
+#endif
+
+#if REGULAR_9
+
+static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
+ /* U+0020 "\u0020" */
+ 0x00,
+
+ /* U+0021 "!" */
+ 0xFA,
+
+ /* U+0022 "\"" */
+ 0xB4,
+
+ /* U+0023 "#" */
+ 0x55, 0xF5, 0xFA, 0xA0,
+
+ /* U+0024 "$" */
+ 0x75, 0x68, 0xE2, 0xD5, 0xC4,
+
+ /* U+0025 "%" */
+ 0x4A, 0xC5, 0x04, 0x28, 0xD2, 0x80,
+
+ /* U+0026 "&" */
+ 0x31, 0x24, 0x9C, 0x96, 0x27, 0x40,
+
+ /* U+0027 "'" */
+ 0xC0,
+
+ /* U+0028 "(" */
+ 0x2A, 0x49, 0x22, 0x20,
+
+ /* U+0029 ")" */
+ 0x88, 0x92, 0x4A, 0x80,
+
+ /* U+002A "*" */
+ 0xEA, 0x80,
+
+ /* U+002B "+" */
+ 0x21, 0x3E, 0x42, 0x00,
+
+ /* U+002C "," */
+ 0xC0,
+
+ /* U+002D "-" */
+ 0xC0,
+
+ /* U+002E "." */
+ 0x80,
+
+ /* U+002F "/" */
+ 0x25, 0x25, 0x20,
+
+ /* U+0030 "0" */
+ 0x69, 0x99, 0x99, 0x60,
+
+ /* U+0031 "1" */
+ 0x75, 0x54,
+
+ /* U+0032 "2" */
+ 0x69, 0x12, 0x24, 0xF0,
+
+ /* U+0033 "3" */
+ 0x69, 0x12, 0x19, 0x60,
+
+ /* U+0034 "4" */
+ 0x11, 0x95, 0x2F, 0x88, 0x40,
+
+ /* U+0035 "5" */
+ 0x74, 0xE9, 0x19, 0x60,
+
+ /* U+0036 "6" */
+ 0x69, 0xE9, 0x99, 0x60,
+
+ /* U+0037 "7" */
+ 0xF1, 0x22, 0x44, 0x40,
+
+ /* U+0038 "8" */
+ 0x69, 0x96, 0x99, 0x60,
+
+ /* U+0039 "9" */
+ 0x69, 0x99, 0x79, 0x60,
+
+ /* U+003A ":" */
+ 0x88,
+
+ /* U+003B ";" */
+ 0x8C,
+
+ /* U+003C "<" */
+ 0x2A, 0x22,
+
+ /* U+003D "=" */
+ 0xF0, 0xF0,
+
+ /* U+003E ">" */
+ 0x88, 0xA8,
+
+ /* U+003F "?" */
+ 0x74, 0x42, 0x62, 0x00, 0x80,
+
+ /* U+0040 "@" */
+ 0x3C, 0x42, 0x95, 0xAD, 0xA9, 0xAA, 0xBC, 0x43, 0x3C,
+
+ /* U+0041 "A" */
+ 0x10, 0x51, 0x12, 0x27, 0xC8, 0x91, 0x00,
+
+ /* U+0042 "B" */
+ 0xE9, 0x9F, 0x99, 0xE0,
+
+ /* U+0043 "C" */
+ 0x74, 0x61, 0x08, 0x45, 0xC0,
+
+ /* U+0044 "D" */
+ 0xF4, 0x63, 0x18, 0xC7, 0xC0,
+
+ /* U+0045 "E" */
+ 0xFC, 0x21, 0xF8, 0x43, 0xE0,
+
+ /* U+0046 "F" */
+ 0xF8, 0x8E, 0x88, 0x80,
+
+ /* U+0047 "G" */
+ 0x74, 0x61, 0x38, 0xC5, 0xC0,
+
+ /* U+0048 "H" */
+ 0x8C, 0x63, 0xF8, 0xC6, 0x20,
+
+ /* U+0049 "I" */
+ 0xFE,
+
+ /* U+004A "J" */
+ 0x11, 0x11, 0x19, 0xE0,
+
+ /* U+004B "K" */
+ 0x8C, 0xA9, 0x8A, 0x4A, 0x20,
+
+ /* U+004C "L" */
+ 0x88, 0x88, 0x88, 0xF0,
+
+ /* U+004D "M" */
+ 0x83, 0x8F, 0x1D, 0x5A, 0xB5, 0x64, 0x80,
+
+ /* U+004E "N" */
+ 0x8E, 0x73, 0x59, 0xCE, 0x20,
+
+ /* U+004F "O" */
+ 0x74, 0x63, 0x18, 0xC5, 0xC0,
+
+ /* U+0050 "P" */
+ 0xF9, 0x9F, 0x88, 0x80,
+
+ /* U+0051 "Q" */
+ 0x74, 0x63, 0x18, 0xC9, 0xE0,
+
+ /* U+0052 "R" */
+ 0xF4, 0x63, 0xE9, 0x46, 0x20,
+
+ /* U+0053 "S" */
+ 0x69, 0x86, 0x19, 0x60,
+
+ /* U+0054 "T" */
+ 0xF9, 0x08, 0x42, 0x10, 0x80,
+
+ /* U+0055 "U" */
+ 0x8C, 0x63, 0x18, 0xC5, 0xC0,
+
+ /* U+0056 "V" */
+ 0x44, 0x89, 0x12, 0x22, 0x85, 0x04, 0x00,
+
+ /* U+0057 "W" */
+ 0x88, 0xCA, 0x55, 0x4A, 0xA5, 0x52, 0xA8, 0x88,
+
+ /* U+0058 "X" */
+ 0x8A, 0x94, 0x45, 0x2A, 0x20,
+
+ /* U+0059 "Y" */
+ 0x8A, 0x94, 0x42, 0x10, 0x80,
+
+ /* U+005A "Z" */
+ 0xFC, 0x21, 0x08, 0x42, 0x0F, 0xC0,
+
+ /* U+005B "[" */
+ 0xEA, 0xAA, 0xC0,
+
+ /* U+005C "\\" */
+ 0x91, 0x24, 0x48,
+
+ /* U+005D "]" */
+ 0xD5, 0x55, 0xC0,
+
+ /* U+005E "^" */
+ 0x56, 0x80,
+
+ /* U+005F "_" */
+ 0xF8,
+
+ /* U+0060 "`" */
+ 0x90,
+
+ /* U+0061 "a" */
+ 0xF1, 0x79, 0xF0,
+
+ /* U+0062 "b" */
+ 0x88, 0xE9, 0x99, 0xE0,
+
+ /* U+0063 "c" */
+ 0x69, 0x89, 0x60,
+
+ /* U+0064 "d" */
+ 0x11, 0x79, 0x99, 0x70,
+
+ /* U+0065 "e" */
+ 0x69, 0xF8, 0x70,
+
+ /* U+0066 "f" */
+ 0x2B, 0xA4, 0x90,
+
+ /* U+0067 "g" */
+ 0x79, 0x99, 0x79, 0x60,
+
+ /* U+0068 "h" */
+ 0x88, 0xE9, 0x99, 0x90,
+
+ /* U+0069 "i" */
+ 0xBE,
+
+ /* U+006A "j" */
+ 0x45, 0x55, 0x80,
+
+ /* U+006B "k" */
+ 0x88, 0x9A, 0xEA, 0x90,
+
+ /* U+006C "l" */
+ 0xFE,
+
+ /* U+006D "m" */
+ 0xFD, 0x26, 0x4C, 0x99, 0x20,
+
+ /* U+006E "n" */
+ 0xE9, 0x99, 0x90,
+
+ /* U+006F "o" */
+ 0x69, 0x99, 0x60,
+
+ /* U+0070 "p" */
+ 0xE9, 0x99, 0xE8, 0x80,
+
+ /* U+0071 "q" */
+ 0x79, 0x99, 0x71, 0x10,
+
+ /* U+0072 "r" */
+ 0xF2, 0x48,
+
+ /* U+0073 "s" */
+ 0x78, 0x61, 0xE0,
+
+ /* U+0074 "t" */
+ 0x09, 0xA4, 0x98,
+
+ /* U+0075 "u" */
+ 0x99, 0x99, 0x70,
+
+ /* U+0076 "v" */
+ 0x8A, 0x94, 0xA2, 0x00,
+
+ /* U+0077 "w" */
+ 0xAD, 0x6B, 0x55, 0x00,
+
+ /* U+0078 "x" */
+ 0x96, 0x46, 0x90,
+
+ /* U+0079 "y" */
+ 0x8A, 0x94, 0xA2, 0x11, 0x00,
+
+ /* U+007A "z" */
+ 0xE5, 0x4E,
+
+ /* U+007B "{" */
+ 0x69, 0x28, 0x92, 0x60,
+
+ /* U+007C "|" */
+ 0xFF,
+
+ /* U+007D "}" */
+ 0xC9, 0x22, 0x92, 0xC0,
+
+ /* U+007E "~" */
+ 0xDB,
+
+};
+
+static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 48, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0} /* U+0020 */,
+ {.bitmap_index = 1, .adv_w = 48, .box_w = 1, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0021 */,
+ {.bitmap_index = 2, .adv_w = 48, .box_w = 3, .box_h = 2, .ofs_x = 0, .ofs_y = 5} /* U+0022 */,
+ {.bitmap_index = 3, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0023 */,
+ {.bitmap_index = 7, .adv_w = 80, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -1} /* U+0024 */,
+ {.bitmap_index = 12, .adv_w = 128, .box_w = 6, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0025 */,
+ {.bitmap_index = 18, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0026 */,
+ {.bitmap_index = 24, .adv_w = 32, .box_w = 1, .box_h = 2, .ofs_x = 0, .ofs_y = 5} /* U+0027 */,
+ {.bitmap_index = 25, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+0028 */,
+ {.bitmap_index = 29, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+0029 */,
+ {.bitmap_index = 33, .adv_w = 64, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 4} /* U+002A */,
+ {.bitmap_index = 35, .adv_w = 80, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+002B */,
+ {.bitmap_index = 39, .adv_w = 48, .box_w = 1, .box_h = 2, .ofs_x = 1, .ofs_y = -1} /* U+002C */,
+ {.bitmap_index = 40, .adv_w = 48, .box_w = 2, .box_h = 1, .ofs_x = 0, .ofs_y = 2} /* U+002D */,
+ {.bitmap_index = 41, .adv_w = 48, .box_w = 1, .box_h = 1, .ofs_x = 1, .ofs_y = 0} /* U+002E */,
+ {.bitmap_index = 42, .adv_w = 48, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+002F */,
+ {.bitmap_index = 45, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0030 */,
+ {.bitmap_index = 49, .adv_w = 80, .box_w = 2, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0031 */,
+ {.bitmap_index = 51, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0032 */,
+ {.bitmap_index = 55, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0033 */,
+ {.bitmap_index = 59, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0034 */,
+ {.bitmap_index = 64, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0035 */,
+ {.bitmap_index = 68, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0036 */,
+ {.bitmap_index = 72, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0037 */,
+ {.bitmap_index = 76, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0038 */,
+ {.bitmap_index = 80, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0039 */,
+ {.bitmap_index = 84, .adv_w = 48, .box_w = 1, .box_h = 5, .ofs_x = 1, .ofs_y = 0} /* U+003A */,
+ {.bitmap_index = 85, .adv_w = 48, .box_w = 1, .box_h = 6, .ofs_x = 1, .ofs_y = -1} /* U+003B */,
+ {.bitmap_index = 86, .adv_w = 80, .box_w = 3, .box_h = 5, .ofs_x = 1, .ofs_y = 1} /* U+003C */,
+ {.bitmap_index = 88, .adv_w = 80, .box_w = 4, .box_h = 3, .ofs_x = 0, .ofs_y = 2} /* U+003D */,
+ {.bitmap_index = 90, .adv_w = 80, .box_w = 3, .box_h = 5, .ofs_x = 1, .ofs_y = 1} /* U+003E */,
+ {.bitmap_index = 92, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+003F */,
+ {.bitmap_index = 97, .adv_w = 144, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = -2} /* U+0040 */,
+ {.bitmap_index = 106, .adv_w = 96, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0041 */,
+ {.bitmap_index = 113, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0042 */,
+ {.bitmap_index = 117, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0043 */,
+ {.bitmap_index = 122, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0044 */,
+ {.bitmap_index = 127, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0045 */,
+ {.bitmap_index = 132, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0046 */,
+ {.bitmap_index = 136, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0047 */,
+ {.bitmap_index = 141, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0048 */,
+ {.bitmap_index = 146, .adv_w = 48, .box_w = 1, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0049 */,
+ {.bitmap_index = 147, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+004A */,
+ {.bitmap_index = 151, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+004B */,
+ {.bitmap_index = 156, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+004C */,
+ {.bitmap_index = 160, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+004D */,
+ {.bitmap_index = 167, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+004E */,
+ {.bitmap_index = 172, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+004F */,
+ {.bitmap_index = 177, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0050 */,
+ {.bitmap_index = 181, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0051 */,
+ {.bitmap_index = 186, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0052 */,
+ {.bitmap_index = 191, .adv_w = 96, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0053 */,
+ {.bitmap_index = 195, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0054 */,
+ {.bitmap_index = 200, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0055 */,
+ {.bitmap_index = 205, .adv_w = 96, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0056 */,
+ {.bitmap_index = 212, .adv_w = 144, .box_w = 9, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0057 */,
+ {.bitmap_index = 220, .adv_w = 80, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0058 */,
+ {.bitmap_index = 225, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0} /* U+0059 */,
+ {.bitmap_index = 230, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+005A */,
+ {.bitmap_index = 236, .adv_w = 48, .box_w = 2, .box_h = 9, .ofs_x = 1, .ofs_y = -2} /* U+005B */,
+ {.bitmap_index = 239, .adv_w = 48, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+005C */,
+ {.bitmap_index = 242, .adv_w = 48, .box_w = 2, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+005D */,
+ {.bitmap_index = 245, .adv_w = 48, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 4} /* U+005E */,
+ {.bitmap_index = 247, .adv_w = 80, .box_w = 5, .box_h = 1, .ofs_x = 0, .ofs_y = -2} /* U+005F */,
+ {.bitmap_index = 248, .adv_w = 48, .box_w = 2, .box_h = 2, .ofs_x = 0, .ofs_y = 5} /* U+0060 */,
+ {.bitmap_index = 249, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0061 */,
+ {.bitmap_index = 252, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0062 */,
+ {.bitmap_index = 256, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0063 */,
+ {.bitmap_index = 259, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0064 */,
+ {.bitmap_index = 263, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0065 */,
+ {.bitmap_index = 266, .adv_w = 64, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0066 */,
+ {.bitmap_index = 269, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0067 */,
+ {.bitmap_index = 273, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0068 */,
+ {.bitmap_index = 277, .adv_w = 32, .box_w = 1, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+0069 */,
+ {.bitmap_index = 278, .adv_w = 48, .box_w = 2, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+006A */,
+ {.bitmap_index = 281, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+006B */,
+ {.bitmap_index = 285, .adv_w = 32, .box_w = 1, .box_h = 7, .ofs_x = 0, .ofs_y = 0} /* U+006C */,
+ {.bitmap_index = 286, .adv_w = 128, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+006D */,
+ {.bitmap_index = 291, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+006E */,
+ {.bitmap_index = 294, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+006F */,
+ {.bitmap_index = 297, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0070 */,
+ {.bitmap_index = 301, .adv_w = 80, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0071 */,
+ {.bitmap_index = 305, .adv_w = 48, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0072 */,
+ {.bitmap_index = 307, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0073 */,
+ {.bitmap_index = 310, .adv_w = 48, .box_w = 3, .box_h = 7, .ofs_x = -1, .ofs_y = 0} /* U+0074 */,
+ {.bitmap_index = 313, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0075 */,
+ {.bitmap_index = 316, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0076 */,
+ {.bitmap_index = 320, .adv_w = 96, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0077 */,
+ {.bitmap_index = 324, .adv_w = 80, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+0078 */,
+ {.bitmap_index = 327, .adv_w = 96, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = -2} /* U+0079 */,
+ {.bitmap_index = 332, .adv_w = 64, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 0} /* U+007A */,
+ {.bitmap_index = 334, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+007B */,
+ {.bitmap_index = 338, .adv_w = 48, .box_w = 1, .box_h = 8, .ofs_x = 1, .ofs_y = -1} /* U+007C */,
+ {.bitmap_index = 339, .adv_w = 48, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = -2} /* U+007D */,
+ {.bitmap_index = 343, .adv_w = 80, .box_w = 4, .box_h = 2, .ofs_x = 0, .ofs_y = 2} /* U+007E */,
+};
+
+static const lv_font_fmt_txt_cmap_t cmaps[] = {
+ {.range_start = 32, .range_length = 95, .glyph_id_start = 1,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,
+ .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}
+};
+
+static const lv_font_fmt_txt_dsc_t font_dsc = {
+ .glyph_bitmap = glyph_bitmap,
+ .glyph_dsc = glyph_dsc,
+ .cmaps = cmaps,
+ .kern_dsc = NULL,
+ .kern_scale = 0,
+ .cmap_num = 1,
+ .bpp = 1,
+ .kern_classes = 0,
+ .bitmap_format = 0,
+ .stride = 0,
+};
+
+const UG_FONT font_regular_9 = {
+ .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,
+ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,
+ .line_height = 9,
+ .base_line = 2,
+ .subpx = LV_FONT_SUBPX_NONE,
+ .underline_position = -1,
+ .underline_thickness = 0,
+ .static_bitmap = 0,
+ .dsc = &font_dsc,
+ .fallback = NULL,
+ .user_data = NULL,
+};
+
+#endif /* REGULAR_9 */
### src/ui/fonts/regular_9_bootloader.h
@@ -0,0 +1,8 @@
+#ifndef TTF2LVGL_REGULAR_9_BOOTLOADER_H
+#define TTF2LVGL_REGULAR_9_BOOTLOADER_H
+
+#include <ugui.h>
+
+extern const UG_FONT font_regular_9;
+
+#endif /* TTF2LVGL_REGULAR_9_BOOTLOADER_H */
### src/ui/fonts/regular_fonts.h
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef _REGULAR_FONTS_H_
+#define _REGULAR_FONTS_H_
+
+#include "regular_11.h"
+#include "regular_12.h"
+#include "regular_9.h"
+#include "monogram_16.h"
+
+#endif
### src/ui/oled/oled.c
@@ -57,13 +57,11 @@
#include <driver_init.h>
#include <hardfault.h>
#include <memory/memory_shared.h>
-#include <screen.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <ui/oled/sh1107.h>
#include <ui/oled/ssd1312.h>
-#include <ui/ugui/ugui.h>
static bool _frame_buffer_updated = false;
static uint8_t _frame_buffer[128 * 8];
### src/ui/ugui/ugui.c
@@ -51,6 +51,7 @@
#include <stdbool.h>
#include <string.h>
+#include <hardfault.h>
#include <ui/oled/oled.h>
#include <util.h>
#include <utils_assert.h>
@@ -87,99 +88,128 @@ static void _UG_PSet(UG_S16 x, UG_S16 y, UG_COLOR c)
gui->pset(x, y, c);
}
-static void _UG_PutChar( char chr, UG_S16 x, UG_S16 y, UG_COLOR fc, UG_COLOR bc,
- const UG_FONT *font)
-{
- UG_U16 i, j, k, xo, yo, c, bn, actual_char_width;
- UG_U8 b, bt;
- UG_U32 index;
- UG_COLOR color;
-
- bt = (UG_U8)chr;
-
- switch (bt ) {
- case 0xF6:
- bt = 0x94;
- break; // ö
- case 0xD6:
- bt = 0x99;
- break; // Ö
- case 0xFC:
- bt = 0x81;
- break; // ü
- case 0xDC:
- bt = 0x9A;
- break; // Ü
- case 0xE4:
- bt = 0x84;
- break; // ä
- case 0xC4:
- bt = 0x8E;
- break; // Ä
- case 0xB5:
- bt = 0xE6;
- break; // µ
- case 0xB0:
- bt = 0xF8;
- break; // °
- default:
- break;
+static bool _UG_IsUtf8Continuation(uint8_t byte)
+{
+ return (byte & 0xC0) == 0x80;
+}
+
+/**
+ * Decodes the next UTF-8 codepoint and returns the byte after it.
+ *
+ * The leading byte determines the sequence length. ASCII bytes are returned
+ * directly, valid 2-, 3-, and 4-byte sequences are assembled from their payload
+ * bits. Returns NULL on malformed UTF-8, leaving `codepoint` unchanged.
+ * At the NUL terminator, sets `codepoint` to zero and returns `str` unchanged.
+ */
+static const char* _UG_NextCodepoint(const char* str, uint32_t* codepoint)
+{
+ const uint8_t* bytes = (const uint8_t*)str;
+ if (bytes[0] == '\0') {
+ *codepoint = '\0';
+ return str;
+ }
+ if (bytes[0] < 0x80) {
+ *codepoint = bytes[0];
+ return str + 1;
+ }
+ if (bytes[0] >= 0xC2 && bytes[0] <= 0xDF && _UG_IsUtf8Continuation(bytes[1])) {
+ *codepoint = ((uint32_t)(bytes[0] & 0x1F) << 6) | (uint32_t)(bytes[1] & 0x3F);
+ return str + 2;
+ }
+ if (bytes[0] >= 0xE0 && bytes[0] <= 0xEF && _UG_IsUtf8Continuation(bytes[1]) &&
+ (bytes[0] != 0xE0 || bytes[1] >= 0xA0) &&
+ (bytes[0] != 0xED || bytes[1] <= 0x9F) && _UG_IsUtf8Continuation(bytes[2])) {
+ *codepoint = ((uint32_t)(bytes[0] & 0x0F) << 12) |
+ ((uint32_t)(bytes[1] & 0x3F) << 6) | (uint32_t)(bytes[2] & 0x3F);
+ return str + 3;
+ }
+ if (bytes[0] >= 0xF0 && bytes[0] <= 0xF4 && _UG_IsUtf8Continuation(bytes[1]) &&
+ (bytes[0] != 0xF0 || bytes[1] >= 0x90) &&
+ (bytes[0] != 0xF4 || bytes[1] <= 0x8F) && _UG_IsUtf8Continuation(bytes[2]) &&
+ _UG_IsUtf8Continuation(bytes[3])) {
+ *codepoint = ((uint32_t)(bytes[0] & 0x07) << 18) |
+ ((uint32_t)(bytes[1] & 0x3F) << 12) |
+ ((uint32_t)(bytes[2] & 0x3F) << 6) | (uint32_t)(bytes[3] & 0x3F);
+ return str + 4;
+ }
+ return NULL;
+}
+
+static bool _UG_GetGlyph(const UG_FONT* font, uint32_t codepoint, lv_font_glyph_dsc_t* glyph_dsc)
+{
+ for (const lv_font_t* f = font; f != NULL; f = f->fallback) {
+ if (f->get_glyph_dsc == NULL) {
+ continue;
+ }
+ if (f->get_glyph_dsc(f, glyph_dsc, codepoint, 0)) {
+ glyph_dsc->resolved_font = f;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool UG_GetCharWidth(const UG_FONT* font, uint32_t codepoint, UG_U16* width)
+{
+ lv_font_glyph_dsc_t glyph_dsc;
+ if (!_UG_GetGlyph(font, codepoint, &glyph_dsc)) {
+ return false;
}
+ *width = glyph_dsc.adv_w;
+ return true;
+}
- if (bt < font->start_char || bt > font->end_char) {
+static bool _UG_GlyphPixelSet(
+ const uint8_t* bitmap,
+ const lv_font_glyph_dsc_t* glyph_dsc,
+ UG_U16 x,
+ UG_U16 y)
+{
+ uint32_t bit_index = (uint32_t)y * glyph_dsc->box_w + x;
+ return ((bitmap[bit_index / 8] >> (7 - (bit_index % 8))) & 0x01) != 0;
+}
+
+static void _UG_PutCodepoint( uint32_t codepoint, UG_S16 x, UG_S16 y, UG_COLOR fc, UG_COLOR bc,
+ const UG_FONT *font)
+{
+ lv_font_glyph_dsc_t glyph_dsc;
+ if (!_UG_GetGlyph(font, codepoint, &glyph_dsc)) {
+ return;
+ }
+ const lv_font_t* resolved_font = glyph_dsc.resolved_font;
+ if (resolved_font == NULL || glyph_dsc.format != LV_FONT_GLYPH_FORMAT_A1 ||
+ glyph_dsc.stride != 0) {
return;
}
- yo = y;
- bn = font->char_width;
- if ( !bn ) {
+ if (x + glyph_dsc.adv_w < 0 || x > gui->x_dim) {
return;
}
- bn >>= 3;
- if ( font->char_width % 8 ) {
- bn++;
+
+ for (UG_S16 row = 0; row < font->line_height; row++) {
+ for (UG_U16 col = 0; col < glyph_dsc.adv_w; col++) {
+ _UG_PSet(x + col, y + row, bc);
+ }
+ }
+ if (codepoint == '\t' || glyph_dsc.box_w == 0 || glyph_dsc.box_h == 0 ||
+ resolved_font->get_glyph_bitmap == NULL) {
+ return;
}
- actual_char_width = (font->widths ? font->widths[bt - font->start_char] :
- font->char_width);
- if (x + actual_char_width < 0 || x > gui->x_dim) {
+ const uint8_t* bitmap = (const uint8_t*)resolved_font->get_glyph_bitmap(&glyph_dsc, NULL);
+ if (bitmap == NULL) {
return;
}
- if (font->font_type == FONT_TYPE_1BPP) {
- index = (bt - font->start_char) * font->char_height * bn;
- for ( j = 0; j < font->char_height; j++ ) {
- xo = x;
- c = actual_char_width;
- for ( i = 0; i < bn; i++ ) {
- b = font->p[index++];
- for ( k = 0; (k < 8) && c; k++ ) {
- if ( b & 0x01 ) {
- _UG_PSet(xo, yo, fc);
- } else {
- _UG_PSet(xo, yo, bc);
- }
- b >>= 1;
- xo++;
- c--;
- }
- }
- yo++;
- }
- } else if (font->font_type == FONT_TYPE_8BPP) {
- index = (bt - font->start_char) * font->char_height * font->char_width;
- for ( j = 0; j < font->char_height; j++ ) {
- xo = x;
- for ( i = 0; i < actual_char_width; i++ ) {
- b = font->p[index++];
- color = ((((fc & 0xFF) * b + (bc & 0xFF) * (256 - b)) >> 8) & 0xFF) |//Blue component
- ((((fc & 0xFF00) * b + (bc & 0xFF00) * (256 - b)) >> 8) & 0xFF00) |//Green component
- ((((fc & 0xFF0000) * b + (bc & 0xFF0000) * (256 - b)) >> 8) & 0xFF0000); //Red component
- _UG_PSet(xo, yo, color);
- xo++;
+ UG_S16 glyph_y =
+ font->line_height - resolved_font->base_line - glyph_dsc.box_h - glyph_dsc.ofs_y;
+ for (UG_U16 row = 0; row < glyph_dsc.box_h; row++) {
+ for (UG_U16 col = 0; col < glyph_dsc.box_w; col++) {
+ UG_S16 xo = x + glyph_dsc.ofs_x + col;
+ UG_S16 yo = y + glyph_y + row;
+ if (_UG_GlyphPixelSet(bitmap, &glyph_dsc, col, row)) {
+ _UG_PSet(xo, yo, fc);
}
- index += font->char_width - actual_char_width;
- yo++;
}
}
}
@@ -190,39 +220,41 @@ static void _UG_PutString( UG_S16 x, UG_S16 y, UG_S16 *xout, UG_S16 *yout, const
ASSERT(gui != NULL);
UG_S16 xp, yp;
- UG_U8 cw;
- char chr;
+ UG_U16 cw;
+ uint32_t codepoint;
UG_S16 max_x = x;
xp = x;
yp = y;
- const int str_length = strlens(str);
+ const char* cursor = str;
- for (int i = 0; i < str_length; i++) {
- chr = str[i];
- if (chr != '\n' && (chr < gui->font.start_char || chr > gui->font.end_char)) {
+ while (*cursor != '\0') {
+ cursor = _UG_NextCodepoint(cursor, &codepoint);
+ if (cursor == NULL) {
+ Abort("Invalid UTF-8 string");
+ }
+ if (codepoint != '\n' && !UG_GetCharWidth(gui->font, codepoint, &cw)) {
continue;
}
- if ( chr == '\n' ) {
+ if ( codepoint == '\n' ) {
if (autobreak == 1) {
xp = gui->x_dim;
} else {
xp = x;
- yp += gui->font.char_height + gui->char_v_space;
+ yp += gui->font->line_height + gui->char_v_space;
}
continue;
}
- cw = gui->font.widths ? gui->font.widths[chr - gui->font.start_char] :
- gui->font.char_width;
if ( autobreak == 1 && xp + cw > gui->x_dim - 1 ) {
xp = x;
- yp += gui->font.char_height + gui->char_v_space;
+ yp += gui->font->line_height + gui->char_v_space;
}
if (!calconly) {
- UG_PutChar(chr, xp, yp, gui->fore_color, gui->back_color);
+ _UG_PutCodepoint(
+ codepoint, xp, yp, gui->fore_color, gui->back_color, gui->font);
}
xp += cw + gui->char_h_space;
@@ -234,7 +266,7 @@ static void _UG_PutString( UG_S16 x, UG_S16 y, UG_S16 *xout, UG_S16 *yout, const
*xout = max_x;
}
if (yout) {
- *yout = yp + gui->font.char_height;
+ *yout = yp + gui->font->line_height;
}
}
@@ -248,7 +280,7 @@ UG_S16 UG_Init( UG_GUI *g, void (*p)(UG_S16, UG_S16, UG_COLOR),
g->pset = p;
g->x_dim = x;
g->y_dim = y;
- g->font = *font;
+ g->font = font;
g->char_h_space = 1;
g->char_v_space = 1;
g->fore_color = C_WHITE;
@@ -264,7 +296,7 @@ void UG_FontSelect( const UG_FONT *font )
ASSERT(gui != NULL);
ASSERT(font != NULL);
- gui->font = *font;
+ gui->font = font;
}
void UG_FillScreen( UG_COLOR c )
@@ -633,15 +665,42 @@ static bool _is_whitespace(char c) {
}
static UG_S16 _word_width(const char* p) {
- const UG_FONT* font = &gui->font;
+ const UG_FONT* font = gui->font;
UG_S16 x = 0;
while(!_is_whitespace(*p)) {
- x += font->widths[(UG_U8)*p - font->start_char];
- p += 1;
+ uint32_t codepoint = 0;
+ p = _UG_NextCodepoint(p, &codepoint);
+ if (p == NULL) {
+ Abort("Invalid UTF-8 string");
+ }
+ UG_U16 char_width = 0;
+ if (UG_GetCharWidth(font, codepoint, &char_width)) {
+ x += char_width;
+ }
}
return x;
}
+static void _copy_codepoint(const char** str, char** str_out, UG_S16* x)
+{
+ const UG_FONT* font = gui->font;
+ const char* next;
+ uint32_t codepoint = 0;
+ UG_U16 char_width = 0;
+ next = _UG_NextCodepoint(*str, &codepoint);
+ if (next == NULL) {
+ Abort("Invalid UTF-8 string");
+ }
+ while (*str < next) {
+ **str_out = **str;
+ *str_out += 1;
+ *str += 1;
+ }
+ if (UG_GetCharWidth(font, codepoint, &char_width)) {
+ *x += char_width;
+ }
+}
+
// Try to wrap string at spaces if it is longer than `width` pixels.
// Since the purpose of this function is to wrap title text, only wrap a single time. The rest of
// the title may span/overflow the whole screen.
@@ -653,7 +712,7 @@ void UG_WrapTitleString(const char* str, char* str_out, UG_S16 width) {
ASSERT(str_out != NULL);
const char* start = str;
- const UG_FONT* font = &gui->font;
+ const UG_FONT* font = gui->font;
UG_S16 x = 0;
// This loop will copy bytes until the first newline.
@@ -668,7 +727,9 @@ void UG_WrapTitleString(const char* str, char* str_out, UG_S16 width) {
}
if (*str == ' ') {
UG_S16 wwidth = _word_width(str+1);
- if (x + font->widths[(UG_U8)' ' - font->start_char] + wwidth > width) {
+ UG_U16 space_width = 0;
+ UG_GetCharWidth(font, ' ', &space_width);
+ if (x + space_width + wwidth > width) {
*str_out = '\n';
str_out += 1;
str += 1;
@@ -678,12 +739,7 @@ void UG_WrapTitleString(const char* str, char* str_out, UG_S16 width) {
str_out += 1;
str += 1;
while (!_is_whitespace(*str)) {
- *str_out = *str;
- if (*str >= font->start_char){
- x += font->widths[(UG_U8)*str - font->start_char];
- }
- str_out += 1;
- str += 1;
+ _copy_codepoint(&str, &str_out, &x);
}
continue;
}
@@ -696,12 +752,7 @@ void UG_WrapTitleString(const char* str, char* str_out, UG_S16 width) {
break;
}
}
- *str_out = *str;
- if (*str >= font->start_char && *str < font->end_char){
- x += font->widths[(UG_U8)*str - font->start_char];
- }
- str_out += 1;
- str += 1;
+ _copy_codepoint(&str, &str_out, &x);
}
// Copy any bytes that are left
@@ -815,7 +866,7 @@ void UG_PutChar( char chr, UG_S16 x, UG_S16 y, UG_COLOR fc, UG_COLOR bc )
{
ASSERT(gui != NULL);
- _UG_PutChar(chr, x, y, fc, bc, &gui->font);
+ _UG_PutCodepoint((UG_U8)chr, x, y, fc, bc, gui->font);
}
void UG_SetForecolor( UG_COLOR c )
### src/ui/ugui/ugui.h
@@ -25,6 +25,8 @@
#include <stdlib.h>
#include <math.h>
+#include <ui/fonts/lvgl.h>
+
/* -------------------------------------------------------------------------------- */
/* -- TYPEDEFS -- */
/* -------------------------------------------------------------------------------- */
@@ -40,22 +42,9 @@ typedef UG_U8 UG_COLOR;
/* -------------------------------------------------------------------------------- */
/* -- µGUI FONTS -- */
/* -------------------------------------------------------------------------------- */
-typedef enum {
- FONT_TYPE_1BPP,
- FONT_TYPE_8BPP
-} FONT_TYPE;
-
-typedef struct {
- unsigned char *p;
- FONT_TYPE font_type;
- UG_S16 char_width;
- UG_S16 char_height;
- UG_U16 start_char;
- UG_U16 end_char;
- UG_U8 *widths;
-} UG_FONT;
-
-#define UG_FONT_DATA const
+// Fonts retained by the GUI or components must have static lifetime, including their referenced
+// glyph data and fallback fonts.
+typedef lv_font_t UG_FONT;
/* -------------------------------------------------------------------------------- */
/* -- µGUI CORE STRUCTURE -- */
@@ -64,7 +53,7 @@ typedef struct {
void (*pset)(UG_S16, UG_S16, UG_COLOR);
UG_S16 x_dim;
UG_S16 y_dim;
- UG_FONT font;
+ const UG_FONT *font;
UG_S8 char_h_space;
UG_S8 char_v_space;
UG_COLOR fore_color;
@@ -91,8 +80,16 @@ typedef struct {
/* -- PROTOTYPES -- */
/* -------------------------------------------------------------------------------- */
+/**
+ * Initializes and selects the GUI, retaining `font` for later rendering.
+ * @param[in] font The initial font. Must have static lifetime.
+ */
UG_S16 UG_Init( UG_GUI *g, void (*p)(UG_S16, UG_S16, UG_COLOR),
const UG_FONT *font, UG_S16 x, UG_S16 y );
+/**
+ * Selects and retains the font in the current GUI.
+ * @param[in] font The font to use. Must have static lifetime.
+ */
void UG_FontSelect( const UG_FONT *font );
void UG_FillScreen( UG_COLOR c );
void UG_FillFrame( UG_S16 x1, UG_S16 y1, UG_S16 x2, UG_S16 y2, UG_COLOR c );
@@ -120,6 +117,7 @@ void UG_PutStringNoBreak( UG_S16 x, UG_S16 y, const char *str);
void UG_MeasureString( UG_S16 *xout, UG_S16 *yout, const char *str);
void UG_MeasureStringNoBreak(UG_S16 *xout, UG_S16 *yout, const char *str);
void UG_MeasureStringCentered( UG_S16 *xout, UG_S16 *yout, const char *str);
+bool UG_GetCharWidth(const UG_FONT* font, uint32_t codepoint, UG_U16* width);
void UG_PutStringNoBreakCenter( UG_S16 x, UG_S16 y, UG_S16 width, const char *str);
void UG_PutStringCentered( UG_S16 x, UG_S16 y, UG_S16 width, UG_S16 height, const char *str);
void UG_PutChar( char chr, UG_S16 x, UG_S16 y, UG_COLOR fc, UG_COLOR bc );
### src/util.c
@@ -69,20 +69,6 @@ intptr_t util_utf8_strlcpy(char* dst, const char* src, const size_t dst_len)
return util_utf8_copy(dst, dst_len, src, strlen(src));
}
-bool util_is_printable_ascii(const char* str, const bool allow_newline)
-{
- if (str == NULL) {
- return false;
- }
- for (; *str != '\0'; str++) {
- const unsigned char chr = (unsigned char)*str;
- if ((chr < 32 || chr > 126) && !(allow_newline && chr == '\n')) {
- return false;
- }
- }
- return true;
-}
-
void util_uint8_to_hex(const uint8_t* in_bin, const size_t in_len, char* out)
{
memset(out, 0, in_len * 2 + 1);
### src/util.h
@@ -63,9 +63,6 @@ intptr_t util_utf8_copy(char* dst, size_t dst_len, const char* src, size_t src_l
*/
intptr_t util_utf8_strlcpy(char* dst, const char* src, size_t dst_len);
-/** Returns true if `str` contains only printable ASCII, optionally including newlines. */
-bool util_is_printable_ascii(const char* str, bool allow_newline);
-
// `out` must be of size in_len*2+1. Use BB_HEX_SIZE() to compute the size.
void util_uint8_to_hex(const uint8_t* in_bin, size_t in_len, char* out);
### test/unit-test/CMakeLists.txt
@@ -51,6 +51,8 @@ else()
""
ui_components
""
+ lockscreen
+ ""
ui_util
""
ui_component_gestures
@@ -68,7 +70,7 @@ else()
util
""
ugui
- ""
+ "-Wl,--wrap=Abort"
)
list(LENGTH TEST_LIST TEST_LIST_LEN)
### test/unit-test/test_lockscreen.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: Apache-2.0
+
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <cmocka.h>
+
+#include "../../src/ui/components/lockscreen.c"
+
+static UG_GUI gui;
+
+static void _set_pixel(UG_S16 x, UG_S16 y, UG_COLOR color)
+{
+ (void)x;
+ (void)y;
+ (void)color;
+}
+
+static int _setup(void** state)
+{
+ (void)state;
+ UG_Init(&gui, _set_pixel, &font_regular_9, SCREEN_WIDTH, SCREEN_HEIGHT);
+ return 0;
+}
+
+static void test_truncate_to_fit_utf8(void** state)
+{
+ (void)state;
+ const char* names[] = {
+ "ThisIsANiceValidNameWhichIsMoreThan48ButLessThan63ü",
+ "üüüüüüüüüüüüüüüüüüüüüüüüüüüüüüü",
+ };
+ for (size_t i = 0; i < sizeof(names) / sizeof(*names); i++) {
+ char out[MEMORY_DEVICE_MAX_LEN_WITH_NULL + 3] = {0};
+ assert_false(label_fits_width(names[i], &font_regular_9, SCREEN_WIDTH));
+ _truncate_to_fit(names[i], out, sizeof(out), &font_regular_9, SCREEN_WIDTH);
+
+ const size_t len = strlen(out);
+ assert_true(len > 3);
+ assert_string_equal(out + len - 3, "...");
+ assert_memory_equal(out, names[i], len - 3);
+ assert_int_equal(
+ rust_util_utf8_truncate(rust_util_bytes((const uint8_t*)out, len), len), len);
+ assert_true(label_fits_width(out, &font_regular_9, SCREEN_WIDTH));
+ }
+}
+
+static void test_truncate_to_fit_capacity(void** state)
+{
+ (void)state;
+ const char* name = "1234567üThisNameIsTooLongToFitOnTheScreen";
+ char out[12] = {0};
+ // Reserving the ellipsis leaves eight bytes, which would split the two-byte ü.
+ _truncate_to_fit(name, out, sizeof(out), &font_regular_9, SCREEN_WIDTH);
+ assert_string_equal(out, "1234567...");
+
+ char ellipsis_only[4] = {0};
+ _truncate_to_fit(name, ellipsis_only, sizeof(ellipsis_only), &font_regular_9, SCREEN_WIDTH);
+ assert_string_equal(ellipsis_only, "...");
+}
+
+static void test_truncate_to_fit_short_name(void** state)
+{
+ (void)state;
+ char out[MEMORY_DEVICE_MAX_LEN_WITH_NULL + 3] = {0};
+ _truncate_to_fit("BïtBöx", out, sizeof(out), &font_regular_9, SCREEN_WIDTH);
+ assert_string_equal(out, "BïtBöx");
+ _truncate_to_fit("", out, sizeof(out), &font_regular_9, SCREEN_WIDTH);
+ assert_string_equal(out, "");
+}
+
+int main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_truncate_to_fit_utf8),
+ cmocka_unit_test(test_truncate_to_fit_capacity),
+ cmocka_unit_test(test_truncate_to_fit_short_name),
+ };
+ return cmocka_run_group_tests(tests, _setup, NULL);
+}
### test/unit-test/test_memory.c
@@ -538,7 +538,7 @@ static void _test_memory_get_device_name(void** state)
char name_out[MEMORY_DEVICE_MAX_LEN_WITH_NULL] = {0};
EMPTYCHUNK(chunk);
memset(chunk + _addr_device_name, 0, MEMORY_DEVICE_MAX_LEN_WITH_NULL);
- const char* device_name = "foo bar";
+ const char* device_name = "BïtBöx";
snprintf((char*)chunk + _addr_device_name, MEMORY_DEVICE_MAX_LEN_WITH_NULL, "%s", device_name);
expect_value(__wrap_memory_read_chunk_fake, chunk_num, 1);
@@ -588,6 +588,7 @@ static void _test_memory_device_name(void** state)
const char* device_name = "test name";
_set_device_name(device_name);
+ _set_device_name("BïtBöx");
const char* device_name2 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
_set_device_name(device_name2);
}
### test/unit-test/test_ugui.c
@@ -5,7 +5,9 @@
#include <stddef.h>
#include <cmocka.h>
-#include "ui/fonts/arial_fonts.h"
+#include "ui/fonts/password_12.h"
+#include "ui/fonts/password_9.h"
+#include "ui/fonts/regular_fonts.h"
#include "ui/ugui/ugui.h"
#include <string.h>
@@ -25,13 +27,52 @@ static UG_S16 last_x;
static UG_S16 last_y;
static UG_COLOR last_color;
static uint8_t pixels_set;
+static size_t set_pixel_count = 0;
+static size_t black_pixel_count = 0;
+
+void __wrap_Abort(const char* msg)
+{
+ check_expected(msg);
+ mock_assert(false, msg, __FILE__, __LINE__);
+}
+
+static void _assert_supported_font_subset(const UG_FONT* font)
+{
+ assert_non_null(font);
+ assert_ptr_equal(font->get_glyph_dsc, lv_font_get_glyph_dsc_fmt_txt);
+ assert_ptr_equal(font->get_glyph_bitmap, lv_font_get_bitmap_fmt_txt);
+ assert_non_null(font->dsc);
+
+ const lv_font_fmt_txt_dsc_t* font_dsc = (const lv_font_fmt_txt_dsc_t*)font->dsc;
+ assert_int_equal(font_dsc->bpp, 1);
+ assert_int_equal(font_dsc->stride, 0);
+ assert_int_equal(font_dsc->bitmap_format, LV_FONT_FMT_TXT_PLAIN);
+ assert_null(font_dsc->kern_dsc);
+ assert_int_equal(font_dsc->kern_scale, 0);
+ assert_int_equal(font_dsc->kern_classes, 0);
+ for (uint16_t i = 0; i < font_dsc->cmap_num; i++) {
+ const lv_font_fmt_txt_cmap_t* cmap = &font_dsc->cmaps[i];
+ assert_int_equal(cmap->type, LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY);
+ assert_null(cmap->unicode_list);
+ assert_null(cmap->glyph_id_ofs_list);
+ assert_int_equal(cmap->list_length, 0);
+ }
+
+ if (font->fallback != NULL) {
+ _assert_supported_font_subset(font->fallback);
+ }
+}
static void _set_pixel(UG_S16 x, UG_S16 y, UG_COLOR color)
{
last_x = x;
last_y = y;
last_color = color;
pixels_set++;
+ set_pixel_count++;
+ if (color == C_BLACK) {
+ black_pixel_count++;
+ }
}
static void _reset_pixel_capture(void)
@@ -45,7 +86,7 @@ static void _reset_pixel_capture(void)
static void _test_ugui_word_wrap(void** state)
{
(void)state; /* unused */
- UG_Init(&gui, _set_pixel, &font_font_a_11X10, 128, 64);
+ UG_Init(&gui, _set_pixel, &font_regular_9, 128, 64);
for (size_t i = 0; i < sizeof(data) / sizeof(*data); ++i) {
char buf[1024] = {0};
printf("test:\n%s\n", data[i][0]);
@@ -64,7 +105,7 @@ static void _draw_pixel(void* ctx)
static void _test_ugui_render_rotated_180(void** state)
{
(void)state; /* unused */
- UG_Init(&gui, _set_pixel, &font_font_a_11X10, 128, 64);
+ UG_Init(&gui, _set_pixel, &font_regular_11, 128, 64);
_reset_pixel_capture();
UG_RenderRotated180(10, 20, 30, 10, _draw_pixel, NULL);
@@ -83,7 +124,7 @@ static void _test_ugui_render_rotated_180(void** state)
static void _test_ugui_measure_string_centered(void** state)
{
(void)state;
- UG_Init(&gui, _set_pixel, &font_font_a_11X10, 128, 64);
+ UG_Init(&gui, _set_pixel, &font_regular_11, 128, 64);
UG_S16 centered_width = 0;
UG_S16 centered_height = 0;
@@ -96,12 +137,246 @@ static void _test_ugui_measure_string_centered(void** state)
assert_int_equal(centered_height, 2 * single_line_height + 2 * gui.char_v_space);
}
+static bool _capture_glyph_dsc(
+ const lv_font_t* font,
+ lv_font_glyph_dsc_t* glyph_dsc,
+ uint32_t codepoint,
+ uint32_t codepoint_next)
+{
+ (void)font;
+ check_expected(codepoint);
+ (void)codepoint_next;
+ memset(glyph_dsc, 0, sizeof(*glyph_dsc));
+ glyph_dsc->adv_w = 1;
+ return true;
+}
+
+static void _test_ugui_utf8_validation(void** state)
+{
+ (void)state;
+ static const UG_FONT capture_font = {
+ .get_glyph_dsc = _capture_glyph_dsc,
+ .line_height = 1,
+ };
+ UG_Init(&gui, _set_pixel, &capture_font, 128, 64);
+ UG_FontSetHSpace(0);
+
+ const struct {
+ const char* text;
+ uint32_t codepoint;
+ } valid[] = {
+ {"A", 0x41},
+ {"\xc2\x80", 0x80},
+ {"\xdf\xbf", 0x7ff},
+ {"\xe0\xa0\x80", 0x800},
+ {"\xed\x9f\xbf", 0xd7ff},
+ {"\xee\x80\x80", 0xe000},
+ {"\xef\xbf\xbf", 0xffff},
+ {"\xf0\x90\x80\x80", 0x10000},
+ {"\xf4\x8f\xbf\xbf", 0x10ffff},
+ };
+ UG_S16 width = 0;
+ UG_MeasureStringNoBreak(&width, NULL, "");
+ assert_int_equal(width, 0);
+ for (size_t i = 0; i < sizeof(valid) / sizeof(*valid); ++i) {
+ expect_value(_capture_glyph_dsc, codepoint, valid[i].codepoint);
+ UG_MeasureStringNoBreak(&width, NULL, valid[i].text);
+ assert_int_equal(width, 1);
+ }
+
+ const char* invalid[] = {
+ "\x80", // Stray continuation byte.
+ "\xbf",
+ "\xc0\xaf", // Overlong encodings.
+ "\xc1\xbf",
+ "\xe0\x80\xaf",
+ "\xf0\x80\x80\xaf",
+ "\xed\xa0\x80", // Surrogate.
+ "\xf4\x90\x80\x80", // Above U+10FFFF.
+ "\xf5\x80\x80\x80", // Invalid leading bytes.
+ "\xff",
+ "\xc2", // Truncated sequences.
+ "\xe4",
+ "\xe0\xa0",
+ "\xf0",
+ "\xf0\x90",
+ "\xf0\x90\x80",
+ "\xc2"
+ "A", // Invalid continuation bytes.
+ "\xe0\xa0"
+ "A",
+ "\xf0\x90\x80"
+ "A",
+ };
+ for (size_t i = 0; i < sizeof(invalid) / sizeof(*invalid); ++i) {
+ expect_string(__wrap_Abort, msg, "Invalid UTF-8 string");
+ expect_assert_failure(UG_MeasureStringNoBreak(&width, NULL, invalid[i]));
+ }
+
+ // Reject malformed input after a valid prefix as well.
+ expect_value(_capture_glyph_dsc, codepoint, 'A');
+ expect_string(__wrap_Abort, msg, "Invalid UTF-8 string");
+ expect_assert_failure(UG_MeasureStringNoBreak(&width, NULL, "A\xff"));
+}
+
+static void _test_ugui_word_wrap_invalid_utf8(void** state)
+{
+ (void)state;
+ UG_Init(&gui, _set_pixel, &font_regular_9, 128, 64);
+ char output[32] = {0};
+
+ // Reject malformed input when measuring the first or a following word.
+ expect_string(__wrap_Abort, msg, "Invalid UTF-8 string");
+ expect_assert_failure(UG_WrapTitleString("\xff", output, 55));
+ expect_string(__wrap_Abort, msg, "Invalid UTF-8 string");
+ expect_assert_failure(UG_WrapTitleString("A \xff", output, 55));
+
+ // A tab ends the initial width scan, so copying detects this error.
+ expect_string(__wrap_Abort, msg, "Invalid UTF-8 string");
+ expect_assert_failure(UG_WrapTitleString("\t\xff", output, 55));
+}
+
+static void _test_ugui_lvgl_font(void** state)
+{
+ (void)state; /* unused */
+ UG_Init(&gui, _set_pixel, &font_regular_9, 128, 64);
+
+ UG_S16 width = 0;
+ UG_S16 height = 0;
+ UG_MeasureStringNoBreak(
+ &width,
+ &height,
+ "A"
+ "\xc3"
+ "\xa4");
+ assert_true(width > 0);
+ assert_int_equal(height, font_regular_9.line_height);
+
+ set_pixel_count = 0;
+ black_pixel_count = 0;
+ UG_PutString(0, 0, " ");
+ assert_true(set_pixel_count >= (size_t)font_regular_9.line_height);
+ assert_int_equal(set_pixel_count, black_pixel_count);
+}
+
+static void _test_ugui_lvgl_font_fallback(void** state)
+{
+ (void)state; /* unused */
+ UG_Init(&gui, _set_pixel, &font_password_12, 128, 64);
+
+ UG_U16 width = 0;
+ assert_true(UG_GetCharWidth(&font_password_12, ' ', &width));
+ assert_true(width > 0);
+ assert_true(UG_GetCharWidth(&font_password_12, 'A', &width));
+ assert_true(width > 0);
+
+ set_pixel_count = 0;
+ black_pixel_count = 0;
+ UG_PutString(0, 0, " ");
+ assert_true(set_pixel_count > black_pixel_count);
+
+ set_pixel_count = 0;
+ black_pixel_count = 0;
+ UG_PutString(0, 0, "A");
+ assert_true(set_pixel_count > black_pixel_count);
+}
+
+static void _test_ugui_fonts_use_supported_subset(void** state)
+{
+ (void)state; /* unused */
+ _assert_supported_font_subset(&font_regular_9);
+ _assert_supported_font_subset(&font_regular_11);
+ _assert_supported_font_subset(&font_regular_12);
+ _assert_supported_font_subset(&font_monogram_16);
+ _assert_supported_font_subset(&font_password_9);
+ _assert_supported_font_subset(&font_password_12);
+}
+
+static void _test_ugui_fonts_exclude_ambiguous_characters(void** state)
+{
+ (void)state;
+ const UG_FONT* fonts[] = {
+ &font_regular_9,
+ &font_regular_11,
+ &font_regular_12,
+ &font_monogram_16,
+ &font_password_9,
+ &font_password_12,
+ };
+ for (size_t i = 0; i < sizeof(fonts) / sizeof(*fonts); i++) {
+ UG_U16 width = 0;
+ assert_true(UG_GetCharWidth(fonts[i], ' ', &width));
+ assert_true(UG_GetCharWidth(fonts[i], '-', &width));
+ assert_false(UG_GetCharWidth(fonts[i], 0x00A0, &width)); // Non-breaking space.
+ assert_false(UG_GetCharWidth(fonts[i], 0x00AD, &width)); // Soft hyphen.
+ }
+}
+
+static uint8_t _glyph_pixels[32][32];
+
+static void _set_glyph_pixel(UG_S16 x, UG_S16 y, UG_COLOR color)
+{
+ assert_in_range(x, 0, 31);
+ assert_in_range(y, 0, 31);
+ _glyph_pixels[y][x] = color == C_WHITE;
+}
+
+static uint32_t _hash_bytes(uint32_t hash, const uint8_t* bytes, size_t len)
+{
+ for (size_t i = 0; i < len; i++) {
+ hash = (hash ^ bytes[i]) * 16777619u;
+ }
+ return hash;
+}
+
+static void _test_ugui_ascii_font_pixels_and_metrics(void** state)
+{
+ (void)state;
+ // Lock down printable ASCII glyph pixels, positions, advances and line heights.
+ const struct {
+ const UG_FONT* font;
+ uint32_t hash;
+ } cases[] = {
+ {&font_regular_9, 0xea2a3af8},
+ {&font_regular_11, 0x7a72fbc2},
+ {&font_regular_12, 0x3f5b6308},
+ {&font_password_9, 0x3e5071ab},
+ {&font_password_12, 0xf1db9eeb},
+ {&font_monogram_16, 0xd2698414},
+ };
+ for (size_t i = 0; i < sizeof(cases) / sizeof(*cases); i++) {
+ UG_Init(&gui, _set_glyph_pixel, cases[i].font, 32, 32);
+ UG_FontSetHSpace(0);
+ uint32_t hash = 2166136261u;
+ for (uint8_t codepoint = 32; codepoint <= 126; codepoint++) {
+ memset(_glyph_pixels, 0, sizeof(_glyph_pixels));
+ UG_PutChar((char)codepoint, 8, 8, C_WHITE, C_BLACK);
+ const char text[] = {(char)codepoint, '\0'};
+ UG_S16 width = 0;
+ UG_S16 height = 0;
+ UG_MeasureStringNoBreak(&width, &height, text);
+ const uint8_t metrics[] = {
+ (uint8_t)width, (uint8_t)(width >> 8), (uint8_t)height, (uint8_t)(height >> 8)};
+ hash = _hash_bytes(hash, metrics, sizeof(metrics));
+ hash = _hash_bytes(hash, (const uint8_t*)_glyph_pixels, sizeof(_glyph_pixels));
+ }
+ assert_int_equal(hash, cases[i].hash);
+ }
+}
+
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(_test_ugui_word_wrap),
cmocka_unit_test(_test_ugui_render_rotated_180),
cmocka_unit_test(_test_ugui_measure_string_centered),
+ cmocka_unit_test(_test_ugui_utf8_validation),
+ cmocka_unit_test(_test_ugui_word_wrap_invalid_utf8),
+ cmocka_unit_test(_test_ugui_lvgl_font),
+ cmocka_unit_test(_test_ugui_lvgl_font_fallback),
+ cmocka_unit_test(_test_ugui_fonts_use_supported_subset),
+ cmocka_unit_test(_test_ugui_fonts_exclude_ambiguous_characters),
+ cmocka_unit_test(_test_ugui_ascii_font_pixels_and_metrics),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}
### test/unit-test/test_ui_components.c
@@ -15,8 +15,7 @@
#include <ui/components/left_arrow.h>
#include <ui/components/right_arrow.h>
#include <ui/components/status.h>
-#include <ui/fonts/arial_fonts.h>
-#include <ui/fonts/monogram_5X9.h>
+#include <ui/fonts/regular_fonts.h>
#include <ui/ugui/ugui.h>
#include <ui/ui_util.h>
@@ -35,7 +34,7 @@ static void _set_pixel(UG_S16 x, UG_S16 y, UG_COLOR color)
static int _setup(void** state)
{
(void)state;
- UG_Init(&gui, _set_pixel, &font_font_a_11X10, 128, 64);
+ UG_Init(&gui, _set_pixel, &font_regular_11, 128, 64);
return 0;
}
@@ -58,10 +57,10 @@ static void assert_ui_component_functions(component_t* component)
static void test_ui_components_label(void** state)
{
- assert_true(label_fits_width("Test", &font_font_a_11X10, 128));
- assert_true(label_fits_width("11111111111111111 BNB", &font_font_a_9X9, 128));
+ assert_true(label_fits_width("Test", &font_regular_11, 128));
+ assert_true(label_fits_width("11111111111111111 BNB", &font_regular_9, 128));
assert_false(
- label_fits_width("This label is much wider than the screen", &font_font_a_9X9, 128));
+ label_fits_width("This label is much wider than the screen", &font_regular_9, 128));
component_t* mock_component = fake_component_create();
@@ -132,7 +131,7 @@ static void test_ui_components_confirm(void** state)
const confirm_params_t params = {
.title = "Is the Code correct?",
.body = "CODE",
- .font = &font_monogram_5X9,
+ .font = &font_monogram_16,
};
component_t* confirm = confirm_create(¶ms, confirm_callback, NULL);
assert_non_null(confirm);
### test/unit-test/test_ui_util.c
@@ -6,7 +6,7 @@
#include <stddef.h>
#include <cmocka.h>
-#include <ui/fonts/arial_fonts.h>
+#include <ui/fonts/regular_fonts.h>
#include <ui/ui_util.h>
#include "fake_component.h"
@@ -213,7 +213,7 @@ static void test_ui_util_position_right_top(void** state)
static void test_ui_util_component_render_rotated_180(void** state)
{
(void)state;
- UG_Init(&gui, _set_pixel, &font_font_a_11X10, 128, 64);
+ UG_Init(&gui, _set_pixel, &font_regular_11, 128, 64);
component_t component = {
.f = &_pixel_component_functions,
.dimension = {.width = 10, .height = 8},
### test/unit-test/test_util.c
@@ -75,23 +75,12 @@ static void test_util_utf8_copy(void** state)
assert_string_equal(out, "");
}
-static void test_util_is_printable_ascii(void** state)
-{
- (void)state;
-
- assert_true(util_is_printable_ascii("printable ASCII", false));
- assert_false(util_is_printable_ascii("line one\nline two", false));
- assert_true(util_is_printable_ascii("line one\nline two", true));
- assert_false(util_is_printable_ascii("t\xC3\xA4st", true));
-}
-
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_minmax),
cmocka_unit_test(test_util_strlcpy),
cmocka_unit_test(test_util_utf8_copy),
- cmocka_unit_test(test_util_is_printable_ascii),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}
### tools/ttf2lvgl/.gitignore
@@ -0,0 +1,2 @@
+*.o
+ttf2lvgl
### tools/ttf2lvgl/Makefile
@@ -0,0 +1,26 @@
+PKG_CONFIG ?= pkg-config
+
+FREETYPE_CFLAGS := $(shell $(PKG_CONFIG) --cflags freetype2)
+FREETYPE_LIBS := $(shell $(PKG_CONFIG) --libs freetype2)
+ICU_CFLAGS := $(shell $(PKG_CONFIG) --cflags icu-uc)
+ICU_LIBS := $(shell $(PKG_CONFIG) --libs icu-uc)
+
+CFLAGS ?= -Wall -Wextra -g
+CPPFLAGS += $(FREETYPE_CFLAGS) $(ICU_CFLAGS)
+LDLIBS += $(FREETYPE_LIBS) $(ICU_LIBS)
+
+OBJS = ttf2lvgl.o
+
+.PHONY: all clean test
+
+all: ttf2lvgl
+
+ttf2lvgl: $(OBJS)
+ $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
+
+test: ttf2lvgl
+ ./test.sh
+
+clean:
+ rm -f $(OBJS)
+ rm -f ttf2lvgl
### tools/ttf2lvgl/README.md
@@ -0,0 +1,52 @@
+ttf2lvgl
+========
+
+`ttf2lvgl` converts fonts supported by FreeType into LVGL's uncompressed
+`lv_font_fmt_txt` C format.
+
+The rasterizer intentionally matches the old `ttf2ugui` tool:
+
+* `--bpp=1` uses `FT_LOAD_RENDER | FT_LOAD_TARGET_MONO` and stores the same
+ monochrome glyph pixels in LVGL bit order.
+* `--bpp=8` renders the font at 16x size with the same monochrome target,
+ downsamples every 16x16 block, and stores the same 0..255 coverage values.
+
+Glyphs are emitted with tight bounding boxes. LVGL metrics (`ofs_x`, `ofs_y`,
+`adv_w`, `line_height`, and `base_line`) preserve the FreeType placement.
+Requested code points that are not present in the font's charmap are omitted
+from the generated glyph descriptors and cmaps.
+The `--show` preview decodes its input as UTF-8 with ICU before rendering.
+Generated font objects use the local `lv_font_get_glyph_dsc_fmt_txt` and
+`lv_font_get_bitmap_fmt_txt` callbacks. The BitBox02 OLED implementation of
+those callbacks only supports 1bpp, unstrided, no-kerning, `FORMAT0_TINY`
+fonts. Dumped fonts are exported as `const UG_FONT font_<name>` and the
+generated header includes `<ugui.h>` and declares that `UG_FONT` object. If
+`--name` already starts with `font_`, the public symbol is not double-prefixed.
+
+Examples:
+
+```
+./ttf2lvgl --font Luna.ttf --dpi 140 --size 14 --range 32-127 --dump
+./ttf2lvgl --font Luna.ttf --dpi 140 --size 14 --range 32-127 --show "aString"
+./ttf2lvgl --font Luna.ttf --dpi 140 --size 14 --range 32-127 --dump --bpp=8
+./ttf2lvgl --font Luna.ttf --size 14 --range 32-127,160,U+0100-U+017F \
+ --dump --name luna_14 --output luna_14.c
+```
+
+If `--range` is omitted, the legacy `--minchar`/`--maxchar` range is used,
+defaulting to `32-126`.
+If `--name` is omitted, the base name uses the lowercased font file basename and
+requested font size. If `--name` is given, it must be a valid C identifier and
+is used as the base name. If `--output` is omitted, the file name follows the
+base name.
+
+Compiling
+---------
+
+FreeType and ICU development headers and `pkg-config` are required. Run:
+
+```
+make
+```
+
+Run `make test` to exercise valid 1bpp and 8bpp conversions and the command-line validation.
### tools/ttf2lvgl/test.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+set -eu
+
+export LC_ALL=C
+
+tool=./ttf2lvgl
+font=../../src/ui/fonts/monogram.ttf
+test_dir=$(mktemp -d "${TMPDIR:-/tmp}/ttf2lvgl.XXXXXX")
+trap 'rm -r -- "$test_dir"' EXIT
+
+expect_failure() {
+ if "$@" >/dev/null 2>&1; then
+ echo "unexpected success: $*" >&2
+ exit 1
+ fi
+}
+
+"$tool" \
+ --dump \
+ --font "$font" \
+ --size 16 \
+ --range '32,48-57,97-102' \
+ --name test_font \
+ --output "$test_dir/test_font.c"
+test -s "$test_dir/test_font.c"
+test -s "$test_dir/test_font.h"
+grep -Fxq '#ifndef TTF2LVGL_TEST_FONT_H' "$test_dir/test_font.h"
+grep -Fxq '#define TTF2LVGL_TEST_FONT_H' "$test_dir/test_font.h"
+grep -Fxq '#endif /* TTF2LVGL_TEST_FONT_H */' "$test_dir/test_font.h"
+if grep -n '[[:blank:]]$' "$test_dir/test_font.c"; then
+ echo "generated source contains trailing whitespace" >&2
+ exit 1
+fi
+
+"$tool" --show 'café' --font "$font" --size 16 --range '32-126,U+00E9' >/dev/null
+"$tool" \
+ --dump \
+ --font "$font" \
+ --size 16 \
+ --bpp 8 \
+ --range 65 \
+ --name eight_bpp \
+ --output "$test_dir/eight_bpp.c"
+"$tool" \
+ --dump \
+ --font "$font" \
+ --size 16 \
+ --range 32 \
+ --name space_only \
+ --output "$test_dir/space_only.c"
+grep -q '\.line_height = [1-9]' "$test_dir/space_only.c"
+
+expect_failure "$tool" --show A --font "$font" --size=-1 --range 65
+expect_failure "$tool" --show A --font "$font" --size=nan --range 65
+expect_failure "$tool" --show A --font "$font" --size=1junk --range 65
+expect_failure "$tool" --show A --font "$font" --size=5000 --range 65
+expect_failure "$tool" --show A --font "$font" --size=16 --dpi=1junk --range 65
+expect_failure "$tool" --show A --font "$font" --size=16 --range '65,,66'
+expect_failure "$tool" --show A --font "$font" --size=16 --range U+D800
+expect_failure "$tool" --show A --font "$font" --size=16 --range 65 unexpected
+expect_failure \
+ "$tool" --dump --font "$font" --size=16 --range 65 --output "$test_dir/collision.h"
+expect_failure \
+ "$tool" --dump --font "$font" --size=16 --range 65 --output "$test_dir/bad\"name.c"
### tools/ttf2lvgl/ttf2lvgl.c
@@ -0,0 +1,1327 @@
+/*
+ * Copyright (c) 2015, Ari Suutari <ari@stonepile.fi>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, 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.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+/*
+ * 19.10.2017 jkpublic@kartech.biz - Added support for 8BPP fonts (anti aliased)
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <getopt.h>
+#include <limits.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include <unicode/uchar.h>
+#include <unicode/utf8.h>
+
+#define SCREEN_WIDTH 132
+#define SCREEN_HEIGHT 40
+#define MAX_RASTER_SIZE 4096
+#define MAX_LVGL_BITMAP_SIZE ((size_t)1 << 20)
+
+typedef struct {
+ int codepoint;
+ int adv_w;
+ int box_w;
+ int box_h;
+ int ofs_x;
+ int ofs_y;
+ size_t bitmap_index;
+ size_t bitmap_size;
+ uint8_t* bitmap;
+} Glyph;
+
+typedef struct {
+ int bpp;
+ int line_height;
+ int baseline;
+ Glyph* glyphs;
+ size_t glyph_count;
+ size_t bitmap_size;
+ UChar32* codepoints;
+ size_t codepoint_count;
+ struct {
+ uint32_t range_start;
+ uint16_t range_length;
+ uint16_t glyph_id_start;
+ }* cmaps;
+ size_t cmap_count;
+} LvglFont;
+
+typedef struct {
+ UChar32* codepoints;
+ size_t count;
+ size_t capacity;
+} Codepoints;
+
+static float font_size = 0;
+static int dpi = 0;
+static int bpp = 1;
+static int min_char = 32;
+static int max_char = 126;
+static bool minmax_used = false;
+static bool range_used = false;
+static int dump = 0;
+static char* font_file = NULL;
+static char* show_text = NULL;
+static char* font_name_arg = NULL;
+static char* output_file_arg = NULL;
+static Codepoints range_codepoints = {0};
+
+static void usage(void);
+
+static size_t checked_size_add(size_t left, size_t right)
+{
+ if (left > SIZE_MAX - right) {
+ fprintf(stderr, "allocation size overflow\n");
+ exit(2);
+ }
+ return left + right;
+}
+
+static size_t checked_size_multiply(size_t left, size_t right)
+{
+ if (left != 0 && right > SIZE_MAX / left) {
+ fprintf(stderr, "allocation size overflow\n");
+ exit(2);
+ }
+ return left * right;
+}
+
+static void* xmalloc(size_t size)
+{
+ void* ptr = malloc(size == 0 ? 1 : size);
+ if (ptr == NULL) {
+ perror("malloc");
+ exit(2);
+ }
+ return ptr;
+}
+
+static void* xcalloc(size_t count, size_t size)
+{
+ if (count == 0 || size == 0) {
+ count = 1;
+ size = 1;
+ } else {
+ (void)checked_size_multiply(count, size);
+ }
+ void* ptr = calloc(count, size);
+ if (ptr == NULL) {
+ perror("calloc");
+ exit(2);
+ }
+ return ptr;
+}
+
+static void* xreallocarray(void* ptr, size_t count, size_t size)
+{
+ size_t allocation_size = checked_size_multiply(count, size);
+ void* out = realloc(ptr, allocation_size == 0 ? 1 : allocation_size);
+ if (out == NULL) {
+ perror("realloc");
+ exit(2);
+ }
+ return out;
+}
+
+static char* xstrdup(const char* str)
+{
+ char* out = strdup(str);
+ if (out == NULL) {
+ perror("strdup");
+ exit(2);
+ }
+ return out;
+}
+
+static char* path_basename_no_ext(const char* path)
+{
+ const char* base_name = strrchr(path, '/');
+ base_name = base_name == NULL ? path : base_name + 1;
+
+ char* out = xstrdup(base_name);
+ char* dot = strrchr(out, '.');
+ if (dot != NULL) {
+ *dot = '\0';
+ }
+ return out;
+}
+
+static char* sanitize_identifier(const char* name, bool uppercase)
+{
+ size_t len = strlen(name);
+ char* out = xmalloc(checked_size_add(len, 2));
+ size_t pos = 0;
+
+ if (len == 0 || isdigit((unsigned char)name[0])) {
+ out[pos++] = '_';
+ }
+
+ for (size_t i = 0; i < len; i++) {
+ unsigned char ch = (unsigned char)name[i];
+ if (isalnum(ch)) {
+ out[pos++] = (char)(uppercase ? toupper(ch) : ch);
+ } else {
+ out[pos++] = '_';
+ }
+ }
+
+ out[pos] = '\0';
+ return out;
+}
+
+static void lowercase_identifier(char* text)
+{
+ for (size_t i = 0; text[i] != '\0'; i++) {
+ text[i] = (char)tolower((unsigned char)text[i]);
+ }
+}
+
+static bool is_valid_c_identifier(const char* name)
+{
+ if (name[0] == '\0' || !(isalpha((unsigned char)name[0]) || name[0] == '_')) {
+ return false;
+ }
+ for (size_t i = 1; name[i] != '\0'; i++) {
+ if (!(isalnum((unsigned char)name[i]) || name[i] == '_')) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static char* font_size_suffix(float requested_size)
+{
+ char text[64];
+ snprintf(text, sizeof(text), "%g", requested_size);
+
+ char* out = xstrdup(text);
+ for (size_t i = 0; out[i] != '\0'; i++) {
+ if (!isalnum((unsigned char)out[i])) {
+ out[i] = '_';
+ }
+ }
+ return out;
+}
+
+static char* default_font_name(const char* font_file, float requested_size)
+{
+ char* base_name = path_basename_no_ext(font_file);
+ char* sanitized_base = sanitize_identifier(base_name, false);
+ lowercase_identifier(sanitized_base);
+ free(base_name);
+
+ char* size_suffix = font_size_suffix(requested_size);
+ size_t len = checked_size_add(
+ checked_size_add(strlen(sanitized_base), strlen(size_suffix)), 2);
+ char* out = xmalloc(len);
+ snprintf(out, len, "%s_%s", sanitized_base, size_suffix);
+ free(size_suffix);
+ free(sanitized_base);
+ return out;
+}
+
+static char* output_header_name(const char* output_file)
+{
+ char* out = xstrdup(output_file);
+ char* slash = strrchr(out, '/');
+ char* base = slash == NULL ? out : slash + 1;
+ char* dot = strrchr(base, '.');
+ size_t stem_len = dot == NULL ? strlen(out) : (size_t)(dot - out);
+ size_t len = checked_size_add(stem_len, sizeof(".h"));
+ out = xreallocarray(out, len, 1);
+ memcpy(out + stem_len, ".h", sizeof(".h"));
+ return out;
+}
+
+static char* public_font_symbol(const char* font_name)
+{
+ if (strncmp(font_name, "font_", 5) == 0) {
+ return xstrdup(font_name);
+ }
+
+ size_t len = checked_size_add(
+ checked_size_add(strlen("font_"), strlen(font_name)), 1);
+ char* out = xmalloc(len);
+ snprintf(out, len, "font_%s", font_name);
+ return out;
+}
+
+static void codepoints_append(Codepoints* codepoints, UChar32 codepoint)
+{
+ if (codepoint < 0 || codepoint > 0x10FFFF ||
+ (codepoint >= 0xD800 && codepoint <= 0xDFFF)) {
+ fprintf(stderr, "invalid Unicode code point: U+%X\n", (unsigned int)codepoint);
+ exit(1);
+ }
+
+ if (codepoints->count == codepoints->capacity) {
+ size_t new_capacity =
+ codepoints->capacity == 0 ? 32 : checked_size_multiply(codepoints->capacity, 2);
+ UChar32* new_codepoints = xreallocarray(
+ codepoints->codepoints, new_capacity, sizeof(*new_codepoints));
+ codepoints->codepoints = new_codepoints;
+ codepoints->capacity = new_capacity;
+ }
+ codepoints->codepoints[codepoints->count++] = codepoint;
+}
+
+static int compare_codepoints(const void* a, const void* b)
+{
+ UChar32 left = *(const UChar32*)a;
+ UChar32 right = *(const UChar32*)b;
+ return (left > right) - (left < right);
+}
+
+static void codepoints_sort_dedup(Codepoints* codepoints)
+{
+ if (codepoints->count == 0) {
+ return;
+ }
+
+ qsort(
+ codepoints->codepoints,
+ codepoints->count,
+ sizeof(*codepoints->codepoints),
+ compare_codepoints);
+
+ size_t out = 1;
+ for (size_t i = 1; i < codepoints->count; i++) {
+ if (codepoints->codepoints[i] != codepoints->codepoints[out - 1]) {
+ codepoints->codepoints[out++] = codepoints->codepoints[i];
+ }
+ }
+ codepoints->count = out;
+}
+
+static void parse_codepoint(const char* text, UChar32* out)
+{
+ while (isspace((unsigned char)*text)) {
+ text++;
+ }
+
+ int base = 10;
+ if (text[0] == 'U' || text[0] == 'u') {
+ if (text[1] != '+') {
+ fprintf(stderr, "invalid code point: %s\n", text);
+ exit(1);
+ }
+ text += 2;
+ base = 16;
+ } else if (text[0] == '0' && (text[1] == 'x' || text[1] == 'X')) {
+ text += 2;
+ base = 16;
+ }
+
+ char* end = NULL;
+ errno = 0;
+ unsigned long value = strtoul(text, &end, base);
+ while (isspace((unsigned char)*end)) {
+ end++;
+ }
+ if (errno == ERANGE || end == text || *end != '\0' || value > 0x10FFFF) {
+ fprintf(stderr, "invalid code point: %s\n", text);
+ exit(1);
+ }
+ *out = (UChar32)value;
+}
+
+static void parse_codepoint_range_item(char* item, Codepoints* codepoints)
+{
+ while (isspace((unsigned char)*item)) {
+ item++;
+ }
+ if (*item == '\0') {
+ fprintf(stderr, "empty code point range\n");
+ exit(1);
+ }
+
+ char* dash = strchr(item, '-');
+ if (dash == NULL) {
+ UChar32 codepoint;
+ parse_codepoint(item, &codepoint);
+ codepoints_append(codepoints, codepoint);
+ return;
+ }
+
+ *dash = '\0';
+ UChar32 first;
+ UChar32 last;
+ parse_codepoint(item, &first);
+ parse_codepoint(dash + 1, &last);
+ if (last < first) {
+ fprintf(
+ stderr,
+ "invalid descending code point range: U+%04X-U+%04X\n",
+ (unsigned int)first,
+ (unsigned int)last);
+ exit(1);
+ }
+ for (UChar32 codepoint = first; codepoint <= last; codepoint++) {
+ codepoints_append(codepoints, codepoint);
+ }
+}
+
+static void parse_codepoint_ranges(const char* text, Codepoints* codepoints)
+{
+ char* copy = xstrdup(text);
+ char* item = copy;
+ for (char* cursor = copy;; cursor++) {
+ if (*cursor != ',' && *cursor != '\0') {
+ continue;
+ }
+ bool at_end = *cursor == '\0';
+ *cursor = '\0';
+ parse_codepoint_range_item(item, codepoints);
+ codepoints_sort_dedup(codepoints);
+ if (at_end) {
+ break;
+ }
+ item = cursor + 1;
+ }
+ free(copy);
+}
+
+static void append_legacy_codepoint_range(Codepoints* codepoints)
+{
+ if (min_char < 0 || max_char < min_char || max_char > 0x10FFFF) {
+ usage();
+ exit(1);
+ }
+ for (int ch = min_char; ch <= max_char; ch++) {
+ codepoints_append(codepoints, (UChar32)ch);
+ }
+}
+
+static Codepoints utf8_to_codepoints(const char* text)
+{
+ size_t text_len = strlen(text);
+ if (text_len > INT32_MAX) {
+ fprintf(stderr, "preview text is too long\n");
+ exit(1);
+ }
+
+ const uint8_t* utf8 = (const uint8_t*)text;
+ int32_t utf8_len = (int32_t)text_len;
+ int32_t offset = 0;
+ Codepoints out = {
+ .codepoints = xmalloc(checked_size_multiply(
+ text_len == 0 ? 1 : text_len, sizeof(*out.codepoints))),
+ .count = 0,
+ .capacity = text_len == 0 ? 1 : text_len,
+ };
+
+ while (offset < utf8_len) {
+ int32_t previous_offset = offset;
+ UChar32 codepoint;
+ U8_NEXT(utf8, offset, utf8_len, codepoint);
+ if (codepoint < 0) {
+ fprintf(stderr, "invalid UTF-8 sequence at byte offset %d\n", previous_offset);
+ exit(1);
+ }
+ codepoints_append(&out, codepoint);
+ }
+
+ return out;
+}
+
+static size_t lvgl_bitmap_size(int width, int height, int bits_per_pixel)
+{
+ if (width <= 0 || height <= 0) {
+ return 0;
+ }
+ size_t pixel_count = checked_size_multiply((size_t)width, (size_t)height);
+ if (bits_per_pixel == 8) {
+ return pixel_count;
+ }
+ return checked_size_add(pixel_count, 7) / 8;
+}
+
+static void validate_ft_bitmap(const FT_Bitmap* bitmap, UChar32 codepoint)
+{
+ if (bitmap->width > INT_MAX || bitmap->rows > INT_MAX ||
+ bitmap->pixel_mode != FT_PIXEL_MODE_MONO) {
+ fprintf(stderr, "unsupported bitmap for U+%04X\n", (unsigned int)codepoint);
+ exit(1);
+ }
+ if (bitmap->width == 0 || bitmap->rows == 0) {
+ return;
+ }
+ if (bitmap->buffer == NULL) {
+ fprintf(stderr, "missing bitmap buffer for U+%04X\n", (unsigned int)codepoint);
+ exit(1);
+ }
+
+ int64_t signed_pitch = bitmap->pitch;
+ uint64_t pitch = (uint64_t)(signed_pitch < 0 ? -signed_pitch : signed_pitch);
+ size_t min_pitch = checked_size_add((size_t)bitmap->width, 7) / 8;
+ if (pitch < min_pitch || pitch > SIZE_MAX ||
+ (bitmap->rows - 1) > SIZE_MAX / (size_t)pitch) {
+ fprintf(stderr, "invalid bitmap pitch for U+%04X\n", (unsigned int)codepoint);
+ exit(1);
+ }
+}
+
+static bool ft_mono_pixel(const FT_Bitmap* bitmap, int x, int y)
+{
+ if (x < 0 || y < 0 || x >= (int)bitmap->width || y >= (int)bitmap->rows) {
+ return false;
+ }
+
+ int64_t signed_pitch = bitmap->pitch;
+ size_t pitch = (size_t)(signed_pitch < 0 ? -signed_pitch : signed_pitch);
+ size_t row_index =
+ signed_pitch >= 0 ? (size_t)y : (size_t)bitmap->rows - 1 - (size_t)y;
+ const uint8_t* row = bitmap->buffer + row_index * pitch;
+ uint8_t byte = row[x / 8];
+ return (byte & (1 << (7 - (x % 8)))) != 0;
+}
+
+static void set_lvgl_pixel(Glyph* glyph, int x, int y, int bits_per_pixel, uint8_t value)
+{
+ if (x < 0 || y < 0 || x >= glyph->box_w || y >= glyph->box_h) {
+ return;
+ }
+
+ if (bits_per_pixel == 8) {
+ glyph->bitmap[(size_t)y * (size_t)glyph->box_w + (size_t)x] = value;
+ return;
+ }
+
+ if (value == 0) {
+ return;
+ }
+ size_t bit_index = (size_t)y * (size_t)glyph->box_w + (size_t)x;
+ glyph->bitmap[bit_index / 8] |= (uint8_t)(1 << (7 - (bit_index % 8)));
+}
+
+static void set_glyph_metrics(Glyph* glyph, const FT_GlyphSlot slot, int bpp_mul)
+{
+ uint64_t box_w = slot->bitmap.width / (unsigned int)bpp_mul;
+ uint64_t box_h = slot->bitmap.rows / (unsigned int)bpp_mul;
+ int64_t adv_w = slot->advance.x / 64 / bpp_mul;
+ int64_t ofs_x = slot->bitmap_left / bpp_mul;
+ int64_t ofs_y = slot->bitmap_top / bpp_mul - (int64_t)box_h;
+
+ if (adv_w < 0 || adv_w > 255) {
+ fprintf(
+ stderr,
+ "advance width too large for default LVGL glyph descriptor: U+%04X\n",
+ glyph->codepoint);
+ exit(1);
+ }
+ if (box_w > 255 || box_h > 255 || ofs_x < -128 || ofs_x > 127 || ofs_y < -128 ||
+ ofs_y > 127) {
+ fprintf(
+ stderr,
+ "glyph metrics too large for default LVGL glyph descriptor: U+%04X\n",
+ glyph->codepoint);
+ exit(1);
+ }
+
+ glyph->adv_w = (int)adv_w;
+ glyph->box_w = (int)box_w;
+ glyph->box_h = (int)box_h;
+ glyph->ofs_x = (int)ofs_x;
+ glyph->ofs_y = (int)ofs_y;
+}
+
+static void build_cmaps(LvglFont* font)
+{
+ if (font->codepoint_count == 0) {
+ return;
+ }
+
+ font->cmaps = xcalloc(font->codepoint_count, sizeof(*font->cmaps));
+ size_t cmap_count = 0;
+ size_t range_start_index = 0;
+
+ while (range_start_index < font->codepoint_count) {
+ size_t range_end_index = range_start_index + 1;
+ while (range_end_index < font->codepoint_count &&
+ font->codepoints[range_end_index] == font->codepoints[range_end_index - 1] + 1 &&
+ range_end_index - range_start_index < UINT16_MAX) {
+ range_end_index++;
+ }
+
+ font->cmaps[cmap_count].range_start = (uint32_t)font->codepoints[range_start_index];
+ font->cmaps[cmap_count].range_length = (uint16_t)(range_end_index - range_start_index);
+ font->cmaps[cmap_count].glyph_id_start = (uint16_t)(range_start_index + 1);
+ cmap_count++;
+ if (cmap_count > 511) {
+ fprintf(stderr, "too many LVGL cmaps; combine adjacent code point ranges\n");
+ exit(1);
+ }
+ range_start_index = range_end_index;
+ }
+
+ font->cmap_count = cmap_count;
+}
+
+static Codepoints filter_present_codepoints(FT_Face face, const Codepoints* codepoints)
+{
+ Codepoints present_codepoints = {0};
+
+ for (size_t i = 0; i < codepoints->count; i++) {
+ UChar32 codepoint = codepoints->codepoints[i];
+ if (FT_Get_Char_Index(face, (FT_ULong)codepoint) != 0) {
+ codepoints_append(&present_codepoints, codepoint);
+ }
+ }
+
+ return present_codepoints;
+}
+
+static void validate_requested_size(float requested_size, int display_dpi, int bpp_mul)
+{
+ double scaled_size = (double)requested_size * bpp_mul;
+ double raster_size =
+ display_dpi > 0 ? scaled_size * (double)display_dpi / 72.0 : scaled_size;
+ if (!isfinite(scaled_size) || !isfinite(raster_size) || raster_size > MAX_RASTER_SIZE) {
+ fprintf(stderr, "requested font size is too large\n");
+ exit(1);
+ }
+
+ if (display_dpi > 0) {
+ double char_size = scaled_size * 64.0;
+ if (char_size < 1 || char_size > FT_LONG_MAX) {
+ fprintf(stderr, "requested font size is out of range\n");
+ exit(1);
+ }
+ } else if (scaled_size < 1 || scaled_size > UINT_MAX) {
+ fprintf(stderr, "requested font size is out of range\n");
+ exit(1);
+ }
+}
+
+static LvglFont* convert_font(
+ const char* font,
+ int display_dpi,
+ float requested_size,
+ int bits_per_pixel,
+ const Codepoints* codepoints)
+{
+ int bpp_mul;
+ switch (bits_per_pixel) {
+ case 1:
+ bpp_mul = 1;
+ break;
+ case 8:
+ bpp_mul = 16;
+ break;
+ default:
+ fprintf(stderr, "Bits per pixel must be 1 or 8, not %d\n", bits_per_pixel);
+ exit(1);
+ }
+ validate_requested_size(requested_size, display_dpi, bpp_mul);
+
+ FT_Library library;
+ int error = FT_Init_FreeType(&library);
+ if (error) {
+ fprintf(stderr, "ft init err %d\n", error);
+ exit(1);
+ }
+
+ FT_Face face;
+ error = FT_New_Face(library, font, 0, &face);
+ if (error) {
+ fprintf(stderr, "new face err %d\n", error);
+ exit(1);
+ }
+
+ if (display_dpi > 0) {
+ FT_F26Dot6 char_size = (FT_F26Dot6)((double)requested_size * 64.0 * bpp_mul);
+ FT_UInt ft_dpi = (FT_UInt)display_dpi;
+ error = FT_Set_Char_Size(
+ face, 0, char_size, ft_dpi, ft_dpi);
+ } else {
+ FT_UInt pixel_size = (FT_UInt)((double)requested_size * bpp_mul);
+ error = FT_Set_Pixel_Sizes(face, 0, pixel_size);
+ }
+ if (error) {
+ fprintf(stderr, "set pixel sizes err %d\n", error);
+ exit(1);
+ }
+
+ Codepoints present_codepoints = filter_present_codepoints(face, codepoints);
+ if (present_codepoints.count == 0) {
+ fprintf(stderr, "none of the requested code points are present in the font\n");
+ exit(1);
+ }
+ if (present_codepoints.count > UINT16_MAX) {
+ fprintf(stderr, "too many glyphs present for LVGL cmap glyph ids\n");
+ exit(1);
+ }
+
+ int64_t max_ascent = 0;
+ int64_t max_descent = 0;
+
+ for (size_t i = 0; i < present_codepoints.count; i++) {
+ UChar32 codepoint = present_codepoints.codepoints[i];
+ error = FT_Load_Char(face, (FT_ULong)codepoint, FT_LOAD_RENDER | FT_LOAD_TARGET_MONO);
+ if (error) {
+ fprintf(stderr, "load char U+%04X err %d\n", (unsigned int)codepoint, error);
+ exit(1);
+ }
+ validate_ft_bitmap(&face->glyph->bitmap, codepoint);
+
+ int64_t rows = face->glyph->bitmap.rows;
+ int64_t top = face->glyph->bitmap_top;
+ int64_t descent = rows > top ? rows - top : 0;
+ int64_t ascent = top > 0 ? top : 0;
+
+ if (descent > max_descent) {
+ max_descent = descent;
+ }
+ if (ascent > max_ascent) {
+ max_ascent = ascent;
+ }
+ }
+
+ int64_t line_height = (max_ascent + max_descent) / bpp_mul;
+ int64_t baseline = max_ascent / bpp_mul;
+ if (line_height == 0) {
+ int64_t metrics_ascent =
+ face->size->metrics.ascender > 0 ? face->size->metrics.ascender / 64 : 0;
+ int64_t metrics_descent =
+ face->size->metrics.descender < 0 ? -(face->size->metrics.descender / 64) : 0;
+ line_height = (metrics_ascent + metrics_descent) / bpp_mul;
+ baseline = metrics_ascent / bpp_mul;
+ }
+ if (line_height <= 0 || line_height > INT_MAX || baseline < 0 || baseline > line_height) {
+ fprintf(stderr, "font line metrics are out of range\n");
+ exit(1);
+ }
+
+ LvglFont* out = xcalloc(1, sizeof(*out));
+ out->bpp = bits_per_pixel;
+ out->line_height = (int)line_height;
+ out->baseline = (int)baseline;
+ out->glyph_count = present_codepoints.count;
+ out->glyphs = xcalloc(out->glyph_count, sizeof(*out->glyphs));
+ out->codepoint_count = present_codepoints.count;
+ out->codepoints = xmalloc(out->codepoint_count * sizeof(*out->codepoints));
+ memcpy(
+ out->codepoints,
+ present_codepoints.codepoints,
+ out->codepoint_count * sizeof(*out->codepoints));
+ build_cmaps(out);
+
+ for (size_t glyph_index = 0; glyph_index < present_codepoints.count; glyph_index++) {
+ UChar32 codepoint = present_codepoints.codepoints[glyph_index];
+ error = FT_Load_Char(face, (FT_ULong)codepoint, FT_LOAD_RENDER | FT_LOAD_TARGET_MONO);
+ if (error) {
+ fprintf(stderr, "load char U+%04X err %d\n", (unsigned int)codepoint, error);
+ exit(1);
+ }
+ validate_ft_bitmap(&face->glyph->bitmap, codepoint);
+
+ Glyph* glyph = &out->glyphs[glyph_index];
+ glyph->codepoint = codepoint;
+ set_glyph_metrics(glyph, face->glyph, bpp_mul);
+ glyph->bitmap_index = out->bitmap_size;
+ glyph->bitmap_size = lvgl_bitmap_size(glyph->box_w, glyph->box_h, bits_per_pixel);
+ if (glyph->bitmap_size > MAX_LVGL_BITMAP_SIZE - out->bitmap_size) {
+ fprintf(stderr, "bitmap too large for default LVGL glyph descriptor\n");
+ exit(1);
+ }
+ glyph->bitmap = xcalloc(glyph->bitmap_size, 1);
+
+ for (int y = 0; y < glyph->box_h; y++) {
+ for (int x = 0; x < glyph->box_w; x++) {
+ int coverage = 0;
+ for (int y_idx = 0; y_idx < bpp_mul; y_idx++) {
+ for (int x_idx = 0; x_idx < bpp_mul; x_idx++) {
+ if (ft_mono_pixel(
+ &face->glyph->bitmap, x * bpp_mul + x_idx, y * bpp_mul + y_idx)) {
+ coverage++;
+ }
+ }
+ }
+
+ if (bits_per_pixel == 1) {
+ set_lvgl_pixel(glyph, x, y, bits_per_pixel, coverage != 0 ? 1 : 0);
+ } else {
+ set_lvgl_pixel(glyph, x, y, bits_per_pixel, (uint8_t)((255 * coverage) / 256));
+ }
+ }
+ }
+
+ out->bitmap_size += glyph->bitmap_size;
+ }
+
+ FT_Done_Face(face);
+ FT_Done_FreeType(library);
+ free(present_codepoints.codepoints);
+ return out;
+}
+
+static void print_bytes(FILE* out, const uint8_t* bytes, size_t len)
+{
+ for (size_t i = 0; i < len; i++) {
+ if (i % 12 == 0) {
+ fprintf(out, " ");
+ }
+ fprintf(out, "0x%02X,", bytes[i]);
+ if (i % 12 == 11 || i + 1 == len) {
+ fprintf(out, "\n");
+ } else {
+ fprintf(out, " ");
+ }
+ }
+}
+
+static void close_output(FILE* out, const char* path)
+{
+ bool write_failed = ferror(out) != 0;
+ if (fclose(out) != 0 || write_failed) {
+ fprintf(stderr, "failed to write %s\n", path);
+ exit(2);
+ }
+}
+
+static void print_comment_text(FILE* out, const char* text)
+{
+ while (*text != '\0') {
+ if (*text == '\n' || *text == '\r') {
+ fputc(' ', out);
+ text++;
+ } else if (text[0] == '*' && text[1] == '/') {
+ fputs("* /", out);
+ text += 2;
+ } else {
+ fputc((unsigned char)*text, out);
+ text++;
+ }
+ }
+}
+
+static bool is_safe_header_basename(const char* name)
+{
+ for (const unsigned char* cursor = (const unsigned char*)name; *cursor != '\0'; cursor++) {
+ if (iscntrl(*cursor) || *cursor == '"' || *cursor == '\\') {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void print_utf8_codepoint(FILE* out, UChar32 codepoint)
+{
+ if (codepoint <= 0x7F) {
+ fputc((char)codepoint, out);
+ } else if (codepoint <= 0x7FF) {
+ fputc((char)(0xC0 | (codepoint >> 6)), out);
+ fputc((char)(0x80 | (codepoint & 0x3F)), out);
+ } else if (codepoint <= 0xFFFF) {
+ fputc((char)(0xE0 | (codepoint >> 12)), out);
+ fputc((char)(0x80 | ((codepoint >> 6) & 0x3F)), out);
+ fputc((char)(0x80 | (codepoint & 0x3F)), out);
+ } else {
+ fputc((char)(0xF0 | (codepoint >> 18)), out);
+ fputc((char)(0x80 | ((codepoint >> 12) & 0x3F)), out);
+ fputc((char)(0x80 | ((codepoint >> 6) & 0x3F)), out);
+ fputc((char)(0x80 | (codepoint & 0x3F)), out);
+ }
+}
+
+static void print_glyph_comment(FILE* out, UChar32 codepoint)
+{
+ fprintf(out, " /* U+%04X \"", (unsigned int)codepoint);
+ switch (codepoint) {
+ case '\0':
+ fprintf(out, "\\0");
+ break;
+ case '\b':
+ fprintf(out, "\\b");
+ break;
+ case '\t':
+ fprintf(out, "\\t");
+ break;
+ case '\n':
+ fprintf(out, "\\n");
+ break;
+ case '\f':
+ fprintf(out, "\\f");
+ break;
+ case '\r':
+ fprintf(out, "\\r");
+ break;
+ case '"':
+ fprintf(out, "\\\"");
+ break;
+ case '\\':
+ fprintf(out, "\\\\");
+ break;
+ default:
+ if (!u_isgraph(codepoint) ||
+ u_hasBinaryProperty(codepoint, UCHAR_DEFAULT_IGNORABLE_CODE_POINT)) {
+ fprintf(out, codepoint <= 0xFFFF ? "\\u%04X" : "\\U%08X", (unsigned int)codepoint);
+ } else {
+ print_utf8_codepoint(out, codepoint);
+ }
+ break;
+ }
+ fprintf(out, "\" */\n");
+}
+
+static void print_codepoint_ranges(FILE* out, const LvglFont* font)
+{
+ for (size_t i = 0; i < font->cmap_count; i++) {
+ const uint32_t range_start = font->cmaps[i].range_start;
+ const uint32_t range_end = range_start + font->cmaps[i].range_length - 1;
+ if (i > 0) {
+ fprintf(out, ",");
+ }
+ if (range_start == range_end) {
+ fprintf(out, "%u", range_start);
+ } else {
+ fprintf(out, "%u-%u", range_start, range_end);
+ }
+ }
+}
+
+static void dump_font(const LvglFont* font, const char* font_file_path, const char* font_name)
+{
+ char* symbol = NULL;
+ if (font_name == NULL) {
+ symbol = default_font_name(font_file_path, font_size);
+ } else {
+ if (!is_valid_c_identifier(font_name)) {
+ fprintf(stderr, "invalid --name: must be a valid C identifier\n");
+ exit(1);
+ }
+ symbol = xstrdup(font_name);
+ }
+ char* symbol_upper = sanitize_identifier(symbol, true);
+ char* public_symbol = public_font_symbol(symbol);
+
+ char* out_file = output_file_arg == NULL ? NULL : xstrdup(output_file_arg);
+ if (out_file == NULL) {
+ size_t len = checked_size_add(strlen(symbol), 3);
+ out_file = xmalloc(len);
+ snprintf(out_file, len, "%s.c", symbol);
+ }
+
+ char* header_file = output_header_name(out_file);
+ if (strcmp(out_file, header_file) == 0) {
+ fprintf(stderr, "output and generated header paths must be different\n");
+ exit(1);
+ }
+ char* header_basename = strrchr(header_file, '/');
+ header_basename = header_basename == NULL ? header_file : header_basename + 1;
+ if (!is_safe_header_basename(header_basename)) {
+ fprintf(stderr, "generated header name cannot be represented in a C include\n");
+ exit(1);
+ }
+
+ FILE* out = fopen(out_file, "w");
+ if (out == NULL) {
+ perror(out_file);
+ exit(2);
+ }
+
+ fprintf(
+ out, "/*******************************************************************************\n");
+ fprintf(out, " * Size: %g px\n", font_size);
+ fprintf(out, " * Bpp: %d\n", font->bpp);
+ fprintf(out, " * Opts: --dump --bpp %d --size %g", font->bpp, font_size);
+ if (dpi > 0) {
+ fprintf(out, " --dpi %d", dpi);
+ }
+ fprintf(out, " --font ");
+ print_comment_text(out, font_file_path);
+ fprintf(out, " --range ");
+ print_codepoint_ranges(out, font);
+ fprintf(out, " --name %s --output ", symbol);
+ print_comment_text(out, out_file);
+ fprintf(out, "\n");
+ fprintf(
+ out,
+ " ******************************************************************************/\n\n");
+
+ fprintf(out, "#ifdef __has_include\n");
+ fprintf(out, " #if __has_include(\"lvgl.h\")\n");
+ fprintf(out, " #ifndef LV_LVGL_H_INCLUDE_SIMPLE\n");
+ fprintf(out, " #define LV_LVGL_H_INCLUDE_SIMPLE\n");
+ fprintf(out, " #endif\n");
+ fprintf(out, " #endif\n");
+ fprintf(out, "#endif\n\n");
+ fprintf(out, "#ifdef LV_LVGL_H_INCLUDE_SIMPLE\n");
+ fprintf(out, " #include \"lvgl.h\"\n");
+ fprintf(out, "#else\n");
+ fprintf(out, " #include \"lvgl/lvgl.h\"\n");
+ fprintf(out, "#endif\n\n");
+ fprintf(out, "#include \"%s\"\n\n", header_basename);
+
+ fprintf(out, "#ifndef %s\n", symbol_upper);
+ fprintf(out, "#define %s 1\n", symbol_upper);
+ fprintf(out, "#endif\n\n");
+ fprintf(out, "#if %s\n\n", symbol_upper);
+
+ fprintf(out, "static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {\n");
+ if (font->bitmap_size == 0) {
+ fprintf(out, " 0x00\n");
+ } else {
+ for (size_t i = 0; i < font->glyph_count; i++) {
+ const Glyph* glyph = &font->glyphs[i];
+ print_glyph_comment(out, glyph->codepoint);
+ if (glyph->bitmap_size > 0) {
+ print_bytes(out, glyph->bitmap, glyph->bitmap_size);
+ }
+ if (i + 1 < font->glyph_count && glyph->bitmap_size > 0) {
+ fprintf(out, "\n");
+ }
+ }
+ }
+ fprintf(out, "};\n\n");
+
+ fprintf(out, "static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {\n");
+ fprintf(
+ out,
+ " {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, "
+ ".ofs_y = 0} /* id = 0 reserved */,\n");
+ for (size_t i = 0; i < font->glyph_count; i++) {
+ const Glyph* glyph = &font->glyphs[i];
+ fprintf(
+ out,
+ " {.bitmap_index = %zu, .adv_w = %d, .box_w = %d, .box_h = %d, "
+ ".ofs_x = %d, .ofs_y = %d} /* U+%04X */%s\n",
+ glyph->bitmap_index,
+ glyph->adv_w << 4,
+ glyph->box_w,
+ glyph->box_h,
+ glyph->ofs_x,
+ glyph->ofs_y,
+ glyph->codepoint,
+ i + 1 < font->glyph_count ? "," : "");
+ }
+ fprintf(out, "};\n\n");
+
+ fprintf(out, "static const lv_font_fmt_txt_cmap_t cmaps[] = {\n");
+ for (size_t i = 0; i < font->cmap_count; i++) {
+ fprintf(
+ out,
+ " {.range_start = %u, .range_length = %u, .glyph_id_start = %u,\n"
+ " .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0,\n"
+ " .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY}%s\n",
+ font->cmaps[i].range_start,
+ font->cmaps[i].range_length,
+ font->cmaps[i].glyph_id_start,
+ i + 1 < font->cmap_count ? "," : "");
+ }
+ fprintf(out, "};\n\n");
+
+ fprintf(out, "static const lv_font_fmt_txt_dsc_t font_dsc = {\n");
+ fprintf(out, " .glyph_bitmap = glyph_bitmap,\n");
+ fprintf(out, " .glyph_dsc = glyph_dsc,\n");
+ fprintf(out, " .cmaps = cmaps,\n");
+ fprintf(out, " .kern_dsc = NULL,\n");
+ fprintf(out, " .kern_scale = 0,\n");
+ fprintf(out, " .cmap_num = %zu,\n", font->cmap_count);
+ fprintf(out, " .bpp = %d,\n", font->bpp);
+ fprintf(out, " .kern_classes = 0,\n");
+ fprintf(out, " .bitmap_format = 0,\n");
+ fprintf(out, " .stride = 0,\n");
+ fprintf(out, "};\n\n");
+
+ fprintf(out, "const UG_FONT %s = {\n", public_symbol);
+ fprintf(out, " .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,\n");
+ fprintf(out, " .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,\n");
+ fprintf(out, " .line_height = %d,\n", font->line_height);
+ fprintf(out, " .base_line = %d,\n", font->line_height - font->baseline);
+ fprintf(out, " .subpx = LV_FONT_SUBPX_NONE,\n");
+ fprintf(out, " .underline_position = -1,\n");
+ fprintf(out, " .underline_thickness = 0,\n");
+ fprintf(out, " .static_bitmap = 0,\n");
+ fprintf(out, " .dsc = &font_dsc,\n");
+ fprintf(out, " .fallback = NULL,\n");
+ fprintf(out, " .user_data = NULL,\n");
+ fprintf(out, "};\n\n");
+ fprintf(out, "#endif /* %s */\n", symbol_upper);
+ close_output(out, out_file);
+
+ out = fopen(header_file, "w");
+ if (out == NULL) {
+ perror(header_file);
+ exit(2);
+ }
+ fprintf(out, "#ifndef TTF2LVGL_%s_H\n", symbol_upper);
+ fprintf(out, "#define TTF2LVGL_%s_H\n\n", symbol_upper);
+ fprintf(out, "#include <ugui.h>\n\n");
+ fprintf(out, "extern const UG_FONT %s;\n\n", public_symbol);
+ fprintf(out, "#endif /* TTF2LVGL_%s_H */\n", symbol_upper);
+ close_output(out, header_file);
+
+ free(public_symbol);
+ free(symbol);
+ free(symbol_upper);
+ free(out_file);
+ free(header_file);
+}
+
+static const Glyph* glyph_for_codepoint(const LvglFont* font, UChar32 codepoint)
+{
+ size_t left = 0;
+ size_t right = font->codepoint_count;
+ while (left < right) {
+ size_t mid = left + (right - left) / 2;
+ if (font->codepoints[mid] == codepoint) {
+ return &font->glyphs[mid];
+ }
+ if (font->codepoints[mid] < codepoint) {
+ left = mid + 1;
+ } else {
+ right = mid;
+ }
+ }
+ return NULL;
+}
+
+static uint8_t lvgl_opacity(const Glyph* glyph, int bits_per_pixel, int x, int y)
+{
+ if (x < 0 || y < 0 || x >= glyph->box_w || y >= glyph->box_h || glyph->bitmap_size == 0) {
+ return 0;
+ }
+ if (bits_per_pixel == 8) {
+ return glyph->bitmap[(size_t)y * (size_t)glyph->box_w + (size_t)x];
+ }
+
+ size_t bit_index = (size_t)y * (size_t)glyph->box_w + (size_t)x;
+ return (glyph->bitmap[bit_index / 8] & (1 << (7 - (bit_index % 8)))) != 0 ? 255 : 0;
+}
+
+static void show_font(const LvglFont* font, const Codepoints* text)
+{
+ uint8_t screen[SCREEN_HEIGHT][SCREEN_WIDTH];
+ memset(screen, 0, sizeof(screen));
+
+ for (int x = 0; x < SCREEN_WIDTH; x++) {
+ screen[0][x] = 255;
+ screen[SCREEN_HEIGHT - 1][x] = 255;
+ }
+ for (int y = 0; y < SCREEN_HEIGHT; y++) {
+ screen[y][0] = 255;
+ screen[y][SCREEN_WIDTH - 1] = 255;
+ }
+
+ int pen_x = 2;
+ int pen_y = 2;
+ int baseline_y = font->baseline;
+
+ for (size_t i = 0; i < text->count; i++) {
+ const Glyph* glyph = glyph_for_codepoint(font, text->codepoints[i]);
+ if (glyph == NULL) {
+ continue;
+ }
+
+ int glyph_x = pen_x + glyph->ofs_x;
+ int glyph_y = pen_y + baseline_y - glyph->box_h - glyph->ofs_y;
+ for (int y = 0; y < glyph->box_h; y++) {
+ for (int x = 0; x < glyph->box_w; x++) {
+ uint8_t opacity = lvgl_opacity(glyph, font->bpp, x, y);
+ int out_x = glyph_x + x;
+ int out_y = glyph_y + y;
+ if (opacity == 0 || out_x < 0 || out_y < 0 || out_x >= SCREEN_WIDTH ||
+ out_y >= SCREEN_HEIGHT) {
+ continue;
+ }
+ screen[out_y][out_x] = opacity;
+ }
+ }
+ pen_x += glyph->adv_w;
+ }
+
+ for (int y = 0; y < SCREEN_HEIGHT; y++) {
+ for (int x = 0; x < SCREEN_WIDTH; x++) {
+ if (screen[y][x] == 0) {
+ putchar(' ');
+ } else if (screen[y][x] == 255) {
+ putchar('*');
+ } else {
+ putchar('+');
+ }
+ }
+ putchar('\n');
+ }
+}
+
+static void usage(void)
+{
+ fprintf(
+ stderr,
+ "ttf2lvgl {--show text|--dump} --font=fontfile [--dpi=displaydpi] "
+ "--size=fontsize [--bpp=bitsperpixel] [--range=RANGES] "
+ "[--name=symbol] [--output=file.c]\n");
+ fprintf(
+ stderr,
+ "Ranges are comma-separated code points or ranges, e.g. 32-127,160,U+0100-U+017F.\n");
+ fprintf(stderr, "If --dpi is not given, font size is assumed to be pixels.\n");
+ fprintf(stderr, "Bits per pixel must be 1 or 8. Default is 1.\n");
+}
+
+static int parse_int_option(const char* option, const char* text, int min, int max)
+{
+ char* end = NULL;
+ errno = 0;
+ long value = strtol(text, &end, 10);
+ if (errno == ERANGE || end == text || *end != '\0' || value < min || value > max) {
+ fprintf(stderr, "invalid --%s value: %s\n", option, text);
+ exit(1);
+ }
+ return (int)value;
+}
+
+static float parse_size_option(const char* text)
+{
+ char* end = NULL;
+ errno = 0;
+ float value = strtof(text, &end);
+ if (errno == ERANGE || end == text || *end != '\0' || !isfinite(value) || value <= 0) {
+ fprintf(stderr, "invalid --size value: %s\n", text);
+ exit(1);
+ }
+ return value;
+}
+
+static struct option longopts[] = {
+ {"show", required_argument, NULL, 'a'},
+ {"dump", no_argument, &dump, 1},
+ {"dpi", required_argument, NULL, 'd'},
+ {"minchar", required_argument, NULL, 'z'},
+ {"maxchar", required_argument, NULL, 'e'},
+ {"size", required_argument, NULL, 's'},
+ {"font", required_argument, NULL, 'f'},
+ {"bpp", required_argument, NULL, 'b'},
+ {"range", required_argument, NULL, 'r'},
+ {"name", required_argument, NULL, 'n'},
+ {"output", required_argument, NULL, 'o'},
+ {NULL, 0, NULL, 0},
+};
+
+int main(int argc, char** argv)
+{
+ int ch;
+ while ((ch = getopt_long(argc, argv, "", longopts, NULL)) != -1) {
+ switch (ch) {
+ case 'f':
+ font_file = optarg;
+ break;
+ case 'a':
+ show_text = optarg;
+ break;
+ case 's':
+ font_size = parse_size_option(optarg);
+ break;
+ case 'd':
+ dpi = parse_int_option("dpi", optarg, 0, INT_MAX);
+ break;
+ case 'b':
+ bpp = parse_int_option("bpp", optarg, 1, 8);
+ if (bpp != 1 && bpp != 8) {
+ fprintf(stderr, "Bits per pixel must be 1 or 8. Default is 1.\n");
+ exit(1);
+ }
+ break;
+ case 'z':
+ min_char = parse_int_option("minchar", optarg, 0, 0x10FFFF);
+ minmax_used = true;
+ break;
+ case 'e':
+ max_char = parse_int_option("maxchar", optarg, 0, 0x10FFFF);
+ minmax_used = true;
+ break;
+ case 'r':
+ range_used = true;
+ parse_codepoint_ranges(optarg, &range_codepoints);
+ break;
+ case 'n':
+ font_name_arg = optarg;
+ break;
+ case 'o':
+ output_file_arg = optarg;
+ break;
+ case 0:
+ break;
+ default:
+ usage();
+ exit(1);
+ }
+ }
+
+ if (optind != argc) {
+ fprintf(stderr, "unexpected positional argument: %s\n", argv[optind]);
+ exit(1);
+ }
+
+ if (range_used && minmax_used) {
+ fprintf(stderr, "--range cannot be combined with --minchar or --maxchar\n");
+ exit(1);
+ }
+ if (!range_used) {
+ append_legacy_codepoint_range(&range_codepoints);
+ }
+ codepoints_sort_dedup(&range_codepoints);
+
+ if ((!dump && show_text == NULL) || font_file == NULL || font_size == 0 ||
+ range_codepoints.count == 0) {
+ usage();
+ exit(1);
+ }
+
+ LvglFont* font = convert_font(font_file, dpi, font_size, bpp, &range_codepoints);
+
+ if (show_text != NULL) {
+ Codepoints show_codepoints = utf8_to_codepoints(show_text);
+ show_font(font, &show_codepoints);
+ free(show_codepoints.codepoints);
+ }
+
+ if (dump) {
+ dump_font(font, font_file, font_name_arg);
+ }
+
+ for (size_t i = 0; i < font->glyph_count; i++) {
+ free(font->glyphs[i].bitmap);
+ }
+ free(font->glyphs);
+ free(font->codepoints);
+ free(font->cmaps);
+ free(font);
+ free(range_codepoints.codepoints);
+}
### tools/ttf2ugui
@@ -1 +0,0 @@
-Subproject commit 1d1a254065fa0852fb51fdf6efc7b4d70feae391Why this scored 35/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.