diff --git a/lv_conf_template.h b/lv_conf_template.h index 0f22fe8f8..4060bef49 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -236,7 +236,7 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i # define LV_LOG_LEVEL LV_LOG_LEVEL_WARN /* 1: Print the log with 'printf'; - * 0: user need to register a callback with `lv_log_register_print`*/ + * 0: user need to register a callback with `lv_log_register_print_cb`*/ # define LV_LOG_PRINTF 0 #endif /*LV_USE_LOG*/ @@ -344,15 +344,19 @@ typedef void * lv_font_user_data_t; /*Can break (wrap) texts on these chars*/ #define LV_TXT_BREAK_CHARS " ,.;:-_" - /* If a character is at least this long, will break wherever "prettiest" */ - #define LV_TXT_LINE_BREAK_LONG_LEN 12 - /* Minimum number of characters of a word to put on a line before a break */ - #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 +/* If a word is at least this long, will break wherever "prettiest" + * To disable, set to a value <= 0 */ +#define LV_TXT_LINE_BREAK_LONG_LEN 12 - /* Minimum number of characters of a word to put on a line after a break */ - #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 +/* Minimum number of characters in a long word to put on a line before a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 +/* Minimum number of characters in a long word to put on a line after a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 + /* Support bidirectional texts. * Allows mixing Left-to-Right and Right-to-Left texts. * The direction will be processed according to the Unicode Bidirectioanl Algorithm: diff --git a/lvgl.h b/lvgl.h index cff4fe82f..e3b60da43 100644 --- a/lvgl.h +++ b/lvgl.h @@ -23,6 +23,7 @@ extern "C" { #include "src/lv_core/lv_obj.h" #include "src/lv_core/lv_group.h" +#include "src/lv_core/lv_indev.h" #include "src/lv_core/lv_refr.h" #include "src/lv_core/lv_disp.h" diff --git a/src/lv_conf_checker.h b/src/lv_conf_checker.h index b7149d0db..4c9a08d3e 100644 --- a/src/lv_conf_checker.h +++ b/src/lv_conf_checker.h @@ -269,9 +269,11 @@ /* Export integer constant to binding. * This macro is used with constants in the form of LV_ that * should also appear on lvgl binding API such as Micropython + * + * The default value just prevents a GCC warning. */ #ifndef LV_EXPORT_CONST_INT -#define LV_EXPORT_CONST_INT(int_value) +#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning #endif /*=================== @@ -314,7 +316,7 @@ #endif /* 1: Print the log with 'printf'; - * 0: user need to register a callback with `lv_log_register_print`*/ + * 0: user need to register a callback with `lv_log_register_print_cb`*/ #ifndef LV_LOG_PRINTF # define LV_LOG_PRINTF 0 #endif @@ -473,21 +475,25 @@ #define LV_TXT_BREAK_CHARS " ,.;:-_" #endif - /* If a character is at least this long, will break wherever "prettiest" */ + +/* If a word is at least this long, will break wherever "prettiest" + * To disable, set to a value <= 0 */ #ifndef LV_TXT_LINE_BREAK_LONG_LEN - #define LV_TXT_LINE_BREAK_LONG_LEN 12 +#define LV_TXT_LINE_BREAK_LONG_LEN 12 #endif - /* Minimum number of characters of a word to put on a line before a break */ +/* Minimum number of characters in a long word to put on a line before a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ #ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN - #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 #endif - /* Minimum number of characters of a word to put on a line after a break */ +/* Minimum number of characters in a long word to put on a line after a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ #ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN - #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 #endif - + /* Support bidirectional texts. * Allows mixing Left-to-Right and Right-to-Left texts. * The direction will be processed according to the Unicode Bidirectioanl Algorithm: diff --git a/src/lv_core/lv_debug.h b/src/lv_core/lv_debug.h index 3536a7323..bc5b0a6e1 100644 --- a/src/lv_core/lv_debug.h +++ b/src/lv_core/lv_debug.h @@ -136,6 +136,8 @@ do { \ #else /* LV_USE_DEBUG == 0 */ +#define LV_DEBUG_ASSERT(expr, msg, value) do{}while(0) + #define LV_ASSERT_NULL(p) true #define LV_ASSERT_MEM(p) true #define LV_ASSERT_STR(p) true diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index 32a18b4f7..de9db39f2 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -318,19 +318,19 @@ static void lv_refr_area(const lv_area_t * area_p) tmp.x2 = 0; tmp.y1 = 0; - lv_coord_t y_tmp = max_row - 1; + lv_coord_t h_tmp = max_row; do { - tmp.y2 = y_tmp; + tmp.y2 = h_tmp - 1; disp_refr->driver.rounder_cb(&disp_refr->driver, &tmp); /*If this height fits into `max_row` then fine*/ if(lv_area_get_height(&tmp) <= max_row) break; /*Decrement the height of the area until it fits into `max_row` after rounding*/ - y_tmp--; - } while(y_tmp != 0); + h_tmp--; + } while(h_tmp > 0); - if(y_tmp == 0) { + if(h_tmp <= 0) { LV_LOG_WARN("Can't set VDB height using the round function. (Wrong round_cb or to " "small VDB)"); return; diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index b2df852db..6d90584c2 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -212,7 +212,7 @@ void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_styl * @param duration duration of the animation in milliseconds * @param delay delay before the animation in milliseconds */ -static inline void lv_style_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay) +static inline void lv_style_anim_set_time(lv_anim_t * a, uint16_t duration, int16_t delay) { lv_anim_set_time(a, duration, delay); } diff --git a/src/lv_draw/lv_draw_arc.c b/src/lv_draw/lv_draw_arc.c index 9f94dc5cb..f8008f935 100644 --- a/src/lv_draw/lv_draw_arc.c +++ b/src/lv_draw/lv_draw_arc.c @@ -98,7 +98,6 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons lv_draw_rect(&round_area, clip_area, &circle_style, LV_OPA_COVER); } - } diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index f28c47ebb..d23de6e88 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -58,7 +58,7 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * if(src == NULL) { LV_LOG_WARN("Image draw: src is NULL"); lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER); - lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL); + lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR); return; } @@ -68,7 +68,7 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * if(res == LV_RES_INV) { LV_LOG_WARN("Image draw error"); lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER); - lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL); + lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR); return; } } @@ -205,7 +205,7 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas if(cdsc->dec_dsc.error_msg != NULL) { LV_LOG_WARN("Image draw error"); lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER); - lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL); + lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR); } /* The decoder open could open the image and gave the entire uncompressed image. * Just draw it!*/ diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index b9d6d7834..a957a44e0 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -10,6 +10,7 @@ #include "../lv_misc/lv_math.h" #include "../lv_hal/lv_hal_disp.h" #include "../lv_core/lv_refr.h" +#include "../lv_misc/lv_bidi.h" /********************* * DEFINES @@ -71,16 +72,13 @@ static const uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping w */ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale, const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel, - lv_draw_label_hint_t * hint) + lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir) { const lv_font_t * font = style->text.font; lv_coord_t w; /*No need to waste processor time if string is empty*/ - if (txt[0] == '\0') - { - return; - } + if (txt[0] == '\0') return; if((flag & LV_TXT_FLAG_EXPAND) == 0) { /*Normally use the label's width as width*/ @@ -89,7 +87,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st /*If EXAPND is enabled then not limit the text's width to the object's width*/ lv_point_t p; lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, - flag); + flag); w = p.x; } @@ -127,6 +125,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st pos.y += hint->y; } + uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag); /*Go the first visible line*/ @@ -161,6 +160,18 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8; + uint16_t sel_start = 0xFFFF; + uint16_t sel_end = 0xFFFF; + if(sel) { + sel_start = sel->start; + sel_end = sel->end; + if(sel_start > sel_end) { + uint16_t tmp = sel_start; + sel_start = sel_end; + sel_end = tmp; + } + } + cmd_state_t cmd_state = CMD_STATE_WAIT; uint32_t i; uint16_t par_start = 0; @@ -177,12 +188,31 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st } /*Write all letter of a line*/ cmd_state = CMD_STATE_WAIT; - i = line_start; + i = 0; uint32_t letter; uint32_t letter_next; - while(i < line_end) { - letter = lv_txt_encoded_next(txt, &i); - letter_next = lv_txt_encoded_next(&txt[i], NULL); +#if LV_USE_BIDI + char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1); + lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0); +#else + const char *bidi_txt = txt + line_start; +#endif + + while(i < line_end - line_start) { + uint16_t logical_char_pos = 0; + if(sel_start != 0xFFFF && sel_end != 0xFFFF) { +#if LV_USE_BIDI + logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start); + uint16_t t = lv_txt_encoded_get_char_id(bidi_txt, i); + logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, bidi_dir, t, NULL); +#else + logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start + i); +#endif + } + + letter = lv_txt_encoded_next(bidi_txt, &i); + letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL); + /*Handle the re-color command*/ if((flag & LV_TXT_FLAG_RECOLOR) != 0) { @@ -205,7 +235,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st /*Get the parameter*/ if(i - par_start == LABEL_RECOLOR_PAR_LENGTH + 1) { char buf[LABEL_RECOLOR_PAR_LENGTH + 1]; - memcpy(buf, &txt[par_start], LABEL_RECOLOR_PAR_LENGTH); + memcpy(buf, &bidi_txt[par_start], LABEL_RECOLOR_PAR_LENGTH); buf[LABEL_RECOLOR_PAR_LENGTH] = '\0'; int r, g, b; r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]); @@ -227,18 +257,14 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st letter_w = lv_font_get_glyph_width(font, letter, letter_next); - if(sel) { - if(sel->start != 0xFFFF && sel->end != 0xFFFF) { - int char_ind = lv_encoded_get_char_id(txt, i); - /*Do not draw the rectangle on the character at `sel_start`.*/ - if(char_ind > sel->start && char_ind <= sel->end) { - lv_area_t sel_coords; - sel_coords.x1 = pos.x; - sel_coords.y1 = pos.y; - sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1; - sel_coords.y2 = pos.y + line_height - 1; - lv_draw_rect(&sel_coords, mask, &sel_style, opa); - } + if(sel_start != 0xFFFF && sel_end != 0xFFFF) { + if(logical_char_pos >= sel_start && logical_char_pos < sel_end) { + lv_area_t sel_coords; + sel_coords.x1 = pos.x; + sel_coords.y1 = pos.y; + sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1; + sel_coords.y2 = pos.y + line_height - 1; + lv_draw_rect(&sel_coords, mask, &sel_style, opa); } } @@ -256,7 +282,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st /*Align to middle*/ if(flag & LV_TXT_FLAG_CENTER) { line_width = - lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag); + lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag); pos.x += (lv_area_get_width(coords) - line_width) / 2; @@ -264,7 +290,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st /*Align to the right*/ else if(flag & LV_TXT_FLAG_RIGHT) { line_width = - lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag); + lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag); pos.x += lv_area_get_width(coords) - line_width; } @@ -684,13 +710,13 @@ static uint8_t hex_char_to_num(char hex) if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/ switch(hex) { - case 'A': result = 10; break; - case 'B': result = 11; break; - case 'C': result = 12; break; - case 'D': result = 13; break; - case 'E': result = 14; break; - case 'F': result = 15; break; - default: result = 0; break; + case 'A': result = 10; break; + case 'B': result = 11; break; + case 'C': result = 12; break; + case 'D': result = 13; break; + case 'E': result = 14; break; + case 'F': result = 15; break; + default: result = 0; break; } } diff --git a/src/lv_draw/lv_draw_label.h b/src/lv_draw/lv_draw_label.h index d1a77948e..6dc4d6464 100644 --- a/src/lv_draw/lv_draw_label.h +++ b/src/lv_draw/lv_draw_label.h @@ -14,6 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "lv_draw.h" +#include "../lv_misc/lv_bidi.h" /********************* * DEFINES @@ -62,10 +63,11 @@ typedef struct { * @param flag settings for the text from 'txt_flag_t' enum * @param offset text offset in x and y direction (NULL if unused) * @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none) + * @param bidi_dir base direction of the text */ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale, const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel, - lv_draw_label_hint_t * hint); + lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir); /********************** * MACROS diff --git a/src/lv_font/lv_font_heb_16.c b/src/lv_font/lv_font_heb_16.c new file mode 100644 index 000000000..b7723192e --- /dev/null +++ b/src/lv_font/lv_font_heb_16.c @@ -0,0 +1,1133 @@ +#include "../../lvgl.h" + +/******************************************************************************* + * Size: 16 px + * Bpp: 4 + * Opts: --font /usr/share/fonts/truetype/culmus/FrankRuehlCLM-Medium.ttf -r 0x20-0x7F -r 0x5d0-0x5ea --size 16 --format lvgl --bpp 4 --no-compress -o /home/amirgon/esp/projects/lv_mpy/lib/lv_bindings/lvgl/src/lv_font/lv_font_heb_16.c + ******************************************************************************/ + +#ifndef LV_FONT_HEB_16 +#define LV_FONT_HEB_16 1 +#endif + +#if LV_FONT_HEB_16 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { + /* U+20 " " */ + + /* U+21 "!" */ + 0xab, 0xef, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x1, + 0x46, 0xde, 0x57, + + /* U+22 "\"" */ + 0xa, 0xc3, 0xe4, 0xf, 0x87, 0xf1, 0x1f, 0x18, + 0x90, 0x2a, 0x9, 0x20, 0x12, 0x3, 0x0, + + /* U+23 "#" */ + 0x0, 0x69, 0xc, 0x20, 0x0, 0x86, 0xe, 0x0, + 0x0, 0xa4, 0xe, 0x0, 0x3f, 0xff, 0xff, 0xf2, + 0x0, 0xe0, 0x4a, 0x0, 0x0, 0xe0, 0x68, 0x0, + 0x8f, 0xff, 0xff, 0xc0, 0x4, 0xa0, 0xa4, 0x0, + 0x6, 0x80, 0xd2, 0x0, 0x9, 0x60, 0xf0, 0x0, + + /* U+24 "$" */ + 0x0, 0xc, 0x10, 0x0, 0x1, 0xd4, 0x0, 0x6, + 0xce, 0xab, 0x1, 0xe0, 0xc4, 0xf5, 0x3e, 0xc, + 0x4f, 0x31, 0xfb, 0xd1, 0x0, 0x5, 0xff, 0xd5, + 0x0, 0x2, 0xde, 0xf6, 0x6, 0x1c, 0x1a, 0xb5, + 0xf6, 0xc1, 0x5b, 0x3f, 0x1c, 0x1a, 0x60, 0x6d, + 0xfc, 0x80, 0x0, 0xc, 0x10, 0x0, 0x0, 0x60, + 0x0, + + /* U+25 "%" */ + 0x0, 0x8e, 0x60, 0x3, 0x90, 0x0, 0x8f, 0x49, + 0x11, 0xc2, 0x0, 0x1f, 0x80, 0x7c, 0xa9, 0x0, + 0x5, 0xf1, 0xc, 0x15, 0x10, 0x0, 0x4f, 0x6, + 0x90, 0x80, 0x0, 0x0, 0xac, 0x80, 0x71, 0x2b, + 0xc3, 0x0, 0x0, 0x18, 0xe, 0x91, 0xa0, 0x0, + 0x9, 0x17, 0xf1, 0xa, 0x0, 0x2, 0x90, 0xc9, + 0x3, 0x60, 0x0, 0xa1, 0xc, 0x70, 0xa0, 0x0, + 0x39, 0x0, 0x4e, 0xc3, 0x0, + + /* U+26 "&" */ + 0x0, 0x9, 0xab, 0x20, 0x0, 0x0, 0x5, 0xc0, + 0x5b, 0x0, 0x0, 0x0, 0x8c, 0x5, 0xc0, 0x0, + 0x0, 0x7, 0xf2, 0xc6, 0x0, 0x0, 0x0, 0x3f, + 0xf7, 0x0, 0x0, 0x0, 0x8, 0xdc, 0x7, 0xcd, + 0xb0, 0xb, 0x54, 0xf5, 0x7, 0xa0, 0x3, 0xf2, + 0xb, 0xe0, 0xa1, 0x0, 0x4f, 0x60, 0x2f, 0xc6, + 0x2, 0x20, 0xee, 0x30, 0x9f, 0xa3, 0xb1, 0x3, + 0xcf, 0xc6, 0x6e, 0xe5, 0x0, + + /* U+27 "'" */ + 0xa, 0xc0, 0xf8, 0x1f, 0x12, 0xa0, 0x12, 0x0, + + /* U+28 "(" */ + 0x0, 0x6, 0x0, 0xa6, 0x6, 0xc0, 0xe, 0x60, + 0x4f, 0x30, 0x6f, 0x10, 0x7f, 0x0, 0x7f, 0x10, + 0x4f, 0x20, 0xe, 0x60, 0x7, 0xb0, 0x0, 0xb4, + 0x0, 0x7, + + /* U+29 ")" */ + 0x24, 0x0, 0x0, 0xb5, 0x0, 0x2, 0xf1, 0x0, + 0xc, 0x80, 0x0, 0x8e, 0x0, 0x7, 0xf1, 0x0, + 0x6f, 0x20, 0x7, 0xf1, 0x0, 0x8e, 0x0, 0xb, + 0x90, 0x1, 0xf2, 0x0, 0xa6, 0x0, 0x25, 0x0, + 0x0, + + /* U+2A "*" */ + 0x0, 0xb, 0x0, 0x0, 0x50, 0xb0, 0x50, 0x1c, + 0x77, 0x7b, 0x0, 0x6, 0xf4, 0x0, 0x1d, 0x57, + 0x7d, 0x0, 0x30, 0xc0, 0x40, 0x0, 0x9, 0x0, + 0x0, + + /* U+2B "+" */ + 0x0, 0x4, 0x40, 0x0, 0x0, 0x8, 0x90, 0x0, + 0x0, 0x8, 0x90, 0x0, 0x0, 0x8, 0x90, 0x0, + 0x4f, 0xff, 0xff, 0xf6, 0x2, 0x29, 0xa2, 0x21, + 0x0, 0x8, 0x90, 0x0, 0x0, 0x8, 0x90, 0x0, + + /* U+2C "," */ + 0x3b, 0xa, 0xf4, 0x4c, 0x6, 0x40, 0x10, 0x0, + + /* U+2D "-" */ + 0x19, 0x99, 0x90, 0x5f, 0xff, 0xd0, + + /* U+2E "." */ + 0x18, 0xa, 0xf3, 0x3b, 0x0, + + /* U+2F "/" */ + 0x0, 0x0, 0xe1, 0x0, 0x3, 0xb0, 0x0, 0x8, + 0x60, 0x0, 0xe, 0x10, 0x0, 0x3c, 0x0, 0x0, + 0x87, 0x0, 0x0, 0xd2, 0x0, 0x2, 0xc0, 0x0, + 0x8, 0x70, 0x0, 0xd, 0x20, 0x0, 0x2d, 0x0, + 0x0, + + /* U+30 "0" */ + 0x0, 0x8d, 0xd4, 0x0, 0x7, 0xd0, 0x4f, 0x20, + 0xe, 0x70, 0xe, 0x80, 0x3f, 0x50, 0xb, 0xd0, + 0x6f, 0x40, 0xb, 0xf0, 0x7f, 0x40, 0xb, 0xf0, + 0x6f, 0x40, 0xb, 0xf0, 0x4f, 0x50, 0xc, 0xd0, + 0xe, 0x70, 0xe, 0x80, 0x7, 0xd0, 0x4f, 0x20, + 0x0, 0x9d, 0xd4, 0x0, + + /* U+31 "1" */ + 0x0, 0xd, 0x0, 0x1, 0xbf, 0x0, 0x6d, 0xff, + 0x0, 0x0, 0xbf, 0x0, 0x0, 0xbf, 0x0, 0x0, + 0xbf, 0x0, 0x0, 0xbf, 0x0, 0x0, 0xbf, 0x0, + 0x0, 0xbf, 0x0, 0x0, 0xbf, 0x0, 0x6c, 0xff, + 0xd8, + + /* U+32 "2" */ + 0x1, 0xac, 0xd8, 0x0, 0xc2, 0x4, 0xf7, 0x2e, + 0x20, 0xe, 0xc2, 0xfc, 0x0, 0xfd, 0x7, 0x50, + 0x3f, 0x90, 0x0, 0xb, 0xe2, 0x0, 0x7, 0xf3, + 0x0, 0x3, 0xe3, 0x2, 0x1, 0xe3, 0x0, 0xb0, + 0xbd, 0xaa, 0xbd, 0x5f, 0xff, 0xff, 0xb0, + + /* U+33 "3" */ + 0x1, 0xac, 0xd8, 0x0, 0xb6, 0x4, 0xf6, 0xf, + 0xb0, 0xf, 0xa0, 0x96, 0x0, 0xf8, 0x0, 0x0, + 0x6c, 0x10, 0x7, 0xef, 0x90, 0x0, 0x0, 0x4f, + 0x91, 0x83, 0x0, 0xde, 0x6f, 0x70, 0xd, 0xd3, + 0xe0, 0x3, 0xf7, 0x5, 0xcc, 0xd7, 0x0, + + /* U+34 "4" */ + 0x0, 0x0, 0x4b, 0x0, 0x0, 0x0, 0xdb, 0x0, + 0x0, 0x6, 0xfb, 0x0, 0x0, 0xd, 0xfb, 0x0, + 0x0, 0x87, 0xfb, 0x0, 0x1, 0xd0, 0xfb, 0x0, + 0xa, 0x50, 0xfb, 0x0, 0x3c, 0x0, 0xfb, 0x0, + 0x7d, 0xdd, 0xff, 0xd1, 0x0, 0x0, 0xfb, 0x0, + 0x0, 0x1c, 0xff, 0x90, + + /* U+35 "5" */ + 0x6, 0x82, 0x5, 0x50, 0x8f, 0xff, 0xe1, 0x9, + 0xab, 0x92, 0x0, 0xa2, 0x0, 0x0, 0xc, 0xce, + 0xd7, 0x0, 0xc2, 0x6, 0xf6, 0x0, 0x0, 0xe, + 0xc1, 0xa4, 0x0, 0xde, 0x6f, 0x80, 0xe, 0xb2, + 0xf0, 0x5, 0xf4, 0x5, 0xcc, 0xc5, 0x0, + + /* U+36 "6" */ + 0x0, 0x3c, 0xcd, 0x30, 0x3, 0xf4, 0xf, 0xc0, + 0xb, 0xa0, 0xb, 0x80, 0x1f, 0x60, 0x0, 0x0, + 0x5f, 0x6b, 0xd9, 0x0, 0x7f, 0xe4, 0x5f, 0x90, + 0x6f, 0x80, 0xb, 0xf0, 0x5f, 0x60, 0xa, 0xf1, + 0x1f, 0x70, 0xb, 0xe0, 0x9, 0xd0, 0x1f, 0x60, + 0x0, 0x9d, 0xd8, 0x0, + + /* U+37 "7" */ + 0x0, 0x0, 0x0, 0x0, 0xef, 0xff, 0xfd, 0xf, + 0xaa, 0xad, 0x82, 0xa0, 0x0, 0xc2, 0x25, 0x0, + 0x3c, 0x0, 0x0, 0xa, 0x60, 0x0, 0x1, 0xf1, + 0x0, 0x0, 0x7d, 0x0, 0x0, 0xd, 0xb0, 0x0, + 0x1, 0xfa, 0x0, 0x0, 0x4f, 0xa0, 0x0, 0x2, + 0xe6, 0x0, + + /* U+38 "8" */ + 0x1, 0x9c, 0xd8, 0x0, 0xa, 0x80, 0xd, 0x60, + 0xf, 0x40, 0x9, 0xa0, 0xf, 0xb0, 0xc, 0x60, + 0x8, 0xfe, 0xb9, 0x0, 0x0, 0xdf, 0xfe, 0x30, + 0xd, 0x70, 0x6f, 0xc0, 0x5f, 0x0, 0x6, 0xf0, + 0x7e, 0x0, 0x5, 0xe0, 0x2f, 0x40, 0xb, 0x80, + 0x4, 0xcc, 0xc8, 0x0, + + /* U+39 "9" */ + 0x1, 0xbd, 0xd5, 0x0, 0xc, 0xa0, 0x4f, 0x30, + 0x4f, 0x50, 0xe, 0xa0, 0x7f, 0x30, 0xc, 0xe0, + 0x6f, 0x40, 0xd, 0xf0, 0x2f, 0xa0, 0x5f, 0xf0, + 0x5, 0xef, 0xbc, 0xf0, 0x0, 0x0, 0xd, 0xb0, + 0x9, 0x40, 0x1f, 0x60, 0x3f, 0x90, 0x9c, 0x0, + 0x8, 0xdc, 0x91, 0x0, + + /* U+3A ":" */ + 0x3b, 0xa, 0xf3, 0x18, 0x0, 0x0, 0x0, 0x1, + 0x80, 0xaf, 0x33, 0xb0, + + /* U+3B ";" */ + 0x18, 0xa, 0xf3, 0x3b, 0x0, 0x0, 0x0, 0x0, + 0x40, 0x8f, 0x26, 0xf1, 0x48, 0x5, 0x10, + + /* U+3C "<" */ + 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x2a, 0xf5, + 0x0, 0x2a, 0xf9, 0x10, 0x1a, 0xfa, 0x20, 0x0, + 0x5f, 0xa0, 0x0, 0x0, 0x4, 0xce, 0x70, 0x0, + 0x0, 0x4, 0xce, 0x70, 0x0, 0x0, 0x4, 0xc6, + 0x0, 0x0, 0x0, 0x0, + + /* U+3D "=" */ + 0x4f, 0xff, 0xff, 0xf6, 0x2, 0x22, 0x22, 0x21, + 0x0, 0x0, 0x0, 0x0, 0x5f, 0xff, 0xff, 0xf6, + 0x2, 0x22, 0x22, 0x21, + + /* U+3E ">" */ + 0x33, 0x0, 0x0, 0x0, 0x4f, 0xb3, 0x0, 0x0, + 0x1, 0x9f, 0xb3, 0x0, 0x0, 0x1, 0x9f, 0xb2, + 0x0, 0x0, 0x9, 0xf6, 0x0, 0x7, 0xed, 0x50, + 0x6, 0xed, 0x50, 0x0, 0x5d, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+3F "?" */ + 0x7, 0xce, 0xc2, 0x5, 0xf5, 0xe, 0xe0, 0x6f, + 0x60, 0xbf, 0x10, 0x20, 0xe, 0xe0, 0x0, 0x7, + 0xf3, 0x0, 0x1, 0xe3, 0x0, 0x0, 0x48, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x55, 0x0, 0x0, + 0xd, 0xd0, 0x0, 0x0, 0x66, 0x0, 0x0, + + /* U+40 "@" */ + 0x0, 0x19, 0xbb, 0xb3, 0x0, 0x1, 0xc3, 0x0, + 0x1a, 0x40, 0xa, 0x20, 0x0, 0x0, 0xd0, 0x1a, + 0x1, 0xa7, 0x84, 0x74, 0x56, 0xe, 0x54, 0xf2, + 0x56, 0x65, 0x7e, 0x4, 0xe0, 0x64, 0x56, 0x9a, + 0x8, 0xb0, 0xa0, 0x2a, 0x8a, 0xd, 0x74, 0x60, + 0xa, 0x39, 0x84, 0xa5, 0x91, 0x1, 0xc3, 0x0, + 0x9, 0x60, 0x0, 0x19, 0xcb, 0xb4, 0x0, + + /* U+41 "A" */ + 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x1, + 0xf9, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xe0, 0x0, + 0x0, 0x0, 0xc, 0xaf, 0x50, 0x0, 0x0, 0x1, + 0xd1, 0xfa, 0x0, 0x0, 0x0, 0x77, 0xb, 0xf1, + 0x0, 0x0, 0xc, 0x20, 0x5f, 0x60, 0x0, 0x2, + 0xfc, 0xcc, 0xfc, 0x0, 0x0, 0x86, 0x0, 0x9, + 0xf2, 0x0, 0xe, 0x20, 0x0, 0x2f, 0x80, 0x1d, + 0xfd, 0x40, 0x4c, 0xff, 0x80, + + /* U+42 "B" */ + 0x6d, 0xfe, 0xbc, 0xd5, 0x0, 0x2f, 0x50, 0x8, + 0xf1, 0x2, 0xf5, 0x0, 0x3f, 0x60, 0x2f, 0x50, + 0x3, 0xf4, 0x2, 0xf5, 0x0, 0xac, 0x0, 0x2f, + 0xcb, 0xed, 0x20, 0x2, 0xf5, 0x0, 0x5f, 0x50, + 0x2f, 0x50, 0x0, 0xdd, 0x2, 0xf5, 0x0, 0xb, + 0xd0, 0x2f, 0x50, 0x2, 0xf8, 0x6d, 0xfd, 0xbb, + 0xc7, 0x0, + + /* U+43 "C" */ + 0x0, 0x19, 0xba, 0xa5, 0x80, 0x1d, 0x60, 0x3, + 0xf9, 0x9, 0xd0, 0x0, 0x7, 0xa1, 0xf8, 0x0, + 0x0, 0x1a, 0x4f, 0x60, 0x0, 0x0, 0x26, 0xf5, + 0x0, 0x0, 0x0, 0x5f, 0x60, 0x0, 0x0, 0x2, + 0xf8, 0x0, 0x0, 0x9, 0xc, 0xc0, 0x0, 0x2, + 0x80, 0x2e, 0x50, 0x0, 0xb1, 0x0, 0x2a, 0xba, + 0xa2, 0x0, + + /* U+44 "D" */ + 0x6d, 0xfd, 0xab, 0xc6, 0x0, 0x2, 0xf5, 0x0, + 0x2e, 0x80, 0x2, 0xf5, 0x0, 0x7, 0xf2, 0x2, + 0xf5, 0x0, 0x2, 0xf8, 0x2, 0xf5, 0x0, 0x0, + 0xfa, 0x2, 0xf5, 0x0, 0x0, 0xfb, 0x2, 0xf5, + 0x0, 0x0, 0xfa, 0x2, 0xf5, 0x0, 0x2, 0xf7, + 0x2, 0xf5, 0x0, 0x6, 0xf2, 0x2, 0xf5, 0x0, + 0x1e, 0x80, 0x6d, 0xfd, 0xaa, 0xb5, 0x0, + + /* U+45 "E" */ + 0x6d, 0xfd, 0xbb, 0xef, 0x60, 0x2f, 0x50, 0x1, + 0xc7, 0x2, 0xf5, 0x0, 0x5, 0x80, 0x2f, 0x50, + 0x71, 0x19, 0x2, 0xf5, 0x1d, 0x20, 0x10, 0x2f, + 0xce, 0xf2, 0x0, 0x2, 0xf5, 0xd, 0x20, 0x0, + 0x2f, 0x50, 0x92, 0x9, 0x2, 0xf5, 0x0, 0x1, + 0xb0, 0x2f, 0x50, 0x0, 0xaa, 0x6d, 0xfd, 0xbb, + 0xef, 0x90, + + /* U+46 "F" */ + 0x6d, 0xfd, 0xbb, 0xff, 0x50, 0x2f, 0x50, 0x1, + 0xd6, 0x2, 0xf5, 0x0, 0x6, 0x60, 0x2f, 0x50, + 0x71, 0x37, 0x2, 0xf5, 0x1d, 0x20, 0x10, 0x2f, + 0xce, 0xf2, 0x0, 0x2, 0xf5, 0xd, 0x20, 0x0, + 0x2f, 0x50, 0x92, 0x0, 0x2, 0xf5, 0x0, 0x0, + 0x0, 0x2f, 0x50, 0x0, 0x0, 0x6d, 0xfd, 0xa0, + 0x0, 0x0, + + /* U+47 "G" */ + 0x0, 0x19, 0xbb, 0xb4, 0xa0, 0x0, 0x1d, 0x60, + 0x2, 0xeb, 0x0, 0xa, 0xc0, 0x0, 0x5, 0xc0, + 0x1, 0xf8, 0x0, 0x0, 0xb, 0x0, 0x5f, 0x50, + 0x0, 0x0, 0x0, 0x6, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x6f, 0x50, 0x0, 0xad, 0xdb, 0x33, 0xf7, + 0x0, 0x0, 0x8e, 0x0, 0xc, 0xc0, 0x0, 0x9, + 0xe0, 0x0, 0x2e, 0x60, 0x1, 0xde, 0x0, 0x0, + 0x2a, 0xba, 0xa2, 0xb0, 0x0, + + /* U+48 "H" */ + 0x6d, 0xfd, 0x80, 0x6d, 0xfd, 0x70, 0x2f, 0x50, + 0x0, 0x3f, 0x40, 0x2, 0xf5, 0x0, 0x3, 0xf4, + 0x0, 0x2f, 0x50, 0x0, 0x3f, 0x40, 0x2, 0xf5, + 0x0, 0x3, 0xf4, 0x0, 0x2f, 0xdc, 0xcc, 0xdf, + 0x40, 0x2, 0xf5, 0x0, 0x3, 0xf4, 0x0, 0x2f, + 0x50, 0x0, 0x3f, 0x40, 0x2, 0xf5, 0x0, 0x3, + 0xf4, 0x0, 0x2f, 0x50, 0x0, 0x3f, 0x40, 0x6d, + 0xfd, 0x80, 0x7d, 0xfd, 0x70, + + /* U+49 "I" */ + 0x5c, 0xfe, 0xa0, 0xf, 0x70, 0x0, 0xf7, 0x0, + 0xf, 0x70, 0x0, 0xf7, 0x0, 0xf, 0x70, 0x0, + 0xf7, 0x0, 0xf, 0x70, 0x0, 0xf7, 0x0, 0xf, + 0x70, 0x5c, 0xfe, 0xa0, + + /* U+4A "J" */ + 0x0, 0x2b, 0xff, 0xb1, 0x0, 0x0, 0xcb, 0x0, + 0x0, 0x0, 0xcb, 0x0, 0x0, 0x0, 0xcb, 0x0, + 0x0, 0x0, 0xcb, 0x0, 0x0, 0x0, 0xcb, 0x0, + 0x0, 0x0, 0xcb, 0x0, 0x9f, 0x40, 0xca, 0x0, + 0xef, 0x30, 0xd9, 0x0, 0xa1, 0x3, 0xf4, 0x0, + 0x2a, 0xad, 0x70, 0x0, + + /* U+4B "K" */ + 0x6d, 0xfd, 0x80, 0xbf, 0xfc, 0x10, 0x2f, 0x50, + 0x0, 0xd5, 0x0, 0x2, 0xf5, 0x0, 0x96, 0x0, + 0x0, 0x2f, 0x50, 0x78, 0x0, 0x0, 0x2, 0xf5, + 0x5f, 0x20, 0x0, 0x0, 0x2f, 0x9c, 0xfb, 0x0, + 0x0, 0x2, 0xfd, 0x17, 0xf4, 0x0, 0x0, 0x2f, + 0x50, 0xd, 0xd0, 0x0, 0x2, 0xf5, 0x0, 0x4f, + 0x80, 0x0, 0x2f, 0x50, 0x0, 0xbf, 0x20, 0x6d, + 0xfd, 0x80, 0x9e, 0xfe, 0x70, + + /* U+4C "L" */ + 0x5c, 0xfe, 0x90, 0x0, 0x0, 0x1f, 0x60, 0x0, + 0x0, 0x1, 0xf6, 0x0, 0x0, 0x0, 0x1f, 0x60, + 0x0, 0x0, 0x1, 0xf6, 0x0, 0x0, 0x0, 0x1f, + 0x60, 0x0, 0x0, 0x1, 0xf6, 0x0, 0x0, 0x10, + 0x1f, 0x60, 0x0, 0x19, 0x1, 0xf6, 0x0, 0x5, + 0x70, 0x1f, 0x60, 0x1, 0xd6, 0x5c, 0xfe, 0xbb, + 0xff, 0x50, + + /* U+4D "M" */ + 0x6d, 0xff, 0x0, 0x0, 0x5f, 0xfb, 0x10, 0x2d, + 0xf4, 0x0, 0x9, 0xdb, 0x0, 0x2, 0x9e, 0x90, + 0x0, 0xbc, 0xb0, 0x0, 0x29, 0xae, 0x0, 0x37, + 0xcb, 0x0, 0x2, 0x95, 0xf3, 0x8, 0x2c, 0xb0, + 0x0, 0x29, 0xf, 0x80, 0xb0, 0xcb, 0x0, 0x2, + 0x90, 0xbd, 0x19, 0xc, 0xb0, 0x0, 0x29, 0x5, + 0xf9, 0x40, 0xcb, 0x0, 0x2, 0x90, 0x1f, 0xf0, + 0xc, 0xb0, 0x0, 0x5c, 0x0, 0xbb, 0x0, 0xcb, + 0x0, 0x8f, 0xfc, 0x16, 0x62, 0xbf, 0xfb, 0x10, + + /* U+4E "N" */ + 0x8e, 0xf5, 0x0, 0x2d, 0xff, 0x70, 0x3f, 0xe1, + 0x0, 0xe, 0x30, 0x3, 0xbf, 0xa0, 0x0, 0xb1, + 0x0, 0x38, 0x7f, 0x40, 0xb, 0x0, 0x3, 0x80, + 0xce, 0x0, 0xb0, 0x0, 0x38, 0x2, 0xf9, 0xb, + 0x0, 0x3, 0x80, 0x8, 0xf4, 0xb0, 0x0, 0x38, + 0x0, 0xd, 0xdb, 0x0, 0x3, 0x80, 0x0, 0x3f, + 0xf0, 0x0, 0x6b, 0x0, 0x0, 0x8f, 0x0, 0x8f, + 0xfd, 0x0, 0x0, 0xd0, 0x0, + + /* U+4F "O" */ + 0x0, 0x1a, 0xbb, 0xb4, 0x0, 0x1, 0xe6, 0x0, + 0x2e, 0x50, 0xa, 0xd0, 0x0, 0x7, 0xf1, 0x1f, + 0x80, 0x0, 0x2, 0xf7, 0x4f, 0x60, 0x0, 0x0, + 0xfa, 0x6f, 0x50, 0x0, 0x0, 0xfb, 0x5f, 0x60, + 0x0, 0x0, 0xfa, 0x1f, 0x80, 0x0, 0x2, 0xf7, + 0xb, 0xd0, 0x0, 0x7, 0xf1, 0x1, 0xe6, 0x0, + 0x2e, 0x50, 0x0, 0x1a, 0xbb, 0xb4, 0x0, + + /* U+50 "P" */ + 0x6d, 0xfd, 0xbb, 0xc6, 0x0, 0x3f, 0x50, 0x5, + 0xf4, 0x3, 0xf5, 0x0, 0xf, 0x90, 0x3f, 0x50, + 0x1, 0xf9, 0x3, 0xf5, 0x0, 0x8f, 0x30, 0x3f, + 0xca, 0xba, 0x30, 0x3, 0xf5, 0x0, 0x0, 0x0, + 0x3f, 0x50, 0x0, 0x0, 0x3, 0xf5, 0x0, 0x0, + 0x0, 0x3f, 0x50, 0x0, 0x0, 0x6d, 0xfd, 0x90, + 0x0, 0x0, + + /* U+51 "Q" */ + 0x0, 0x19, 0xbb, 0xb4, 0x0, 0x1, 0xd6, 0x0, + 0x2e, 0x50, 0x9, 0xd0, 0x0, 0x6, 0xf1, 0x1f, + 0x90, 0x0, 0x2, 0xf7, 0x4f, 0x70, 0x0, 0x0, + 0xfb, 0x6f, 0x60, 0x0, 0x0, 0xfc, 0x5f, 0x60, + 0x0, 0x0, 0xfa, 0x1f, 0x82, 0xab, 0x31, 0xf6, + 0xa, 0xca, 0x1, 0xd7, 0xe0, 0x1, 0xdd, 0x0, + 0xaf, 0x40, 0x0, 0x19, 0xba, 0xec, 0x0, 0x0, + 0x0, 0x0, 0x7f, 0x18, 0x0, 0x0, 0x0, 0x4f, + 0x8a, 0x0, 0x0, 0x0, 0xa, 0xe4, + + /* U+52 "R" */ + 0x7d, 0xfd, 0xbb, 0xc4, 0x0, 0x3, 0xf4, 0x0, + 0x7f, 0x20, 0x3, 0xf4, 0x0, 0x3f, 0x60, 0x3, + 0xf4, 0x0, 0x3f, 0x50, 0x3, 0xf4, 0x0, 0xad, + 0x0, 0x3, 0xfc, 0xce, 0x70, 0x0, 0x3, 0xf4, + 0x7, 0xd0, 0x0, 0x3, 0xf4, 0x0, 0xf6, 0x0, + 0x3, 0xf4, 0x0, 0xea, 0x3, 0x3, 0xf4, 0x0, + 0xbe, 0x55, 0x7d, 0xfd, 0x70, 0x4e, 0xc1, + + /* U+53 "S" */ + 0x1, 0xab, 0xa8, 0x84, 0xb, 0x40, 0x5, 0xf5, + 0xf, 0x0, 0x0, 0xa6, 0xf, 0x70, 0x0, 0x35, + 0xb, 0xfd, 0x84, 0x0, 0x0, 0x9e, 0xff, 0xd1, + 0x11, 0x0, 0x38, 0xf9, 0x47, 0x0, 0x0, 0x6c, + 0x4d, 0x0, 0x0, 0x3b, 0x4f, 0x90, 0x0, 0x96, + 0x48, 0x6b, 0xab, 0x70, + + /* U+54 "T" */ + 0x9f, 0xdd, 0xfd, 0xdf, 0x79, 0xa0, 0x4f, 0x30, + 0xb8, 0xa2, 0x4, 0xf3, 0x4, 0x8a, 0x0, 0x4f, + 0x30, 0x9, 0x20, 0x4, 0xf3, 0x0, 0x20, 0x0, + 0x4f, 0x30, 0x0, 0x0, 0x4, 0xf3, 0x0, 0x0, + 0x0, 0x4f, 0x30, 0x0, 0x0, 0x4, 0xf3, 0x0, + 0x0, 0x0, 0x4f, 0x30, 0x0, 0x0, 0x9d, 0xfd, + 0x80, 0x0, + + /* U+55 "U" */ + 0x8d, 0xfc, 0x60, 0x1d, 0xff, 0x70, 0x5f, 0x20, + 0x0, 0xc, 0x40, 0x5, 0xf2, 0x0, 0x0, 0xa2, + 0x0, 0x5f, 0x20, 0x0, 0x9, 0x10, 0x5, 0xf2, + 0x0, 0x0, 0x91, 0x0, 0x5f, 0x20, 0x0, 0x9, + 0x10, 0x5, 0xf2, 0x0, 0x0, 0x91, 0x0, 0x5f, + 0x20, 0x0, 0xa, 0x0, 0x4, 0xf4, 0x0, 0x0, + 0xb0, 0x0, 0xd, 0xd1, 0x0, 0x86, 0x0, 0x0, + 0x1a, 0xec, 0xc6, 0x0, 0x0, + + /* U+56 "V" */ + 0x1c, 0xff, 0xb0, 0xa, 0xff, 0x80, 0xd, 0xd0, + 0x0, 0x9, 0x70, 0x0, 0x7f, 0x20, 0x0, 0xc0, + 0x0, 0x1, 0xf8, 0x0, 0x2a, 0x0, 0x0, 0xc, + 0xe0, 0x7, 0x50, 0x0, 0x0, 0x6f, 0x30, 0xc0, + 0x0, 0x0, 0x1, 0xf9, 0x2a, 0x0, 0x0, 0x0, + 0xa, 0xe8, 0x40, 0x0, 0x0, 0x0, 0x5f, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0xf9, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x40, 0x0, 0x0, + + /* U+57 "W" */ + 0xaf, 0xe9, 0x3d, 0xfd, 0x62, 0xdf, 0xd0, 0xc, + 0xc0, 0x1, 0xf7, 0x0, 0xd, 0x0, 0x7, 0xf1, + 0x0, 0xec, 0x0, 0x38, 0x0, 0x3, 0xf5, 0x2, + 0xff, 0x0, 0x74, 0x0, 0x0, 0xea, 0x6, 0x7f, + 0x50, 0xb0, 0x0, 0x0, 0x9e, 0xa, 0x1e, 0x90, + 0xb0, 0x0, 0x0, 0x5f, 0x4b, 0x9, 0xd4, 0x70, + 0x0, 0x0, 0xf, 0xc8, 0x4, 0xfb, 0x30, 0x0, + 0x0, 0xb, 0xf4, 0x0, 0xfe, 0x0, 0x0, 0x0, + 0x6, 0xf0, 0x0, 0xba, 0x0, 0x0, 0x0, 0x2, + 0xb0, 0x0, 0x66, 0x0, 0x0, + + /* U+58 "X" */ + 0xb, 0xff, 0xb0, 0x7f, 0xfb, 0x0, 0x9, 0xf3, + 0x0, 0xa6, 0x0, 0x0, 0x1e, 0xc0, 0x2b, 0x0, + 0x0, 0x0, 0x6f, 0x6b, 0x10, 0x0, 0x0, 0x0, + 0xcf, 0x70, 0x0, 0x0, 0x0, 0x4, 0xf8, 0x0, + 0x0, 0x0, 0x0, 0xab, 0xf2, 0x0, 0x0, 0x0, + 0x49, 0x1e, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x6f, + 0x50, 0x0, 0x9, 0x90, 0x0, 0xce, 0x10, 0xd, + 0xff, 0x80, 0x9e, 0xfd, 0x60, + + /* U+59 "Y" */ + 0x1c, 0xff, 0xb1, 0x3c, 0xfe, 0x50, 0xb, 0xf1, + 0x0, 0xe, 0x10, 0x0, 0x3f, 0x90, 0x5, 0x70, + 0x0, 0x0, 0xaf, 0x20, 0xc0, 0x0, 0x0, 0x2, + 0xfb, 0x68, 0x0, 0x0, 0x0, 0x8, 0xfe, 0x10, + 0x0, 0x0, 0x0, 0x1f, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0xe9, 0x0, 0x0, 0x0, 0x0, 0xe, 0x90, + 0x0, 0x0, 0x0, 0x0, 0xe9, 0x0, 0x0, 0x0, + 0x5, 0xbf, 0xeb, 0x10, 0x0, + + /* U+5A "Z" */ + 0x1f, 0xfc, 0xbc, 0xf8, 0x2f, 0x20, 0xb, 0xf1, + 0x39, 0x0, 0x3f, 0x70, 0x35, 0x0, 0xce, 0x0, + 0x0, 0x5, 0xf5, 0x0, 0x0, 0xe, 0xc0, 0x0, + 0x0, 0x7f, 0x30, 0x2, 0x1, 0xfa, 0x0, 0x1a, + 0x9, 0xf2, 0x0, 0x59, 0x2f, 0x90, 0x0, 0xc8, + 0xaf, 0xbb, 0xbe, 0xf7, + + /* U+5B "[" */ + 0x2f, 0x98, 0x2f, 0x10, 0x2f, 0x10, 0x2f, 0x10, + 0x2f, 0x10, 0x2f, 0x10, 0x2f, 0x10, 0x2f, 0x10, + 0x2f, 0x10, 0x2f, 0x10, 0x2f, 0x10, 0x1c, 0x88, + + /* U+5C "\\" */ + 0xb1, 0x0, 0x0, 0x4, 0x70, 0x0, 0x0, 0xb, + 0x0, 0x0, 0x0, 0x57, 0x0, 0x0, 0x0, 0xb0, + 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, 0xb0, 0x0, + 0x0, 0x6, 0x50, 0x0, 0x0, 0xb, 0x0, + + /* U+5D "]" */ + 0x48, 0xd8, 0x0, 0xa8, 0x0, 0xa8, 0x0, 0xa8, + 0x0, 0xa8, 0x0, 0xa8, 0x0, 0xa8, 0x0, 0xa8, + 0x0, 0xa8, 0x0, 0xa8, 0x0, 0xa8, 0x48, 0xa6, + + /* U+5E "^" */ + 0x0, 0xc, 0xd0, 0x0, 0x0, 0x3e, 0xe4, 0x0, + 0x0, 0xa8, 0x6c, 0x0, 0x2, 0xf1, 0xe, 0x30, + 0x9, 0x90, 0x7, 0xb0, 0x1f, 0x10, 0x0, 0xe2, + + /* U+5F "_" */ + 0xee, 0xee, 0xee, 0x90, + + /* U+60 "`" */ + 0x41, 0x0, 0x7c, 0x0, 0x3, 0x90, + + /* U+61 "a" */ + 0x4, 0xaa, 0xc5, 0x0, 0xf, 0x40, 0x5e, 0x0, + 0x8, 0x20, 0x5f, 0x0, 0x3, 0xa9, 0x9f, 0x0, + 0x2f, 0x30, 0x4f, 0x0, 0x5f, 0x0, 0xaf, 0x10, + 0xb, 0xdb, 0x4c, 0xd1, + + /* U+62 "b" */ + 0xaf, 0x60, 0x0, 0x0, 0xd6, 0x0, 0x0, 0xd, + 0x60, 0x0, 0x0, 0xd6, 0x0, 0x0, 0xd, 0x9a, + 0xd9, 0x0, 0xdc, 0x0, 0xe7, 0xd, 0x70, 0x9, + 0xc0, 0xd5, 0x0, 0x7e, 0xe, 0x60, 0x8, 0xc0, + 0xeb, 0x0, 0xd6, 0xb, 0x5b, 0xb7, 0x0, + + /* U+63 "c" */ + 0x3, 0xca, 0xb1, 0xe, 0x50, 0xe6, 0x6f, 0x0, + 0x82, 0x8e, 0x0, 0x0, 0x6f, 0x0, 0x2, 0x1f, + 0x70, 0x56, 0x4, 0xde, 0x90, + + /* U+64 "d" */ + 0x0, 0x3, 0xbf, 0x50, 0x0, 0x0, 0xf, 0x50, + 0x0, 0x0, 0xf, 0x50, 0x0, 0x0, 0xf, 0x50, + 0x3, 0xdc, 0x7f, 0x50, 0xe, 0x70, 0x7f, 0x50, + 0x4f, 0x10, 0xf, 0x50, 0x6f, 0x0, 0xf, 0x50, + 0x4f, 0x0, 0xf, 0x50, 0xe, 0x50, 0x6f, 0x50, + 0x3, 0xcb, 0x7f, 0xd4, + + /* U+65 "e" */ + 0x3, 0xba, 0xb1, 0x0, 0xe4, 0x7, 0xa0, 0x5f, + 0x0, 0x4f, 0x7, 0xfa, 0xab, 0xd2, 0x6f, 0x0, + 0x0, 0x1, 0xf6, 0x0, 0xa0, 0x3, 0xcc, 0xb3, + 0x0, + + /* U+66 "f" */ + 0x0, 0x7b, 0xc5, 0x3, 0xe0, 0xab, 0x8, 0xb0, + 0x11, 0x9, 0xb0, 0x0, 0x7d, 0xea, 0x10, 0x9, + 0xb0, 0x0, 0x9, 0xb0, 0x0, 0x9, 0xb0, 0x0, + 0x9, 0xb0, 0x0, 0x9, 0xb0, 0x0, 0x5e, 0xe8, + 0x0, + + /* U+67 "g" */ + 0x4, 0xb9, 0xb9, 0xe1, 0xf, 0x20, 0x7a, 0x60, + 0x2f, 0x0, 0x5e, 0x0, 0xe, 0x40, 0x9a, 0x0, + 0x9, 0xc9, 0x81, 0x0, 0x4b, 0x43, 0x31, 0x0, + 0x1d, 0xff, 0xff, 0x20, 0x5b, 0x0, 0xb, 0x60, + 0xa7, 0x0, 0xa, 0x30, 0x2b, 0xa9, 0xa6, 0x0, + + /* U+68 "h" */ + 0x8e, 0xa0, 0x0, 0x0, 0x9, 0xa0, 0x0, 0x0, + 0x9, 0xa0, 0x0, 0x0, 0x9, 0xa0, 0x0, 0x0, + 0x9, 0xa8, 0xed, 0x20, 0x9, 0xe4, 0xb, 0xb0, + 0x9, 0xc0, 0x6, 0xd0, 0x9, 0xa0, 0x6, 0xd0, + 0x9, 0xa0, 0x6, 0xd0, 0x9, 0xa0, 0x6, 0xd0, + 0x5e, 0xe6, 0x4c, 0xf8, + + /* U+69 "i" */ + 0x7, 0xa0, 0x4, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x8e, 0xc0, 0x8, 0xc0, 0x8, 0xc0, 0x8, 0xc0, + 0x8, 0xc0, 0x8, 0xc0, 0x5d, 0xe7, + + /* U+6A "j" */ + 0x0, 0x7, 0xb0, 0x0, 0x46, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9e, 0xc0, 0x0, 0x8c, 0x0, + 0x8, 0xc0, 0x0, 0x8c, 0x0, 0x8, 0xc0, 0x0, + 0x8c, 0x0, 0x8, 0xb0, 0x0, 0x8a, 0xf, 0x3a, + 0x60, 0xbb, 0xa0, + + /* U+6B "k" */ + 0x9e, 0xa0, 0x0, 0x0, 0x9, 0xa0, 0x0, 0x0, + 0x9, 0xa0, 0x0, 0x0, 0x9, 0xa0, 0x0, 0x0, + 0x9, 0xa2, 0xbf, 0xc2, 0x9, 0xa0, 0xa5, 0x0, + 0x9, 0xa8, 0x90, 0x0, 0x9, 0xfb, 0xe1, 0x0, + 0x9, 0xb0, 0xda, 0x0, 0x9, 0xa0, 0x3f, 0x50, + 0x5e, 0xe6, 0x6f, 0xf8, + + /* U+6C "l" */ + 0x8e, 0xb0, 0x8, 0xb0, 0x8, 0xb0, 0x8, 0xb0, + 0x8, 0xb0, 0x8, 0xb0, 0x8, 0xb0, 0x8, 0xb0, + 0x8, 0xb0, 0x8, 0xb0, 0x5d, 0xe7, + + /* U+6D "m" */ + 0x7e, 0xba, 0xec, 0x3b, 0xea, 0x0, 0x9, 0xf3, + 0xd, 0xe2, 0x1e, 0x60, 0x9, 0xc0, 0xa, 0xa0, + 0xc, 0x80, 0x9, 0xb0, 0xa, 0x90, 0xb, 0x80, + 0x9, 0xb0, 0xa, 0x90, 0xb, 0x80, 0x9, 0xb0, + 0xa, 0x90, 0xb, 0x80, 0x5e, 0xe6, 0x6e, 0xd5, + 0x7e, 0xd5, + + /* U+6E "n" */ + 0x7e, 0xb9, 0xed, 0x10, 0x9, 0xf4, 0xb, 0xb0, + 0x9, 0xc0, 0x6, 0xd0, 0x9, 0xa0, 0x6, 0xd0, + 0x9, 0xa0, 0x6, 0xd0, 0x9, 0xa0, 0x6, 0xd0, + 0x5e, 0xe6, 0x4c, 0xf8, + + /* U+6F "o" */ + 0x3, 0xba, 0xa0, 0x0, 0xe3, 0x8, 0xa0, 0x6f, + 0x0, 0x4f, 0x8, 0xe0, 0x3, 0xf2, 0x6f, 0x0, + 0x4f, 0x0, 0xe3, 0x9, 0xa0, 0x3, 0xba, 0xa1, + 0x0, + + /* U+70 "p" */ + 0x7e, 0xba, 0xca, 0x0, 0x9, 0xf3, 0xb, 0xa0, + 0x9, 0xc0, 0x5, 0xf0, 0x9, 0xb0, 0x4, 0xf1, + 0x9, 0xc0, 0x6, 0xf0, 0x9, 0xf2, 0xb, 0x90, + 0x9, 0xba, 0xda, 0x0, 0x9, 0xb0, 0x0, 0x0, + 0x9, 0xb0, 0x0, 0x0, 0x5d, 0xe7, 0x0, 0x0, + + /* U+71 "q" */ + 0x3, 0xca, 0x94, 0x60, 0xe, 0x40, 0x6f, 0x40, + 0x5f, 0x0, 0x1f, 0x40, 0x7e, 0x0, 0xf, 0x40, + 0x6f, 0x0, 0x1f, 0x40, 0x1f, 0x50, 0x7f, 0x40, + 0x4, 0xdc, 0x7f, 0x40, 0x0, 0x0, 0xf, 0x40, + 0x0, 0x0, 0xf, 0x40, 0x0, 0x1, 0x9f, 0xb2, + + /* U+72 "r" */ + 0x8e, 0xa5, 0xb8, 0x9, 0xc4, 0xaa, 0x9, 0xf0, + 0x0, 0x9, 0xc0, 0x0, 0x9, 0xa0, 0x0, 0x9, + 0xa0, 0x0, 0x5e, 0xe7, 0x0, + + /* U+73 "s" */ + 0x8, 0xaa, 0xb3, 0x29, 0x0, 0xb3, 0x2e, 0x73, + 0x31, 0x7, 0xef, 0xe2, 0x34, 0x2, 0xa8, 0x5c, + 0x0, 0x47, 0x59, 0xa9, 0xa1, + + /* U+74 "t" */ + 0x0, 0x90, 0x0, 0x39, 0x0, 0xb, 0x90, 0x7, + 0xed, 0xa5, 0xa, 0x90, 0x0, 0xa9, 0x0, 0xa, + 0x90, 0x0, 0xa9, 0x8, 0x9, 0xb0, 0xa0, 0x3d, + 0xd4, + + /* U+75 "u" */ + 0x8f, 0x90, 0x8e, 0xc0, 0xa, 0x90, 0x8, 0xc0, + 0xa, 0x90, 0x8, 0xc0, 0xa, 0x90, 0x8, 0xc0, + 0xa, 0x90, 0x9, 0xc0, 0x8, 0xb0, 0x1e, 0xc0, + 0x1, 0xcc, 0x99, 0xfb, + + /* U+76 "v" */ + 0x9f, 0xb2, 0x5f, 0xc0, 0xc, 0x80, 0xb, 0x0, + 0x6, 0xe0, 0x28, 0x0, 0x0, 0xf5, 0x82, 0x0, + 0x0, 0x9b, 0xa0, 0x0, 0x0, 0x3f, 0x60, 0x0, + 0x0, 0xc, 0x10, 0x0, + + /* U+77 "w" */ + 0x7f, 0xb2, 0xcf, 0x72, 0xdd, 0x10, 0xc8, 0x3, + 0xf1, 0x9, 0x20, 0x6, 0xd0, 0x8e, 0x70, 0xa0, + 0x0, 0x1f, 0x3a, 0x6c, 0x37, 0x0, 0x0, 0xbc, + 0x71, 0xfb, 0x10, 0x0, 0x6, 0xf1, 0xb, 0xc0, + 0x0, 0x0, 0x1b, 0x0, 0x56, 0x0, 0x0, + + /* U+78 "x" */ + 0x8f, 0xd3, 0xaf, 0x70, 0x9, 0xe1, 0x76, 0x0, + 0x0, 0xdc, 0x90, 0x0, 0x0, 0x4f, 0x50, 0x0, + 0x0, 0xa9, 0xe1, 0x0, 0x7, 0x60, 0xda, 0x0, + 0x9f, 0x92, 0xdf, 0xb0, + + /* U+79 "y" */ + 0x8f, 0xc2, 0x5e, 0xc0, 0xb, 0xa0, 0xb, 0x0, + 0x4, 0xf1, 0x19, 0x0, 0x0, 0xe6, 0x73, 0x0, + 0x0, 0x8d, 0xb0, 0x0, 0x0, 0x2f, 0x80, 0x0, + 0x0, 0xb, 0x20, 0x0, 0x0, 0xa, 0x0, 0x0, + 0xc6, 0x74, 0x0, 0x0, 0xad, 0x70, 0x0, 0x0, + + /* U+7A "z" */ + 0x2f, 0xba, 0xfa, 0x29, 0x6, 0xf2, 0x13, 0x1e, + 0x70, 0x0, 0xad, 0x0, 0x4, 0xf3, 0x6, 0xd, + 0x90, 0x1b, 0x6f, 0xba, 0xeb, + + /* U+7B "{" */ + 0x0, 0x99, 0x0, 0xf0, 0x1, 0xe0, 0x1, 0xe0, + 0x2, 0xd0, 0xb, 0x60, 0x8, 0x90, 0x1, 0xd0, + 0x1, 0xe0, 0x1, 0xe0, 0x0, 0xf0, 0x0, 0x69, + + /* U+7C "|" */ + 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, + 0x79, 0x79, 0x79, + + /* U+7D "}" */ + 0x4c, 0x20, 0x8, 0x70, 0x7, 0x80, 0x7, 0x80, + 0x6, 0x90, 0x1, 0xc4, 0x3, 0xc2, 0x7, 0x80, + 0x7, 0x80, 0x7, 0x80, 0x9, 0x60, 0x49, 0x10, + + /* U+7E "~" */ + 0x8, 0xeb, 0x50, 0x72, 0x1a, 0x15, 0xdf, 0xb0, + 0x0, 0x0, 0x1, 0x0, + + /* U+5D0 "א" */ + 0x5, 0x0, 0x3, 0x0, 0xe, 0x80, 0x3f, 0xd3, + 0x9, 0xf5, 0x1d, 0xf7, 0x0, 0xcf, 0x37, 0x61, + 0x2, 0xde, 0xed, 0x0, 0xb, 0x82, 0xff, 0x0, + 0xd, 0xd0, 0x5f, 0xa0, 0xb, 0xf5, 0x7, 0xf5, + 0x2f, 0xf7, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, + + /* U+5D1 "ב" */ + 0x13, 0x0, 0x0, 0x4, 0xff, 0xff, 0x70, 0x2d, + 0xee, 0xfd, 0x0, 0x0, 0x4, 0xf0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x27, + 0x2, 0xee, 0xef, 0xe7, 0x6f, 0xff, 0xff, 0x40, + + /* U+5D2 "ג" */ + 0x3, 0x0, 0x0, 0xa, 0xff, 0x30, 0x6, 0xef, + 0x60, 0x0, 0x9, 0x50, 0x0, 0x7, 0x40, 0x0, + 0x8, 0x70, 0x0, 0xd, 0xc0, 0x1e, 0xf4, 0xe1, + 0x5f, 0xd0, 0x72, + + /* U+5D3 "ד" */ + 0x22, 0x0, 0x0, 0x8, 0xff, 0xff, 0xfa, 0x4d, + 0xee, 0xef, 0x90, 0x0, 0x0, 0xb0, 0x0, 0x0, + 0x49, 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x5b, + 0x0, 0x0, 0x5, 0xd0, 0x0, 0x0, 0x68, 0x0, + + /* U+5D4 "ה" */ + 0x4, 0x0, 0x0, 0x0, 0x2f, 0xff, 0xff, 0xf0, + 0x1c, 0xee, 0xee, 0xf0, 0x0, 0x0, 0x3, 0x90, + 0x0, 0x0, 0x6, 0x80, 0xd, 0x20, 0x7, 0x90, + 0xf, 0x20, 0x6, 0xb0, 0xf, 0x20, 0x6, 0xc0, + 0x1f, 0x0, 0x7, 0x70, 0x1, 0x0, 0x0, 0x0, + + /* U+5D5 "ו" */ + 0x3, 0x0, 0x4f, 0xf7, 0x2d, 0xfd, 0x0, 0x2d, + 0x0, 0xd, 0x0, 0xd, 0x0, 0xd, 0x0, 0xd, + 0x0, 0x9, + + /* U+5D6 "ז" */ + 0x4, 0x0, 0x3, 0xff, 0xa0, 0x1d, 0xff, 0x0, + 0xa, 0x0, 0x3, 0xb0, 0x0, 0x4c, 0x0, 0x3, + 0xe0, 0x0, 0x3e, 0x0, 0x4, 0x90, 0x0, + + /* U+5D7 "ח" */ + 0x3, 0x0, 0x0, 0x0, 0x4f, 0xff, 0xff, 0xf3, + 0x1d, 0xfe, 0xee, 0xf4, 0x8, 0x60, 0x0, 0xc0, + 0xd, 0x20, 0x2, 0xc0, 0xd, 0x30, 0x2, 0xe0, + 0xe, 0x30, 0x1, 0xf0, 0xe, 0x40, 0x1, 0xf0, + 0xd, 0x0, 0x2, 0xb0, + + /* U+5D8 "ט" */ + 0x3, 0x0, 0x0, 0x0, 0x2f, 0xf3, 0x2e, 0xb0, + 0x1d, 0xf6, 0xdf, 0xf3, 0x5, 0x64, 0xb4, 0xe5, + 0xa, 0x31, 0x0, 0x75, 0xc, 0x40, 0x0, 0x74, + 0xa, 0x80, 0x0, 0xc1, 0x7, 0xfe, 0xee, 0xd0, + 0x5, 0xff, 0xff, 0x70, + + /* U+5D9 "י" */ + 0x3, 0x0, 0x4f, 0xf7, 0x2d, 0xfc, 0x0, 0x4a, + 0x0, 0x84, 0x0, 0x50, + + /* U+5DA "ך" */ + 0x22, 0x0, 0x0, 0x6, 0xff, 0xff, 0xe0, 0x3d, + 0xee, 0xed, 0x0, 0x0, 0x4, 0x60, 0x0, 0x0, + 0x56, 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, 0x67, + 0x0, 0x0, 0x6, 0x80, 0x0, 0x0, 0x69, 0x0, + 0x0, 0x7, 0xa0, 0x0, 0x0, 0x7b, 0x0, 0x0, + 0x8, 0x90, 0x0, 0x0, 0x41, 0x0, + + /* U+5DB "כ" */ + 0x4, 0x0, 0x0, 0x1, 0xff, 0xff, 0x80, 0xc, + 0xee, 0xff, 0x30, 0x0, 0x0, 0xb7, 0x0, 0x0, + 0x3, 0x90, 0x0, 0x0, 0x39, 0x0, 0x0, 0x9, + 0x70, 0xde, 0xee, 0xf2, 0x3f, 0xff, 0xf7, 0x0, + + /* U+5DC "ל" */ + 0x31, 0x0, 0x0, 0x8, 0xf1, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, 0x2a, 0x0, + 0x0, 0x3, 0xff, 0xff, 0xf7, 0x2e, 0xee, 0xef, + 0xa0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x9, 0x80, + 0x0, 0x4, 0xd1, 0x0, 0x8, 0x90, 0x0, 0x5, + 0xb0, 0x0, 0x0, 0x69, 0x0, 0x0, + + /* U+5DD "ם" */ + 0x3, 0x0, 0x0, 0x0, 0xff, 0xff, 0xf8, 0xb, + 0xfe, 0xef, 0xe0, 0xa2, 0x0, 0x1e, 0xc, 0x0, + 0x0, 0xc1, 0xb0, 0x0, 0xc, 0x2c, 0x0, 0x0, + 0xd2, 0xfe, 0xee, 0xee, 0x1f, 0xff, 0xff, 0xc0, + + /* U+5DE "מ" */ + 0x3, 0x0, 0x0, 0x0, 0x2f, 0xd1, 0x8e, 0x40, + 0x1f, 0xf8, 0xff, 0xf0, 0x0, 0xa8, 0x14, 0xe5, + 0x2, 0xb0, 0x0, 0x76, 0x8, 0x60, 0x0, 0x56, + 0xc, 0x20, 0x0, 0x65, 0xe, 0x18, 0xee, 0xf3, + 0xe, 0xd, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, + + /* U+5DF "ן" */ + 0x13, 0x0, 0x5f, 0xf8, 0x2d, 0xfb, 0x0, 0x86, + 0x0, 0xb1, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xe1, + 0x0, 0xe2, 0x0, 0xe2, 0x0, 0xf3, 0x0, 0xf2, + 0x0, 0x50, + + /* U+5E0 "נ" */ + 0x3, 0x10, 0x0, 0x9f, 0xe2, 0x6, 0xef, 0x40, + 0x0, 0xa2, 0x0, 0xb, 0x10, 0x0, 0xb1, 0x0, + 0xb, 0x53, 0xee, 0xf7, 0x7f, 0xff, 0x50, + + /* U+5E1 "ס" */ + 0x3, 0x0, 0x0, 0x0, 0xff, 0xff, 0xa0, 0xc, + 0xfe, 0xef, 0x80, 0xa2, 0x0, 0x5c, 0xb, 0x0, + 0x0, 0xb2, 0xb0, 0x0, 0xc, 0xf, 0x40, 0x7, + 0xb0, 0xcf, 0xff, 0xf6, 0x2, 0xcf, 0xe8, 0x0, + + /* U+5E2 "ע" */ + 0x3, 0x0, 0x21, 0x0, 0x3f, 0xd3, 0x8f, 0xe2, + 0x1e, 0xf7, 0x5f, 0xf3, 0x0, 0xa0, 0x2, 0xb0, + 0x2, 0xd0, 0xa, 0x30, 0x0, 0xd9, 0x2e, 0x0, + 0x0, 0x2d, 0x8a, 0x0, 0x0, 0xb, 0xf6, 0x0, + 0x6, 0xdf, 0xd0, 0x0, 0x5f, 0xf9, 0x10, 0x0, + 0x59, 0x10, 0x0, 0x0, + + /* U+5E3 "ף" */ + 0x4, 0x0, 0x0, 0x1, 0xff, 0xff, 0xd1, 0xc, + 0xfe, 0xef, 0x60, 0x93, 0x0, 0x77, 0xf, 0xfa, + 0x3, 0x81, 0xb5, 0xa0, 0x49, 0x0, 0x0, 0x4, + 0x90, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x5, 0xb0, + 0x0, 0x0, 0x6b, 0x0, 0x0, 0x6, 0xc0, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0x4, 0x20, + + /* U+5E4 "פ" */ + 0x4, 0x0, 0x0, 0x0, 0xff, 0xff, 0xe2, 0xb, + 0xfe, 0xef, 0x90, 0x75, 0x0, 0x4c, 0xe, 0xfb, + 0x0, 0xb0, 0xc5, 0xc0, 0xc, 0x0, 0x0, 0x4, + 0xb0, 0xde, 0xee, 0xf9, 0x3f, 0xff, 0xff, 0x40, + + /* U+5E5 "ץ" */ + 0x13, 0x0, 0x40, 0x5, 0xff, 0x2e, 0xf6, 0x2d, + 0xf4, 0xaf, 0xa0, 0xd, 0x15, 0x91, 0x2, 0xa3, + 0xa0, 0x0, 0x3a, 0xc0, 0x0, 0x2, 0xf7, 0x0, + 0x0, 0x1f, 0x30, 0x0, 0x0, 0xf2, 0x0, 0x0, + 0xe, 0x30, 0x0, 0x0, 0xd4, 0x0, 0x0, 0xd, + 0x40, 0x0, 0x0, 0x60, 0x0, 0x0, + + /* U+5E6 "צ" */ + 0x3, 0x0, 0x30, 0x3, 0xff, 0x3b, 0xf9, 0x1c, + 0xe5, 0x8f, 0xc0, 0x6, 0x54, 0xa0, 0x0, 0x5c, + 0xc0, 0x0, 0x0, 0xcd, 0x50, 0x0, 0x0, 0x7f, + 0x80, 0xde, 0xee, 0xfc, 0x2f, 0xff, 0xff, 0x80, + + /* U+5E7 "ק" */ + 0x4, 0x0, 0x0, 0x0, 0x2f, 0xff, 0xff, 0x90, + 0x1c, 0xee, 0xef, 0xf1, 0x1, 0x0, 0x2, 0xf2, + 0xe, 0x0, 0x0, 0xf1, 0xf, 0x0, 0x9, 0xb0, + 0xf, 0x2, 0xca, 0x10, 0xf, 0x1d, 0x30, 0x0, + 0xf, 0x57, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, + 0xf, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x5, 0x0, 0x0, 0x0, + + /* U+5E8 "ר" */ + 0x3, 0x0, 0x0, 0x4, 0xff, 0xff, 0xd1, 0x2d, + 0xee, 0xef, 0x50, 0x0, 0x0, 0xa6, 0x0, 0x0, + 0x8, 0x60, 0x0, 0x0, 0x86, 0x0, 0x0, 0x8, + 0x60, 0x0, 0x0, 0x86, 0x0, 0x0, 0x7, 0x40, + + /* U+5E9 "ש" */ + 0x2, 0x0, 0x20, 0x1, 0x0, 0x3f, 0xd7, 0xea, + 0x6e, 0x80, 0x2f, 0xf7, 0xef, 0x7f, 0xf0, 0x6, + 0x60, 0x86, 0x1, 0xd0, 0xb, 0x31, 0xe0, 0x9, + 0x50, 0xb, 0x46, 0x90, 0x4b, 0x0, 0x8, 0x9a, + 0x21, 0xe2, 0x0, 0x4, 0xff, 0xef, 0xa0, 0x0, + 0x0, 0xff, 0xff, 0x20, 0x0, + + /* U+5EA "ת" */ + 0x2, 0x10, 0x0, 0x0, 0x8, 0xff, 0xff, 0xd1, + 0x5, 0xef, 0xee, 0xf5, 0x0, 0xb3, 0x0, 0xa6, + 0x3, 0xc0, 0x0, 0x86, 0x4, 0xb0, 0x0, 0x86, + 0x3, 0xd0, 0x0, 0x86, 0x6e, 0xf0, 0x0, 0x86, + 0xaf, 0xb0, 0x0, 0x73 +}; + + +/*--------------------- + * 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 = 80, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 64, .box_w = 2, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 11, .adv_w = 96, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 6}, + {.bitmap_index = 26, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 66, .adv_w = 112, .box_w = 7, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115, .adv_w = 176, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 176, .adv_w = 176, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 237, .adv_w = 48, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 6}, + {.bitmap_index = 245, .adv_w = 80, .box_w = 4, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 271, .adv_w = 80, .box_w = 5, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 304, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 329, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 361, .adv_w = 64, .box_w = 3, .box_h = 5, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 369, .adv_w = 96, .box_w = 6, .box_h = 2, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 375, .adv_w = 64, .box_w = 3, .box_h = 3, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 380, .adv_w = 64, .box_w = 6, .box_h = 11, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 413, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 457, .adv_w = 128, .box_w = 6, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 490, .adv_w = 128, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 529, .adv_w = 128, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 568, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 612, .adv_w = 128, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 651, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 695, .adv_w = 128, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 737, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 781, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 825, .adv_w = 64, .box_w = 3, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 837, .adv_w = 64, .box_w = 3, .box_h = 10, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 852, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 888, .adv_w = 128, .box_w = 8, .box_h = 5, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 908, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 944, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 983, .adv_w = 160, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1038, .adv_w = 160, .box_w = 11, .box_h = 11, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 1099, .adv_w = 160, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1149, .adv_w = 160, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1199, .adv_w = 160, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1254, .adv_w = 160, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1304, .adv_w = 144, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1354, .adv_w = 160, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1415, .adv_w = 176, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1476, .adv_w = 80, .box_w = 5, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1504, .adv_w = 112, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1548, .adv_w = 160, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1609, .adv_w = 144, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1659, .adv_w = 208, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1731, .adv_w = 176, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1792, .adv_w = 160, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1847, .adv_w = 144, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1897, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 1967, .adv_w = 160, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2022, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2066, .adv_w = 144, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2116, .adv_w = 176, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2177, .adv_w = 160, .box_w = 11, .box_h = 11, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 2238, .adv_w = 208, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2315, .adv_w = 144, .box_w = 11, .box_h = 11, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 2376, .adv_w = 144, .box_w = 11, .box_h = 11, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 2437, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2481, .adv_w = 64, .box_w = 4, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2505, .adv_w = 128, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2544, .adv_w = 64, .box_w = 4, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2568, .adv_w = 128, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 2592, .adv_w = 112, .box_w = 7, .box_h = 1, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2596, .adv_w = 64, .box_w = 4, .box_h = 3, .ofs_x = 0, .ofs_y = 8}, + {.bitmap_index = 2602, .adv_w = 112, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2630, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2669, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2690, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2734, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2759, .adv_w = 64, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2792, .adv_w = 112, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2832, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2876, .adv_w = 64, .box_w = 4, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2898, .adv_w = 64, .box_w = 5, .box_h = 14, .ofs_x = -2, .ofs_y = -3}, + {.bitmap_index = 2933, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2977, .adv_w = 64, .box_w = 4, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2999, .adv_w = 192, .box_w = 12, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3041, .adv_w = 128, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3069, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3094, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3134, .adv_w = 112, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3174, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3195, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3216, .adv_w = 80, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3241, .adv_w = 128, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3269, .adv_w = 112, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3297, .adv_w = 160, .box_w = 11, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3336, .adv_w = 112, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3364, .adv_w = 112, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3404, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3425, .adv_w = 64, .box_w = 4, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3449, .adv_w = 128, .box_w = 2, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 3460, .adv_w = 64, .box_w = 4, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3484, .adv_w = 128, .box_w = 8, .box_h = 3, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 3496, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3536, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3568, .adv_w = 96, .box_w = 6, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3595, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3627, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3667, .adv_w = 80, .box_w = 4, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3685, .adv_w = 80, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3708, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3744, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3780, .adv_w = 64, .box_w = 4, .box_h = 6, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 3792, .adv_w = 112, .box_w = 7, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 3838, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3870, .adv_w = 112, .box_w = 7, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3916, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3948, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3988, .adv_w = 64, .box_w = 4, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 4014, .adv_w = 80, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4037, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4069, .adv_w = 128, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4113, .adv_w = 112, .box_w = 7, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 4159, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4191, .adv_w = 112, .box_w = 7, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 4237, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4269, .adv_w = 128, .box_w = 8, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 4321, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4353, .adv_w = 160, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4398, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + + + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 1488, .range_length = 27, .glyph_id_start = 96, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + } +}; + +/*----------------- + * KERNING + *----------------*/ + + +/*Pair left and right glyphs for kerning*/ +static const uint8_t kern_pair_glyph_ids[] = +{ + 13, 18, + 14, 34, + 14, 53, + 14, 55, + 14, 56, + 14, 58, + 15, 18, + 17, 18, + 17, 21, + 17, 24, + 18, 13, + 18, 15, + 18, 17, + 18, 18, + 18, 19, + 18, 20, + 18, 21, + 18, 22, + 18, 23, + 18, 24, + 18, 25, + 18, 26, + 19, 18, + 19, 21, + 19, 24, + 20, 18, + 20, 21, + 20, 24, + 21, 18, + 21, 21, + 21, 24, + 22, 18, + 22, 21, + 22, 24, + 23, 18, + 23, 21, + 23, 24, + 24, 13, + 24, 15, + 24, 18, + 24, 19, + 24, 20, + 24, 21, + 24, 22, + 24, 23, + 24, 24, + 24, 25, + 24, 27, + 24, 28, + 25, 18, + 25, 21, + 25, 24, + 26, 18, + 26, 24 +}; + +/* Kerning between the respective left and right glyphs + * 4.4 format which needs to scaled with `kern_scale`*/ +static const int8_t kern_pair_values[] = +{ + -7, -1, -16, -12, -9, -19, -9, -11, + 1, -2, -5, -5, -11, -7, 0, -6, + -12, -6, -11, -18, -7, -5, -8, 1, + -3, -10, 0, -6, -7, 3, -10, -13, + 1, -8, -8, 2, -4, -15, -15, -8, + -7, -7, -16, -8, -8, -4, -8, -16, + -16, -9, 2, -5, -10, -2 +}; + +/*Collect the kern pair's data in one place*/ +static const lv_font_fmt_txt_kern_pair_t kern_pairs = +{ + .glyph_ids = kern_pair_glyph_ids, + .values = kern_pair_values, + .pair_cnt = 54, + .glyph_ids_size = 0 +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_dsc_t font_dsc = { + .glyph_bitmap = gylph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = &kern_pairs, + .kern_scale = 16, + .cmap_num = 2, + .bpp = 4, + .kern_classes = 0, + .bitmap_format = 0 +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +lv_font_t lv_font_heb_16 = { + .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 = 17, /*The maximum line height required by the font*/ + .base_line = 4, /*Baseline measured from the bottom of the line*/ + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + +#endif /*#if LV_FONT_HEB_16*/ + diff --git a/src/lv_misc/lv_anim.h b/src/lv_misc/lv_anim.h index 299f7c455..36cc35adc 100644 --- a/src/lv_misc/lv_anim.h +++ b/src/lv_misc/lv_anim.h @@ -129,10 +129,10 @@ static inline void lv_anim_set_exec_cb(lv_anim_t * a, void * var, lv_anim_exec_x * @param duration duration of the animation in milliseconds * @param delay delay before the animation in milliseconds */ -static inline void lv_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay) +static inline void lv_anim_set_time(lv_anim_t * a, uint16_t duration, int16_t delay) { a->time = duration; - a->act_time = -delay; + a->act_time = (int16_t)(-delay); } /** diff --git a/src/lv_misc/lv_area.c b/src/lv_misc/lv_area.c index 025e1733e..de649c5b0 100644 --- a/src/lv_misc/lv_area.c +++ b/src/lv_misc/lv_area.c @@ -192,6 +192,19 @@ bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p) return is_in; } +/** + * Increment or decrement an area's size by a single amount + * @param a_p pointer to an area to grow + * @param amount amount to increment the area, or negative to decrement + */ +void lv_area_increment(lv_area_t * a_p, const lv_coord_t amount) +{ + a_p->x1 -= amount; + a_p->y1 -= amount; + a_p->x2 += amount; + a_p->y2 += amount; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_misc/lv_area.h b/src/lv_misc/lv_area.h index 149df2302..211bebd84 100644 --- a/src/lv_misc/lv_area.h +++ b/src/lv_misc/lv_area.h @@ -85,7 +85,7 @@ inline static void lv_area_copy(lv_area_t * dest, const lv_area_t * src) */ static inline lv_coord_t lv_area_get_width(const lv_area_t * area_p) { - return area_p->x2 - area_p->x1 + 1; + return (lv_coord_t)(area_p->x2 - area_p->x1 + 1); } /** @@ -95,7 +95,7 @@ static inline lv_coord_t lv_area_get_width(const lv_area_t * area_p) */ static inline lv_coord_t lv_area_get_height(const lv_area_t * area_p) { - return area_p->y2 - area_p->y1 + 1; + return (lv_coord_t)(area_p->y2 - area_p->y1 + 1); } /** @@ -168,6 +168,13 @@ bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p); */ bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p); +/** + * Increment or decrement an area's size by a single amount + * @param a_p pointer to an area to grow + * @param amount amount to increment the area, or negative to decrement + */ +void lv_area_increment(lv_area_t * a_p, const lv_coord_t amount); + /********************** * MACROS **********************/ diff --git a/src/lv_misc/lv_bidi.c b/src/lv_misc/lv_bidi.c index e9929bc67..bde752071 100644 --- a/src/lv_misc/lv_bidi.c +++ b/src/lv_misc/lv_bidi.c @@ -6,32 +6,49 @@ /********************* * INCLUDES *********************/ -#include "lv_bidi.h" #include +#include "lv_bidi.h" #include "lv_txt.h" +#include "../lv_draw/lv_draw.h" #if LV_USE_BIDI /********************* * DEFINES *********************/ +#define LV_BIDI_BRACKLET_DEPTH 4 + +// Highest bit of the 16-bit pos_conv value specifies whether this pos is RTL or not +#define GET_POS(x) ((x) & 0x7FFF) +#define IS_RTL_POS(x) (((x) & 0x8000) != 0) +#define SET_RTL_POS(x, is_rtl) (GET_POS(x) | ((is_rtl)? 0x8000: 0)) /********************** * TYPEDEFS **********************/ +typedef struct +{ + uint32_t bracklet_pos; + lv_bidi_dir_t dir; +}bracket_stack_t; /********************** * STATIC PROTOTYPES **********************/ -static void process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir); -static uint32_t get_next_paragraph(const char * txt); -static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t * len); -static void rtl_reverse(char * dest, const char * src, uint32_t len); +static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len, uint16_t * pos_conv_len); +static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *pos_conv_out, uint16_t pos_conv_rd_base, uint16_t pos_conv_len); static uint32_t char_change_to_pair(uint32_t letter); +static lv_bidi_dir_t bracket_process(const char * txt, uint32_t next_pos, uint32_t len, uint32_t letter, lv_bidi_dir_t base_dir); +static void fill_pos_conv(uint16_t * out, uint16_t len, uint16_t index); +static uint32_t get_txt_len(const char * txt, uint32_t max_len); /********************** * STATIC VARIABLES **********************/ +static const uint8_t bracket_left[] = {"<({["}; +static const uint8_t bracket_right[] = {">)}]"}; +static bracket_stack_t br_stack[LV_BIDI_BRACKLET_DEPTH]; +static uint8_t br_stack_p; /********************** * MACROS @@ -43,7 +60,6 @@ static uint32_t char_change_to_pair(uint32_t letter); void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir) { - if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(str_in); uint32_t par_start = 0; @@ -55,8 +71,8 @@ void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir } while(str_in[par_start] != '\0') { - par_len = get_next_paragraph(&str_in[par_start]); - process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir); + par_len = lv_bidi_get_next_paragraph(&str_in[par_start]); + lv_bidi_process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir, NULL, 0); par_start += par_len; while(str_in[par_start] == '\n' || str_in[par_start] == '\r') { @@ -121,7 +137,7 @@ bool lv_bidi_letter_is_rtl(uint32_t letter) bool lv_bidi_letter_is_neutral(uint32_t letter) { uint16_t i; - static const char neutrals[] = " \t\n\r.,:;'\"`!?%/\\=()[]{}<>@#&$|"; + static const char neutrals[] = " \t\n\r.,:;'\"`!?%/\\-=()[]{}<>@#&$|"; for(i = 0; neutrals[i] != '\0'; i++) { if(letter == (uint32_t)neutrals[i]) return true; } @@ -129,62 +145,120 @@ bool lv_bidi_letter_is_neutral(uint32_t letter) return false; } +uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos, bool *is_rtl) +{ + uint32_t pos_conv_len = get_txt_len(str_in, len); + void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t)); + if (bidi_txt) *bidi_txt = buf; + uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len); + lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len); + if (is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[visual_pos]); + return GET_POS(pos_conv_buf[visual_pos]); +} -/********************** - * STATIC FUNCTIONS - **********************/ +uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos, bool *is_rtl) +{ + uint32_t pos_conv_len = get_txt_len(str_in, len); + void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t)); + if (bidi_txt) *bidi_txt = buf; + uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len); + lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len); + for (uint16_t i = 0; i < pos_conv_len; i++){ + if (GET_POS(pos_conv_buf[i]) == logical_pos){ + if (is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[i]); + return i; + } + } + return (uint16_t) -1; +} -static void process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir) +void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir, uint16_t *pos_conv_out, uint16_t pos_conv_len) { uint32_t run_len = 0; lv_bidi_dir_t run_dir; uint32_t rd = 0; uint32_t wr; - if(base_dir == LV_BIDI_DIR_RTL) wr = len; - else wr = 0; + uint16_t pos_conv_run_len = 0; + uint16_t pos_conv_rd = 0; + uint16_t pos_conv_wr; - str_out[len] = '\0'; + if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(str_in); + if(base_dir == LV_BIDI_DIR_RTL) { + wr = len; + pos_conv_wr = pos_conv_len; + } + else { + wr = 0; + pos_conv_wr = 0; + } + + if (str_out) str_out[len] = '\0'; lv_bidi_dir_t dir = base_dir; + /*Empty the bracket stack*/ + br_stack_p = 0; + /*Process neutral chars in the beginning*/ while(rd < len) { uint32_t letter = lv_txt_encoded_next(str_in, &rd); + pos_conv_rd++; dir = lv_bidi_get_letter_dir(letter); + if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(str_in, rd, len, letter, base_dir); if(dir != LV_BIDI_DIR_NEUTRAL && dir != LV_BIDI_DIR_WEAK) break; } - if(rd && str_in[rd] != '\0') lv_txt_encoded_prev(str_in, &rd); + if(rd && str_in[rd] != '\0') { + lv_txt_encoded_prev(str_in, &rd); + pos_conv_rd--; + } if(rd) { if(base_dir == LV_BIDI_DIR_LTR) { - memcpy(&str_out[wr], str_in, rd); - wr += rd; + if (str_out) { + memcpy(&str_out[wr], str_in, rd); + wr += rd; + } + if (pos_conv_out) { + fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_rd, 0); + pos_conv_wr += pos_conv_rd; + } } else { wr -= rd; - rtl_reverse(&str_out[wr], str_in, rd); + pos_conv_wr -= pos_conv_rd; + rtl_reverse(str_out? &str_out[wr]: NULL, str_in, rd, pos_conv_out? &pos_conv_out[pos_conv_wr]: NULL, 0, pos_conv_rd); } } /*Get and process the runs*/ - while(rd < len) { - run_dir = get_next_run(&str_in[rd], base_dir, &run_len); + + while(rd < len && str_in[rd]) { + run_dir = get_next_run(&str_in[rd], base_dir, len - rd, &run_len, &pos_conv_run_len); if(base_dir == LV_BIDI_DIR_LTR) { - if(run_dir == LV_BIDI_DIR_LTR) memcpy(&str_out[wr], &str_in[rd], run_len); - else rtl_reverse(&str_out[wr], &str_in[rd], run_len); + if(run_dir == LV_BIDI_DIR_LTR) { + if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len); + if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd); + } + else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len); wr += run_len; + pos_conv_wr += pos_conv_run_len; } else { wr -= run_len; - if(run_dir == LV_BIDI_DIR_LTR) memcpy(&str_out[wr], &str_in[rd], run_len); - else rtl_reverse(&str_out[wr], &str_in[rd], run_len); + pos_conv_wr -= pos_conv_run_len; + if(run_dir == LV_BIDI_DIR_LTR) { + if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len); + if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd); + } + else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len); } rd += run_len; + pos_conv_rd += pos_conv_run_len; } } -static uint32_t get_next_paragraph(const char * txt) +uint32_t lv_bidi_get_next_paragraph(const char * txt) { uint32_t i = 0; @@ -197,20 +271,53 @@ static uint32_t get_next_paragraph(const char * txt) return i; } -static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t * len) +/********************** + * STATIC FUNCTIONS + **********************/ + +static uint32_t get_txt_len(const char * txt, uint32_t max_len) +{ + uint32_t len = 0; + uint32_t i = 0; + + while(i < max_len && txt[i] != '\0') { + lv_txt_encoded_next(txt, &i); + len++; + } + + return len; +} + +static void fill_pos_conv(uint16_t * out, uint16_t len, uint16_t index) +{ + for (uint16_t i = 0; i < len; i++) + { + out[i] = SET_RTL_POS(index, false); + index++; + } +} + +static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len, uint16_t * pos_conv_len) { uint32_t i = 0; uint32_t letter; + uint16_t pos_conv_i = 0; + letter = lv_txt_encoded_next(txt, NULL); lv_bidi_dir_t dir = lv_bidi_get_letter_dir(letter); + if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(txt, 0, max_len, letter, base_dir); /*Find the first strong char. Skip the neutrals*/ while(dir == LV_BIDI_DIR_NEUTRAL || dir == LV_BIDI_DIR_WEAK) { letter = lv_txt_encoded_next(txt, &i); + pos_conv_i++; dir = lv_bidi_get_letter_dir(letter); - if(txt[i] == '\0' || txt[i] == '\n' || txt[i] == '\r') { + if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(txt, i, max_len, letter, base_dir); + + if(i >= max_len || txt[i] == '\0' || txt[i] == '\n' || txt[i] == '\r') { *len = i; + *pos_conv_len = pos_conv_i; return base_dir; } } @@ -219,83 +326,119 @@ static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint uint32_t i_prev = i; uint32_t i_last_strong = i; + uint16_t pos_conv_i_prev = pos_conv_i; + uint16_t pos_conv_i_last_strong = pos_conv_i; /*Find the next char which has different direction*/ lv_bidi_dir_t next_dir = base_dir; - while(txt[i] != '\0'&& txt[i] != '\n' && txt[i] != '\r') { + while(i_prev < max_len && txt[i] != '\0' && txt[i] != '\n' && txt[i] != '\r') { letter = lv_txt_encoded_next(txt, &i); + pos_conv_i++; next_dir = lv_bidi_get_letter_dir(letter); + if(next_dir == LV_BIDI_DIR_NEUTRAL) next_dir = bracket_process(txt, i, max_len, letter, base_dir); /*New dir found?*/ if((next_dir == LV_BIDI_DIR_RTL || next_dir == LV_BIDI_DIR_LTR) && next_dir != run_dir) { /*Include neutrals if `run_dir == base_dir` */ - if(run_dir == base_dir) *len = i_prev; + if(run_dir == base_dir) { + *len = i_prev; + *pos_conv_len = pos_conv_i_prev; + } /*Exclude neutrals if `run_dir != base_dir` */ - else *len = i_last_strong; + else { + *len = i_last_strong; + *pos_conv_len = pos_conv_i_last_strong; + } return run_dir; } - if(next_dir != LV_BIDI_DIR_NEUTRAL) i_last_strong = i; + if(next_dir != LV_BIDI_DIR_NEUTRAL) { + i_last_strong = i; + pos_conv_i_last_strong = pos_conv_i; + } i_prev = i; + pos_conv_i_prev = pos_conv_i; } - /*Handle end of of string. Apply `base_dir` on trailing neutrals*/ /*Include neutrals if `run_dir == base_dir` */ - if(run_dir == base_dir) *len = i_prev; + if(run_dir == base_dir) { + *len = i_prev; + *pos_conv_len = pos_conv_i_prev; + } /*Exclude neutrals if `run_dir != base_dir` */ - else *len = i_last_strong; + else { + *len = i_last_strong; + *pos_conv_len = pos_conv_i_last_strong; + } return run_dir; - } -static void rtl_reverse(char * dest, const char * src, uint32_t len) +static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *pos_conv_out, uint16_t pos_conv_rd_base, uint16_t pos_conv_len) { uint32_t i = len; uint32_t wr = 0; + uint16_t pos_conv_i = pos_conv_len; + uint16_t pos_conv_wr = 0; while(i) { uint32_t letter = lv_txt_encoded_prev(src, &i); + uint16_t pos_conv_letter = --pos_conv_i; /*Keep weak letters (numbers) as LTR*/ if(lv_bidi_letter_is_weak(letter)) { uint32_t last_weak = i; uint32_t first_weak = i; + uint16_t pos_conv_last_weak = pos_conv_i; + uint16_t pos_conv_first_weak = pos_conv_i; while(i) { letter = lv_txt_encoded_prev(src, &i); + pos_conv_letter = --pos_conv_i; + /*No need to call `char_change_to_pair` because there not such chars here*/ /*Finish on non-weak char */ /*but treat number and currency related chars as weak*/ - if(lv_bidi_letter_is_weak(letter) == false && letter != '.' && letter != ',' && letter != '$') { + if (lv_bidi_letter_is_weak(letter) == false && letter != '.' && letter != ',' && letter != '$' && letter != '%') { lv_txt_encoded_next(src, &i); /*Rewind one letter*/ + pos_conv_i++; first_weak = i; + pos_conv_first_weak = pos_conv_i; break; } } - if(i == 0) first_weak = 0; + if(i == 0) { + first_weak = 0; + pos_conv_first_weak = 0; + } - memcpy(&dest[wr], &src[first_weak], last_weak - first_weak + 1); + if (dest) memcpy(&dest[wr], &src[first_weak], last_weak - first_weak + 1); + if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_last_weak - pos_conv_first_weak + 1, pos_conv_rd_base + pos_conv_first_weak); wr += last_weak - first_weak + 1; - + pos_conv_wr += pos_conv_last_weak - pos_conv_first_weak + 1; } + /*Simply store in reversed order*/ else { uint32_t letter_size = lv_txt_encoded_size((const char *)&src[i]); /*Swap arithmetical symbols*/ if(letter_size == 1) { uint32_t new_letter = letter = char_change_to_pair(letter); - dest[wr] = (uint8_t)new_letter; - wr += 1; + if (dest) dest[wr] = (uint8_t)new_letter; + if (pos_conv_out) pos_conv_out[pos_conv_wr] = SET_RTL_POS(pos_conv_rd_base + pos_conv_letter, true); + wr++; + pos_conv_wr++; } /*Just store the letter*/ else { - memcpy(&dest[wr], &src[i], letter_size); + if (dest) memcpy(&dest[wr], &src[i], letter_size); + if (pos_conv_out) pos_conv_out[pos_conv_wr] = SET_RTL_POS(pos_conv_rd_base + pos_conv_i, true); wr += letter_size; + pos_conv_wr++; } } } @@ -303,19 +446,95 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len) static uint32_t char_change_to_pair(uint32_t letter) { - static uint8_t left[] = {"<({["}; - static uint8_t right[] = {">)}]"}; uint8_t i; - for(i = 0; left[i] != '\0'; i++) { - if(letter == left[i]) return right[i]; + for(i = 0; bracket_left[i] != '\0'; i++) { + if(letter == bracket_left[i]) return bracket_right[i]; } - for(i = 0; right[i] != '\0'; i++) { - if(letter == right[i]) return left[i]; + for(i = 0; bracket_right[i] != '\0'; i++) { + if(letter == bracket_right[i]) return bracket_left[i]; } return letter; } +static lv_bidi_dir_t bracket_process(const char * txt, uint32_t next_pos, uint32_t len, uint32_t letter, lv_bidi_dir_t base_dir) +{ + lv_bidi_dir_t bracket_dir = LV_BIDI_DIR_NEUTRAL; + + uint8_t i; + /*Is the letter an opening bracket?*/ + for(i = 0; bracket_left[i] != '\0'; i++) { + if(bracket_left[i] == letter) { + /* If so find it's matching closing bracket. + * If a char with base dir. direction is found then the brackets will have `base_dir` direction*/ + uint32_t txt_i = next_pos; + while(txt_i < len) { + uint32_t letter_next = lv_txt_encoded_next(txt, &txt_i); + if(letter_next == bracket_right[i]) { + /*Closing bracket found*/ + break; + } else { + /*Save the dir*/ + lv_bidi_dir_t letter_dir = lv_bidi_get_letter_dir(letter_next); + if(letter_dir == base_dir) { + bracket_dir = base_dir; + } + } + } + + /*There were no matching closing bracket*/ + if(txt_i > len) return LV_BIDI_DIR_NEUTRAL; + + /*There where a strong char with base dir in the bracket so the dir is found.*/ + if(bracket_dir != LV_BIDI_DIR_NEUTRAL && bracket_dir != LV_BIDI_DIR_WEAK) break; + + /*If there were no matching strong chars in the brackets then check the previous chars*/ + txt_i = next_pos; + if(txt_i) lv_txt_encoded_prev(txt, &txt_i); + while(txt_i > 0) { + uint32_t letter_next = lv_txt_encoded_prev(txt, &txt_i); + lv_bidi_dir_t letter_dir = lv_bidi_get_letter_dir(letter_next); + if(letter_dir == LV_BIDI_DIR_LTR || letter_dir == LV_BIDI_DIR_RTL) { + bracket_dir = letter_dir; + break; + } + } + + + /*There where a previous strong char which can be used*/ + if(bracket_dir != LV_BIDI_DIR_NEUTRAL) break; + + /*There were no strong chars before the bracket, so use the base dir.*/ + if(txt_i == 0) bracket_dir = base_dir; + + break; + } + } + + + /*The letter was an opening bracket*/ + if(bracket_left[i] != '\0') { + + if(bracket_dir == LV_BIDI_DIR_NEUTRAL || br_stack_p == LV_BIDI_BRACKLET_DEPTH) return LV_BIDI_DIR_NEUTRAL; + + br_stack[br_stack_p].bracklet_pos = i; + br_stack[br_stack_p].dir = bracket_dir; + + br_stack_p++; + return bracket_dir; + } else if(br_stack_p > 0) { + /*Is the letter a closing bracket of the last opening?*/ + if(letter == bracket_right[br_stack[br_stack_p - 1].bracklet_pos]) { + bracket_dir = br_stack[br_stack_p - 1].dir; + br_stack_p--; + return bracket_dir; + } + } + + return LV_BIDI_DIR_NEUTRAL; +} + + #endif /*LV_USE_BIDI*/ diff --git a/src/lv_misc/lv_bidi.h b/src/lv_misc/lv_bidi.h index 233765ca2..215727aa7 100644 --- a/src/lv_misc/lv_bidi.h +++ b/src/lv_misc/lv_bidi.h @@ -53,11 +53,15 @@ typedef uint8_t lv_bidi_dir_t; #if LV_USE_BIDI void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir); +void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir, uint16_t *pos_conv_out, uint16_t pos_conv_len); +uint32_t lv_bidi_get_next_paragraph(const char * txt); lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt); lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter); bool lv_bidi_letter_is_weak(uint32_t letter); bool lv_bidi_letter_is_rtl(uint32_t letter); bool lv_bidi_letter_is_neutral(uint32_t letter); +uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos, bool *is_rtl); +uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos, bool *is_rtl); /********************** * MACROS diff --git a/src/lv_misc/lv_color.c b/src/lv_misc/lv_color.c index f5bec62bb..cd4825dfe 100644 --- a/src/lv_misc/lv_color.c +++ b/src/lv_misc/lv_color.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ #include "lv_color.h" +#include "lv_math.h" /********************* * DEFINES @@ -105,39 +106,66 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v) } /** - * Convert an RGB color to HSV - * @param r red - * @param g green - * @param b blue - * @return the given RGB color n HSV + * Convert a 32-bit RGB color to HSV + * @param r8 8-bit red + * @param g8 8-bit green + * @param b8 8-bit blue + * @return the given RGB color in HSV */ -lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b) +lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) { + uint16_t r = ((uint32_t)r8 << 10) / 255; + uint16_t g = ((uint32_t)g8 << 10) / 255; + uint16_t b = ((uint32_t)b8 << 10) / 255; + + uint16_t rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b); + uint16_t rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b); + lv_color_hsv_t hsv; - uint8_t rgbMin, rgbMax; - rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b); - rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b); + // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness + hsv.v = (100 * rgbMax) >> 10; - hsv.v = rgbMax; - if(hsv.v == 0) { + int32_t delta = rgbMax - rgbMin; + if (LV_MATH_ABS(delta) < 3) { hsv.h = 0; hsv.s = 0; return hsv; } - hsv.s = 255 * (long)(rgbMax - rgbMin) / hsv.v; - if(hsv.s == 0) { + // https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation + hsv.s = 100 * delta / rgbMax; + if(hsv.s < 3) { hsv.h = 0; return hsv; } + // https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma + int32_t h; if(rgbMax == r) - hsv.h = 0 + 43 * (g - b) / (rgbMax - rgbMin); + h = (((g - b) << 10) / delta) + (g < b ? (6 << 10) : 0); // between yellow & magenta else if(rgbMax == g) - hsv.h = 85 + 43 * (b - r) / (rgbMax - rgbMin); + h = (((b - r) << 10) / delta) + (2 << 10); // between cyan & yellow + else if(rgbMax == b) + h = (((r - g) << 10) / delta) + (4 << 10); // between magenta & cyan else - hsv.h = 171 + 43 * (r - g) / (rgbMax - rgbMin); + h = 0; + h *= 60; + h >>= 10; + if (h < 0) h += 360; + hsv.h = h; return hsv; } + +/** + * Convert a color to HSV + * @param color color + * @return the given color in HSV + */ +lv_color_hsv_t lv_color_to_hsv(lv_color_t color) +{ + lv_color32_t color32; + color32.full = lv_color_to32(color); + return lv_color_rgb_to_hsv(color32.ch.red, color32.ch.green, color32.ch.blue); +} diff --git a/src/lv_misc/lv_color.h b/src/lv_misc/lv_color.h index 78741b3a2..c90dd852f 100644 --- a/src/lv_misc/lv_color.h +++ b/src/lv_misc/lv_color.h @@ -90,6 +90,110 @@ enum { #error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!" #endif +/*--------------------------------------- + * Macros for all existing color depths + * to set/get values of the color channels + *------------------------------------------*/ +# define LV_COLOR_SET_R1(c, v) (c).ch.red = (uint8_t)((v) & 0x1); +# define LV_COLOR_SET_G1(c, v) (c).ch.green = (uint8_t)((v) & 0x1); +# define LV_COLOR_SET_B1(c, v) (c).ch.blue = (uint8_t)((v) & 0x1); +# define LV_COLOR_SET_A1(c, v) + +# define LV_COLOR_GET_R1(c) (c).ch.red +# define LV_COLOR_GET_G1(c) (c).ch.green +# define LV_COLOR_GET_B1(c) (c).ch.blue +# define LV_COLOR_GET_A1(c) 1 + +# define LV_COLOR_SET_R8(c, v) (c).ch.red = (uint8_t)((v) & 0x7); +# define LV_COLOR_SET_G8(c, v) (c).ch.green = (uint8_t)((v) & 0x7); +# define LV_COLOR_SET_B8(c, v) (c).ch.blue = (uint8_t)((v) & 0x3); +# define LV_COLOR_SET_A8(c, v) do {} while(0) + +# define LV_COLOR_GET_R8(c) (c).ch.red +# define LV_COLOR_GET_G8(c) (c).ch.green +# define LV_COLOR_GET_B8(c) (c).ch.blue +# define LV_COLOR_GET_A8(c) 0xFF + +# define LV_COLOR_SET_R16(c, v) (c).ch.red = (uint16_t)((v) & 0x1F); +# define LV_COLOR_SET_G16(c, v) (c).ch.green = (uint16_t)((v) & 0x3F); +# define LV_COLOR_SET_G16_SWAP(c, v) {(c).ch.green_h = (uint16_t)(((v) >> 3) & 0x7); (c).ch.green_l = (uint16_t)((v) & 0x7);} +# define LV_COLOR_SET_B16(c, v) (c).ch.blue = (uint16_t)((v) & 0x1F); +# define LV_COLOR_SET_A16(c, v) do {} while(0) + +# define LV_COLOR_GET_R16(c) (c).ch.red +# define LV_COLOR_GET_G16(c) (c).ch.green +# define LV_COLOR_GET_G16_SWAP(c) (((c).ch.green_h << 3) + (c).ch.green_l) +# define LV_COLOR_GET_B16(c) (c).ch.blue +# define LV_COLOR_GET_A16(c) 0xFF + +# define LV_COLOR_SET_R32(c, v) (c).ch.red = (uint32_t)((v) & 0xFF); +# define LV_COLOR_SET_G32(c, v) (c).ch.green = (uint32_t)((v) & 0xFF); +# define LV_COLOR_SET_B32(c, v) (c).ch.blue = (uint32_t)((v) & 0xFF); +# define LV_COLOR_SET_A32(c, v) (c).ch.alpha = (uint32_t)((v) & 0xFF); + +# define LV_COLOR_GET_R32(c) (c).ch.red +# define LV_COLOR_GET_G32(c) (c).ch.green +# define LV_COLOR_GET_B32(c) (c).ch.blue +# define LV_COLOR_GET_A32(c) (c).ch.alpha + + +/*--------------------------------------- + * Macros for the current color depth + * to set/get values of the color channels + *------------------------------------------*/ +#if LV_COLOR_DEPTH == 1 +# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R1(c,v) +# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G1(c,v) +# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B1(c,v) +# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A1(c,v) + +# define LV_COLOR_GET_R(c) LV_COLOR_GET_R1(c) +# define LV_COLOR_GET_G(c) LV_COLOR_GET_G1(c) +# define LV_COLOR_GET_B(c) LV_COLOR_GET_B1(c) +# define LV_COLOR_GET_A(c) LV_COLOR_GET_A1(c) + +#elif LV_COLOR_DEPTH == 8 +# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R8(c,v) +# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G8(c,v) +# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B8(c,v) +# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A8(c,v) + +# define LV_COLOR_GET_R(c) LV_COLOR_GET_R8(c) +# define LV_COLOR_GET_G(c) LV_COLOR_GET_G8(c) +# define LV_COLOR_GET_B(c) LV_COLOR_GET_B8(c) +# define LV_COLOR_GET_A(c) LV_COLOR_GET_A8(c) + +#elif LV_COLOR_DEPTH == 16 +# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R16(c,v) +# if LV_COLOR_16_SWAP == 0 +# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G16(c,v) +# else +# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G16_SWAP(c,v) +# endif +# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B16(c,v) +# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A16(c,v) + +# define LV_COLOR_GET_R(c) LV_COLOR_GET_R16(c) +# if LV_COLOR_16_SWAP == 0 +# define LV_COLOR_GET_G(c) LV_COLOR_GET_G16(c) +# else +# define LV_COLOR_GET_G(c) LV_COLOR_GET_G16_SWAP(c) +# endif +# define LV_COLOR_GET_B(c) LV_COLOR_GET_B16(c) +# define LV_COLOR_GET_A(c) LV_COLOR_GET_A16(c) + +#elif LV_COLOR_DEPTH == 32 +# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R32(c,v) +# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G32(c,v) +# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B32(c,v) +# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A32(c,v) + +# define LV_COLOR_GET_R(c) LV_COLOR_GET_R32(c) +# define LV_COLOR_GET_G(c) LV_COLOR_GET_G32(c) +# define LV_COLOR_GET_B(c) LV_COLOR_GET_B32(c) +# define LV_COLOR_GET_A(c) LV_COLOR_GET_A32(c) +#endif + /********************** * TYPEDEFS **********************/ @@ -194,24 +298,19 @@ static inline uint8_t lv_color_to1(lv_color_t color) #if LV_COLOR_DEPTH == 1 return color.full; #elif LV_COLOR_DEPTH == 8 - if((color.ch.red & 0x4) || (color.ch.green & 0x4) || (color.ch.blue & 0x2)) { + if((LV_COLOR_GET_R(color) & 0x4) || (LV_COLOR_GET_G(color) & 0x4) || (LV_COLOR_GET_B(color) & 0x2)) { return 1; } else { return 0; } #elif LV_COLOR_DEPTH == 16 -#if LV_COLOR_16_SWAP == 0 - if((color.ch.red & 0x10) || (color.ch.green & 0x20) || (color.ch.blue & 0x10)) { + if((LV_COLOR_GET_R(color) & 0x10) || (LV_COLOR_GET_G(color) & 0x20) || (LV_COLOR_GET_B(color) & 0x10)) { return 1; -#else - if((color.ch.red & 0x10) || (color.ch.green_h & 0x20) || (color.ch.blue & 0x10)) { - return 1; -#endif } else { return 0; } #elif LV_COLOR_DEPTH == 32 - if((color.ch.red & 0x80) || (color.ch.green & 0x80) || (color.ch.blue & 0x80)) { + if((LV_COLOR_GET_R(color) & 0x80) || (LV_COLOR_GET_G(color) & 0x80) || (LV_COLOR_GET_B(color) & 0x80)) { return 1; } else { return 0; @@ -229,31 +328,23 @@ static inline uint8_t lv_color_to8(lv_color_t color) #elif LV_COLOR_DEPTH == 8 return color.full; #elif LV_COLOR_DEPTH == 16 - -#if LV_COLOR_16_SWAP == 0 lv_color8_t ret; - ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/ - ret.ch.green = color.ch.green >> 3; /* 6 - 3 = 3*/ - ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/ + LV_COLOR_SET_R8(ret, LV_COLOR_GET_R(color) >> 2); /* 5 - 3 = 2*/ + LV_COLOR_SET_G8(ret, LV_COLOR_GET_G(color) >> 3); /* 6 - 3 = 3*/ + LV_COLOR_SET_B8(ret, LV_COLOR_GET_B(color) >> 3); /* 5 - 2 = 3*/ return ret.full; -#else - lv_color8_t ret; - ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/ - ret.ch.green = color.ch.green_h; /* 6 - 3 = 3*/ - ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/ - return ret.full; -#endif #elif LV_COLOR_DEPTH == 32 lv_color8_t ret; - ret.ch.red = color.ch.red >> 5; /* 8 - 3 = 5*/ - ret.ch.green = color.ch.green >> 5; /* 8 - 3 = 5*/ - ret.ch.blue = color.ch.blue >> 6; /* 8 - 2 = 6*/ + LV_COLOR_SET_R8(ret, LV_COLOR_GET_R(color) >> 5); /* 8 - 3 = 5*/ + LV_COLOR_SET_G8(ret, LV_COLOR_GET_G(color) >> 5); /* 8 - 3 = 5*/ + LV_COLOR_SET_B8(ret, LV_COLOR_GET_B(color) >> 6); /* 8 - 2 = 6*/ return ret.full; #endif } static inline uint16_t lv_color_to16(lv_color_t color) { + #if LV_COLOR_DEPTH == 1 if(color.full == 0) return 0; @@ -261,34 +352,30 @@ static inline uint16_t lv_color_to16(lv_color_t color) return 0xFFFF; #elif LV_COLOR_DEPTH == 8 lv_color16_t ret; + LV_COLOR_SET_R16(ret, LV_COLOR_GET_R(color) * 4); /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/ #if LV_COLOR_16_SWAP == 0 - ret.ch.red = color.ch.red * 4; /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/ - ret.ch.green = color.ch.green * 9; /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/ - ret.ch.blue = color.ch.blue * 10; /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/ + LV_COLOR_SET_G16(ret, LV_COLOR_GET_G(color) * 9); /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/ #else - ret.red = color.ch.red * 4; - uint8_t g_tmp = color.ch.green * 9; - ret.ch.green_h = (g_tmp & 0x1F) >> 3; - ret.ch.green_l = g_tmp & 0x07; - ret.ch.blue = color.ch.blue * 10; + LV_COLOR_SET_G16_SWAP(ret, (LV_COLOR_GET_G(color) * 9)); /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/ #endif + LV_COLOR_SET_B16(ret, LV_COLOR_GET_B(color) * 10); /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/ return ret.full; #elif LV_COLOR_DEPTH == 16 return color.full; #elif LV_COLOR_DEPTH == 32 lv_color16_t ret; + LV_COLOR_SET_R16(ret, LV_COLOR_GET_R(color) >> 3); /* 8 - 5 = 3*/ + #if LV_COLOR_16_SWAP == 0 - ret.ch.red = color.ch.red >> 3; /* 8 - 5 = 3*/ - ret.ch.green = color.ch.green >> 2; /* 8 - 6 = 2*/ - ret.ch.blue = color.ch.blue >> 3; /* 8 - 5 = 3*/ + LV_COLOR_SET_G16(ret, LV_COLOR_GET_G(color) >> 2); /* 8 - 6 = 2*/ #else - ret.ch.red = color.ch.red >> 3; - ret.ch.green_h = (color.ch.green & 0xE0) >> 5; - ret.ch.green_l = (color.ch.green & 0x1C) >> 2; - ret.ch.blue = color.ch.blue >> 3; + LV_COLOR_SET_G16_SWAP(ret, ret.ch.green_h = (LV_COLOR_GET_G(color) >> 2); /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/ #endif + LV_COLOR_SET_B16(ret, LV_COLOR_GET_B(color) >> 3); /* 8 - 5 = 3*/ return ret.full; #endif + + return 0; } static inline uint32_t lv_color_to32(lv_color_t color) @@ -300,10 +387,10 @@ static inline uint32_t lv_color_to32(lv_color_t color) return 0xFFFFFFFF; #elif LV_COLOR_DEPTH == 8 lv_color32_t ret; - ret.ch.red = color.ch.red * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/ - ret.ch.green = color.ch.green * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/ - ret.ch.blue = color.ch.blue * 85; /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/ - ret.ch.alpha = 0xFF; + LV_COLOR_SET_R32(ret, LV_COLOR_GET_R(color) * 36); /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/ + LV_COLOR_SET_G32(ret, LV_COLOR_GET_G(color) * 36); /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/ + LV_COLOR_SET_B32(ret, LV_COLOR_GET_B(color) * 85); /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/ + LV_COLOR_SET_A32(color, 0xFF); return ret.full; #elif LV_COLOR_DEPTH == 16 /** @@ -335,14 +422,10 @@ static inline uint32_t lv_color_to32(lv_color_t color) * 6 259 3 0 255 */ lv_color32_t ret; - ret.ch.red = ( color.ch.red * 263 + 7 ) >> 5; -#if LV_COLOR_16_SWAP == 0 - ret.ch.green = ( color.ch.green * 259 + 3 ) >> 6; -#else - ret.ch.green = (((color.ch.green_h << 3) + color.ch.green_l) * 259 + 3 ) >> 6; -#endif - ret.ch.blue = ( color.ch.blue * 263 + 7 ) >> 5; - ret.ch.alpha = 0xFF; + LV_COLOR_SET_R32(ret, (LV_COLOR_GET_R(color) * 263 + 7 ) >> 5); + LV_COLOR_SET_G32(ret, (LV_COLOR_GET_G(color) * 259 + 3 ) >> 6); + LV_COLOR_SET_B32(ret, (LV_COLOR_GET_B(color) * 263 + 7 ) >> 5); + LV_COLOR_SET_A32(ret, 0xFF); return ret.full; #elif LV_COLOR_DEPTH == 32 return color.full; @@ -362,21 +445,10 @@ static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix) lv_color_t ret; #if LV_COLOR_DEPTH != 1 /*LV_COLOR_DEPTH == 8, 16 or 32*/ - ret.ch.red = (uint16_t)((uint16_t)c1.ch.red * mix + (c2.ch.red * (256 - mix))) >> 8; -#if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP - /*If swapped Green is in 2 parts*/ - uint16_t g_1 = (c1.ch.green_h << 3) + c1.ch.green_l; - uint16_t g_2 = (c2.ch.green_h << 3) + c2.ch.green_l; - uint16_t g_out = (uint16_t)((uint16_t)g_1 * mix + (g_2 * (256 - mix))) >> 8; - ret.ch.green_h = g_out >> 3; - ret.ch.green_l = g_out & 0x7; -#else - ret.ch.green = (uint16_t)((uint16_t)c1.ch.green * mix + (c2.ch.green * (256 - mix))) >> 8; -#endif - ret.ch.blue = (uint16_t)((uint16_t)c1.ch.blue * mix + (c2.ch.blue * (256 - mix))) >> 8; -#if LV_COLOR_DEPTH == 32 - ret.ch.alpha = 0xFF; -#endif + LV_COLOR_SET_R(ret, (uint16_t)((uint16_t) LV_COLOR_GET_R(c1) * mix + LV_COLOR_GET_R(c2) * (255 - mix)) >> 8); + LV_COLOR_SET_G(ret, (uint16_t)((uint16_t) LV_COLOR_GET_G(c1) * mix + LV_COLOR_GET_G(c2) * (255 - mix)) >> 8); + LV_COLOR_SET_B(ret, (uint16_t)((uint16_t) LV_COLOR_GET_B(c1) * mix + LV_COLOR_GET_B(c2) * (255 - mix)) >> 8); + LV_COLOR_SET_A(ret, 0xFF); #else /*LV_COLOR_DEPTH == 1*/ ret.full = mix > LV_OPA_50 ? c1.full : c2.full; @@ -454,16 +526,16 @@ static inline uint8_t lv_color_brightness(lv_color_t color) { lv_color32_t c32; c32.full = lv_color_to32(color); - uint16_t bright = 3 * c32.ch.red + c32.ch.blue + 4 * c32.ch.green; - return (uint16_t)bright >> 3; + uint16_t bright = (uint16_t)(3u * LV_COLOR_GET_R32(c32) + LV_COLOR_GET_B32(c32) + 4u * LV_COLOR_GET_G32(c32)); + return (uint8_t)(bright >> 3); } /* The most simple macro to create a color from R,G and B values */ #if LV_COLOR_DEPTH == 1 -#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(b8 >> 7 | g8 >> 7 | r8 >> 7)}) +#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){.full = (b8 >> 7 | g8 >> 7 | r8 >> 7)}) static inline lv_color_t lv_color_make(int r8, int g8, int b8) { - lv_color_t color; + lv_color_t color = { 0 }; color.full = (b8 >> 7 | g8 >> 7 | r8 >> 7); return color; } @@ -472,43 +544,36 @@ static inline lv_color_t lv_color_make(int r8, int g8, int b8) static inline lv_color_t lv_color_make(uint8_t r8, int g8, int b8) { lv_color_t color; - color.ch.blue = b8 >> 6; - color.ch.green = g8 >> 5; - color.ch.red = r8 >> 5; + LV_COLOR_SET_B(color, b8 >> 6); + LV_COLOR_SET_G(color, g8 >> 5); + LV_COLOR_SET_R(color, r8 >> 5); + LV_COLOR_SET_A(color, 0xFF); return color; } #elif LV_COLOR_DEPTH == 16 #if LV_COLOR_16_SWAP == 0 #define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}}) -static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8) -{ - lv_color_t color; - color.ch.blue = (uint16_t)(b8 >> 3); - color.ch.green = (uint16_t)(g8 >> 2); - color.ch.red = (uint16_t)(r8 >> 3); - return color; -} #else #define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{g8 >> 5, r8 >> 3, b8 >> 3, (g8 >> 2) & 0x7}}) +#endif static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8) { lv_color_t color; - color.ch.green_h = (uint16_t)(g8 >> 5); - color.ch.red = (uint16_t)(r8 >> 3); - color.ch.blue = (uint16_t)(b8 >> 3); - color.ch.green_l = (uint16_t)((g8 >> 2) & 0x7); + LV_COLOR_SET_B(color, b8 >> 3); + LV_COLOR_SET_G(color, g8 >> 2); + LV_COLOR_SET_R(color, r8 >> 3); + LV_COLOR_SET_A(color, 0xFF); return color; } -#endif #elif LV_COLOR_DEPTH == 32 #define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/ static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8) { lv_color_t color; - color.ch.blue = b8; - color.ch.green = g8; - color.ch.red = r8; - color.ch.alpha = 0xff; + LV_COLOR_SET_B(color, b8); + LV_COLOR_SET_G(color, g8); + LV_COLOR_SET_R(color, r8); + LV_COLOR_SET_A(color, 0xFF); return color; } #endif @@ -534,13 +599,20 @@ static inline lv_color_t lv_color_hex3(uint32_t c) lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v); /** - * Convert an RGB color to HSV - * @param r red - * @param g green - * @param b blue - * @return the given RGB color n HSV + * Convert a 32-bit RGB color to HSV + * @param r8 8-bit red + * @param g8 8-bit green + * @param b8 8-bit blue + * @return the given RGB color in HSV */ -lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b); +lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8); + +/** + * Convert a color to HSV + * @param color color + * @return the given color in HSV + */ +lv_color_hsv_t lv_color_to_hsv(lv_color_t color); /********************** * MACROS diff --git a/src/lv_misc/lv_log.c b/src/lv_misc/lv_log.c index 2d12da4e1..acbdfb732 100644 --- a/src/lv_misc/lv_log.c +++ b/src/lv_misc/lv_log.c @@ -12,6 +12,7 @@ #if LV_LOG_PRINTF #include #endif + /********************* * DEFINES *********************/ diff --git a/src/lv_misc/lv_math.c b/src/lv_misc/lv_math.c index 534bea0f8..77db624c4 100644 --- a/src/lv_misc/lv_math.c +++ b/src/lv_misc/lv_math.c @@ -312,7 +312,6 @@ uint16_t lv_atan2(int x, int y) return degree; } - /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_misc/lv_math.h b/src/lv_misc/lv_math.h index 76b3c7041..2782e887a 100644 --- a/src/lv_misc/lv_math.h +++ b/src/lv_misc/lv_math.h @@ -70,7 +70,6 @@ void lv_sqrt(uint32_t x, lv_sqrt_res_t * q); */ uint16_t lv_atan2(int x, int y); - /********************** * MACROS **********************/ diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index 504483004..ddf6d0179 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -56,7 +56,7 @@ uint32_t (*lv_txt_encoded_conv_wc)(uint32_t) = lv_txt_utf8_con uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *) = lv_txt_utf8_next; uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *) = lv_txt_utf8_prev; uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_utf8_get_byte_id; -uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t) = lv_txt_utf8_get_char_id; +uint32_t (*lv_txt_encoded_get_char_id)(const char *, uint32_t) = lv_txt_utf8_get_char_id; uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_utf8_get_length; #elif LV_TXT_ENC == LV_TXT_ENC_ASCII uint8_t (*lv_txt_encoded_size)(const char *) = lv_txt_iso8859_1_size; @@ -65,7 +65,7 @@ uint32_t (*lv_txt_encoded_conv_wc)(uint32_t) = lv_txt_iso8859_ uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *) = lv_txt_iso8859_1_next; uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *) = lv_txt_iso8859_1_prev; uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_byte_id; -uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_char_id; +uint32_t (*lv_txt_encoded_get_char_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_char_id; uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_iso8859_1_get_length; #endif @@ -149,17 +149,21 @@ void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * * 3. Return i=9, pointing at breakchar '\n' * 4. Parenting lv_txt_get_next_line() would detect subsequent '\0' * + * TODO: Returned word_w_ptr may overestimate the returned word's width when + * max_width is reached. In current usage, this has no impact. + * * @param txt a '\0' terminated string * @param font pointer to a font * @param letter_space letter space * @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid line breaks * @param flags settings for the text from 'txt_flag_type' enum * @param[out] word_w_ptr width (in pixels) of the parsed word. May be NULL. + * @param force Force return the fraction of the word that can fit in the provided space. * @return the index of the first char of the next word (in byte index not letter index. With UTF-8 they are different) */ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, lv_coord_t letter_space, lv_coord_t max_width, - lv_txt_flag_t flag, uint32_t *word_w_ptr) + lv_txt_flag_t flag, uint32_t *word_w_ptr, bool force) { if(txt == NULL || txt[0] == '\0') return 0; if(font == NULL) return 0; @@ -179,6 +183,7 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, letter = lv_txt_encoded_next(txt, &i_next); i_next_next = i_next; + /* Obtain the full word, regardless if it fits or not in max_width */ while(txt[i] != '\0') { letter_next = lv_txt_encoded_next(txt, &i_next_next); word_len++; @@ -196,17 +201,10 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, letter_w = lv_font_get_glyph_width(font, letter, letter_next); cur_w += letter_w; - /* Test if this character fits within max_width */ - if( break_index == NO_BREAK_FOUND && cur_w > max_width) { + if(break_index == NO_BREAK_FOUND && cur_w > max_width) { break_index = i; - if(break_index > 0) { /* zero is possible if first character doesn't fit in width */ - lv_txt_encoded_prev(txt, &break_index); - break_letter_count = word_len - 2; - } - else{ - break_letter_count = word_len - 1; - } + break_letter_count = word_len - 1; /* break_index is now pointing at the character that doesn't fit */ } @@ -237,14 +235,17 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, return i; } +#if LV_TXT_LINE_BREAK_LONG_LEN > 0 /* Word doesn't fit in provided space, but isn't "long" */ if(word_len < LV_TXT_LINE_BREAK_LONG_LEN) { - if(word_w_ptr != NULL) *word_w_ptr = 0; + if( force ) return break_index; + if(word_w_ptr != NULL) *word_w_ptr = 0; /* Return no word */ return 0; } /* Word is "long," but insufficient amounts can fit in provided space */ if(break_letter_count < LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN) { + if( force ) return break_index; if(word_w_ptr != NULL) *word_w_ptr = 0; return 0; } @@ -256,16 +257,24 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, /* Move pointer "i" backwards */ for(;n_move>0; n_move--){ lv_txt_encoded_prev(txt, &i); - // todo: it would be appropriate to update the returned word width here + // TODO: it would be appropriate to update the returned word width here // However, in current usage, this doesn't impact anything. } } - return i; +#else + if( force ) return break_index; + if(word_w_ptr != NULL) *word_w_ptr = 0; /* Return no word */ + (void) break_letter_count; + return 0; +#endif } /** * Get the next line of text. Check line length and break chars too. + * + * A line of txt includes the \n character. + * * @param txt a '\0' terminated string * @param font pointer to a font * @param letter_space letter space @@ -285,7 +294,7 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, while(txt[i] != '\0' && max_width > 0) { uint32_t word_w = 0; - uint32_t advance = lv_txt_get_next_word(&txt[i], font, letter_space, max_width, flag, &word_w); + uint32_t advance = lv_txt_get_next_word(&txt[i], font, letter_space, max_width, flag, &word_w, i==0); max_width -= word_w; if( advance == 0 ){ @@ -295,21 +304,16 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, i += advance; - if(txt[i] == '\n') break; + if(txt[0] == '\n') break; + + if(txt[i] == '\n'){ + i++; /* Include the following newline in the current line */ + break; + } + } - /* If this is the last of the string, make sure pointer is at NULL-terminator. - * This catches the case, for example of a string ending in "\n" */ - if(txt[i] != '\0'){ - uint32_t i_next = i; - int tmp; - uint32_t letter_next = lv_txt_encoded_next(txt, &i_next); /*Gets current character*/ - tmp = i_next; - letter_next = lv_txt_encoded_next(txt, &i_next); /*Gets subsequent character*/ - if(letter_next == '\0') i = tmp; - } - - /*Always step at least one to avoid infinite loops*/ + /* Always step at least one to avoid infinite loops */ if(i == 0) { lv_txt_encoded_next(txt, &i); } diff --git a/src/lv_misc/lv_txt.h b/src/lv_misc/lv_txt.h index 6fc6e4a63..865e2c97c 100644 --- a/src/lv_misc/lv_txt.h +++ b/src/lv_misc/lv_txt.h @@ -188,7 +188,7 @@ extern uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t); * @param byte_id byte index * @return character index of the letter at 'byte_id'th position */ -extern uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t); +extern uint32_t (*lv_txt_encoded_get_char_id)(const char *, uint32_t); /** * Get the number of characters (and NOT bytes) in a string. diff --git a/src/lv_objx/lv_btnm.c b/src/lv_objx/lv_btnm.c index 25797f186..37bf82614 100644 --- a/src/lv_objx/lv_btnm.c +++ b/src/lv_objx/lv_btnm.c @@ -670,11 +670,6 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar lv_txt_flag_t txt_flag = LV_TXT_FLAG_NONE; if(ext->recolor) txt_flag = LV_TXT_FLAG_RECOLOR; -#if LV_USE_BIDI - char * bidi_buf = lv_mem_alloc(64); - lv_bidi_dir_t base_dir = lv_obj_get_base_dir(btnm); -#endif - for(btn_i = 0; btn_i < ext->btn_cnt; btn_i++, txt_i++) { /*Search the next valid text in the map*/ while(strcmp(ext->map_p[txt_i], "\n") == 0) { @@ -743,22 +738,8 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar area_tmp.x2 = area_tmp.x1 + txt_size.x; area_tmp.y2 = area_tmp.y1 + txt_size.y; -#if LV_USE_BIDI == 0 - lv_draw_label(&area_tmp, clip_area, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, NULL, NULL); -#else - uint32_t txt_len = strlen(ext->map_p[txt_i]) + 1; - if(txt_len > lv_mem_get_size(bidi_buf)) { - bidi_buf = lv_mem_realloc(bidi_buf, txt_len); - } - - lv_bidi_process(ext->map_p[txt_i], bidi_buf, base_dir); - lv_draw_label(&area_tmp, clip_area, btn_style, opa_scale, bidi_buf, txt_flag, NULL, NULL, NULL); -#endif + lv_draw_label(&area_tmp, clip_area, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, NULL, NULL, lv_obj_get_base_dir(btnm)); } - -#if LV_USE_BIDI - lv_mem_free(bidi_buf); -#endif } return LV_DESIGN_RES_OK; } diff --git a/src/lv_objx/lv_calendar.c b/src/lv_objx/lv_calendar.c index 1b92331b7..c4346706d 100644 --- a/src/lv_objx/lv_calendar.c +++ b/src/lv_objx/lv_calendar.c @@ -670,6 +670,9 @@ static lv_coord_t get_day_names_height(lv_obj_t * calendar) static void draw_header(lv_obj_t * calendar, const lv_area_t * mask) { lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar); + + lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(calendar); + lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar); lv_area_t header_area; @@ -687,19 +690,19 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask) txt_buf[5] = '\0'; strcpy(&txt_buf[5], get_month_name(calendar, ext->showed_date.month)); header_area.y1 += ext->style_header->body.padding.top; - lv_draw_label(&header_area, mask, ext->style_header, opa_scale, txt_buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL); + lv_draw_label(&header_area, mask, ext->style_header, opa_scale, txt_buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL, bidi_dir); /*Add the left arrow*/ const lv_style_t * arrow_style = ext->btn_pressing < 0 ? ext->style_header_pr : ext->style_header; header_area.x1 += ext->style_header->body.padding.left; - lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_LEFT, LV_TXT_FLAG_NONE, NULL, NULL, NULL); + lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_LEFT, LV_TXT_FLAG_NONE, NULL, NULL, NULL, bidi_dir); /*Add the right arrow*/ arrow_style = ext->btn_pressing > 0 ? ext->style_header_pr : ext->style_header; header_area.x1 = header_area.x2 - ext->style_header->body.padding.right - lv_txt_get_width(LV_SYMBOL_RIGHT, strlen(LV_SYMBOL_RIGHT), arrow_style->text.font, arrow_style->text.line_space, LV_TXT_FLAG_NONE); - lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_RIGHT, LV_TXT_FLAG_NONE, NULL, NULL, NULL); + lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_RIGHT, LV_TXT_FLAG_NONE, NULL, NULL, NULL, bidi_dir); } /** @@ -710,6 +713,7 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask) static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask) { lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar); + lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(calendar); lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar); lv_coord_t l_pad = ext->style_day_names->body.padding.left; @@ -724,7 +728,7 @@ static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask) label_area.x1 = calendar->coords.x1 + (w * i) / 7 + l_pad; label_area.x2 = label_area.x1 + box_w - 1; lv_draw_label(&label_area, mask, ext->style_day_names, opa_scale, get_day_name(calendar, i), LV_TXT_FLAG_CENTER, - NULL, NULL, NULL); + NULL, NULL, NULL, bidi_dir); } } @@ -736,6 +740,7 @@ static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask) static void draw_days(lv_obj_t * calendar, const lv_area_t * mask) { lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar); + lv_bidi_dir_t bidi_dir = lv_obj_get_base_dir(calendar); const lv_style_t * style_bg = lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG); lv_area_t label_area; lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar); @@ -853,7 +858,7 @@ static void draw_days(lv_obj_t * calendar, const lv_area_t * mask) /*Write the day's number*/ lv_utils_num_to_str(day_cnt, buf); - lv_draw_label(&label_area, mask, final_style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL); + lv_draw_label(&label_area, mask, final_style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL, bidi_dir); /*Go to the next day*/ day_cnt++; diff --git a/src/lv_objx/lv_canvas.c b/src/lv_objx/lv_canvas.c index 4c7fbdaa5..efb991e9b 100644 --- a/src/lv_objx/lv_canvas.c +++ b/src/lv_objx/lv_canvas.c @@ -823,7 +823,7 @@ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord default: flag = LV_TXT_FLAG_NONE; break; } - lv_draw_label(&coords, &mask, style, LV_OPA_COVER, txt, flag, NULL, NULL, NULL); + lv_draw_label(&coords, &mask, style, LV_OPA_COVER, txt, flag, NULL, NULL, NULL, lv_obj_get_base_dir(canvas)); lv_refr_set_disp_refreshing(refr_ori); } diff --git a/src/lv_objx/lv_chart.c b/src/lv_objx/lv_chart.c index 327af66a9..471bfb650 100644 --- a/src/lv_objx/lv_chart.c +++ b/src/lv_objx/lv_chart.c @@ -1394,7 +1394,7 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask, uint a.x2 = p2.x + size.x + LV_CHART_AXIS_TO_LABEL_DISTANCE; } - lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL); + lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL, lv_obj_get_base_dir(chart)); } } @@ -1480,7 +1480,7 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask) /* set the area at some distance of the major tick len under of the tick */ lv_area_t a = {(p2.x - size.x / 2), (p2.y + LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.x + size.x / 2), (p2.y + size.y + LV_CHART_AXIS_TO_LABEL_DISTANCE)}; - lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL); + lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL, lv_obj_get_base_dir(chart)); } } } diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index a47169fe8..d7226c658 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1,6 +1,7 @@ /** * @file lv_cpicker.c * + * From @AloyseTech and @paulpv. */ /********************* @@ -57,10 +58,11 @@ static lv_design_res_t lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * clip_area, lv_design_mode_t mode); static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); -static void invalidate_indic(lv_obj_t * cpicker); static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); +static void invalidate_indic(lv_obj_t * cpicker); +static lv_area_t get_indic_area(lv_obj_t * cpicker); static void next_color_mode(lv_obj_t * cpicker); static lv_res_t double_click_reset(lv_obj_t * cpicker); @@ -105,6 +107,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) if(ext == NULL) return NULL; /*Initialize the allocated 'ext' */ + ext->type = LV_CPICKER_DEF_TYPE; ext->hsv = LV_CPICKER_DEF_HSV; ext->indic.style = &lv_style_plain; ext->indic.colored = 0; @@ -120,8 +123,8 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*If no copy do the basic initialization*/ if(copy == NULL) { + lv_obj_set_size(new_cpicker, LV_DPI * 2, LV_DPI * 2); lv_obj_set_protect(new_cpicker, LV_PROTECT_PRESS_LOST); - refr_indic_pos(new_cpicker); lv_theme_t * th = lv_theme_get_current(); if(th) { lv_cpicker_set_style(new_cpicker, LV_CPICKER_STYLE_MAIN, th->style.bg); @@ -200,91 +203,85 @@ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_ * Set the current hue of a colorpicker. * @param cpicker pointer to colorpicker object * @param hue current selected hue [0..360] + * @return true if changed, otherwise false */ -void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) +bool lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) { - LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - ext->hsv.h = hue % 360; - - if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) refr_indic_pos(cpicker); - - if(ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { - lv_obj_invalidate(cpicker); - } + lv_color_hsv_t hsv = lv_cpicker_get_hsv(cpicker); + hsv.h = hue; + return lv_cpicker_set_hsv(cpicker, hsv); } /** * Set the current saturation of a colorpicker. * @param cpicker pointer to colorpicker object * @param saturation current selected saturation [0..100] + * @return true if changed, otherwise false */ -void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) +bool lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) { - LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - ext->hsv.s = saturation > 100 ? 100 : saturation; - - if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) refr_indic_pos(cpicker); - - if(ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { - lv_obj_invalidate(cpicker); - } + lv_color_hsv_t hsv = lv_cpicker_get_hsv(cpicker); + hsv.s = saturation; + return lv_cpicker_set_hsv(cpicker, hsv); } /** * Set the current value of a colorpicker. * @param cpicker pointer to colorpicker object * @param val current selected value [0..100] + * @return true if changed, otherwise false */ -void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) +bool lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) { - LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - ext->hsv.v = val > 100 ? 100 : val; - - if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) refr_indic_pos(cpicker); - - if(ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { - lv_obj_invalidate(cpicker); - } + lv_color_hsv_t hsv = lv_cpicker_get_hsv(cpicker); + hsv.v = val; + return lv_cpicker_set_hsv(cpicker, hsv); } /** * Set the current hsv of a colorpicker. * @param cpicker pointer to colorpicker object * @param color current selected hsv + * @return true if changed, otherwise false */ -void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) +bool lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) { LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + if (hsv.h > 360) hsv.h %= 360; + if (hsv.s > 100) hsv.s = 100; + if (hsv.v > 100) hsv.v = 100; + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + if (ext->hsv.h == hsv.h && ext->hsv.s == hsv.s && ext->hsv.v == hsv.v) return false; + ext->hsv = hsv; + refr_indic_pos(cpicker); - lv_obj_invalidate(cpicker); + + if (ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { + lv_obj_invalidate(cpicker); + } + + return true; } /** * Set the current color of a colorpicker. * @param cpicker pointer to colorpicker object * @param color current selected color + * @return true if changed, otherwise false */ -void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) +bool lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) { LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); lv_color32_t c32; c32.full = lv_color_to32(color); - lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(c32.ch.red, c32.ch.green, c32.ch.blue)); + return lv_cpicker_set_hsv(cpicker, + lv_color_rgb_to_hsv(LV_COLOR_GET_R(color), LV_COLOR_GET_G(color), LV_COLOR_GET_B(color))); } /** @@ -662,25 +659,10 @@ static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t lv_draw_rect(&rect_area, mask, &style, opa_scale); } } -/** - * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_circle` - */ + static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); - - lv_coord_t h = lv_obj_get_height(cpicker); - uint16_t r; - if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; - else if(ext->type == LV_CPICKER_TYPE_RECT) r = h / 2; - - lv_area_t ind_area; - ind_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; - ind_area.y1 = cpicker->coords.y1 + ext->indic.pos.y - r - style_indic->body.padding.right; - ind_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.top; - ind_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; lv_style_t style_cir; lv_style_copy(&style_cir, ext->indic.style); @@ -691,8 +673,38 @@ static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_ style_cir.body.grad_color = style_cir.body.main_color; } + lv_area_t indic_area = get_indic_area(cpicker); - lv_draw_rect(&ind_area, mask, &style_cir, opa_scale); + lv_draw_rect(&indic_area, mask, &style_cir, opa_scale); +} + +static void invalidate_indic(lv_obj_t * cpicker) +{ + lv_area_t indic_area = get_indic_area(cpicker); + + lv_inv_area(lv_obj_get_disp(cpicker), &indic_area); +} + +static lv_area_t get_indic_area(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); + + uint16_t r; + if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; + else if(ext->type == LV_CPICKER_TYPE_RECT) { + lv_coord_t h = lv_obj_get_height(cpicker); + r = h / 2; + } + + lv_area_t indic_area; + indic_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; + indic_area.y1 = cpicker->coords.y1 + ext->indic.pos.y - r - style_indic->body.padding.right; + indic_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.top; + indic_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; + + return indic_area; } /** @@ -725,8 +737,7 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p } else if(sign == LV_SIGNAL_CORD_CHG) { /*Refresh extended draw area to make knob visible*/ if(lv_obj_get_width(cpicker) != lv_area_get_width(param) || - lv_obj_get_height(cpicker) != lv_area_get_height(param)) - { + lv_obj_get_height(cpicker) != lv_area_get_height(param)) { lv_obj_refresh_ext_draw_pad(cpicker); refr_indic_pos(cpicker); } @@ -753,10 +764,10 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p break; } - lv_cpicker_set_hsv(cpicker, hsv_cur); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_cpicker_set_hsv(cpicker, hsv_cur)) { + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { lv_color_hsv_t hsv_cur; @@ -774,10 +785,10 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p break; } - lv_cpicker_set_hsv(cpicker, hsv_cur); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_cpicker_set_hsv(cpicker, hsv_cur)) { + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } } else if(sign == LV_SIGNAL_PRESSED) { @@ -785,7 +796,7 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); res = double_click_reset(cpicker); if(res != LV_RES_OK) return res; - } else if(sign == LV_SIGNAL_PRESSING){ + } else if(sign == LV_SIGNAL_PRESSING) { lv_indev_t * indev = lv_indev_get_act(); if(indev == NULL) return res; @@ -846,30 +857,31 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p angle = lv_atan2(p.x, p.y) % 360; } + lv_color_hsv_t hsv_cur; + hsv_cur = ext->hsv; + switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - if(ext->hsv.h != angle) lv_cpicker_set_hue(cpicker, angle); + hsv_cur.h = angle; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = (angle * 100) / 360; - if(ext->hsv.s != angle) lv_cpicker_set_saturation(cpicker, angle); + hsv_cur.s = (angle * 100) / 360; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = (angle * 100) / 360; - if(ext->hsv.v != angle) lv_cpicker_set_value(cpicker, angle); + hsv_cur.v = (angle * 100) / 360; break; } - refr_indic_pos(cpicker); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_cpicker_set_hsv(cpicker, hsv_cur)) { + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } return res; } -static void next_color_mode(lv_obj_t * cpicker ) +static void next_color_mode(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->color_mode = (ext->color_mode + 1) % 3; @@ -877,32 +889,6 @@ static void next_color_mode(lv_obj_t * cpicker ) lv_obj_invalidate(cpicker); } - -/** - * Indicator points need to match those set in lv_cpicker_disc_design/lv_cpicker_rect_design - */ -static void invalidate_indic(lv_obj_t * cpicker) -{ - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); - - lv_coord_t h = lv_obj_get_height(cpicker); - - uint16_t r; - if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; - else if(ext->type == LV_CPICKER_TYPE_RECT) r = h / 2; - - lv_area_t indic_area; - indic_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; - indic_area.y1 = cpicker->coords.y1 + ext->indic.pos.y - r - style_indic->body.padding.top; - indic_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.right; - indic_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; - - lv_inv_area(lv_obj_get_disp(cpicker), &indic_area); -} - static void refr_indic_pos(lv_obj_t * cpicker) { invalidate_indic(cpicker); @@ -927,15 +913,14 @@ static void refr_indic_pos(lv_obj_t * cpicker) ext->indic.pos.x = ind_pos; ext->indic.pos.y = h / 2; - } - if(ext->type == LV_CPICKER_TYPE_DISC) { + } else if(ext->type == LV_CPICKER_TYPE_DISC) { const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); lv_coord_t r = w / 2 - style_main->line.width / 2; uint16_t angle = get_angle(cpicker); ext->indic.pos.x = (((int32_t)r * lv_trigo_sin(angle)) >> LV_TRIGO_SHIFT); ext->indic.pos.y = (((int32_t)r * lv_trigo_sin(angle + 90)) >> LV_TRIGO_SHIFT); ext->indic.pos.x = ext->indic.pos.x + w / 2; - ext->indic.pos.y = ext->indic.pos.y + w / 2; + ext->indic.pos.y = ext->indic.pos.y + h / 2; } invalidate_indic(cpicker); @@ -947,21 +932,25 @@ static lv_res_t double_click_reset(lv_obj_t * cpicker) lv_indev_t * indev = lv_indev_get_act(); /*Double clicked? Use long press time as double click time out*/ if(lv_tick_elaps(ext->last_click_time) < indev->driver.long_press_time) { + lv_color_hsv_t hsv_cur; + hsv_cur = ext->hsv; + switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - lv_cpicker_set_hue(cpicker, LV_CPICKER_DEF_HUE); + hsv_cur.h = LV_CPICKER_DEF_HUE; break; case LV_CPICKER_COLOR_MODE_SATURATION: - lv_cpicker_set_saturation(cpicker, LV_CPICKER_DEF_SATURATION); + hsv_cur.s = LV_CPICKER_DEF_SATURATION; break; case LV_CPICKER_COLOR_MODE_VALUE: - lv_cpicker_set_value(cpicker, LV_CPICKER_DEF_VALUE); + hsv_cur.v = LV_CPICKER_DEF_VALUE; break; } - lv_res_t res; - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_cpicker_set_hsv(cpicker, hsv_cur)) { + lv_res_t res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } ext->last_click_time = lv_tick_get(); diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 7bce0fec8..a9feee5ae 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -93,7 +93,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy); * @param cpicker pointer to a colorpicker object * @param type new type of the colorpicker (from 'lv_cpicker_type_t' enum) */ -void lv_cpicker_set_type(lv_obj_t * chart, lv_cpicker_type_t type); +void lv_cpicker_set_type(lv_obj_t * cpicker, lv_cpicker_type_t type); /** * Set a style of a colorpicker. @@ -106,37 +106,42 @@ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_ /** * Set the current hue of a colorpicker. * @param cpicker pointer to colorpicker object - * @param hue current selected hue + * @param hue current selected hue [0..360] + * @return true if changed, otherwise false */ -void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue); +bool lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue); /** * Set the current saturation of a colorpicker. * @param cpicker pointer to colorpicker object - * @param saturation current selected saturation + * @param saturation current selected saturation [0..100] + * @return true if changed, otherwise false */ -void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation); +bool lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation); /** * Set the current value of a colorpicker. * @param cpicker pointer to colorpicker object - * @param val current selected value + * @param val current selected value [0..100] + * @return true if changed, otherwise false */ -void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val); +bool lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val); /** * Set the current hsv of a colorpicker. * @param cpicker pointer to colorpicker object * @param hsv current selected hsv + * @return true if changed, otherwise false */ -void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv); +bool lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv); /** * Set the current color of a colorpicker. * @param cpicker pointer to colorpicker object * @param color current selected color + * @return true if changed, otherwise false */ -void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color); +bool lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color); /** * Set the current color mode. diff --git a/src/lv_objx/lv_ddlist.c b/src/lv_objx/lv_ddlist.c index 570873136..697431627 100644 --- a/src/lv_objx/lv_ddlist.c +++ b/src/lv_objx/lv_ddlist.c @@ -609,7 +609,7 @@ static lv_design_res_t lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * cli new_style.text.opa = sel_style->text.opa; lv_txt_flag_t flag = lv_ddlist_get_txt_flag(ddlist); lv_draw_label(&ext->label->coords, &mask_sel, &new_style, opa_scale, lv_label_get_text(ext->label), - flag, NULL, NULL, NULL); + flag, NULL, NULL, NULL, lv_obj_get_base_dir(ddlist)); } } @@ -642,9 +642,9 @@ static lv_design_res_t lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * cli bool area_ok; area_ok = lv_area_intersect(&mask_arrow, clip_area, &area_arrow); if(area_ok) { + /*Use a down arrow in ddlist, you can replace it with yourcustom symbol*/ lv_draw_label(&area_arrow, &mask_arrow, &new_style, opa_scale, LV_SYMBOL_DOWN, LV_TXT_FLAG_NONE, - NULL, NULL, NULL); /*Use a down arrow in ddlist, you can replace it with your - custom symbol*/ + NULL, NULL, NULL, lv_obj_get_base_dir(ddlist)); } } } diff --git a/src/lv_objx/lv_gauge.c b/src/lv_objx/lv_gauge.c index e4ae3849d..a15ab1e7f 100644 --- a/src/lv_objx/lv_gauge.c +++ b/src/lv_objx/lv_gauge.c @@ -389,7 +389,7 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask) label_cord.x2 = label_cord.x1 + label_size.x; label_cord.y2 = label_cord.y1 + label_size.y; - lv_draw_label(&label_cord, mask, style, opa_scale, scale_txt, LV_TXT_FLAG_NONE, NULL, NULL, NULL); + lv_draw_label(&label_cord, mask, style, opa_scale, scale_txt, LV_TXT_FLAG_NONE, NULL, NULL, NULL, lv_obj_get_base_dir(gauge)); } } /** diff --git a/src/lv_objx/lv_img.c b/src/lv_objx/lv_img.c index b6c6fe50f..06b81fad0 100644 --- a/src/lv_objx/lv_img.c +++ b/src/lv_objx/lv_img.c @@ -479,10 +479,10 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area cords_tmp.y1 = coords.y1; cords_tmp.y2 = coords.y1 + ext->h - 1; - for(; cords_tmp.y1 < coords.y2; cords_tmp.y1 += ext->h, cords_tmp.y2 += ext->h) { + for(; cords_tmp.y1 <= coords.y2; cords_tmp.y1 += ext->h, cords_tmp.y2 += ext->h) { cords_tmp.x1 = coords.x1; cords_tmp.x2 = coords.x1 + ext->w - 1; - for(; cords_tmp.x1 < coords.x2; cords_tmp.x1 += ext->w, cords_tmp.x2 += ext->w) { + for(; cords_tmp.x1 <= coords.x2; cords_tmp.x1 += ext->w, cords_tmp.x2 += ext->w) { lv_draw_img(&cords_tmp, clip_area, ext->src, style, ext->angle, ext->zoom, ext->antialias, opa_scale); } } @@ -491,7 +491,7 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area lv_style_t style_mod; lv_style_copy(&style_mod, style); style_mod.text.color = style->image.color; - lv_draw_label(&coords, clip_area, &style_mod, opa_scale, ext->src, LV_TXT_FLAG_NONE, NULL, NULL, NULL); + lv_draw_label(&coords, clip_area, &style_mod, opa_scale, ext->src, LV_TXT_FLAG_NONE, NULL, NULL, NULL, lv_obj_get_base_dir(img)); } else { /*Trigger the error handler of image drawer*/ LV_LOG_WARN("lv_img_design: image source type is unknown"); diff --git a/src/lv_objx/lv_imgbtn.c b/src/lv_objx/lv_imgbtn.c index 346289ec1..1ef6e93f3 100644 --- a/src/lv_objx/lv_imgbtn.c +++ b/src/lv_objx/lv_imgbtn.c @@ -301,7 +301,7 @@ static lv_design_res_t lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * cli #if LV_IMGBTN_TILED == 0 const void * src = ext->img_src[state]; if(lv_img_src_get_type(src) == LV_IMG_SRC_SYMBOL) { - lv_draw_label(&imgbtn->coords, clip_area, style, opa_scale, src, LV_TXT_FLAG_NONE, NULL, NULL, NULL); + lv_draw_label(&imgbtn->coords, clip_area, style, opa_scale, src, LV_TXT_FLAG_NONE, NULL, NULL, NULL, lv_obj_get_base_dir(imgbtn)); } else { lv_draw_img(&imgbtn->coords, clip_area, src, style, 0, LV_IMG_ZOOM_NONE, false, opa_scale); } diff --git a/src/lv_objx/lv_kb.c b/src/lv_objx/lv_kb.c index 003bd4d33..1913316a2 100644 --- a/src/lv_objx/lv_kb.c +++ b/src/lv_objx/lv_kb.c @@ -396,7 +396,7 @@ void lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event) /*Add the characters to the text area if set*/ if(ext->ta == NULL) return; - if(strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) + if(strcmp(txt, "Enter") == 0 || strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) lv_ta_add_char(ext->ta, '\n'); else if(strcmp(txt, LV_SYMBOL_LEFT) == 0) lv_ta_cursor_left(ext->ta); diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index a9073ca00..3cac59c02 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -205,12 +205,8 @@ void lv_label_set_text(lv_obj_t * label, const char * text) LV_ASSERT_MEM(ext->text); if(ext->text == NULL) return; -#if LV_USE_BIDI == 0 strcpy(ext->text, text); -#else - lv_bidi_dir_t base_dir = lv_obj_get_base_dir(label); - lv_bidi_process(text, ext->text, base_dir); -#endif + /*Now the text is dynamically allocated*/ ext->static_txt = 0; } @@ -582,7 +578,7 @@ uint16_t lv_label_get_anim_speed(const lv_obj_t * label) * index (different in UTF-8) * @param pos store the result here (E.g. index = 0 gives 0;0 coordinates) */ -void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t * pos) +void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t char_id, lv_point_t * pos) { LV_ASSERT_OBJ(label, LV_OBJX_NAME); LV_ASSERT_NULL(pos); @@ -610,12 +606,12 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t max_w = LV_COORD_MAX; } - index = lv_txt_encoded_get_byte_id(txt, index); + uint16_t byte_id = lv_txt_encoded_get_byte_id(txt, char_id); /*Search the line of the index letter */; while(txt[new_line_start] != '\0') { new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag); - if(index < new_line_start || txt[new_line_start] == '\0') + if(byte_id < new_line_start || txt[new_line_start] == '\0') break; /*The line of 'index' letter begins at 'line_start'*/ y += letter_height + style->text.line_space; @@ -623,26 +619,50 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t } /*If the last character is line break then go to the next line*/ - if(index > 0) { - if((txt[index - 1] == '\n' || txt[index - 1] == '\r') && txt[index] == '\0') { + if(byte_id > 0) { + if((txt[byte_id - 1] == '\n' || txt[byte_id - 1] == '\r') && txt[byte_id] == '\0') { y += letter_height + style->text.line_space; - line_start = index; + line_start = byte_id; } } - /*Calculate the x coordinate*/ - lv_coord_t x = lv_txt_get_width(&txt[line_start], index - line_start, font, style->text.letter_space, flag); + const char *bidi_txt; + uint16_t visual_byte_pos; +#if LV_USE_BIDI + /*Handle Bidi*/ + if(new_line_start == byte_id) { + visual_byte_pos = byte_id - line_start; + bidi_txt = &txt[line_start]; + } + else { + uint16_t line_char_id = lv_txt_encoded_get_char_id(&txt[line_start], byte_id - line_start); - if(index != line_start) x += style->text.letter_space; + bool is_rtl; + char *mutable_bidi_txt; + uint16_t visual_char_pos = lv_bidi_get_visual_pos(&txt[line_start], &mutable_bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), line_char_id, &is_rtl); + bidi_txt = mutable_bidi_txt; + if (is_rtl) visual_char_pos++; + visual_byte_pos = lv_txt_encoded_get_byte_id(bidi_txt, visual_char_pos); + } +#else + bidi_txt = &txt[line_start]; + visual_byte_pos = byte_id - line_start; +#endif + + + /*Calculate the x coordinate*/ + lv_coord_t x = lv_txt_get_width(bidi_txt, visual_byte_pos, font, style->text.letter_space, flag); + + if(char_id != line_start) x += style->text.letter_space; if(align == LV_LABEL_ALIGN_CENTER) { lv_coord_t line_w; - line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); + line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag); x += lv_obj_get_width(label) / 2 - line_w / 2; } else if(align == LV_LABEL_ALIGN_RIGHT) { lv_coord_t line_w; - line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); + line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag); x += lv_obj_get_width(label) - line_w; } @@ -672,6 +692,8 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) uint8_t letter_height = lv_font_get_line_height(font); lv_coord_t y = 0; lv_txt_flag_t flag = LV_TXT_FLAG_NONE; + uint16_t logical_pos; + char *bidi_txt; if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR; if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND; @@ -689,43 +711,60 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) while(txt[line_start] != '\0') { new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag); - if(pos->y <= y + letter_height) break; /*The line is found (stored in 'line_start')*/ + if(pos->y <= y + letter_height) { + /*The line is found (stored in 'line_start')*/ + /* Include the NULL terminator in the last line */ + uint32_t tmp = new_line_start; + uint32_t letter; + letter = lv_txt_encoded_prev(txt, &tmp); + if(letter != '\n' && txt[new_line_start] == '\0' ) new_line_start++; + break; + } y += letter_height + style->text.line_space; line_start = new_line_start; } +#if LV_USE_BIDI + bidi_txt = lv_draw_get_buf(new_line_start - line_start + 1); + uint16_t txt_len = new_line_start - line_start; + if(bidi_txt[new_line_start] == '\0') txt_len--; + lv_bidi_process_paragraph(txt + line_start, bidi_txt, txt_len, lv_obj_get_base_dir(label), NULL, 0); +#else + bidi_txt = (char*)txt + line_start; +#endif + /*Calculate the x coordinate*/ lv_coord_t x = 0; if(align == LV_LABEL_ALIGN_CENTER) { lv_coord_t line_w; - line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); + line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag); x += lv_obj_get_width(label) / 2 - line_w / 2; } else if(align == LV_LABEL_ALIGN_RIGHT) { lv_coord_t line_w; - line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); + line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag); x += lv_obj_get_width(label) - line_w; } lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT; - uint32_t i = line_start; + uint32_t i = 0; uint32_t i_act = i; uint32_t letter; uint32_t letter_next; if(new_line_start > 0) { - while(i < new_line_start) { + while(i + line_start < new_line_start) { /* Get the current letter.*/ - letter = lv_txt_encoded_next(txt, &i); + letter = lv_txt_encoded_next(bidi_txt, &i); /*Get the next letter too for kerning*/ - letter_next = lv_txt_encoded_next(&txt[i], NULL); + letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL); /*Handle the recolor command*/ if((flag & LV_TXT_FLAG_RECOLOR) != 0) { - if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) { + if(lv_txt_is_cmd(&cmd_state, bidi_txt[i]) != false) { continue; /*Skip the letter is it is part of a command*/ } } @@ -733,7 +772,7 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) x += lv_font_get_glyph_width(font, letter, letter_next); /*Finish if the x position or the last char of the line is reached*/ - if(pos->x < x || i == new_line_start) { + if(pos->x < x || i + line_start == new_line_start) { i = i_act; break; } @@ -742,7 +781,16 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) } } - return lv_encoded_get_char_id(txt, i); +#if LV_USE_BIDI + /*Handle Bidi*/ + bool is_rtl; + logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, txt_len, lv_obj_get_base_dir(label), lv_txt_encoded_get_char_id(bidi_txt, i), &is_rtl); + if (is_rtl) logical_pos++; +#else + logical_pos = lv_txt_encoded_get_char_id(bidi_txt, i); +#endif + + return logical_pos + lv_txt_encoded_get_char_id(txt, line_start); } /** @@ -803,10 +851,11 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos) uint8_t letter_height = lv_font_get_line_height(font); lv_coord_t y = 0; lv_txt_flag_t flag = LV_TXT_FLAG_NONE; + lv_label_align_t align = lv_label_get_align(label); if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR; if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND; - if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER; + if(align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER; /*If the width will be expanded set the max length to very big */ if(ext->long_mode == LV_LABEL_LONG_EXPAND) { @@ -826,11 +875,16 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos) /*Calculate the x coordinate*/ lv_coord_t x = 0; lv_coord_t last_x = 0; - if(ext->align == LV_LABEL_ALIGN_CENTER) { + if(align == LV_LABEL_ALIGN_CENTER) { lv_coord_t line_w; line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); x += lv_obj_get_width(label) / 2 - line_w / 2; } + else if(align == LV_LABEL_ALIGN_RIGHT) { + lv_coord_t line_w; + line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); + x += lv_obj_get_width(label) - line_w; + } lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT; @@ -915,8 +969,6 @@ void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt) lv_mem_free(bidi_buf); #else lv_txt_ins(ext->text, pos, txt); -#endif - lv_label_refr_text(label); } @@ -1024,7 +1076,12 @@ static lv_design_res_t lv_label_design(lv_obj_t * label, const lv_area_t * clip_ sel.start = lv_label_get_text_sel_start(label); sel.end = lv_label_get_text_sel_end(label); +<<<<<<< HEAD lv_draw_label(&coords, clip_area, style, opa_scale, ext->text, flag, &ext->offset, &sel, hint); +======= + lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ext->offset, &sel, hint, lv_obj_get_base_dir(label)); + +>>>>>>> dev-6.1 if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) { lv_point_t size; @@ -1039,15 +1096,23 @@ static lv_design_res_t lv_label_design(lv_obj_t * label, const lv_area_t * clip_ lv_font_get_glyph_width(style->text.font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT; ofs.y = ext->offset.y; +<<<<<<< HEAD lv_draw_label(&coords, clip_area, style, opa_scale, ext->text, flag, &ofs, &sel, NULL); lv_draw_label(&coords, clip_area, style, opa_scale, ext->text, flag, &ofs, &sel, NULL); +======= + lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, &sel, NULL, lv_obj_get_base_dir(label)); +>>>>>>> dev-6.1 } /*Draw the text again below the original to make an circular effect */ if(size.y > lv_obj_get_height(label)) { ofs.x = ext->offset.x; ofs.y = ext->offset.y + size.y + lv_font_get_line_height(style->text.font); +<<<<<<< HEAD lv_draw_label(&coords, clip_area, style, opa_scale, ext->text, flag, &ofs, &sel, NULL); +======= + lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, &sel, NULL, lv_obj_get_base_dir(label)); +>>>>>>> dev-6.1 } } } diff --git a/src/lv_objx/lv_lmeter.c b/src/lv_objx/lv_lmeter.c index 3e949077d..75977e669 100644 --- a/src/lv_objx/lv_lmeter.c +++ b/src/lv_objx/lv_lmeter.c @@ -177,6 +177,21 @@ void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t line_cnt) lv_obj_invalidate(lmeter); } +/** + * Set the angle settings of a line meter + * @param lmeter pointer to a line meter object + * @param angle angle where the meter will be facing (with its center) + */ +void lv_lmeter_set_angle(lv_obj_t * lmeter, uint16_t angle) +{ + lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter); + if(ext->angle == angle) return; + + ext->angle = angle; + + lv_obj_invalidate(lmeter); +} + /*===================== * Getter functions *====================*/ @@ -287,7 +302,7 @@ static lv_design_res_t lv_lmeter_design(lv_obj_t * lmeter, const lv_area_t * cli lv_coord_t x_ofs = lv_obj_get_width(lmeter) / 2 + lmeter->coords.x1; lv_coord_t y_ofs = lv_obj_get_height(lmeter) / 2 + lmeter->coords.y1; - int16_t angle_ofs = 90 + (360 - ext->scale_angle) / 2; + int16_t angle_ofs = ext->angle + 90 + (360 - ext->scale_angle) / 2; int16_t level = (int32_t)((int32_t)(ext->cur_value - ext->min_value) * ext->line_cnt) / (ext->max_value - ext->min_value); uint8_t i; diff --git a/src/lv_objx/lv_lmeter.h b/src/lv_objx/lv_lmeter.h index e1a70a64f..49d662819 100644 --- a/src/lv_objx/lv_lmeter.h +++ b/src/lv_objx/lv_lmeter.h @@ -36,6 +36,7 @@ typedef struct /*No inherited ext.*/ /*Ext. of ancestor*/ /*New data for this type */ uint16_t scale_angle; /*Angle of the scale in deg. (0..360)*/ + uint16_t angle; uint8_t line_cnt; /*Count of lines */ int16_t cur_value; int16_t min_value; @@ -88,6 +89,13 @@ void lv_lmeter_set_range(lv_obj_t * lmeter, int16_t min, int16_t max); */ void lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t line_cnt); +/** + * Set the rotation settings of a line meter + * @param lmeter pointer to a line meter object + * @param angle angle of rotation (relative to the northen axis) + */ +void lv_lmeter_set_angle(lv_obj_t * lmeter, uint16_t angle); + /** * Set the styles of a line meter * @param lmeter pointer to a line meter object diff --git a/src/lv_objx/lv_roller.c b/src/lv_objx/lv_roller.c index 1da920909..c7b761379 100644 --- a/src/lv_objx/lv_roller.c +++ b/src/lv_objx/lv_roller.c @@ -397,7 +397,7 @@ static lv_design_res_t lv_roller_design(lv_obj_t * roller, const lv_area_t * cli new_style.text.color = sel_style->text.color; new_style.text.opa = sel_style->text.opa; lv_draw_label(&ext->ddlist.label->coords, &mask_sel, &new_style, opa_scale, - lv_label_get_text(ext->ddlist.label), txt_align, NULL, NULL, NULL); + lv_label_get_text(ext->ddlist.label), txt_align, NULL, NULL, NULL, lv_obj_get_base_dir(ext->ddlist.label)); } } diff --git a/src/lv_objx/lv_slider.c b/src/lv_objx/lv_slider.c index cdfd963c5..3081e8133 100644 --- a/src/lv_objx/lv_slider.c +++ b/src/lv_objx/lv_slider.c @@ -12,6 +12,7 @@ #include "../lv_core/lv_debug.h" #include "../lv_core/lv_group.h" +#include "../lv_core/lv_indev.h" #include "../lv_draw/lv_draw.h" #include "../lv_themes/lv_theme.h" #include "../lv_misc/lv_math.h" diff --git a/src/lv_objx/lv_sw.c b/src/lv_objx/lv_sw.c index 43c41ca4c..b7c616c16 100644 --- a/src/lv_objx/lv_sw.c +++ b/src/lv_objx/lv_sw.c @@ -18,6 +18,7 @@ #include "../lv_core/lv_debug.h" #include "../lv_themes/lv_theme.h" #include "../lv_misc/lv_math.h" +#include "../lv_core/lv_indev.h" /********************* * DEFINES diff --git a/src/lv_objx/lv_ta.c b/src/lv_objx/lv_ta.c index 1a296120e..e9b117c1a 100644 --- a/src/lv_objx/lv_ta.c +++ b/src/lv_objx/lv_ta.c @@ -1391,7 +1391,7 @@ static lv_design_res_t lv_ta_scrollable_design(lv_obj_t * scrl, const lv_area_t cur_area.x1 += cur_style.body.padding.left; cur_area.y1 += cur_style.body.padding.top; - lv_draw_label(&cur_area, clip_area, &cur_style, opa_scale, letter_buf, LV_TXT_FLAG_NONE, NULL, NULL, NULL); + lv_draw_label(&cur_area, clip_area, &cur_style, opa_scale, letter_buf, LV_TXT_FLAG_NONE, NULL, NULL, NULL, lv_obj_get_base_dir(ta)); } else if(ext->cursor.type == LV_CURSOR_OUTLINE) { cur_style.body.opa = LV_OPA_TRANSP; @@ -1889,7 +1889,7 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_ if(!ext->text_sel_in_prog && !click_outside_label && sign == LV_SIGNAL_PRESSED) { /*Input device just went down. Store the selection start position*/ ext->sel.start = char_id_at_click; - ext->sel.end = LV_DRAW_LABEL_NO_TXT_SEL; + ext->sel.end = LV_LABEL_TEXT_SEL_OFF; ext->text_sel_in_prog = 1; lv_obj_set_drag(lv_page_get_scrl(ta), false); } else if(ext->text_sel_in_prog && sign == LV_SIGNAL_PRESSING) { diff --git a/src/lv_objx/lv_table.c b/src/lv_objx/lv_table.c index 8b5a47db0..fc9d32241 100644 --- a/src/lv_objx/lv_table.c +++ b/src/lv_objx/lv_table.c @@ -145,14 +145,14 @@ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const uint32_t cell = row * ext->col_cnt + col; lv_table_cell_format_t format; - lv_bidi_dir_t base_dir = lv_obj_get_base_dir(table); - /*Save the format byte*/ if(ext->cell_data[cell]) { format.format_byte = ext->cell_data[cell][0]; } /*Initialize the format byte*/ else { +#if LV_USE_BIDI + lv_bidi_dir_t base_dir = lv_obj_get_base_dir(table); if(base_dir == LV_BIDI_DIR_LTR) format.s.align = LV_LABEL_ALIGN_LEFT; else if(base_dir == LV_BIDI_DIR_RTL) format.s.align = LV_LABEL_ALIGN_RIGHT; else if(base_dir == LV_BIDI_DIR_AUTO) @@ -167,12 +167,7 @@ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const } ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/ - -#if LV_USE_BIDI == 0 strcpy(ext->cell_data[cell] + 1, txt); /*+1 to skip the format byte*/ -#else - lv_bidi_process(txt, ext->cell_data[cell] + 1, base_dir); -#endif ext->cell_data[cell][0] = format.format_byte; refr_size(table); @@ -744,7 +739,7 @@ static lv_design_res_t lv_table_design(lv_obj_t * table, const lv_area_t * clip_ label_mask_ok = lv_area_intersect(&label_mask, clip_area, &cell_area); if(label_mask_ok) { lv_draw_label(&txt_area, &label_mask, cell_style, opa_scale, ext->cell_data[cell] + 1, - txt_flags, NULL, NULL, NULL); + txt_flags, NULL, NULL, NULL, lv_obj_get_base_dir(table)); } /*Draw lines after '\n's*/ lv_point_t p1;