From afd07f4bc007ddf4a9e036cd9f4c2db800719653 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 4 Sep 2024 20:21:55 +0200 Subject: support for unknown character in eve font --- fw/fe310/eos/eve/eve_font.c | 51 ++++++++++++++++++++++++--------------- fw/fe310/eos/eve/eve_font.h | 6 ++--- fw/fe310/eos/eve/widget/label.c | 9 ++++++- fw/fe310/eos/eve/widget/selectw.c | 12 +++++++++ fw/fe310/eos/eve/widget/selectw.h | 1 + fw/fe310/eos/eve/widget/strw.c | 47 +++++++++++++++++++++--------------- fw/fe310/eos/eve/widget/textw.c | 46 ++++++++++++++++++++++++++--------- fw/fe310/eos/eve/widget/textw.h | 1 + fw/fe310/eos/unicode.c | 3 ++- 9 files changed, 121 insertions(+), 55 deletions(-) (limited to 'fw/fe310/eos') diff --git a/fw/fe310/eos/eve/eve_font.c b/fw/fe310/eos/eve/eve_font.c index 81df143..cde0a17 100644 --- a/fw/fe310/eos/eve/eve_font.c +++ b/fw/fe310/eos/eve/eve_font.c @@ -14,44 +14,57 @@ void eve_font_init(EVEFont *font, uint8_t font_id) { eve_readb(p, font->w_ch, 128); } -uint8_t eve_font_ch_w(EVEFont *font, ucp_t ch) { +int eve_font_ch_w(EVEFont *font, ucp_t ch) { if (ch < 128) return font->w_ch[ch]; - return 0; + return EVE_ERR; } -uint16_t eve_font_str_w(EVEFont *font, utf8_t *str) { +int eve_font_str_w(EVEFont *font, utf8_t *str, int *str_w, size_t *str_len) { uint16_t r = 0; + size_t len = 0; ucp_t ch; - uint8_t ch_w; - uint8_t ch_l; + int ch_w; + int ch_l; - if (str == NULL) return 0; - - while (*str) { - ch_l = utf8_dec(str, &ch); + while (str[len]) { + ch_l = utf8_dec(str + len, &ch); ch_w = eve_font_ch_w(font, ch); + if (ch_w < 0) { + if (str_w) *str_w = r; + if (str_len) *str_len = len; + return EVE_ERR; + } r += ch_w; - str += ch_l; + len += ch_l; } - return r; + if (str_w) *str_w = r; + if (str_len) *str_len = len; + return EVE_OK; } -uint16_t eve_font_buf_w(EVEFont *font, utf8_t *buf, uint16_t buf_len) { - int i = 0; +int eve_font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len, int *str_w, size_t *str_len) { uint16_t r = 0; + size_t len = 0; ucp_t ch; - uint8_t ch_w; - uint8_t ch_l; + int ch_w; + int ch_l; - while (i < buf_len) { - ch_l = utf8_dec(buf + i, &ch); + while (len < buf_len) { + ch_l = utf8_dec(buf + len, &ch); ch_w = eve_font_ch_w(font, ch); + if (ch_w < 0) { + if (str_w) *str_w = r; + if (str_len) *str_len = len; + return EVE_ERR; + } r += ch_w; - i += ch_l; + len += ch_l; } - return r; + if (str_w) *str_w = r; + if (str_len) *str_len = len; + return EVE_OK; } uint8_t eve_font_h(EVEFont *font) { diff --git a/fw/fe310/eos/eve/eve_font.h b/fw/fe310/eos/eve/eve_font.h index c098519..c384877 100644 --- a/fw/fe310/eos/eve/eve_font.h +++ b/fw/fe310/eos/eve/eve_font.h @@ -10,7 +10,7 @@ typedef struct EVEFont { } EVEFont; void eve_font_init(EVEFont *font, uint8_t font_id); -uint8_t eve_font_ch_w(EVEFont *font, ucp_t ch); -uint16_t eve_font_str_w(EVEFont *font, utf8_t *str); -uint16_t eve_font_buf_w(EVEFont *font, utf8_t *buf, uint16_t buf_len); +int eve_font_ch_w(EVEFont *font, ucp_t ch); +int eve_font_str_w(EVEFont *font, utf8_t *str, int *str_w, size_t *str_len); +int eve_font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len, int *str_w, size_t *str_len); uint8_t eve_font_h(EVEFont *font); diff --git a/fw/fe310/eos/eve/widget/label.c b/fw/fe310/eos/eve/widget/label.c index 43d555d..bf99051 100644 --- a/fw/fe310/eos/eve/widget/label.c +++ b/fw/fe310/eos/eve/widget/label.c @@ -11,12 +11,19 @@ #include "label.h" void eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title) { + size_t title_len; + int title_w, rv; + memset(label, 0, sizeof(EVELabel)); if (g) label->g = *g; + + rv = eve_font_str_w(font, label->title, &title_w, &title_len); + if (rv) title[title_len] = '\0'; + label->font = font; label->title = title; if (label->g.h == 0) label->g.h = eve_font_h(font); - if (label->g.w == 0) label->g.w = eve_font_str_w(font, label->title) + EVE_LABEL_MARGIN; + if (label->g.w == 0) label->g.w = title_w + EVE_LABEL_MARGIN; } void eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page) { diff --git a/fw/fe310/eos/eve/widget/selectw.c b/fw/fe310/eos/eve/widget/selectw.c index b11f9b6..f0dfed9 100644 --- a/fw/fe310/eos/eve/widget/selectw.c +++ b/fw/fe310/eos/eve/widget/selectw.c @@ -75,6 +75,18 @@ void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFon widget->select = widget->multi ? 0 : SELECTW_NOSELECT; } +int eve_selectw_update(EVESelectWidget *widget) { + int rv, i; + + rv = selectw_verify(widget->option, widget->option_size); + if (rv) return rv; + + widget->option_count = selectw_count(widget); + selectw_update_sz(widget, 1); + + return EVE_OK; +} + int eve_selectw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVESelectWidget *widget = (EVESelectWidget *)_widget; EVESelectSpec *tspec = &spec->tspec.select; diff --git a/fw/fe310/eos/eve/widget/selectw.h b/fw/fe310/eos/eve/widget/selectw.h index f1b7071..aa49866 100644 --- a/fw/fe310/eos/eve/widget/selectw.h +++ b/fw/fe310/eos/eve/widget/selectw.h @@ -20,6 +20,7 @@ typedef struct EVESelectSpec { } EVESelectSpec; void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi); +int eve_selectw_update(EVESelectWidget *widget); int eve_selectw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); void eve_selectw_destroy(EVEWidget *_widget); diff --git a/fw/fe310/eos/eve/widget/strw.c b/fw/fe310/eos/eve/widget/strw.c index cd1f51d..873e017 100644 --- a/fw/fe310/eos/eve/widget/strw.c +++ b/fw/fe310/eos/eve/widget/strw.c @@ -30,35 +30,38 @@ void eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size) { EVEWidget *_widget = &widget->w; size_t str_len; - int rv; + int str_w, rv; memset(widget, 0, sizeof(EVEStrWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_STR, g, page, eve_strw_draw, eve_strw_touch, eve_strw_putc); widget->font = font; + rv = utf8_verify(str, str_size, &str_len); - if (rv != UTF_OK) { - if (str_len >= str_size) str_len = 0; - str[str_len] = '\0'; - } + if (rv) str[str_len] = '\0'; + + rv = eve_font_str_w(font, str, &str_w, &str_len); + if (rv) str[str_len] = '\0'; + widget->str = str; widget->str_size = str_size; widget->str_len = str_len; - widget->str_g.w = eve_font_str_w(widget->font, str); + widget->str_g.w = str_w; if (_widget->g.h == 0) _widget->g.h = eve_font_h(widget->font); } int eve_strw_update(EVEStrWidget *widget) { size_t str_len; - int rv; + int str_w, rv; rv = utf8_verify(widget->str, widget->str_size, &str_len); - if (rv != UTF_OK) { - if (str_len >= widget->str_size) str_len = 0; - widget->str[str_len] = '\0'; - } + if (rv) widget->str[str_len] = '\0'; + + rv = eve_font_str_w(widget->font, widget->str, &str_w, &str_len); + if (rv) widget->str[str_len] = '\0'; + widget->str_len = str_len; - widget->str_g.w = eve_font_str_w(widget->font, widget->str); - return (rv == UTF_OK) ? EVE_OK : EVE_ERR; + widget->str_g.w = str_w; + return EVE_OK; } int eve_strw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { @@ -360,18 +363,23 @@ void eve_strw_putc(void *w, int c) { } else { c1 = cursor2; } + } + str = widget->str + c1->ch; + + if (cursor2->on) { del_c = c2->ch - c1->ch; - del_w = eve_font_buf_w(widget->font, str, del_c); + eve_font_buf_w(widget->font, str, del_c, &del_w, NULL); if ((c == CH_CTRLX) || (c == CH_CTRLC)) { eve_clipb_push(str, del_c); if (c == CH_CTRLC) return; } } - str = widget->str + c1->ch; if (CHAR_VALID_INPUT(c)) { ins_c = utf8_enc(c, utf8_buf); + if (ins_c < 0) return; ins_w = eve_font_ch_w(widget->font, c); + if (ins_w < 0) return; } else if (c == CH_CTRLV) { size_t clipb_len = 0; int rv; @@ -379,13 +387,14 @@ void eve_strw_putc(void *w, int c) { clipb = eve_clipb_get(); if (clipb) { rv = utf8_verify(clipb, EVE_CLIPB_SIZE_BUF, &clipb_len); - if (rv != UTF_OK) { + if (!rv) rv = eve_font_str_w(widget->font, clipb, &ins_w, NULL); + if (rv) { clipb = NULL; clipb_len = 0; + ins_w = 0; } } ins_c = clipb_len; - ins_w = eve_font_str_w(widget->font, clipb); } if (widget->str_len + ins_c >= widget->str_size + del_c) { ins_c = 0; @@ -417,8 +426,8 @@ void eve_strw_cursor_set(EVEStrWidget *widget, EVEStrCursor *cursor, int16_t x) int i; int16_t _x, _d; ucp_t ch; - uint8_t ch_w; - uint8_t ch_l; + int ch_w; + int ch_l; EVEWidget *_widget = &widget->w; x = x - _widget->g.x + widget->str_g.x; diff --git a/fw/fe310/eos/eve/widget/textw.c b/fw/fe310/eos/eve/widget/textw.c index d77e245..f85d1e0 100644 --- a/fw/fe310/eos/eve/widget/textw.c +++ b/fw/fe310/eos/eve/widget/textw.c @@ -38,11 +38,13 @@ void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *f memset(widget, 0, sizeof(EVETextWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_TEXT, g, page, eve_textw_draw, eve_textw_touch, eve_textw_putc); widget->font = font; + rv = utf8_verify(text, text_size, &text_len); - if (rv != UTF_OK) { - if (text_len >= text_size) text_len = 0; - text[text_len] = '\0'; - } + if (rv) text[text_len] = '\0'; + + rv = eve_font_str_w(font, text, NULL, &text_len); + if (rv) text[text_len] = '\0'; + widget->text = text; widget->text_size = text_size; widget->text_len = text_len; @@ -52,6 +54,20 @@ void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *f eve_textw_text_update(widget, 0, 0); } +int eve_textw_update(EVETextWidget *widget) { + size_t text_len; + int rv; + + rv = utf8_verify(widget->text, widget->text_size, &text_len); + if (rv != UTF_OK) widget->text[text_len] = '\0'; + + rv = eve_font_str_w(widget->font, widget->text, NULL, &text_len); + if (rv != UTF_OK) widget->text[text_len] = '\0'; + + memset(widget->line, 0xff, widget->line_size * sizeof(uint16_t)); + eve_textw_text_update(widget, 0, 0); +} + int eve_textw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVETextWidget *widget = (EVETextWidget *)_widget; EVETextSpec *tspec = &spec->tspec.text; @@ -360,6 +376,10 @@ void eve_textw_putc(void *w, int c) { } else { c1 = cursor2; } + } + text = widget->text + c1->ch; + + if (cursor2->on) { del_c = c2->ch - c1->ch; if ((c == CH_CTRLX) || (c == CH_CTRLC)) { eve_clipb_push(text, del_c); @@ -367,10 +387,11 @@ void eve_textw_putc(void *w, int c) { } } - text = widget->text + c1->ch; if (CHAR_VALID_INPUT(c)) { ins_c = utf8_enc(c, utf8_buf); + if (ins_c < 0) return; ch_w = eve_font_ch_w(widget->font, c); + if (ch_w < 0) return; } else if (c == CH_CTRLV) { size_t clipb_len = 0; int rv; @@ -378,13 +399,14 @@ void eve_textw_putc(void *w, int c) { clipb = eve_clipb_get(); if (clipb) { rv = utf8_verify(clipb, EVE_CLIPB_SIZE_BUF, &clipb_len); - if (rv != UTF_OK) { + if (!rv) rv = eve_font_str_w(widget->font, clipb, &ch_w, NULL); + if (rv) { clipb = NULL; clipb_len = 0; + ch_w = 0; } } ins_c = clipb_len; - ch_w = eve_font_str_w(widget->font, clipb); } if (widget->text_len + ins_c >= widget->text_size + del_c) { ins_c = 0; @@ -434,8 +456,8 @@ void eve_textw_putc(void *w, int c) { uint16_t eve_textw_text_update(EVETextWidget *widget, uint16_t line, int uievt) { int i; ucp_t ch; - uint8_t ch_w; - uint8_t ch_l; + int ch_w; + int ch_l; uint16_t word_w, line_w, line_b; uint16_t new_h; EVEWidget *_widget = &widget->w; @@ -498,7 +520,7 @@ void eve_textw_cursor_update(EVETextWidget *widget, EVETextCursor *cursor) { int i = LINE_START(widget, cursor->line); uint16_t x = 0; ucp_t ch; - uint8_t ch_l; + int ch_l; EVEWidget *_widget = &widget->w; while ((i < cursor->ch) && (i < LINE_END(widget, cursor->line))) { @@ -515,8 +537,8 @@ void eve_textw_cursor_set(EVETextWidget *widget, EVETextCursor *cursor, uint8_t int16_t _x, _d; uint16_t c_line = LINE_EMPTY; ucp_t ch; - uint8_t ch_w; - uint8_t ch_l; + int ch_w; + int ch_l; EVEWidget *_widget = &widget->w; if ((_widget->tag0 == EVE_NOTAG) && (_widget->tagN == EVE_NOTAG)) { diff --git a/fw/fe310/eos/eve/widget/textw.h b/fw/fe310/eos/eve/widget/textw.h index 1c33733..0fb3505 100644 --- a/fw/fe310/eos/eve/widget/textw.h +++ b/fw/fe310/eos/eve/widget/textw.h @@ -35,6 +35,7 @@ typedef struct EVETextSpec { } EVETextSpec; void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size); +int eve_textw_update(EVETextWidget *widget); int eve_textw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); void eve_textw_destroy(EVEWidget *_widget); diff --git a/fw/fe310/eos/unicode.c b/fw/fe310/eos/unicode.c index d660247..af41d24 100644 --- a/fw/fe310/eos/unicode.c +++ b/fw/fe310/eos/unicode.c @@ -124,8 +124,9 @@ int utf8_verify(utf8_t *str, size_t str_size, size_t *str_len) { break; } } - + if (len == str_size) len -= ch_l; if (str_len) *str_len = len; + return UTF_ERR; } -- cgit v1.2.3