diff --git a/legacy/evas/src/lib/Evas.h b/legacy/evas/src/lib/Evas.h index a6dc08b7f3..9418170c4b 100644 --- a/legacy/evas/src/lib/Evas.h +++ b/legacy/evas/src/lib/Evas.h @@ -320,6 +320,9 @@ extern "C" { double evas_object_text_inset_get (Evas_Object *obj); int evas_object_text_char_pos_get (Evas_Object *obj, int pos, double *cx, double *cy, double *cw, double *ch); int evas_object_text_char_coords_get (Evas_Object *obj, double x, double y, double *cx, double *cy, double *cw, double *ch); + + int evas_string_char_next_get (const char *str, int pos, int *decoded); + int evas_string_char_prev_get (const char *str, int pos, int *decoded); void evas_font_path_clear (Evas *e); void evas_font_path_append (Evas *e, const char *path); diff --git a/legacy/evas/src/lib/canvas/evas_object_text.c b/legacy/evas/src/lib/canvas/evas_object_text.c index db26a001d3..ecfdf9c214 100644 --- a/legacy/evas/src/lib/canvas/evas_object_text.c +++ b/legacy/evas/src/lib/canvas/evas_object_text.c @@ -848,6 +848,46 @@ evas_font_cache_get(Evas *e) return e->engine.func->font_cache_get(e->engine.data.output); } +/** + * To be documented. + * + * FIXME: To be fixed. + * + */ +int +evas_string_char_next_get(const char *str, int pos, int *decoded) +{ + int p, d; + + if (decoded) *decoded = 0; + if (!str) return 0; + if (pos < 0) return 0; + p = pos; + d = evas_common_font_utf8_get_next(str, &p); + if (decoded) *decoded = d; + return p; +} + +/** + * To be documented. + * + * FIXME: To be fixed. + * + */ +int +evas_string_char_prev_get(const char *str, int pos, int *decoded) +{ + int p, d; + + if (decoded) *decoded = 0; + if (!str) return 0; + if (pos < 0) return 0; + p = pos; + d = evas_common_font_utf8_get_prev(str, &p); + if (decoded) *decoded = d; + return p; +} + /* all nice and private */ diff --git a/legacy/evas/src/lib/engines/common/evas_font_main.c b/legacy/evas/src/lib/engines/common/evas_font_main.c index 5281fdf295..58eef5cdd5 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_main.c +++ b/legacy/evas/src/lib/engines/common/evas_font_main.c @@ -117,7 +117,7 @@ evas_common_font_utf8_get_next(unsigned char *buf, int *iindex) r <<= 6; r |= (d3 & 0x3f); } - else + else { /* 4 byte */ d2 = buf[index++]; @@ -133,15 +133,88 @@ evas_common_font_utf8_get_next(unsigned char *buf, int *iindex) r <<= 6; r |= (d3 & 0x3f); r <<= 6; - r |= (d4 & 0x3f); - - } - if (r < 0xdfff && d > 0xd800) - { - /* ill-formed says Table 3.1B in the */ - /* Unicode 3.2 std */ - return 0; + r |= (d4 & 0x3f); } *iindex = index; return r; } + +int +evas_common_font_utf8_get_prev(unsigned char *buf, int *iindex) +{ + /* Reads UTF8 bytes from @buf, starting at *@index and returns + * the code point of the previous valid code point. @index is + * updated ready for the next call. + * + * Returns 0 to indicate an error (e.g. invalid UTF8) + */ + int index = *iindex, r, istart = *iindex; + unsigned char d = buf[index++], d2, d3, d4; + + if (!d) + return 0; + if (d < 0x80) + { + r = d; + } + else if ((d & 0xe0) == 0xc0) + { + /* 2 byte */ + d2 = buf[index++]; + if ((d2 & 0xc0) != 0x80) + return 0; + r = d & 0x1f; /* copy lower 5 */ + r <<= 6; + r |= (d2 & 0x3f); /* copy lower 6 */ + } + else if ((d & 0xf0) == 0xe0) + { + /* 3 byte */ + d2 = buf[index++]; + d3 = buf[index++]; + if ((d2 & 0xc0) != 0x80 || + (d3 & 0xc0) != 0x80) + return 0; + r = d & 0x0f; /* copy lower 4 */ + r <<= 6; + r |= (d2 & 0x3f); + r <<= 6; + r |= (d3 & 0x3f); + } + else + { + /* 4 byte */ + d2 = buf[index++]; + d3 = buf[index++]; + d4 = buf[index++]; + if ((d2 & 0xc0) != 0x80 || + (d3 & 0xc0) != 0x80 || + (d4 & 0xc0) != 0x80) + return 0; + r = d & 0x0f; /* copy lower 4 */ + r <<= 6; + r |= (d2 & 0x3f); + r <<= 6; + r |= (d3 & 0x3f); + r <<= 6; + r |= (d4 & 0x3f); + } + index = istart - 1; + d = buf[index]; + if (!(d & 0x80)) + *iindex = index; + else + { + while (index > 0) + { + index--; + d = buf[index]; + if ((d & 0xc0) != 0x80) + { + *iindex = index; + return r; + } + } + } + return r; +} diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index 848fa46539..9ddb9704ae 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -794,7 +794,8 @@ void evas_common_font_query_advance (RGBA_Font *fn, const char * int evas_common_font_query_char_coords (RGBA_Font *fn, const char *text, int pos, int *cx, int *cy, int *cw, int *ch); int evas_common_font_query_text_at_pos (RGBA_Font *fn, const char *text, int x, int y, int *cx, int *cy, int *cw, int *ch); int evas_common_font_utf8_get_next (unsigned char *buf, int *iindex); - +int evas_common_font_utf8_get_prev (unsigned char *buf, int *iindex); + /****/ void evas_common_tilebuf_init (void);