From 16481ee83d7bde7a28dc8b0d767e0e59d78eb678 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 4 Sep 2024 17:01:05 +0200 Subject: unicode support improvements / bugfixes --- fw/fe310/eos/eve/eve_font.c | 6 ++-- fw/fe310/eos/eve/eve_font.h | 2 +- fw/fe310/eos/eve/widget/selectw.c | 2 +- fw/fe310/eos/eve/widget/strw.c | 13 +++++--- fw/fe310/eos/eve/widget/textw.c | 14 ++++---- fw/fe310/eos/unicode.c | 70 ++++++++++++++++++++++++--------------- fw/fe310/eos/unicode.h | 26 +++++++++------ 7 files changed, 79 insertions(+), 54 deletions(-) (limited to 'fw') diff --git a/fw/fe310/eos/eve/eve_font.c b/fw/fe310/eos/eve/eve_font.c index e1e3aee..81df143 100644 --- a/fw/fe310/eos/eve/eve_font.c +++ b/fw/fe310/eos/eve/eve_font.c @@ -14,14 +14,14 @@ 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, utf32_t ch) { +uint8_t eve_font_ch_w(EVEFont *font, ucp_t ch) { if (ch < 128) return font->w_ch[ch]; return 0; } uint16_t eve_font_str_w(EVEFont *font, utf8_t *str) { uint16_t r = 0; - utf32_t ch; + ucp_t ch; uint8_t ch_w; uint8_t ch_l; @@ -40,7 +40,7 @@ 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 i = 0; uint16_t r = 0; - utf32_t ch; + ucp_t ch; uint8_t ch_w; uint8_t ch_l; diff --git a/fw/fe310/eos/eve/eve_font.h b/fw/fe310/eos/eve/eve_font.h index 87ef41f..c098519 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, utf32_t ch); +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); uint8_t eve_font_h(EVEFont *font); diff --git a/fw/fe310/eos/eve/widget/selectw.c b/fw/fe310/eos/eve/widget/selectw.c index f5bb6e0..b11f9b6 100644 --- a/fw/fe310/eos/eve/widget/selectw.c +++ b/fw/fe310/eos/eve/widget/selectw.c @@ -15,7 +15,7 @@ #define DIVC(x,y) ((x) / (y) + ((x) % (y) != 0)) static int selectw_verify(utf8_t *option, uint16_t option_size) { - int o_len; + size_t o_len; uint16_t o_curr; int rv; diff --git a/fw/fe310/eos/eve/widget/strw.c b/fw/fe310/eos/eve/widget/strw.c index 6bddbe9..cd1f51d 100644 --- a/fw/fe310/eos/eve/widget/strw.c +++ b/fw/fe310/eos/eve/widget/strw.c @@ -29,7 +29,8 @@ void eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size) { EVEWidget *_widget = &widget->w; - int rv, str_len; + size_t str_len; + int 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); @@ -47,7 +48,8 @@ void eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *fon } int eve_strw_update(EVEStrWidget *widget) { - int rv, str_len; + size_t str_len; + int rv; rv = utf8_verify(widget->str, widget->str_size, &str_len); if (rv != UTF_OK) { @@ -317,7 +319,7 @@ void eve_strw_putc(void *w, int c) { if (!cursor1->on) return; if (!cursor2->on && ((c == CH_BS) || (c == CH_DEL))) { - utf32_t uc; + ucp_t uc; str = widget->str + cursor1->ch; switch (c) { @@ -371,7 +373,8 @@ void eve_strw_putc(void *w, int c) { ins_c = utf8_enc(c, utf8_buf); ins_w = eve_font_ch_w(widget->font, c); } else if (c == CH_CTRLV) { - int rv, clipb_len = 0; + size_t clipb_len = 0; + int rv; clipb = eve_clipb_get(); if (clipb) { @@ -413,7 +416,7 @@ void eve_strw_putc(void *w, int c) { void eve_strw_cursor_set(EVEStrWidget *widget, EVEStrCursor *cursor, int16_t x) { int i; int16_t _x, _d; - utf32_t ch; + ucp_t ch; uint8_t ch_w; uint8_t ch_l; EVEWidget *_widget = &widget->w; diff --git a/fw/fe310/eos/eve/widget/textw.c b/fw/fe310/eos/eve/widget/textw.c index 4348b67..d77e245 100644 --- a/fw/fe310/eos/eve/widget/textw.c +++ b/fw/fe310/eos/eve/widget/textw.c @@ -32,7 +32,8 @@ 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) { EVEWidget *_widget = &widget->w; - int rv, text_len; + size_t text_len; + int rv; memset(widget, 0, sizeof(EVETextWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_TEXT, g, page, eve_textw_draw, eve_textw_touch, eve_textw_putc); @@ -327,7 +328,7 @@ void eve_textw_putc(void *w, int c) { if (!cursor1->on) return; if (!cursor2->on && ((c == CH_BS) || (c == CH_DEL))) { - utf32_t uc; + ucp_t uc; text = widget->text + cursor1->ch; switch (c) { @@ -371,7 +372,8 @@ void eve_textw_putc(void *w, int c) { ins_c = utf8_enc(c, utf8_buf); ch_w = eve_font_ch_w(widget->font, c); } else if (c == CH_CTRLV) { - int rv, clipb_len = 0; + size_t clipb_len = 0; + int rv; clipb = eve_clipb_get(); if (clipb) { @@ -431,7 +433,7 @@ void eve_textw_putc(void *w, int c) { uint16_t eve_textw_text_update(EVETextWidget *widget, uint16_t line, int uievt) { int i; - utf32_t ch; + ucp_t ch; uint8_t ch_w; uint8_t ch_l; uint16_t word_w, line_w, line_b; @@ -495,7 +497,7 @@ uint16_t eve_textw_text_update(EVETextWidget *widget, uint16_t line, int uievt) void eve_textw_cursor_update(EVETextWidget *widget, EVETextCursor *cursor) { int i = LINE_START(widget, cursor->line); uint16_t x = 0; - utf32_t ch; + ucp_t ch; uint8_t ch_l; EVEWidget *_widget = &widget->w; @@ -512,7 +514,7 @@ void eve_textw_cursor_set(EVETextWidget *widget, EVETextCursor *cursor, uint8_t int i; int16_t _x, _d; uint16_t c_line = LINE_EMPTY; - utf32_t ch; + ucp_t ch; uint8_t ch_w; uint8_t ch_l; EVEWidget *_widget = &widget->w; diff --git a/fw/fe310/eos/unicode.c b/fw/fe310/eos/unicode.c index 29100c7..d660247 100644 --- a/fw/fe310/eos/unicode.c +++ b/fw/fe310/eos/unicode.c @@ -1,6 +1,6 @@ #include "unicode.h" -int utf8_enc(utf32_t ch, utf8_t *str) { +int utf8_enc(ucp_t ch, utf8_t *str) { if (ch <= 0x7f) { str[0] = ch; return 1; @@ -25,30 +25,30 @@ int utf8_enc(utf32_t ch, utf8_t *str) { } } -int utf8_dec(utf8_t *str, utf32_t *ch) { +int utf8_dec(utf8_t *str, ucp_t *ch) { if ((str[0] & 0x80) == 0x00) { *ch = str[0]; return 1; } else if ((str[0] & 0xe0) == 0xc0) { if ((str[1] & 0xc0) != 0x80) return UTF_ERR; - *ch = (utf32_t)(str[0] & 0x1f) << 6; - *ch |= (utf32_t)(str[1] & 0x3f); + *ch = (ucp_t)(str[0] & 0x1f) << 6; + *ch |= (ucp_t)(str[1] & 0x3f); if (*ch < 0x80) return UTF_ERR; return 2; } else if ((str[0] & 0xf0) == 0xe0) { if (((str[1] & 0xc0) != 0x80) || ((str[2] & 0xc0) != 0x80)) return UTF_ERR; - *ch = (utf32_t)(str[0] & 0x0f) << 12; - *ch |= (utf32_t)(str[1] & 0x3f) << 6; - *ch |= (utf32_t)(str[2] & 0x3f); + *ch = (ucp_t)(str[0] & 0x0f) << 12; + *ch |= (ucp_t)(str[1] & 0x3f) << 6; + *ch |= (ucp_t)(str[2] & 0x3f); if ((*ch >= 0xd800) && (*ch <= 0xdfff)) return UTF_ERR; if (*ch < 0x800) return UTF_ERR; return 3; } else if ((str[0] & 0xf8) == 0xf0) { if (((str[1] & 0xc0) != 0x80) || ((str[2] & 0xc0) != 0x80) || ((str[3] & 0xc0) != 0x80)) return UTF_ERR; - *ch = (utf32_t)(str[0] & 0x07) << 18; - *ch |= (utf32_t)(str[1] & 0x0f) << 12; - *ch |= (utf32_t)(str[2] & 0x3f) << 6; - *ch |= (utf32_t)(str[3] & 0x3f); + *ch = (ucp_t)(str[0] & 0x07) << 18; + *ch |= (ucp_t)(str[1] & 0x0f) << 12; + *ch |= (ucp_t)(str[2] & 0x3f) << 6; + *ch |= (ucp_t)(str[3] & 0x3f); if (*ch < 0x010000) return UTF_ERR; if (*ch > 0x10ffff) return UTF_ERR; return 4; @@ -57,16 +57,25 @@ int utf8_dec(utf8_t *str, utf32_t *ch) { } } -int utf8_len(utf8_t *str) { - if ((*str & 0xf8) == 0xf0) return 4; - if ((*str & 0xf0) == 0xe0) return 3; - if ((*str & 0xe0) == 0xc0) return 2; +int utf8_len_ch(ucp_t ch) { + if (ch <= 0x7f) return 1; + if (ch <= 0x7ff) return 2; + if (ch <= 0xffff) return 3; + if (ch <= 0x10ffff) return 4; + + return UTF_ERR; +} + +int utf8_len_str(utf8_t *str) { if ((*str & 0x80) == 0x00) return 1; + if ((*str & 0xe0) == 0xc0) return 2; + if ((*str & 0xf0) == 0xe0) return 3; + if ((*str & 0xf8) == 0xf0) return 4; return UTF_ERR; } -int utf8_seek(utf8_t *str, int off, utf32_t *ch) { +int utf8_seek(utf8_t *str, int off, ucp_t *ch) { int i; int len = 0; @@ -93,15 +102,16 @@ int utf8_seek(utf8_t *str, int off, utf32_t *ch) { return len; } -int utf8_verify(utf8_t *str, int str_size, int *str_len) { - utf32_t ch; - uint8_t ch_l; - int len = 0; +int utf8_verify(utf8_t *str, size_t str_size, size_t *str_len) { + ucp_t ch; + size_t len = 0; + int ch_l, rv; while (len < str_size) { if (str_size - len < 4) { - int _len = utf8_len(str + len); - if ((_len == UTF_ERR) || ((str_size - len) < _len)) break; + rv = utf8_len_str(str + len); + if (rv < 0) break; + if (str_size - len < rv) break; } ch_l = utf8_dec(str + len, &ch); if (ch_l > 0) { @@ -119,7 +129,7 @@ int utf8_verify(utf8_t *str, int str_size, int *str_len) { return UTF_ERR; } -int utf16_enc(utf32_t ch, uint8_t *str) { +int utf16_enc(ucp_t ch, utf16_t *str) { if (ch <= 0xffff) { if ((ch >= 0xd800) && (ch <= 0xdfff)) return UTF_ERR; str[0] = ch >> 8; @@ -142,7 +152,7 @@ int utf16_enc(utf32_t ch, uint8_t *str) { } } -int utf16_dec(uint8_t *str, utf32_t *ch) { +int utf16_dec(utf16_t *str, ucp_t *ch) { *ch = (str[0] << 8) | str[1]; if ((*ch >= 0xd800) && (*ch <= 0xdfff)) { uint16_t hi = *ch; @@ -158,15 +168,21 @@ int utf16_dec(uint8_t *str, utf32_t *ch) { } } -int utf16_len(uint8_t *str) { +int utf16_len_ch(ucp_t ch) { + if (ch <= 0xffff) return 2; + if (ch <= 0x10ffff) return 4; + + return UTF_ERR; +} + +int utf16_len_str(utf16_t *str) { uint16_t ch = (str[0] << 8) | str[1]; - if ((ch >= 0xdc00) && (ch <= 0xdfff)) return UTF_ERR; if ((ch >= 0xd800) && (ch <= 0xdfff)) return 4; return 2; } -int utf16_seek(uint8_t *str, int off, utf32_t *ch) { +int utf16_seek(utf16_t *str, int off, ucp_t *ch) { int i; int len = 0; uint16_t cu; diff --git a/fw/fe310/eos/unicode.h b/fw/fe310/eos/unicode.h index 12fa99c..1204ea8 100644 --- a/fw/fe310/eos/unicode.h +++ b/fw/fe310/eos/unicode.h @@ -1,19 +1,23 @@ +#include #include #define UTF_OK 0 #define UTF_ERR -1 typedef uint8_t utf8_t; -typedef uint16_t utf16_t; -typedef uint32_t utf32_t; +typedef uint8_t utf16_t; +/* unicode code point*/ +typedef uint32_t ucp_t; -int utf8_enc(utf32_t ch, utf8_t *str); -int utf8_dec(utf8_t *str, utf32_t *ch); -int utf8_len(utf8_t *str); -int utf8_seek(utf8_t *str, int off, utf32_t *ch); -int utf8_verify(utf8_t *str, int str_size, int *str_len); +int utf8_enc(ucp_t ch, utf8_t *str); +int utf8_dec(utf8_t *str, ucp_t *ch); +int utf8_len_ch(ucp_t ch); +int utf8_len_str(utf8_t *str); +int utf8_seek(utf8_t *str, int off, ucp_t *ch); +int utf8_verify(utf8_t *str, size_t str_size, size_t *str_len); -int utf16_enc(utf32_t ch, uint8_t *str); -int utf16_dec(uint8_t *str, utf32_t *ch); -int utf16_len(uint8_t *str); -int utf16_seek(uint8_t *str, int off, utf32_t *ch); +int utf16_enc(ucp_t ch, utf16_t *str); +int utf16_dec(utf16_t *str, ucp_t *ch); +int utf16_len_ch(ucp_t ch); +int utf16_len_str(utf16_t *str); +int utf16_seek(utf16_t *str, int off, ucp_t *ch); -- cgit v1.2.3