mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-26 17:38:39 +00:00
ui.display: add avatar function
This commit is contained in:
parent
76658914fe
commit
be9a05b55a
@ -177,6 +177,48 @@ void display_image(int x, int y, int w, int h, const void *data, int datalen)
|
||||
sinf_inflate(data, datalen, inflate_callback_image, userdata);
|
||||
}
|
||||
|
||||
static void inflate_callback_avatar(uint8_t byte, uint32_t pos, void *userdata)
|
||||
{
|
||||
int w = ((int *)userdata)[0];
|
||||
int x0 = ((int *)userdata)[1];
|
||||
int x1 = ((int *)userdata)[2];
|
||||
int y0 = ((int *)userdata)[3];
|
||||
int y1 = ((int *)userdata)[4];
|
||||
int fgcolor = ((int *)userdata)[5];
|
||||
int bgcolor = ((int *)userdata)[6];
|
||||
int px = (pos / 2) % w;
|
||||
int py = (pos / 2) / w;
|
||||
if (px >= x0 && px <= x1 && py >= y0 && py <= y1) {
|
||||
int d = (px - w / 2) * (px - w / 2) + (py - w / 2) * (py - w / 2);
|
||||
if (d < 70 * 70) { // inside circle
|
||||
DATA(byte);
|
||||
} else
|
||||
if (d >= 72 * 72) { // outside circle
|
||||
DATA((bgcolor >> 8 * (1 - pos % 2)) & 0xFF);
|
||||
} else { // circle
|
||||
DATA((fgcolor >> 8 * (1 - pos % 2)) & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display_avatar(int x, int y, const void *data, int datalen, uint16_t fgcolor, uint16_t bgcolor)
|
||||
{
|
||||
x += DISPLAY_OFFSET[0];
|
||||
y += DISPLAY_OFFSET[1];
|
||||
int x0, y0, x1, y1;
|
||||
clamp_coords(x, y, AVATAR_IMAGE_SIZE, AVATAR_IMAGE_SIZE, &x0, &y0, &x1, &y1);
|
||||
display_set_window(x0, y0, x1, y1);
|
||||
int userdata[7];
|
||||
userdata[0] = AVATAR_IMAGE_SIZE;
|
||||
userdata[1] = x0 - x;
|
||||
userdata[2] = x1 - x;
|
||||
userdata[3] = y0 - y;
|
||||
userdata[4] = y1 - y;
|
||||
userdata[5] = fgcolor;
|
||||
userdata[6] = bgcolor;
|
||||
sinf_inflate(data, datalen, inflate_callback_avatar, userdata);
|
||||
}
|
||||
|
||||
static void inflate_callback_icon(uint8_t byte, uint32_t pos, void *userdata)
|
||||
{
|
||||
uint16_t *colortable = (uint16_t *)(((int *)userdata) + 5);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define FONT_BOLD 2
|
||||
#endif
|
||||
|
||||
#define AVATAR_IMAGE_SIZE 144
|
||||
#define LOADER_ICON_SIZE 64
|
||||
|
||||
#define RGB16(R, G, B) ((R & 0xF8) << 8) | ((G & 0xFC) << 3) | ((B & 0xF8) >> 3)
|
||||
@ -49,6 +50,7 @@ void display_bar(int x, int y, int w, int h, uint16_t c);
|
||||
void display_bar_radius(int x, int y, int w, int h, uint16_t c, uint16_t b, uint8_t r);
|
||||
|
||||
void display_image(int x, int y, int w, int h, const void *data, int datalen);
|
||||
void display_avatar(int x, int y, const void *data, int datalen, uint16_t fgcolor, uint16_t bgcolor);
|
||||
void display_icon(int x, int y, int w, int h, const void *data, int datalen, uint16_t fgcolor, uint16_t bgcolor);
|
||||
|
||||
#ifndef TREZOR_PRINT_DISABLE
|
||||
|
@ -107,10 +107,41 @@ STATIC mp_obj_t mod_trezorui_Display_image(size_t n_args, const mp_obj_t *args)
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_image_obj, 4, 4, mod_trezorui_Display_image);
|
||||
|
||||
/// def avatar(self, x: int, y: int, image: bytes, fgcolor: int, bgcolor: int) -> None:
|
||||
/// '''
|
||||
/// Renders an avatar at position (x,y).
|
||||
/// The image needs to be in TREZOR Optimized Image Format (TOIF) - full-color mode.
|
||||
/// Image needs to be of exactly AVATAR_IMAGE_SIZE x AVATAR_IMAGE_SIZE pixels size.
|
||||
/// '''
|
||||
STATIC mp_obj_t mod_trezorui_Display_avatar(size_t n_args, const mp_obj_t *args) {
|
||||
mp_int_t x = mp_obj_get_int(args[1]);
|
||||
mp_int_t y = mp_obj_get_int(args[2]);
|
||||
mp_buffer_info_t image;
|
||||
mp_get_buffer_raise(args[3], &image, MP_BUFFER_READ);
|
||||
const uint8_t *data = image.buf;
|
||||
if (image.len < 8 || memcmp(data, "TOIf", 4) != 0) {
|
||||
mp_raise_ValueError("Invalid image format");
|
||||
}
|
||||
mp_int_t w = *(uint16_t *)(data + 4);
|
||||
mp_int_t h = *(uint16_t *)(data + 6);
|
||||
if (w != AVATAR_IMAGE_SIZE || h != AVATAR_IMAGE_SIZE) {
|
||||
mp_raise_ValueError("Invalid image size");
|
||||
}
|
||||
mp_int_t datalen = *(uint32_t *)(data + 8);
|
||||
if (datalen != image.len - 12) {
|
||||
mp_raise_ValueError("Invalid size of data");
|
||||
}
|
||||
mp_int_t fgcolor = mp_obj_get_int(args[4]);
|
||||
mp_int_t bgcolor = mp_obj_get_int(args[5]);
|
||||
display_avatar(x, y, data + 12, datalen, fgcolor, bgcolor);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_avatar_obj, 6, 6, mod_trezorui_Display_avatar);
|
||||
|
||||
/// def icon(self, x: int, y: int, icon: bytes, fgcolor: int, bgcolor: int) -> None:
|
||||
/// '''
|
||||
/// Renders an icon at position (x,y), fgcolor is used as foreground color, bgcolor as background.
|
||||
/// The image needs to be in TREZOR Optimized Image Format (TOIF) - gray-scale mode.
|
||||
/// The icon needs to be in TREZOR Optimized Image Format (TOIF) - gray-scale mode.
|
||||
/// '''
|
||||
STATIC mp_obj_t mod_trezorui_Display_icon(size_t n_args, const mp_obj_t *args) {
|
||||
mp_int_t x = mp_obj_get_int(args[1]);
|
||||
@ -380,6 +411,7 @@ STATIC const mp_rom_map_elem_t mod_trezorui_Display_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_bar), MP_ROM_PTR(&mod_trezorui_Display_bar_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_bar_radius), MP_ROM_PTR(&mod_trezorui_Display_bar_radius_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_image), MP_ROM_PTR(&mod_trezorui_Display_image_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_avatar), MP_ROM_PTR(&mod_trezorui_Display_avatar_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_icon), MP_ROM_PTR(&mod_trezorui_Display_icon_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&mod_trezorui_Display_print_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&mod_trezorui_Display_text_obj) },
|
||||
|
Loading…
Reference in New Issue
Block a user