Nickez/bb02 lvgl font#2000
Conversation
Add a local ttf2lvgl converter that emits the LVGL fmt_txt font subset used by the BB02 OLED UI. Document the new workflow and remove the old ttf2ugui submodule now that generated fonts no longer use the uGUI format.
Check in the generated Arial, Monogram, and password font data in LVGL fmt_txt form. Add the local LVGL include shim used by these generated font sources.
Switch the BB02 OLED UI from the old uGUI font structs to LVGL font objects and local fmt_txt callbacks. Wire the new font names through C, CMake, Rust bindings, and tests, and remove the superseded uGUI font sources.
Show valid UTF-8 messages directly when every character is supported by the default BB02 font, falling back to hex otherwise. Truncate long displayable pages on UTF-8 boundaries so label bodies stay within the existing C label buffer limit.
Link the BB02 bootloaders against generated font subsets instead of the full firmware LVGL font data. The Arial subset is sliced from the checked-in arial_9.c data so the existing hand-edited glyph data is preserved for the ASCII range used by the bootloader.
| ifeq ($(ICU_LIBS),) | ||
| ICU_LIBS := -licuuc -licudata | ||
| endif | ||
|
|
There was a problem hiding this comment.
why not something similar for ICU_CFLAGS?
| char* base = slash == NULL ? out : slash + 1; | ||
| char* dot = strrchr(base, '.'); | ||
| if (dot != NULL) { | ||
| strcpy(dot, ".h"); |
There was a problem hiding this comment.
Nit: for foo. it can write past the allocated string.
| if (i + 1 < len) { | ||
| fprintf(out, " "); | ||
| } | ||
| if (i % 12 == 11 || i + 1 == len) { |
There was a problem hiding this comment.
Nit: That creates trailing whitespace at the end of every full 12-byte line. Fix and regenerate?
| } | ||
| } | ||
|
|
||
| static void print_glyph_comment(FILE* out, UChar32 codepoint) |
There was a problem hiding this comment.
It also does that for non-breaking space and soft hyphen, so we get:
/* U+00A0 " " */
0x00,
/* U+00AD "" */
0xE0,This can look confusing because e.g. for U+00A0 it looks like a normal space, when it's not. The function already excludes normal control chars (e.g. newline), but should we escape invisible Unicode too?
There was a problem hiding this comment.
non-breaking space is the same as space except a word processor will not introduce a line break there.
The fact that 00AD is there means that the font had a glyph for it. I wonder how it is rendered on the device... maybe as a hyphen?
| @@ -0,0 +1,5 @@ | |||
| // SPDX-License-Identifier: Apache-2.0 | |||
| UG_S16 x_dim; | ||
| UG_S16 y_dim; | ||
| UG_FONT font; | ||
| const UG_FONT *font; |
There was a problem hiding this comment.
Could we document that the life time contract changed and that callers must never pass a stack/local font? This could be a future dangling pointer trap.
| return false; | ||
| }; | ||
| msg.chars() | ||
| .all(|c| c == '\n' || (!c.is_control() && ui.has_glyph(Font::Default, c))) |
There was a problem hiding this comment.
has_glyph IMO is not the same as "safe to show for signing", since has_glyph allows visually ambiguous characters (e.g. 0020 and 00A0 will look (almost) the same, but represent different bytes).
There was a problem hiding this comment.
Maybe there could be a warning for visually similar character? I think customers expect to be able to sign any message they are provided.
| .all(|c| c == '\n' || (!c.is_control() && ui.has_glyph(Font::Default, c))) | ||
| } | ||
|
|
||
| fn truncate_message_page(page: &str) -> Cow<'_, str> { |
There was a problem hiding this comment.
Although this was present in the old behavior: What is a malicious host puts meaningful content behind byte 640?
| if is_displayable { | ||
| let msg = core::str::from_utf8(msg).unwrap(); | ||
|
|
||
| let pages: Vec<&str> = msg.split('\n').filter(|line| !line.is_empty()).collect(); |
There was a problem hiding this comment.
Not introduced in this PR but still:
pay\nalice and pay\n\nalice will be displayed equally despite being a different byte sequence. Probably out of scope for this PR.
| @@ -53,7 +83,7 @@ pub async fn verify( | |||
| }; | |||
| let params = ConfirmParams { | |||
There was a problem hiding this comment.
here we do not show display_size (in UTF-8 mode we show it). Should we think about showing it here too, especially when trucation happened? Probably out of scope for this PR though.
No description provided.