diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e84dfb..c47f646 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,14 @@ project(new_kbd) zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc) zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/events) +zephyr_compile_definitions( + LV_LVGL_H_INCLUDE_SIMPLE=1 + LV_FONT_MONTSERRAT_14=0 + LV_FONT_UNSCII_8=0 + LV_FONT_DEFAULT=\&ui_font_keyboard_small_18 + "LV_FONT_CUSTOM_DECLARE=LV_FONT_DECLARE(ui_font_keyboard_small_18) LV_FONT_DECLARE(ui_font_keyboard_time_48)" +) + target_compile_definitions(app PRIVATE APP_HID_KEYMAP_DEF_PATH=\"hid_keymap_def.h\" ) @@ -44,4 +52,6 @@ target_sources(app PRIVATE src/modules/time_manager_module.c src/modules/usb_hid_module.c src/modules/ble_hid_module.c + src/ui/fonts/ui_font_keyboard_small_18.c + src/ui/fonts/ui_font_keyboard_time_48.c ) diff --git a/prj.conf b/prj.conf index 40347b8..460d54a 100644 --- a/prj.conf +++ b/prj.conf @@ -84,15 +84,19 @@ CONFIG_MIPI_DBI=y CONFIG_ST7789V=y CONFIG_LVGL=y CONFIG_LV_CONF_MINIMAL=y +CONFIG_LV_COLOR_16_SWAP=y CONFIG_LV_BUILD_EXAMPLES=n CONFIG_LV_BUILD_DEMOS=n CONFIG_LV_USE_LABEL=y -CONFIG_LV_FONT_MONTSERRAT_14=y +CONFIG_LV_USE_FLEX=y +CONFIG_LV_USE_FONT_COMPRESSED=y +CONFIG_LV_TXT_ENC_UTF8=y CONFIG_LV_Z_AUTO_INIT=y CONFIG_LV_Z_VDB_SIZE=25 CONFIG_LV_Z_BITS_PER_PIXEL=16 CONFIG_LV_Z_LVGL_MUTEX=y CONFIG_LV_Z_RUN_LVGL_ON_WORKQUEUE=y +CONFIG_LV_Z_LVGL_WORKQUEUE_STACK_SIZE=8192 CONFIG_LV_Z_FLUSH_THREAD=y CONFIG_LV_Z_DOUBLE_VDB=y CONFIG_LV_Z_MEM_POOL_SIZE=16384 diff --git a/src/modules/display_module.c b/src/modules/display_module.c index 72c6ee5..99d3325 100644 --- a/src/modules/display_module.c +++ b/src/modules/display_module.c @@ -1,3 +1,7 @@ +#include +#include +#include + #include #include #include @@ -9,32 +13,100 @@ #include #define MODULE display +#include #include +#include + +#include "battery_status_event.h" +#include "keyboard_led_event.h" +#include "mode_event.h" +#include "time_manager.h" #include LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); #define DISPLAY_UPDATE_PERIOD_MS 1000 +#define DISPLAY_IDLE_TIMEOUT_MIN 1 #define DISPLAY_BACKLIGHT_BRIGHTNESS 100 +#define DISPLAY_DEMO_BASE_YEAR 2026 +#define DISPLAY_DEMO_BASE_MONTH 3 +#define DISPLAY_DEMO_BASE_DAY 27 +#define DISPLAY_DEMO_BASE_HOUR 14 +#define DISPLAY_DEMO_BASE_MIN 28 +#define DISPLAY_DEMO_BASE_SEC 36 +#define DISPLAY_SYMBOL_PLUG "\xEF\x87\xA6" /* U+F1E6, custom plug glyph in ui_font_keyboard_small_18 */ -struct display_ctx { +LV_FONT_DECLARE(ui_font_keyboard_small_18); +LV_FONT_DECLARE(ui_font_keyboard_time_48); + +enum display_status_id +{ + DISPLAY_STATUS_USB = 0, + DISPLAY_STATUS_BLE, + DISPLAY_STATUS_NUMLOCK, + DISPLAY_STATUS_CAPSLOCK, + DISPLAY_STATUS_COUNT, +}; + +enum display_pm_state +{ + DISPLAY_PM_STATE_ACTIVE = 0, + DISPLAY_PM_STATE_OFF, +}; + +struct display_ui_state +{ + lv_color_t theme_color; + lv_color_t inactive_border_color; + uint8_t battery_level; + mode_type_t mode; + uint8_t led_mask; + uint8_t battery_flags; + bool status_enabled[DISPLAY_STATUS_COUNT]; + lv_obj_t *status_badges[DISPLAY_STATUS_COUNT]; + lv_obj_t *status_labels[DISPLAY_STATUS_COUNT]; + lv_obj_t *battery_icon; + lv_obj_t *battery_label; + lv_obj_t *battery_state_label; + lv_obj_t *date_label; + lv_obj_t *time_label; +}; + +struct display_ctx +{ const struct device *dev; struct display_capabilities caps; struct k_work_delayable update_work; - lv_obj_t *title_label; - lv_obj_t *count_label; + struct k_work_delayable idle_work; + struct display_ui_state ui; uint32_t tick_count; - bool ui_ready; + enum display_pm_state pm_state; bool initialized; }; static struct display_ctx disp = { .dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)), + .ui.theme_color = LV_COLOR_MAKE(0x4C, 0xC9, 0xF0), + .ui.inactive_border_color = LV_COLOR_MAKE(0xA0, 0xA7, 0xB4), + .ui.battery_level = 15U, + .ui.battery_flags = 0U, + .ui.mode = MODE_TYPE_USB, + .ui.status_enabled = {true, true, false, true}, + .pm_state = DISPLAY_PM_STATE_OFF, }; static const struct led_dt_spec display_backlight = LED_DT_SPEC_GET(DT_NODELABEL(backlight)); +static const char *const g_status_texts[DISPLAY_STATUS_COUNT] = { + LV_SYMBOL_USB, + LV_SYMBOL_BLUETOOTH, + "1", + "A", +}; + +static void display_refresh_all_locked(void); + static void display_schedule_update(k_timeout_t delay) { #ifdef CONFIG_LV_Z_RUN_LVGL_ON_WORKQUEUE @@ -44,136 +116,581 @@ static void display_schedule_update(k_timeout_t delay) #endif } -static int display_backlight_init(void) +static void display_schedule_idle_timeout(k_timeout_t delay) +{ + k_work_reschedule(&disp.idle_work, delay); +} + +/* 背光初始化独立处理,避免 UI 创建逻辑里混入硬件使能细节。 */ +static int display_backlight_set(uint8_t brightness) { int err; - if (!led_is_ready_dt(&display_backlight)) { + if (!led_is_ready_dt(&display_backlight)) + { LOG_WRN("Display backlight device not ready"); return 0; } - /* - * 背光亮度交给 pwm-leds 驱动管理,这样后面如果要做调光、呼吸灯或亮度档位, - * 都可以直接沿用 Zephyr 的 LED/PWM 接口,而不需要再单独碰 PWM 寄存器。 - */ - err = led_set_brightness_dt(&display_backlight, DISPLAY_BACKLIGHT_BRIGHTNESS); - if (err) { - LOG_ERR("Failed to set backlight brightness: %d", err); + err = led_set_brightness_dt(&display_backlight, brightness); + if (err) + { + LOG_ERR("Failed to set backlight brightness(%u): %d", brightness, err); return err; } return 0; } -static void display_create_ui_locked(void) +static bool display_is_active(void) { - lv_obj_t *screen = lv_screen_active(); - - /* - * 先显式设置背景和文字颜色,避免把“有画面但颜色刚好看不见”误判为 - * “LVGL 没有刷新”。这里使用高对比度配色,便于快速验证渲染链路。 - */ - lv_obj_set_style_bg_opa(screen, LV_OPA_COVER, LV_PART_MAIN); - lv_obj_set_style_bg_color(screen, lv_color_hex(0x102A43), LV_PART_MAIN); - lv_obj_set_style_text_color(screen, lv_color_hex(0xF0F4F8), LV_PART_MAIN); - lv_obj_clean(screen); - - disp.title_label = lv_label_create(screen); - lv_label_set_text(disp.title_label, "Zephyr LVGL running"); - lv_obj_set_style_text_color(disp.title_label, lv_color_hex(0xF0F4F8), LV_PART_MAIN); - lv_obj_align(disp.title_label, LV_ALIGN_CENTER, 0, -16); - - disp.count_label = lv_label_create(screen); - lv_label_set_text(disp.count_label, "tick 0"); - lv_obj_set_style_text_color(disp.count_label, lv_color_hex(0xFFD166), LV_PART_MAIN); - lv_obj_align(disp.count_label, LV_ALIGN_CENTER, 0, 16); - - disp.ui_ready = true; + return disp.pm_state == DISPLAY_PM_STATE_ACTIVE; } -static void display_update_work_fn(struct k_work *work) +/* 只负责保活屏幕空闲计时,不隐式点亮屏幕。 */ +static void display_kick_idle_timer(void) { - char count_str[24]; - lv_color_t bg_color; + if (!disp.initialized || !display_is_active()) + return; - ARG_UNUSED(work); + display_schedule_idle_timeout(K_MINUTES(DISPLAY_IDLE_TIMEOUT_MIN)); +} - if (!disp.initialized) { +/* 熄屏时同时关闭刷新和背光,并将模块状态切到 OFF。 */ +static void display_sleep(void) +{ + int err; + + if (!disp.initialized || !display_is_active()) + return; + + (void)k_work_cancel_delayable(&disp.update_work); + (void)k_work_cancel_delayable(&disp.idle_work); + + err = display_blanking_on(disp.dev); + if (err) + LOG_WRN("Display blanking on failed: %d", err); + + (void)display_backlight_set(0U); + disp.pm_state = DISPLAY_PM_STATE_OFF; + module_set_state(MODULE_STATE_OFF); +} + +/* 唤醒屏幕后立刻刷新 UI,并重新启动定时刷新和空闲超时。 */ +static void display_wake(void) +{ + int err; + + if (!disp.initialized) + return; + + if (display_is_active()) { + display_kick_idle_timer(); return; } - lvgl_lock(); + err = display_blanking_off(disp.dev); + if (err) + LOG_WRN("Display blanking off failed: %d", err); - if (!disp.ui_ready) { - display_create_ui_locked(); + (void)display_backlight_set(DISPLAY_BACKLIGHT_BRIGHTNESS); + + lvgl_lock(); + display_refresh_all_locked(); + lvgl_unlock(); + + disp.pm_state = DISPLAY_PM_STATE_ACTIVE; + display_schedule_update(K_NO_WAIT); + display_kick_idle_timer(); + module_set_state(MODULE_STATE_READY); +} + +static void display_idle_timeout_fn(struct k_work *work) +{ + ARG_UNUSED(work); + + display_sleep(); +} + +/* 电量颜色与 PC 原型保持一致,顶部状态区能快速表达健康度。 */ +static lv_color_t display_get_battery_color(uint8_t battery_level) +{ + if (battery_level > 70U) + return lv_color_hex(0x8BD450); + + if (battery_level >= 20U) + return lv_color_hex(0xF4D35E); + + return lv_color_hex(0xE63946); +} + +/* 电池图标由精简图标字体提供,不再依赖 LVGL 内建字体资源。 */ +static const char *display_get_battery_symbol(uint8_t battery_level) +{ + if (battery_level > 85U) + return LV_SYMBOL_BATTERY_FULL; + + if (battery_level > 60U) + return LV_SYMBOL_BATTERY_3; + + if (battery_level > 35U) + return LV_SYMBOL_BATTERY_2; + + if (battery_level >= 20U) + return LV_SYMBOL_BATTERY_1; + + return LV_SYMBOL_BATTERY_EMPTY; +} + +/* 模式事件只需要驱动 USB/BLE 两个 badge,2.4G 模式两者都灭。 */ +static void display_update_mode_state(mode_type_t mode) +{ + disp.ui.mode = mode; + disp.ui.status_enabled[DISPLAY_STATUS_USB] = (mode == MODE_TYPE_USB); + disp.ui.status_enabled[DISPLAY_STATUS_BLE] = (mode == MODE_TYPE_BLE); +} + +/* 最新原型只显示 NumLock 和 CapsLock,不再展示 ScrollLock。 */ +static void display_update_keyboard_led_state(uint8_t led_mask) +{ + disp.ui.led_mask = led_mask; + disp.ui.status_enabled[DISPLAY_STATUS_NUMLOCK] = + (led_mask & KEYBOARD_LED_MASK_NUM_LOCK) != 0U; + disp.ui.status_enabled[DISPLAY_STATUS_CAPSLOCK] = + (led_mask & KEYBOARD_LED_MASK_CAPS_LOCK) != 0U; +} + +/* 底部状态条的亮灭与边框颜色联动更新,保持原型机视觉语言。 */ +static void display_refresh_status_bar_locked(void) +{ + for (uint32_t i = 0; i < DISPLAY_STATUS_COUNT; i++) + { + lv_obj_t *badge = disp.ui.status_badges[i]; + lv_obj_t *label = disp.ui.status_labels[i]; + bool active = disp.ui.status_enabled[i]; + + if (!badge || !label) + continue; + + lv_obj_set_style_border_width(badge, 4, 0); + lv_obj_set_style_border_color(badge, + active ? disp.ui.theme_color : disp.ui.inactive_border_color, + 0); + lv_obj_set_style_bg_color(badge, + active ? lv_color_hex(0x1D2735) : lv_color_hex(0x161A20), + 0); + lv_obj_set_style_text_color(label, + active ? lv_color_white() : lv_color_hex(0x7C8798), + 0); + } +} + +/* 电池图标、百分比和状态图标分开更新,便于独立配色。 */ +static void display_refresh_battery_locked(void) +{ + char battery_text[8]; + lv_color_t battery_color; + const char *state_symbol = ""; + lv_color_t state_color = lv_color_white(); + + if (!disp.ui.battery_icon || !disp.ui.battery_label || !disp.ui.battery_state_label) + return; + + battery_color = display_get_battery_color(disp.ui.battery_level); + snprintk(battery_text, sizeof(battery_text), "%u%%", disp.ui.battery_level); + + if ((disp.ui.battery_flags & BATTERY_STATUS_FLAG_FULL) != 0U) + { + state_symbol = DISPLAY_SYMBOL_PLUG; + state_color = lv_color_hex(0x4C9EF5); + } + else if ((disp.ui.battery_flags & BATTERY_STATUS_FLAG_CHARGING) != 0U) + { + state_symbol = LV_SYMBOL_CHARGE; + state_color = lv_color_hex(0xF4D35E); } - bg_color = ((disp.tick_count & 0x01u) == 0U) ? lv_color_hex(0x102A43) : - lv_color_hex(0x1F6F8B); - lv_obj_set_style_bg_color(lv_screen_active(), bg_color, LV_PART_MAIN); + lv_label_set_text(disp.ui.battery_icon, + display_get_battery_symbol(disp.ui.battery_level)); + lv_obj_set_style_text_color(disp.ui.battery_icon, battery_color, 0); + lv_label_set_text(disp.ui.battery_label, battery_text); + lv_label_set_text(disp.ui.battery_state_label, state_symbol); + lv_obj_set_style_text_color(disp.ui.battery_state_label, state_color, 0); +} - snprintk(count_str, sizeof(count_str), "tick %u", disp.tick_count++); - lv_label_set_text(disp.count_label, count_str); - lv_obj_invalidate(lv_screen_active()); +/* + * 时间优先显示 time_manager 的真实快照。 + * 如果当前尚未同步,则退回到固定基准上的 demo 时间,保证 UI 结构始终可见。 + */ +static void display_refresh_datetime_locked(void) +{ + struct time_manager_snapshot snapshot; + char date_text[16]; + char time_text[16]; + int err = time_manager_get_snapshot(&snapshot); + if (!disp.ui.date_label || !disp.ui.time_label) + return; + + if (!err) + { + time_t local_seconds; + struct tm tm_buf; + struct tm *tm_info; + + local_seconds = (time_t)(snapshot.utc_ms / 1000ULL) + + (time_t)((int32_t)snapshot.timezone_min * 60); + tm_info = gmtime_r(&local_seconds, &tm_buf); + + if (tm_info) + { + unsigned int year = (unsigned int)(tm_info->tm_year + 1900); + unsigned int month = (unsigned int)(tm_info->tm_mon + 1); + unsigned int day = (unsigned int)tm_info->tm_mday; + unsigned int hour = (unsigned int)tm_info->tm_hour; + unsigned int minute = (unsigned int)tm_info->tm_min; + unsigned int second = (unsigned int)tm_info->tm_sec; + + snprintk(date_text, sizeof(date_text), "%04u/%02u/%02u", + year, month, day); + snprintk(time_text, sizeof(time_text), "%02u:%02u:%02u", + hour, minute, second); + lv_label_set_text(disp.ui.date_label, date_text); + lv_label_set_text(disp.ui.time_label, time_text); + return; + } + } + + { + uint32_t seconds = disp.tick_count; + uint32_t hour = (DISPLAY_DEMO_BASE_HOUR + (seconds / 3600U)) % 24U; + uint32_t minute = (DISPLAY_DEMO_BASE_MIN + ((seconds / 60U) % 60U)) % 60U; + uint32_t second = (DISPLAY_DEMO_BASE_SEC + (seconds % 60U)) % 60U; + + snprintk(date_text, sizeof(date_text), "%04d/%02d/%02d", + DISPLAY_DEMO_BASE_YEAR, + DISPLAY_DEMO_BASE_MONTH, + DISPLAY_DEMO_BASE_DAY); + snprintk(time_text, sizeof(time_text), "%02u:%02u:%02u", + hour, minute, second); + lv_label_set_text(disp.ui.date_label, date_text); + lv_label_set_text(disp.ui.time_label, time_text); + } +} + +/* 一次性把缓存状态刷到 UI,避免控件创建与状态恢复互相耦合。 */ +static void display_refresh_all_locked(void) +{ + display_refresh_status_bar_locked(); + display_refresh_battery_locked(); + display_refresh_datetime_locked(); +} + +/* 状态 badge 保持原型尺寸和圆角,确保在 320x172 面板上视觉一致。 */ +static void display_create_status_chip_locked(lv_obj_t *parent, enum display_status_id id) +{ + lv_obj_t *badge = lv_obj_create(parent); + lv_obj_t *label; + + lv_obj_remove_style_all(badge); + lv_obj_set_size(badge, 50, 32); + lv_obj_set_style_radius(badge, 10, 0); + lv_obj_set_style_bg_opa(badge, LV_OPA_COVER, 0); + lv_obj_set_style_pad_all(badge, 0, 0); + + label = lv_label_create(badge); + lv_label_set_text(label, g_status_texts[id]); + lv_obj_set_width(label, LV_PCT(100)); + lv_obj_set_style_text_font(label, &ui_font_keyboard_small_18, 0); + lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); + lv_obj_center(label); + + disp.ui.status_badges[id] = badge; + disp.ui.status_labels[id] = label; +} + +/* UI 直接内联到 display_module,保留原型布局而不引入额外 ui 抽象层。 */ +static void display_create_ui_locked(void) +{ + lv_obj_t *screen = lv_screen_active(); + lv_obj_t *content; + lv_obj_t *top_row; + lv_obj_t *battery_wrap; + lv_obj_t *middle_row; + lv_obj_t *bottom_row; + + lv_obj_clean(screen); + lv_obj_set_style_bg_color(screen, lv_color_hex(0x0F1115), 0); + lv_obj_set_style_bg_grad_color(screen, lv_color_hex(0x1A1F29), 0); + lv_obj_set_style_bg_grad_dir(screen, LV_GRAD_DIR_VER, 0); + lv_obj_set_style_bg_opa(screen, LV_OPA_COVER, 0); + lv_obj_set_style_text_color(screen, lv_color_white(), 0); + lv_obj_set_style_pad_all(screen, 0, 0); + lv_obj_set_scrollbar_mode(screen, LV_SCROLLBAR_MODE_OFF); + + content = lv_obj_create(screen); + lv_obj_remove_style_all(content); + lv_obj_set_size(content, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_bg_color(content, lv_color_hex(0x0F1115), 0); + lv_obj_set_style_bg_opa(content, LV_OPA_TRANSP, 0); + lv_obj_set_style_pad_left(content, 14, 0); + lv_obj_set_style_pad_right(content, 14, 0); + lv_obj_set_style_pad_top(content, 8, 0); + lv_obj_set_style_pad_bottom(content, 8, 0); + lv_obj_set_layout(content, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(content, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(content, + LV_FLEX_ALIGN_START, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + + top_row = lv_obj_create(content); + lv_obj_remove_style_all(top_row); + lv_obj_set_width(top_row, LV_PCT(100)); + lv_obj_set_flex_grow(top_row, 1); + lv_obj_set_style_bg_color(top_row, lv_color_hex(0x0F1115), 0); + lv_obj_set_style_bg_opa(top_row, LV_OPA_TRANSP, 0); + lv_obj_set_layout(top_row, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(top_row, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(top_row, + LV_FLEX_ALIGN_SPACE_BETWEEN, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + + disp.ui.date_label = lv_label_create(top_row); + lv_obj_set_style_text_font(disp.ui.date_label, &ui_font_keyboard_small_18, 0); + lv_obj_set_style_text_color(disp.ui.date_label, lv_color_hex(0xD8DEE9), 0); + + battery_wrap = lv_obj_create(top_row); + lv_obj_remove_style_all(battery_wrap); + lv_obj_set_width(battery_wrap, LV_SIZE_CONTENT); + lv_obj_set_layout(battery_wrap, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(battery_wrap, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(battery_wrap, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_column(battery_wrap, 4, 0); + + disp.ui.battery_icon = lv_label_create(battery_wrap); + lv_obj_set_style_text_font(disp.ui.battery_icon, &ui_font_keyboard_small_18, 0); + + disp.ui.battery_label = lv_label_create(battery_wrap); + lv_obj_set_style_text_font(disp.ui.battery_label, &ui_font_keyboard_small_18, 0); + lv_obj_set_style_text_color(disp.ui.battery_label, lv_color_hex(0xD8DEE9), 0); + + disp.ui.battery_state_label = lv_label_create(battery_wrap); + lv_obj_set_style_text_font(disp.ui.battery_state_label, &ui_font_keyboard_small_18, 0); + + middle_row = lv_obj_create(content); + lv_obj_remove_style_all(middle_row); + lv_obj_set_width(middle_row, LV_PCT(100)); + lv_obj_set_flex_grow(middle_row, 2); + lv_obj_set_style_bg_color(middle_row, lv_color_hex(0x0F1115), 0); + lv_obj_set_style_bg_opa(middle_row, LV_OPA_TRANSP, 0); + + disp.ui.time_label = lv_label_create(middle_row); + lv_obj_set_style_text_font(disp.ui.time_label, &ui_font_keyboard_time_48, 0); + lv_obj_set_style_text_color(disp.ui.time_label, lv_color_white(), 0); + lv_obj_center(disp.ui.time_label); + + bottom_row = lv_obj_create(content); + lv_obj_remove_style_all(bottom_row); + lv_obj_set_width(bottom_row, LV_PCT(100)); + lv_obj_set_flex_grow(bottom_row, 1); + lv_obj_set_style_bg_color(bottom_row, lv_color_hex(0x0F1115), 0); + lv_obj_set_style_bg_opa(bottom_row, LV_OPA_TRANSP, 0); + lv_obj_set_layout(bottom_row, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(bottom_row, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(bottom_row, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_column(bottom_row, 6, 0); + + for (uint32_t i = 0; i < DISPLAY_STATUS_COUNT; i++) + display_create_status_chip_locked(bottom_row, (enum display_status_id)i); + + display_refresh_all_locked(); +} + +/* 周期刷新只负责时间区域;状态图标改为事件驱动,避免无谓重绘。 */ +static void display_update_work_fn(struct k_work *work) +{ + ARG_UNUSED(work); + + if (!disp.initialized) + return; + + if (!display_is_active()) + return; + + disp.tick_count++; + + lvgl_lock(); + display_refresh_datetime_locked(); lvgl_unlock(); display_schedule_update(K_MSEC(DISPLAY_UPDATE_PERIOD_MS)); } -static int display_demo_init(void) +/* 显示初始化完成后,后续 UI 更新全部通过事件和定时刷新驱动。 */ +static int display_init(void) { int err; - if (!device_is_ready(disp.dev)) { + if (!device_is_ready(disp.dev)) + { LOG_ERR("Display device not ready"); return -ENODEV; } display_get_capabilities(disp.dev, &disp.caps); - LOG_INF("Display caps: %ux%u fmt=%d", disp.caps.x_resolution, disp.caps.y_resolution, - disp.caps.current_pixel_format); + LOG_INF("Display caps: %ux%u fmt=%d", + disp.caps.x_resolution, + disp.caps.y_resolution, + disp.caps.current_pixel_format); k_work_init_delayable(&disp.update_work, display_update_work_fn); + k_work_init_delayable(&disp.idle_work, display_idle_timeout_fn); disp.tick_count = 0U; - disp.ui_ready = false; err = display_blanking_off(disp.dev); - if (err) { + if (err) + { LOG_ERR("Display blanking off failed: %d", err); return err; } - err = display_backlight_init(); - if (err) { + err = display_backlight_set(DISPLAY_BACKLIGHT_BRIGHTNESS); + if (err) return err; - } + + lvgl_lock(); + display_create_ui_locked(); + lvgl_unlock(); disp.initialized = true; + disp.pm_state = DISPLAY_PM_STATE_ACTIVE; display_schedule_update(K_NO_WAIT); - LOG_INF("LVGL display demo initialized"); + display_kick_idle_timer(); + LOG_INF("Display UI initialized"); return 0; } +/* 电池事件只缓存最新 SOC,UI 若已就绪则立即刷新顶部电池区域。 */ +static bool handle_battery_status_event(const struct battery_status_event *event) +{ + disp.ui.battery_level = battery_status_event_get_soc(event); + disp.ui.battery_flags = battery_status_event_get_flags(event); + + if (!disp.initialized) + return false; + + if (!display_is_active()) + return false; + + lvgl_lock(); + display_refresh_battery_locked(); + lvgl_unlock(); + return false; +} + +/* 模式事件只影响 USB/BLE 两个 badge 的亮灭。 */ +static bool handle_mode_event(const struct mode_event *event) +{ + display_update_mode_state(event->mode_type); + + if (!disp.initialized) + return false; + + if (!display_is_active()) + return false; + + lvgl_lock(); + display_refresh_status_bar_locked(); + lvgl_unlock(); + return false; +} + +/* NumLock/CapsLock/ScrollLock 变化后,底部三个状态 badge 立即更新。 */ +static bool handle_keyboard_led_event(const struct keyboard_led_event *event) +{ + display_update_keyboard_led_state(keyboard_led_event_get_mask(event)); + + if (!disp.initialized) + return false; + + if (!display_is_active()) + return false; + + lvgl_lock(); + display_refresh_status_bar_locked(); + lvgl_unlock(); + return false; +} + +/* 任意按钮事件都可点亮屏幕并重置 1 分钟空闲计时。 */ +static bool handle_button_event(const struct button_event *event) +{ + ARG_UNUSED(event); + + display_wake(); + return false; +} + +static bool handle_power_down_event(void) +{ + display_sleep(); + return false; +} + +static bool handle_wake_up_event(void) +{ + display_wake(); + return false; +} + +static bool handle_module_state_event(const struct module_state_event *event) +{ + if (!check_state(event, MODULE_ID(main), MODULE_STATE_READY)) + return false; + + if (!display_init()) + { + module_set_state(MODULE_STATE_READY); + } + else + { + module_set_state(MODULE_STATE_ERROR); + } + + return false; +} + static bool app_event_handler(const struct app_event_header *aeh) { - if (is_module_state_event(aeh)) { - const struct module_state_event *event = cast_module_state_event(aeh); + if (is_module_state_event(aeh)) + return handle_module_state_event(cast_module_state_event(aeh)); - if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) { - int err = display_demo_init(); + if (is_battery_status_event(aeh)) + return handle_battery_status_event(cast_battery_status_event(aeh)); - if (err) { - module_set_state(MODULE_STATE_ERROR); - } else { - module_set_state(MODULE_STATE_READY); - } - } + if (is_mode_event(aeh)) + return handle_mode_event(cast_mode_event(aeh)); - return false; - } + if (is_keyboard_led_event(aeh)) + return handle_keyboard_led_event(cast_keyboard_led_event(aeh)); + + if (is_button_event(aeh)) + return handle_button_event(cast_button_event(aeh)); + + if (is_power_down_event(aeh)) + return handle_power_down_event(); + + if (is_wake_up_event(aeh)) + return handle_wake_up_event(); __ASSERT_NO_MSG(false); return false; @@ -181,3 +698,9 @@ static bool app_event_handler(const struct app_event_header *aeh) APP_EVENT_LISTENER(MODULE, app_event_handler); APP_EVENT_SUBSCRIBE(MODULE, module_state_event); +APP_EVENT_SUBSCRIBE(MODULE, battery_status_event); +APP_EVENT_SUBSCRIBE(MODULE, mode_event); +APP_EVENT_SUBSCRIBE(MODULE, keyboard_led_event); +APP_EVENT_SUBSCRIBE(MODULE, button_event); +APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event); +APP_EVENT_SUBSCRIBE(MODULE, wake_up_event); diff --git a/src/ui/fonts/ui_font_keyboard_small_18.c b/src/ui/fonts/ui_font_keyboard_small_18.c new file mode 100644 index 0000000..23aa9f7 --- /dev/null +++ b/src/ui/fonts/ui_font_keyboard_small_18.c @@ -0,0 +1,379 @@ +/******************************************************************************* + * Size: 18 px + * Bpp: 4 + * Opts: --format lvgl --output E:\projects\lvgl\lv_port_pc_vscode\src\ui\fonts\ui_font_keyboard_small_18.c --size 18 --bpp 4 --lv-font-name ui_font_keyboard_small_18 --font E:\projects\lvgl\lv_port_pc_vscode\external\ttf\MapleMono-NF-CN-Medium.ttf --range 0x30-0x39 --symbols AS/% --font E:\projects\lvgl\lv_port_pc_vscode\lvgl\scripts\built_in_font\FontAwesome5-Solid+Brands+Regular.woff --range 0xF0E7-0xF0E7 --range 0xF240-0xF240 --range 0xF241-0xF241 --range 0xF242-0xF242 --range 0xF243-0xF243 --range 0xF244-0xF244 --range 0xF1E6-0xF1E6 --range 0xF287-0xF287 --range 0xF293-0xF293 + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef UI_FONT_KEYBOARD_SMALL_18 +#define UI_FONT_KEYBOARD_SMALL_18 1 +#endif + +#if UI_FONT_KEYBOARD_SMALL_18 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0025 "%" */ + 0x6, 0xef, 0xb1, 0x0, 0x90, 0xe, 0x40, 0x92, + 0xc0, 0x17, 0x63, 0xb0, 0xdd, 0x1a, 0x3, 0x22, + 0xc, 0x3, 0xc5, 0x23, 0x41, 0x61, 0xb8, 0x69, + 0x41, 0x42, 0x7, 0x20, 0x69, 0x71, 0xa8, 0x1, + 0x37, 0x7d, 0x8b, 0xcc, 0x84, 0x2, 0x3d, 0x39, + 0x84, 0x6d, 0x0, 0xb8, 0x9d, 0x8f, 0xd4, 0xcc, + 0xe, 0x4a, 0xc0, 0x81, 0xe0, 0xc3, 0x1, 0x66, + 0x4, 0x4, 0x2, 0xc1, 0x2, 0x23, 0x5c, 0x81, + 0x47, 0xb7, 0x0, 0x69, 0x98, 0xb4, 0x0, + + /* U+002F "/" */ + 0x0, 0xf4, 0x79, 0x0, 0x79, 0x80, 0x80, 0x39, + 0x45, 0x40, 0x3d, 0xc1, 0xc0, 0x1c, 0x28, 0x48, + 0x1, 0xcc, 0xa, 0x1, 0xea, 0xa, 0x0, 0xe3, + 0x23, 0x20, 0xe, 0xa0, 0xa0, 0xf, 0x38, 0x30, + 0x7, 0x28, 0xa8, 0x7, 0xb8, 0x38, 0x3, 0x85, + 0x9, 0x0, 0x39, 0x81, 0x40, 0x3d, 0x41, 0x40, + 0x1c, 0x64, 0x64, 0x1, 0xcc, 0x12, 0x1, 0xe0, + + /* U+0030 "0" */ + 0x0, 0x46, 0xfe, 0xb0, 0x5, 0x4e, 0x45, 0x4c, + 0x1, 0xa8, 0xf6, 0xe0, 0x38, 0xd0, 0x40, 0x81, + 0x98, 0x1d, 0x41, 0x0, 0x14, 0x61, 0xe2, 0x4, + 0x38, 0xa2, 0x6, 0x61, 0x2f, 0x33, 0x68, 0x9, + 0x8e, 0x8b, 0x60, 0x80, 0x88, 0x1, 0x12, 0xe, + 0x6, 0xa0, 0xee, 0x0, 0x78, 0x65, 0x3, 0x8, + 0x1a, 0x82, 0x1a, 0x8f, 0x6e, 0x4, 0x88, 0x53, + 0x89, 0x12, 0x58, 0x0, + + /* U+0031 "1" */ + 0x0, 0x1e, 0x7c, 0x80, 0x66, 0xc3, 0x7, 0x0, + 0x92, 0x42, 0x80, 0x40, 0x31, 0xea, 0x88, 0x6, + 0x4c, 0x20, 0xf, 0xff, 0x82, 0x66, 0x42, 0x19, + 0x89, 0x23, 0x38, 0x0, 0x66, 0x50, + + /* U+0032 "2" */ + 0x7, 0xdf, 0xf6, 0xc8, 0x82, 0x41, 0x10, 0xc9, + 0xb4, 0x12, 0x37, 0x59, 0xc4, 0x68, 0xe, 0x40, + 0x1, 0xa0, 0x20, 0xf, 0x70, 0x10, 0x7, 0x13, + 0xa, 0x0, 0x61, 0xf0, 0xb0, 0xc, 0x38, 0x50, + 0xa0, 0x10, 0xe1, 0x3b, 0x80, 0x21, 0xc2, 0x78, + 0x0, 0x87, 0x9, 0xe0, 0x3, 0x59, 0x2, 0xe6, + 0x66, 0xd0, 0x1, 0x19, 0xef, + + /* U+0033 "3" */ + 0x1a, 0xef, 0xf5, 0xa0, 0x1, 0x54, 0x6, 0x29, + 0x6a, 0x9, 0x9d, 0x9d, 0x21, 0x20, 0x3, 0x0, + 0x98, 0x4, 0x3, 0x86, 0x41, 0x0, 0x3, 0x9b, + 0xcc, 0xb2, 0x1, 0x19, 0x0, 0x15, 0x80, 0x3, + 0xff, 0x50, 0xc9, 0x0, 0x72, 0xc8, 0x20, 0x7, + 0xbc, 0x0, 0x28, 0x1, 0x13, 0x2, 0xd5, 0xfe, + 0x6e, 0x85, 0x4e, 0x14, 0x4c, 0x8e, 0x68, 0x0, + + /* U+0034 "4" */ + 0x0, 0xed, 0xe1, 0x0, 0xf4, 0x90, 0xa8, 0x7, + 0x1b, 0x0, 0x7e, 0xe1, 0x30, 0xf, 0x41, 0x43, + 0x0, 0x71, 0xb9, 0xb0, 0x7, 0xbc, 0x3c, 0x3, + 0xce, 0x6c, 0x60, 0x1e, 0x80, 0x4c, 0xc2, 0x4, + 0xd0, 0x20, 0x11, 0x98, 0x40, 0x90, 0x2f, 0xff, + 0x28, 0x5f, 0x0, 0x7f, 0xf1, 0x34, 0x18, 0x0, + + /* U+0035 "5" */ + 0xb, 0xff, 0xf0, 0x82, 0x1, 0x19, 0xc8, 0x22, + 0x2, 0xdc, 0xca, 0xc0, 0x21, 0x0, 0xfc, 0x20, + 0x1e, 0x10, 0x2f, 0xf6, 0xb8, 0x5, 0x8, 0x62, + 0x51, 0x60, 0x7, 0xbc, 0xec, 0x14, 0x30, 0xe, + 0x39, 0x5, 0x0, 0xf7, 0x80, 0x5, 0x0, 0x22, + 0x60, 0x5a, 0xbf, 0xcd, 0xd0, 0xa9, 0xc2, 0x89, + 0x91, 0x22, 0x80, + + /* U+0036 "6" */ + 0x0, 0x86, 0xbd, 0x0, 0x30, 0xe2, 0xc2, 0x0, + 0x6d, 0x2b, 0x70, 0xc, 0xe7, 0x28, 0x1, 0xd0, + 0x88, 0x78, 0x40, 0x3, 0x0, 0x36, 0x1e, 0xe8, + 0x34, 0x1b, 0x3f, 0x9, 0x51, 0x83, 0x8c, 0xe, + 0x3, 0x4c, 0xc, 0x2, 0x70, 0x23, 0x0, 0xe1, + 0x1, 0x70, 0x90, 0xa, 0x3, 0x20, 0x1b, 0xb3, + 0xd0, 0xd8, 0xb5, 0x40, 0xc5, 0xf0, 0x0, + + /* U+0037 "7" */ + 0xdf, 0xff, 0x91, 0x6, 0x7c, 0x0, 0xc9, 0xcc, + 0xe3, 0xb, 0x0, 0xe2, 0x33, 0x80, 0x3a, 0xc2, + 0x80, 0x3c, 0xc0, 0xc0, 0x1c, 0xc0, 0xc0, 0x1e, + 0xb0, 0xb0, 0xe, 0x42, 0x42, 0x0, 0xee, 0xe, + 0x0, 0xe1, 0x51, 0x50, 0xe, 0x90, 0x60, 0xf, + 0x10, 0xc8, 0x6, + + /* U+0038 "8" */ + 0x1, 0xae, 0xfe, 0x80, 0x0, 0xfa, 0x81, 0x8b, + 0xe0, 0x30, 0xaf, 0x67, 0x91, 0xa7, 0x87, 0x80, + 0x48, 0x0, 0xb0, 0x92, 0x3, 0x71, 0x43, 0xb1, + 0xdf, 0xc2, 0xd0, 0x6, 0x90, 0x98, 0x1a, 0x3, + 0xb3, 0x3b, 0x39, 0x21, 0x28, 0x24, 0x0, 0x3e, + 0x1a, 0x60, 0x1c, 0xe0, 0x68, 0x12, 0x1, 0x40, + 0x6c, 0xb, 0x76, 0x7a, 0x13, 0x96, 0x28, 0x18, + 0xb6, 0x0, + + /* U+0039 "9" */ + 0x2, 0xae, 0xfe, 0x91, 0x2, 0xd5, 0x33, 0x3, + 0x60, 0x40, 0x46, 0xe7, 0x21, 0x33, 0x83, 0x80, + 0x50, 0x18, 0x1, 0xe1, 0x1, 0x60, 0x50, 0xa, + 0x0, 0x7c, 0x2a, 0xe7, 0x50, 0x35, 0x28, 0x91, + 0xd5, 0x1, 0x1, 0x77, 0xfa, 0x94, 0xcc, 0x1, + 0xdc, 0x10, 0x1, 0xd4, 0x6c, 0x80, 0x10, 0xda, + 0xa4, 0x80, 0x66, 0x47, 0xb0, 0x8, + + /* U+0041 "A" */ + 0x0, 0xd7, 0xf0, 0x1, 0xf1, 0xa0, 0x38, 0x7, + 0xc8, 0x8, 0x8, 0x1, 0xeb, 0x8, 0xd, 0x0, + 0xe1, 0x34, 0x31, 0x40, 0xe, 0x40, 0xc0, 0x42, + 0x20, 0x6, 0xc0, 0x40, 0xc0, 0x40, 0xc, 0xe2, + 0x60, 0x81, 0x80, 0x11, 0x8, 0xbf, 0xda, 0xa, + 0x1, 0x20, 0x23, 0xbc, 0x60, 0x60, 0xd, 0x9, + 0x88, 0xa4, 0x2c, 0x0, 0x84, 0x40, 0x9, 0x1, + 0x0, 0x41, 0x40, 0x30, 0xa0, 0x80, + + /* U+0053 "S" */ + 0x1, 0x9e, 0xfd, 0x70, 0xb, 0x18, 0xc, 0xa2, + 0x81, 0x49, 0x3b, 0x38, 0x94, 0x48, 0x34, 0x0, + 0x3f, 0x22, 0x41, 0xa0, 0x11, 0x30, 0x29, 0xa7, + 0x4a, 0x80, 0x6c, 0x83, 0x6a, 0xe4, 0x0, 0x9f, + 0x75, 0x3, 0x64, 0x1, 0x89, 0xe4, 0x29, 0xa8, + 0x3, 0x10, 0xf, 0xac, 0x80, 0x5c, 0x1f, 0x60, + 0xdd, 0x9e, 0xa4, 0xc5, 0xaa, 0x6, 0x2d, 0x80, + + /* U+F0E7 "" */ + 0x0, 0x57, 0xff, 0x50, 0x7, 0x94, 0x3, 0x84, + 0x3, 0x84, 0x3, 0xda, 0x1, 0xc4, 0x1, 0xe7, + 0x0, 0xe6, 0x0, 0xe4, 0x10, 0xe, 0xd0, 0xe, + 0x15, 0x59, 0x0, 0x4, 0x1, 0xcb, 0x55, 0x59, + 0x83, 0x0, 0x7f, 0x19, 0x80, 0x80, 0x3f, 0xbc, + 0x3, 0xfe, 0x53, 0x0, 0x7e, 0xed, 0x80, 0x1a, + 0xc0, 0x21, 0x22, 0x9c, 0x2, 0x81, 0x0, 0xfb, + 0x0, 0x2, 0xe0, 0x1f, 0x90, 0x1, 0x60, 0x1f, + 0xc6, 0x6, 0xa0, 0x1f, 0x8c, 0x1, 0xe0, 0x1f, + 0xc8, 0xc, 0x60, 0x1f, 0xe1, 0x80, 0xf, 0xf3, + 0xf0, 0x80, 0x78, + + /* U+F1E6 "" */ + 0x0, 0x25, 0x10, 0x6, 0x79, 0x0, 0xef, 0x55, + 0x0, 0x68, 0x63, 0x0, 0xce, 0x1e, 0x1, 0xe7, + 0x0, 0xff, 0xe9, 0x9, 0x4c, 0x61, 0x16, 0x88, + 0x38, 0x87, 0x6d, 0x45, 0xee, 0xe8, 0x86, 0x73, + 0x80, 0x7f, 0xf0, 0xb8, 0x40, 0x3f, 0xd0, 0xe2, + 0x60, 0x1f, 0xe2, 0x0, 0x30, 0x7, 0xf9, 0x80, + 0x1a, 0x1, 0xfc, 0x26, 0x0, 0x63, 0x0, 0xfd, + 0x60, 0x1b, 0x4c, 0x3, 0xd2, 0xa0, 0x18, 0x72, + 0x4c, 0x0, 0xda, 0xc0, 0x1f, 0x35, 0x0, 0xc9, + 0x0, 0x7f, 0xf6, 0x5e, 0xf4, 0x3, 0xc0, + + /* U+F240 "" */ + 0x4, 0x4f, 0xfe, 0x38, 0x80, 0x2a, 0xef, 0xff, + 0x8f, 0xe2, 0xa, 0x1, 0xff, 0xc7, 0x14, 0x0, + 0xaf, 0xff, 0xff, 0x88, 0x0, 0xa3, 0x0, 0xab, + 0xff, 0xff, 0x84, 0x1, 0x98, 0x3, 0xff, 0x8f, + 0x80, 0x1f, 0xfc, 0xa3, 0x10, 0xf, 0xfe, 0x4c, + 0x8, 0x7, 0x7b, 0xbf, 0xff, 0x8, 0x1c, 0x3, + 0x8c, 0x73, 0x3f, 0xf8, 0x4a, 0x0, 0x34, 0x0, + 0x45, 0xdf, 0xff, 0xe, 0x80, 0x12, 0x32, 0x20, + 0x1f, 0xfc, 0x64, 0x50, + + /* U+F241 "" */ + 0x4, 0x4f, 0xfe, 0x38, 0x80, 0x2a, 0xef, 0xff, + 0x8f, 0xe2, 0xa, 0x1, 0xff, 0xc7, 0x14, 0x0, + 0xaf, 0xff, 0xff, 0x88, 0x0, 0xa3, 0x0, 0xb7, + 0xff, 0xfc, 0xc0, 0x1f, 0x30, 0x7, 0xff, 0x1f, + 0x0, 0x3f, 0xf9, 0x46, 0x20, 0x1f, 0xfc, 0x98, + 0x10, 0xe, 0xb7, 0x7f, 0xf2, 0x80, 0x67, 0x0, + 0xe3, 0x2c, 0xcf, 0xf3, 0xa2, 0x4a, 0x0, 0x34, + 0x0, 0x45, 0xdf, 0xff, 0xe, 0x80, 0x12, 0x32, + 0x20, 0x1f, 0xfc, 0x64, 0x50, + + /* U+F242 "" */ + 0x4, 0x4f, 0xfe, 0x38, 0x80, 0x2a, 0xef, 0xff, + 0x8f, 0xe2, 0xa, 0x1, 0xff, 0xc7, 0x14, 0x0, + 0xaf, 0xff, 0xff, 0x88, 0x0, 0xa3, 0x0, 0xb3, + 0xff, 0xe1, 0x0, 0xff, 0x30, 0x7, 0xff, 0x1f, + 0x0, 0x3f, 0xf9, 0x46, 0x20, 0x1f, 0xfc, 0x98, + 0x10, 0xe, 0xa7, 0x7f, 0x84, 0x3, 0xe7, 0x0, + 0xe3, 0x2c, 0xcf, 0x91, 0x3e, 0x50, 0x1, 0xa0, + 0x2, 0x2e, 0xff, 0xf8, 0x74, 0x0, 0x91, 0x91, + 0x0, 0xff, 0xe3, 0x22, 0x80, + + /* U+F243 "" */ + 0x4, 0x4f, 0xfe, 0x38, 0x80, 0x2a, 0xef, 0xff, + 0x8f, 0xe2, 0xa, 0x1, 0xff, 0xc7, 0x14, 0x0, + 0xaf, 0xff, 0xff, 0x88, 0x0, 0xa3, 0x0, 0xa7, + 0xfe, 0xe0, 0xf, 0xfe, 0x13, 0x0, 0x7f, 0xf1, + 0xf0, 0x3, 0xff, 0x94, 0x62, 0x1, 0xff, 0xc9, + 0x81, 0x0, 0xed, 0x77, 0xa4, 0x3, 0xfe, 0x70, + 0xe, 0x30, 0xcc, 0x8d, 0x13, 0xfc, 0xa0, 0x3, + 0x40, 0x4, 0x5d, 0xff, 0xf0, 0xe8, 0x1, 0x23, + 0x22, 0x1, 0xff, 0xc6, 0x45, 0x0, + + /* U+F244 "" */ + 0x4, 0x4f, 0xfe, 0x38, 0x80, 0x2a, 0xef, 0xff, + 0x8f, 0xe2, 0xa, 0x1, 0xff, 0xc7, 0x14, 0x0, + 0xaf, 0xff, 0xff, 0x88, 0x0, 0xa3, 0x0, 0xff, + 0xe5, 0x30, 0x7, 0xff, 0x1f, 0x0, 0x3f, 0xf9, + 0x46, 0x20, 0x1f, 0xfc, 0x98, 0x10, 0xf, 0xfe, + 0x4b, 0x80, 0x71, 0xa2, 0x7f, 0xf0, 0xd4, 0x0, + 0x68, 0x0, 0x8b, 0xbf, 0xfe, 0x1d, 0x0, 0x24, + 0x64, 0x40, 0x3f, 0xf8, 0xc8, 0xa0, + + /* U+F287 "" */ + 0x0, 0xff, 0xe0, 0x3c, 0x8, 0x7, 0xff, 0x14, + 0x9a, 0x61, 0xf0, 0x3, 0xff, 0x88, 0x9b, 0xc, + 0x0, 0x20, 0xf, 0xfe, 0x25, 0x3f, 0x68, 0x84, + 0x0, 0x7f, 0x88, 0x3, 0x30, 0x40, 0x17, 0x7b, + 0x80, 0x7e, 0x3e, 0xde, 0x30, 0x5, 0xc8, 0x7, + 0xf1, 0x50, 0x80, 0x3c, 0x40, 0x79, 0x24, 0x88, + 0xab, 0xff, 0x73, 0x81, 0x80, 0x45, 0x6c, 0x15, + 0x5f, 0xe8, 0x0, 0x42, 0xa8, 0x2, 0x5f, 0xfc, + 0x88, 0xff, 0xfb, 0x1, 0x35, 0x69, 0x8d, 0xa8, + 0x3, 0x42, 0x18, 0x7, 0x8a, 0xac, 0x80, 0x13, + 0x92, 0x1, 0xc6, 0x90, 0x5, 0x77, 0x28, 0xa8, + 0x7, 0xff, 0x6, 0x52, 0x6d, 0x12, 0xd0, 0xf, + 0xfe, 0x19, 0x61, 0x20, 0x7, 0xff, 0x20, 0xef, + 0x80, 0x3f, 0xf9, 0x47, 0xff, 0x40, 0x7, 0x0, + + /* U+F293 "" */ + 0x0, 0x85, 0xef, 0x75, 0x70, 0x40, 0x1c, 0xbd, + 0x8, 0x4, 0x8f, 0xac, 0x1, 0x25, 0x0, 0x56, + 0xe0, 0x14, 0xa0, 0x2, 0x80, 0x3a, 0x1c, 0x2, + 0x90, 0x41, 0x0, 0xf4, 0x30, 0x0, 0x8f, 0x0, + 0x12, 0x80, 0x1, 0xc9, 0x60, 0x2, 0x18, 0x5, + 0x68, 0x2, 0x44, 0xc0, 0x7, 0x30, 0x2, 0x56, + 0xd0, 0x34, 0x68, 0x0, 0x46, 0x1, 0x52, 0x90, + 0xe, 0x80, 0x4e, 0x1, 0xd2, 0x0, 0x51, 0x0, + 0xc6, 0x1, 0x16, 0x80, 0x1d, 0x80, 0x30, 0x80, + 0xf, 0x9, 0x42, 0x64, 0xa0, 0x7, 0x60, 0x7, + 0x2e, 0x18, 0x31, 0xc0, 0x0, 0xb0, 0x1, 0xf6, + 0x2, 0x14, 0x38, 0x0, 0xf7, 0x0, 0x10, 0x6, + 0x7c, 0x10, 0x3, 0x8b, 0x0, 0x71, 0x60, 0x80, + 0x18, 0x42, 0x50, 0x2, 0xdc, 0x10, 0x1, 0x40, + 0x5, 0x74, 0x60, 0xa2, 0x4, 0xfa, 0x20, 0x19, + 0x73, 0xfb, 0x9f, 0xb0, 0x1, 0x0 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +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 = 173, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 71, .adv_w = 173, .box_w = 9, .box_h = 17, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 127, .adv_w = 173, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 187, .adv_w = 173, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 217, .adv_w = 173, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 270, .adv_w = 173, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 326, .adv_w = 173, .box_w = 10, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 374, .adv_w = 173, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 425, .adv_w = 173, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 480, .adv_w = 173, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 523, .adv_w = 173, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 581, .adv_w = 173, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 635, .adv_w = 173, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 697, .adv_w = 173, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 753, .adv_w = 180, .box_w = 13, .box_h = 19, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 836, .adv_w = 216, .box_w = 14, .box_h = 19, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 915, .adv_w = 360, .box_w = 23, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 983, .adv_w = 360, .box_w = 23, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1052, .adv_w = 360, .box_w = 23, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1121, .adv_w = 360, .box_w = 23, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1191, .adv_w = 360, .box_w = 23, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1253, .adv_w = 360, .box_w = 23, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1365, .adv_w = 252, .box_w = 14, .box_h = 19, .ofs_x = 1, .ofs_y = -3} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_0[] = { + 0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x1c, 0x2e, 0xf0c2, 0xf1c1, + 0xf21b, 0xf21c, 0xf21d, 0xf21e, 0xf21f, 0xf262, 0xf26e +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 37, .range_length = 62063, .glyph_id_start = 1, + .unicode_list = unicode_list_0, .glyph_id_ofs_list = NULL, .list_length = 23, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR == 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +#endif + +#if LVGL_VERSION_MAJOR >= 8 +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 1, + .bpp = 4, + .kern_classes = 0, + .bitmap_format = 1, +#if LVGL_VERSION_MAJOR == 8 + .cache = &cache +#endif +}; + + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t ui_font_keyboard_small_18 = { +#else +lv_font_t ui_font_keyboard_small_18 = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 19, /*The maximum line height required by the font*/ + .base_line = 3, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -3, + .underline_thickness = 1, +#endif + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 + .fallback = NULL, +#endif + .user_data = NULL, +}; + + + +#endif /*#if UI_FONT_KEYBOARD_SMALL_18*/ + diff --git a/src/ui/fonts/ui_font_keyboard_time_48.c b/src/ui/fonts/ui_font_keyboard_time_48.c new file mode 100644 index 0000000..b530773 --- /dev/null +++ b/src/ui/fonts/ui_font_keyboard_time_48.c @@ -0,0 +1,455 @@ +/******************************************************************************* + * Size: 48 px + * Bpp: 4 + * Opts: --format lvgl --output E:\projects\lvgl\lv_port_pc_vscode\src\ui\fonts\ui_font_keyboard_time_48.c --size 48 --bpp 4 --lv-font-name ui_font_keyboard_time_48 --font E:\projects\lvgl\lv_port_pc_vscode\external\ttf\MapleMono-NF-CN-SemiBold.ttf --range 0x30-0x39 --symbols : + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef UI_FONT_KEYBOARD_TIME_48 +#define UI_FONT_KEYBOARD_TIME_48 1 +#endif + +#if UI_FONT_KEYBOARD_TIME_48 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0030 "0" */ + 0x0, 0xfc, 0xb5, 0xbf, 0xf6, 0xd2, 0x80, 0x7f, + 0xf0, 0x97, 0xa9, 0x48, 0x2, 0x25, 0xae, 0x40, + 0xf, 0xfa, 0x28, 0x40, 0x3f, 0x86, 0xdc, 0x3, + 0xfa, 0x1c, 0x3, 0xff, 0x83, 0xe, 0x1, 0xf2, + 0x38, 0x7, 0xff, 0xe, 0xc, 0x3, 0xd2, 0x1, + 0xe5, 0xab, 0x94, 0x0, 0xf7, 0x80, 0x73, 0x10, + 0x7, 0x5d, 0x2a, 0x35, 0xc8, 0x7, 0x1a, 0x0, + 0x6a, 0x0, 0xe8, 0x40, 0xe, 0x65, 0x0, 0xee, + 0x0, 0x88, 0xc0, 0x31, 0x38, 0x7, 0xd6, 0x1, + 0xca, 0x20, 0x4, 0x0, 0xeb, 0x0, 0xfc, 0x2a, + 0x1, 0xca, 0x0, 0xc0, 0xe, 0x70, 0xf, 0xce, + 0xa0, 0x1c, 0x60, 0x7, 0x0, 0xc6, 0x20, 0x1f, + 0x4c, 0x0, 0x7b, 0x0, 0x4, 0x1, 0x94, 0x3, + 0xc3, 0x6c, 0x1, 0xf3, 0x0, 0x80, 0x77, 0x0, + 0x71, 0x62, 0x0, 0x7e, 0x30, 0x20, 0xe, 0x20, + 0xc, 0x98, 0x40, 0x1f, 0xc2, 0xe, 0x1, 0xc2, + 0x1, 0x35, 0x88, 0x7, 0xfc, 0x22, 0x0, 0xe7, + 0x0, 0x44, 0x80, 0x79, 0x60, 0x3, 0x8c, 0x3, + 0xf5, 0xb8, 0x7, 0xa2, 0x84, 0x3, 0xff, 0x80, + 0xd8, 0x80, 0x1e, 0xa7, 0x1, 0x0, 0xe3, 0x10, + 0xe, 0xa3, 0x0, 0xe1, 0xc5, 0x0, 0xfe, 0x70, + 0xf, 0xf8, 0xfc, 0xc0, 0x2e, 0x0, 0xe1, 0x20, + 0xf, 0xf2, 0xe0, 0x80, 0x63, 0x0, 0xc2, 0x2, + 0x1, 0xfc, 0xf4, 0x1, 0xe7, 0x0, 0xc4, 0x0, + 0x20, 0xf, 0xa6, 0x0, 0x3e, 0x20, 0xc, 0xc0, + 0x7, 0x0, 0xe1, 0xc6, 0x0, 0xf9, 0x0, 0x3b, + 0x0, 0x18, 0x1, 0xd0, 0x60, 0x1f, 0xb4, 0x3, + 0x94, 0x0, 0x80, 0x1d, 0x60, 0x1f, 0x85, 0x80, + 0x30, 0x98, 0x0, 0x8c, 0x3, 0x13, 0x80, 0x7d, + 0x60, 0x1c, 0xc0, 0x1a, 0x80, 0x3a, 0x10, 0x3, + 0x9d, 0x40, 0x3a, 0x80, 0x33, 0x10, 0x7, 0x5d, + 0x2a, 0x35, 0xc0, 0x7, 0x29, 0x0, 0x77, 0x0, + 0x79, 0x6a, 0xe5, 0x0, 0x3d, 0x0, 0x1e, 0x38, + 0x0, 0xff, 0xe1, 0xd1, 0x0, 0x7c, 0xf0, 0x1, + 0xff, 0xc1, 0xa5, 0x0, 0xfe, 0x7a, 0x10, 0xf, + 0xe2, 0xc5, 0x0, 0xff, 0x97, 0xa5, 0x48, 0x0, + 0x24, 0xd7, 0xa6, 0x1, 0xe0, + + /* U+0031 "1" */ + 0x0, 0xfc, 0xb7, 0xdf, 0xd6, 0x60, 0x1f, 0xfc, + 0x31, 0xca, 0x41, 0x1, 0x4c, 0x30, 0xf, 0xfe, + 0xa, 0x79, 0x80, 0x7d, 0x20, 0x1f, 0xfc, 0x7, + 0xb1, 0x0, 0xfc, 0xe0, 0x1f, 0xe1, 0xb8, 0x0, + 0xff, 0xe4, 0xe, 0x20, 0x7, 0xff, 0x26, 0x8, + 0x3, 0xca, 0x1, 0xff, 0xc3, 0x40, 0xe, 0x1b, + 0xa4, 0x0, 0xff, 0xe1, 0x18, 0x6, 0x3f, 0x40, + 0x10, 0xf, 0xfe, 0x11, 0x0, 0x4b, 0x82, 0x1, + 0xff, 0xc5, 0x90, 0x2a, 0xa0, 0x7, 0xff, 0x1d, + 0x7f, 0x54, 0x3, 0xff, 0xfe, 0x1, 0xff, 0xff, + 0x0, 0xff, 0xff, 0x80, 0x7f, 0xff, 0xc0, 0x3f, + 0xff, 0xe0, 0x1f, 0xfe, 0xa4, 0x55, 0xf9, 0x80, + 0x31, 0xaa, 0xf8, 0x40, 0x19, 0x75, 0x5f, 0x18, + 0x6, 0x1a, 0xaf, 0x71, 0x9c, 0x1, 0xff, 0xc9, + 0x96, 0x0, 0xff, 0xe5, 0xb, 0x80, 0x7f, 0xf2, + 0x88, 0x90, 0x20, 0x1f, 0xfc, 0x74, 0x80, + + /* U+0032 "2" */ + 0x0, 0xc2, 0xd5, 0x9d, 0xff, 0x76, 0xd3, 0x90, + 0x7, 0xf0, 0xcf, 0x4a, 0x98, 0x80, 0x42, 0x4b, + 0x1b, 0x64, 0x1, 0xe1, 0xf6, 0x0, 0xff, 0xe0, + 0xa6, 0xa8, 0x7, 0x58, 0x80, 0x7f, 0xf1, 0x29, + 0x0, 0x32, 0x0, 0x7f, 0xf1, 0xa8, 0x40, 0x24, + 0x0, 0xe5, 0x9c, 0xdc, 0xa6, 0x0, 0xf0, 0xb0, + 0x5, 0x66, 0x0, 0x7e, 0xa6, 0x32, 0x35, 0x9e, + 0x30, 0xe, 0xa0, 0x8, 0x73, 0x1d, 0x2, 0x1, + 0xf0, 0xe8, 0x7, 0x10, 0x7, 0x18, 0x80, 0x7f, + 0x85, 0x80, 0x38, 0xc0, 0x3f, 0xf8, 0xb8, 0x1, + 0xff, 0xcb, 0x10, 0xf, 0xfe, 0x59, 0x0, 0x71, + 0x0, 0x7f, 0xf1, 0x74, 0x3, 0x8, 0x80, 0x3f, + 0xf8, 0x86, 0x80, 0x19, 0xc0, 0x3f, 0xf8, 0xbe, + 0x1, 0xd4, 0x1, 0xff, 0xc4, 0x83, 0x0, 0xc8, + 0x60, 0x1f, 0xfc, 0x35, 0x70, 0xe, 0x80, 0xf, + 0xfe, 0x1a, 0x50, 0x7, 0x39, 0x80, 0x7f, 0xf0, + 0x8e, 0xc0, 0x38, 0xe0, 0x3, 0xff, 0x84, 0x78, + 0x1, 0xc5, 0xa0, 0x1f, 0xfc, 0x23, 0xc0, 0xe, + 0x1f, 0x10, 0xf, 0xfe, 0x9, 0xe0, 0x7, 0xe, + 0x90, 0x7, 0xff, 0x4, 0xf0, 0x3, 0x87, 0x4c, + 0x3, 0xff, 0x82, 0x78, 0x1, 0xc3, 0xa6, 0x1, + 0xff, 0xc1, 0x3c, 0x0, 0xe1, 0xd3, 0x0, 0xff, + 0xe0, 0x9e, 0x0, 0x70, 0xe9, 0x80, 0x7f, 0xf0, + 0x4f, 0x0, 0x38, 0x74, 0xc0, 0x3f, 0xf8, 0x27, + 0x80, 0x1c, 0x3a, 0x60, 0x1f, 0xfc, 0x13, 0xc0, + 0xe, 0x1d, 0x30, 0xf, 0xfe, 0x9, 0x60, 0x7, + 0x95, 0xd1, 0x3f, 0xc6, 0x20, 0xa, 0x0, 0xf9, + 0x2e, 0xff, 0xec, 0xe8, 0x2, 0x0, 0xff, 0xe4, + 0xb8, 0x98, 0x7, 0xff, 0x28, 0xe8, 0x3, 0xff, + 0x94, 0x47, 0x66, 0x1, 0xff, 0xc6, 0x2b, 0x0, + + /* U+0033 "3" */ + 0x0, 0xcb, 0x39, 0xdf, 0xf7, 0x64, 0xa8, 0x7, + 0xf9, 0xfe, 0x98, 0xc4, 0x2, 0x13, 0x6a, 0xf8, + 0x0, 0xf9, 0x60, 0x3, 0xff, 0x82, 0xfa, 0x40, + 0x1d, 0xc0, 0x1f, 0xfc, 0x32, 0xc2, 0x0, 0xc4, + 0x1, 0xff, 0xc4, 0x1e, 0x0, 0xd6, 0x1, 0x96, + 0x2e, 0xd5, 0x6, 0x1, 0xe3, 0x30, 0x4, 0x58, + 0xcf, 0xd4, 0xe8, 0x85, 0x7c, 0xb1, 0x0, 0xeb, + 0x0, 0xc7, 0x30, 0x20, 0x1f, 0x26, 0x80, 0x71, + 0x80, 0x7f, 0xf1, 0xc, 0x80, 0x33, 0x80, 0x7f, + 0xf1, 0x44, 0x3, 0x38, 0x7, 0xff, 0x10, 0x4c, + 0x3, 0x10, 0x7, 0xff, 0x12, 0xc0, 0x3b, 0x0, + 0x3f, 0xf8, 0x47, 0x8a, 0x1, 0x85, 0x40, 0x3f, + 0x12, 0x21, 0xa3, 0x30, 0x60, 0x1d, 0x60, 0x1f, + 0xe, 0xea, 0xed, 0x2e, 0x60, 0x1e, 0x85, 0x0, + 0xfa, 0x48, 0x3, 0xfc, 0xb8, 0xe0, 0x1f, 0x84, + 0x3, 0xfe, 0x49, 0x20, 0xf, 0xde, 0x1, 0xff, + 0xa, 0xec, 0x0, 0x7c, 0xcc, 0x0, 0xff, 0xe0, + 0xbc, 0x0, 0x7d, 0x3f, 0xf7, 0x6d, 0xc2, 0x0, + 0x79, 0xcc, 0x3, 0xfc, 0x24, 0x8f, 0x78, 0x40, + 0x1d, 0x20, 0x1f, 0xfc, 0x33, 0xc2, 0x0, 0xca, + 0x1, 0xff, 0xc4, 0x1b, 0x0, 0xe3, 0x0, 0xff, + 0xe2, 0x28, 0x7, 0x38, 0x7, 0xff, 0x11, 0xc0, + 0x38, 0x40, 0x3f, 0xf8, 0x84, 0x1, 0xc2, 0x1, + 0xff, 0xc4, 0xd0, 0xe, 0x60, 0xf, 0xfe, 0x1a, + 0xa0, 0x6, 0x12, 0x4, 0xba, 0x50, 0xf, 0xe6, + 0xa0, 0xe, 0x70, 0x4b, 0x45, 0xaf, 0xb8, 0x64, + 0x42, 0xc6, 0xc8, 0x7, 0xac, 0x38, 0x3, 0x91, + 0xe6, 0xed, 0x4e, 0x40, 0x1e, 0x82, 0x1, 0x0, + 0xff, 0xe3, 0x2b, 0x80, 0x3c, 0x3, 0xff, 0x8a, + 0xf4, 0x1, 0x26, 0x28, 0x7, 0xff, 0x5, 0x32, + 0x0, 0x38, 0xeb, 0xed, 0xd0, 0x84, 0x2, 0x24, + 0x8d, 0xb3, 0x0, 0xe0, + + /* U+0034 "4" */ + 0x0, 0xff, 0xe1, 0x26, 0x7f, 0xa8, 0x40, 0x3f, + 0xf8, 0xe7, 0x66, 0x0, 0x5d, 0x0, 0xff, 0xe3, + 0xf0, 0x7, 0x19, 0x0, 0x7f, 0xf1, 0x5c, 0x80, + 0x3c, 0xc0, 0x1f, 0xfc, 0x42, 0x80, 0xf, 0xfe, + 0x67, 0x0, 0x7f, 0xf3, 0x18, 0xc0, 0x3f, 0xf9, + 0x63, 0x20, 0x1f, 0xfc, 0xca, 0x0, 0xff, 0xe6, + 0x2a, 0x0, 0x61, 0x0, 0xff, 0xe3, 0xd, 0x80, + 0x66, 0xa0, 0xf, 0xfe, 0x35, 0x88, 0x4, 0x30, + 0x1, 0xff, 0xc6, 0x45, 0x0, 0xd0, 0x20, 0x1f, + 0xfc, 0x69, 0x0, 0xc4, 0xc0, 0x1f, 0xfc, 0x68, + 0x20, 0xd, 0xc0, 0x1f, 0xfc, 0x63, 0x70, 0xc, + 0xa6, 0x1, 0xff, 0xc6, 0xe0, 0xe, 0xb0, 0xf, + 0xfe, 0x33, 0x90, 0x6, 0x81, 0x0, 0xff, 0xe2, + 0x94, 0x0, 0x62, 0x70, 0xf, 0xfe, 0x37, 0x0, + 0x74, 0x80, 0x7f, 0xf1, 0x98, 0xc0, 0x32, 0x20, + 0x3, 0xff, 0x8a, 0x32, 0x1, 0xc2, 0x3f, 0x0, + 0x78, 0x46, 0x0, 0x9c, 0x3, 0xcb, 0xdd, 0xeb, + 0x0, 0xea, 0xee, 0x94, 0x4, 0x3, 0xff, 0x94, + 0x36, 0x2, 0x1, 0xff, 0xcb, 0x10, 0x71, 0x0, + 0xff, 0xe5, 0x8, 0xe, 0xa0, 0x7, 0xff, 0x20, + 0xa8, 0x0, 0x77, 0xff, 0xff, 0x58, 0x7, 0x5f, + 0xfb, 0x50, 0x3, 0xff, 0xfe, 0x1, 0xff, 0xe0, + 0x70, 0xe, 0x70, 0xf, 0xfe, 0x39, 0x0, 0x71, + 0x0, 0x7f, 0xf1, 0xc6, 0x88, 0x6, 0x84, 0x3, + 0x80, + + /* U+0035 "5" */ + 0x0, 0x93, 0x3f, 0xff, 0xf8, 0x74, 0x1, 0x92, + 0xcc, 0x3, 0xff, 0x86, 0xae, 0x1, 0x78, 0x7, + 0xff, 0x1b, 0x40, 0x25, 0x0, 0xff, 0xe3, 0x10, + 0x7, 0xff, 0x24, 0x68, 0x3, 0xf9, 0xee, 0xff, + 0xd9, 0xc4, 0x1, 0xf9, 0x21, 0x13, 0xfc, 0x60, + 0x1f, 0xe2, 0x0, 0xff, 0xff, 0x80, 0x7f, 0xf1, + 0x8, 0x3, 0xff, 0x94, 0x8a, 0x20, 0x1f, 0xfc, + 0x9a, 0xef, 0xf7, 0x64, 0xa8, 0x7, 0xf1, 0x80, + 0x7f, 0x9, 0xb5, 0x7c, 0x0, 0x7c, 0xc0, 0x1f, + 0xfc, 0x27, 0xd2, 0x0, 0xef, 0x0, 0xff, 0xe1, + 0x96, 0x8, 0x6, 0x4b, 0x30, 0xf, 0xfe, 0x10, + 0xd0, 0x7, 0x26, 0x7f, 0xee, 0xca, 0x61, 0x0, + 0xf2, 0x20, 0x3, 0xfc, 0x26, 0xb3, 0xd0, 0x1, + 0xee, 0x0, 0xff, 0xe1, 0xbd, 0x0, 0x72, 0x80, + 0x7f, 0xf1, 0x15, 0x40, 0x1c, 0x40, 0x1f, 0xfc, + 0x4f, 0x0, 0xe6, 0x0, 0xff, 0xe2, 0x30, 0x7, + 0x8, 0x7, 0xff, 0x11, 0xc0, 0x3f, 0xf9, 0x44, + 0x1, 0xc2, 0x1, 0xff, 0xc4, 0xa0, 0xe, 0x60, + 0xf, 0xfe, 0x1a, 0x98, 0x6, 0x12, 0x4, 0xba, + 0x50, 0xf, 0xe6, 0xa0, 0xe, 0x60, 0x4b, 0x45, + 0xaf, 0xb8, 0x64, 0x42, 0xc6, 0xc8, 0x7, 0xa4, + 0x38, 0x3, 0x91, 0xe6, 0xed, 0x4e, 0x40, 0x1e, + 0x81, 0x1, 0x0, 0xff, 0xe3, 0x33, 0x80, 0x3c, + 0x3, 0xff, 0x8a, 0xf2, 0x1, 0x26, 0x28, 0x7, + 0xff, 0x5, 0x32, 0x0, 0x38, 0xeb, 0xed, 0xd0, + 0x84, 0x2, 0x25, 0x8d, 0xb3, 0x0, 0xe0, + + /* U+0036 "6" */ + 0x0, 0xff, 0xe0, 0x14, 0xf7, 0xf2, 0x0, 0x7f, + 0xf1, 0xa3, 0x58, 0x40, 0x60, 0x3, 0xff, 0x8b, + 0x6e, 0x1, 0xc8, 0x1, 0xff, 0xc3, 0x1c, 0x40, + 0xe, 0x88, 0x0, 0x7f, 0xf0, 0x87, 0xc, 0x3, + 0x16, 0x38, 0x7, 0xff, 0xf, 0x48, 0x3, 0x26, + 0x18, 0x7, 0xff, 0xe, 0x4c, 0x3, 0x2d, 0x88, + 0x7, 0xff, 0xd, 0x58, 0x3, 0x2d, 0x0, 0x7f, + 0xf1, 0x6, 0xc0, 0x31, 0xd0, 0x7, 0xff, 0x16, + 0x4, 0x2, 0x1d, 0x0, 0xff, 0xe2, 0x93, 0x0, + 0x6b, 0x10, 0xf, 0xfe, 0x2d, 0x80, 0x65, 0x50, + 0x7, 0xff, 0x14, 0x58, 0x3, 0x40, 0x13, 0xe7, + 0x7f, 0xb6, 0x50, 0x3, 0xf3, 0x0, 0x66, 0x29, + 0xd8, 0x31, 0x0, 0x13, 0x5d, 0x84, 0x3, 0xd4, + 0x1, 0xb7, 0x4c, 0x1, 0xfc, 0x9e, 0x40, 0x18, + 0x88, 0x1, 0x14, 0x90, 0x7, 0xfc, 0x3e, 0x1, + 0x90, 0x3, 0x11, 0x0, 0x6, 0xf0, 0xc6, 0x1, + 0xe2, 0x80, 0xb, 0x0, 0x3c, 0x59, 0x88, 0x79, + 0xcd, 0x30, 0xe, 0x60, 0x9, 0xc0, 0x38, 0xf4, + 0xc0, 0x38, 0xb0, 0xc0, 0x30, 0xa8, 0x0, 0x80, + 0x3b, 0x80, 0x3f, 0xb8, 0x3, 0xb0, 0x4, 0x3, + 0x94, 0x80, 0x3f, 0x89, 0x0, 0x32, 0x81, 0x80, + 0x77, 0x80, 0x7f, 0xd8, 0x1, 0x88, 0x4, 0x3, + 0x9c, 0x3, 0xfe, 0x20, 0xc, 0x20, 0x1f, 0x18, + 0x7, 0xff, 0x30, 0xc0, 0x3f, 0xf8, 0xc4, 0x1, + 0xce, 0x1, 0xff, 0x68, 0x6, 0x20, 0x10, 0xe, + 0xe0, 0xf, 0xf9, 0x40, 0x33, 0x80, 0x10, 0x3, + 0x22, 0x0, 0x3f, 0x9c, 0x80, 0x36, 0x0, 0x34, + 0x3, 0xad, 0x0, 0x3e, 0x68, 0x0, 0xe7, 0x0, + 0x30, 0x80, 0x75, 0xd2, 0x90, 0x92, 0xdc, 0x80, + 0x73, 0x8, 0x5, 0x60, 0x1e, 0x5a, 0xde, 0xda, + 0x40, 0xe, 0x18, 0x0, 0xca, 0xc0, 0x1f, 0xfc, + 0x5d, 0x10, 0xe, 0x97, 0x0, 0xff, 0xe1, 0xe, + 0x18, 0x7, 0xd1, 0x86, 0x1, 0xff, 0x37, 0x98, + 0x7, 0xf1, 0xe6, 0x1d, 0x4, 0x2, 0x25, 0x9e, + 0x91, 0x0, 0xe0, + + /* U+0037 "7" */ + 0x8, 0xff, 0xff, 0xe3, 0xd9, 0x82, 0x38, 0x7, + 0xff, 0x1d, 0x30, 0x8c, 0x3, 0xff, 0x95, 0x44, + 0x1, 0xff, 0xca, 0x35, 0x30, 0xf, 0xfe, 0x48, + 0x86, 0x62, 0xef, 0xff, 0x83, 0x20, 0x1e, 0xd0, + 0x1, 0xa2, 0x7f, 0xf0, 0x58, 0x40, 0x39, 0x80, + 0x3f, 0xf8, 0x86, 0x20, 0x19, 0x44, 0x3, 0xff, + 0x89, 0x20, 0x1d, 0x20, 0x1f, 0xfc, 0x41, 0x50, + 0xc, 0x46, 0x1, 0xff, 0xc4, 0x90, 0xe, 0xb0, + 0xf, 0xfe, 0x2b, 0x0, 0x73, 0x0, 0x7f, 0xf1, + 0x14, 0x40, 0x33, 0x0, 0x7f, 0xf1, 0x64, 0x3, + 0xac, 0x3, 0xff, 0x88, 0x66, 0x0, 0xc8, 0x40, + 0x1f, 0xfc, 0x49, 0x0, 0xef, 0x0, 0xff, 0xe2, + 0xa, 0x80, 0x62, 0x40, 0xf, 0xfe, 0x23, 0x0, + 0x75, 0x0, 0x7f, 0xf1, 0x64, 0x3, 0x98, 0x3, + 0xff, 0x88, 0xa2, 0x1, 0x94, 0x40, 0x3f, 0xf8, + 0x92, 0x1, 0xd2, 0x1, 0xff, 0xc4, 0x23, 0x0, + 0xc6, 0x60, 0xf, 0xfe, 0x25, 0x80, 0x74, 0x80, + 0x7f, 0xf1, 0x5, 0x80, 0x30, 0xa8, 0x7, 0xff, + 0x11, 0x80, 0x39, 0x80, 0x3f, 0xf8, 0xb4, 0x1, + 0xd2, 0x1, 0xff, 0xc4, 0x42, 0x0, 0xc8, 0x20, + 0x1f, 0xfc, 0x4f, 0x0, 0xef, 0x0, 0xff, 0xe2, + 0x12, 0x0, 0x62, 0x40, 0xf, 0xfe, 0x25, 0x80, + 0x75, 0x80, 0x7f, 0xf1, 0x58, 0x3, 0x98, 0x3, + 0xff, 0x88, 0xc0, 0x1c, 0xc0, 0x1f, 0xfc, 0x5a, + 0x0, 0xeb, 0x0, 0xff, 0xe5, 0x21, 0x0, 0x7f, + 0xf1, 0x60, 0x80, 0xb, 0x40, 0x1f, 0xfc, 0x0, + + /* U+0038 "8" */ + 0x0, 0xf8, 0xe2, 0xfb, 0xfe, 0xdb, 0x72, 0x0, + 0xff, 0xe0, 0x1e, 0x61, 0xd0, 0x40, 0x22, 0x48, + 0xda, 0x20, 0xf, 0xe8, 0xc3, 0x0, 0xff, 0x97, + 0x54, 0x3, 0xe8, 0x70, 0xf, 0xfe, 0x1d, 0x28, + 0x7, 0x1b, 0x80, 0x7f, 0xf1, 0x68, 0x40, 0x34, + 0x0, 0x78, 0xe2, 0xae, 0x9c, 0x80, 0x3d, 0x20, + 0x10, 0xa0, 0x7, 0x4e, 0x3a, 0xa2, 0xc6, 0xb0, + 0x7, 0x28, 0x4, 0x40, 0x1c, 0xac, 0x1, 0xf4, + 0x98, 0x6, 0x20, 0x9, 0xc0, 0x3b, 0xc0, 0x3f, + 0xac, 0x3, 0x84, 0x0, 0xe0, 0x1c, 0x20, 0x1f, + 0xfc, 0x31, 0x0, 0x18, 0x7, 0x18, 0x7, 0xf6, + 0x80, 0x62, 0x0, 0xca, 0x1, 0xa0, 0x80, 0x3e, + 0x45, 0x0, 0xd4, 0x1, 0xa0, 0x3, 0xb6, 0xc, + 0x0, 0x29, 0x36, 0x1, 0x85, 0xc0, 0x31, 0x50, + 0x7, 0x3e, 0x7f, 0xba, 0xd8, 0x3, 0xe, 0x80, + 0x79, 0x70, 0x80, 0x3f, 0xf8, 0x29, 0x86, 0x1, + 0xf1, 0xec, 0x88, 0x7, 0xf1, 0xe5, 0x90, 0x7, + 0xe2, 0xb9, 0x10, 0xf, 0xe3, 0xca, 0x10, 0xf, + 0x97, 0x50, 0x3, 0xff, 0x82, 0xbe, 0x60, 0x1c, + 0x94, 0x1, 0xc5, 0x15, 0x74, 0xe2, 0x1, 0x87, + 0x48, 0x3, 0x50, 0x7, 0x4e, 0xba, 0xa2, 0xc7, + 0x38, 0x6, 0x19, 0x0, 0x9c, 0x40, 0x34, 0xb0, + 0x7, 0xd0, 0xc0, 0x19, 0x10, 0x0, 0xb0, 0xc, + 0x6c, 0x1, 0xfd, 0x0, 0x1d, 0xa0, 0x26, 0x1, + 0xac, 0x3, 0xfc, 0x2a, 0x1, 0x90, 0x8, 0x3, + 0x8c, 0x3, 0xfe, 0xd0, 0xc, 0x40, 0xe0, 0x1f, + 0xfc, 0xc7, 0x0, 0xe2, 0x0, 0xff, 0xb4, 0x3, + 0xc4, 0x1, 0xd4, 0x1, 0xff, 0x20, 0x6, 0x10, + 0x12, 0x0, 0xc6, 0xa0, 0x1f, 0xd2, 0x20, 0x19, + 0x0, 0xa, 0x1, 0xd4, 0xc0, 0x1f, 0x43, 0x0, + 0x77, 0x80, 0x24, 0x3, 0xd3, 0xae, 0xa8, 0xb1, + 0xce, 0x1, 0xc4, 0xa0, 0x1, 0x90, 0xf, 0x14, + 0x55, 0xd3, 0x88, 0x7, 0xb8, 0x3, 0x33, 0x0, + 0x3f, 0xf8, 0xb2, 0x60, 0x1d, 0x2e, 0x1, 0xff, + 0xc3, 0xa6, 0x0, 0xfa, 0x31, 0x0, 0x3f, 0xe5, + 0xe5, 0x0, 0xfe, 0x3b, 0xd8, 0x41, 0x0, 0x89, + 0x67, 0xa8, 0x40, 0x38, + + /* U+0039 "9" */ + 0x0, 0xf8, 0xa2, 0xfb, 0xfe, 0xda, 0x61, 0x0, + 0xff, 0xe0, 0x1e, 0x6b, 0xa0, 0x80, 0x44, 0xb3, + 0xd4, 0x20, 0x1f, 0xd1, 0x86, 0x1, 0xff, 0x2f, + 0x28, 0x7, 0xd2, 0xe0, 0x1f, 0xfc, 0x3a, 0x50, + 0xe, 0x66, 0x0, 0x7f, 0xf1, 0x68, 0x80, 0x34, + 0x0, 0x79, 0xaf, 0xb9, 0xb4, 0x80, 0x1e, 0x90, + 0x9, 0xc4, 0x3, 0x16, 0xca, 0x8, 0x89, 0x6e, + 0xc0, 0x1c, 0x86, 0x0, 0xb0, 0xc, 0x38, 0x40, + 0x1f, 0x25, 0x0, 0x75, 0x80, 0xc, 0x3, 0x30, + 0x80, 0x7f, 0x29, 0x80, 0x64, 0x2, 0x0, 0xeb, + 0x0, 0xff, 0xac, 0x3, 0x10, 0x8, 0x7, 0x10, + 0x7, 0xfc, 0x40, 0x18, 0x40, 0x3e, 0x30, 0xf, + 0xfe, 0x30, 0x80, 0x73, 0x0, 0x7f, 0xda, 0x1, + 0xe2, 0x0, 0xed, 0x0, 0xff, 0x94, 0x3, 0xe3, + 0x0, 0xcc, 0x20, 0x1f, 0xce, 0x40, 0x18, 0x80, + 0x16, 0x1, 0xda, 0x20, 0x1f, 0x34, 0x0, 0x70, + 0x80, 0x18, 0x3, 0x8f, 0xdc, 0xc0, 0x2, 0x97, + 0x20, 0x1e, 0x60, 0x0, 0xb0, 0x7, 0xc, 0x67, + 0xfb, 0xad, 0x0, 0x2, 0x1, 0xb4, 0x2, 0x93, + 0x0, 0xff, 0xe0, 0xc8, 0x80, 0x64, 0x0, 0xda, + 0x80, 0x1f, 0xe1, 0xc1, 0x0, 0xe3, 0x0, 0xc3, + 0x72, 0x40, 0x1f, 0x3f, 0x9d, 0x0, 0x65, 0x0, + 0xf9, 0xb7, 0x26, 0x21, 0x39, 0xf0, 0x2a, 0x40, + 0x1b, 0x80, 0x3f, 0x8d, 0x9d, 0xcc, 0x60, 0x14, + 0x0, 0x62, 0x40, 0xf, 0xfe, 0x2b, 0x90, 0x6, + 0xb0, 0xf, 0xfe, 0x29, 0x40, 0x6, 0x16, 0x0, + 0xff, 0xe2, 0xf0, 0x7, 0x58, 0x7, 0xff, 0x16, + 0x4c, 0x3, 0x1a, 0x80, 0x7f, 0xf1, 0x1d, 0x80, + 0x3b, 0x80, 0x3f, 0xf8, 0x8f, 0x0, 0x1d, 0x24, + 0x1, 0xff, 0xc3, 0x88, 0x0, 0x73, 0x30, 0x3, + 0xff, 0x84, 0x36, 0xe0, 0x1c, 0xb2, 0x1, 0xff, + 0xc2, 0x2c, 0x40, 0xe, 0x5a, 0x0, 0xff, 0xe1, + 0xf9, 0x0, 0x73, 0xd0, 0x7, 0xff, 0x10, 0x80, + 0x3a, 0xa0, 0x3, 0xff, 0x8b, 0x22, 0x4, 0xfc, + 0xa0, 0x1f, 0xf0, + + /* U+003A ":" */ + 0x0, 0xff, 0xe0, 0xd, 0x77, 0xf4, 0x0, 0x43, + 0xea, 0x20, 0x2f, 0x80, 0xb, 0x10, 0xe, 0x37, + 0x5, 0x0, 0xfa, 0xc0, 0x3f, 0x84, 0x3, 0xf8, + 0x41, 0x40, 0x3e, 0xb0, 0xb1, 0x0, 0xe3, 0x70, + 0x1f, 0x61, 0x1, 0x7c, 0x0, 0x86, 0x7b, 0xfa, + 0x0, 0x3f, 0xff, 0xc3, 0x5d, 0xfd, 0x0, 0x10, + 0xfa, 0x88, 0xb, 0xe0, 0x2, 0xc4, 0x3, 0x8d, + 0xc1, 0x40, 0x3e, 0xb0, 0xf, 0xe1, 0x0, 0xfe, + 0x10, 0x50, 0xf, 0xa8, 0x2c, 0x40, 0x38, 0xd8, + 0x7, 0xd8, 0x40, 0x5f, 0x0 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +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 = 461, .box_w = 25, .box_h = 35, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 293, .adv_w = 461, .box_w = 24, .box_h = 35, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 420, .adv_w = 461, .box_w = 24, .box_h = 35, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 660, .adv_w = 461, .box_w = 23, .box_h = 35, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 912, .adv_w = 461, .box_w = 26, .box_h = 35, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1105, .adv_w = 461, .box_w = 23, .box_h = 35, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 1312, .adv_w = 461, .box_w = 25, .box_h = 35, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1587, .adv_w = 461, .box_w = 24, .box_h = 35, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1795, .adv_w = 461, .box_w = 25, .box_h = 35, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2087, .adv_w = 461, .box_w = 25, .box_h = 35, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2362, .adv_w = 461, .box_w = 10, .box_h = 27, .ofs_x = 9, .ofs_y = 0} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + + + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 48, .range_length = 11, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR == 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +#endif + +#if LVGL_VERSION_MAJOR >= 8 +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 1, + .bpp = 4, + .kern_classes = 0, + .bitmap_format = 1, +#if LVGL_VERSION_MAJOR == 8 + .cache = &cache +#endif +}; + + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t ui_font_keyboard_time_48 = { +#else +lv_font_t ui_font_keyboard_time_48 = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 35, /*The maximum line height required by the font*/ + .base_line = 0, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -7, + .underline_thickness = 2, +#endif + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 + .fallback = NULL, +#endif + .user_data = NULL, +}; + + + +#endif /*#if UI_FONT_KEYBOARD_TIME_48*/ +