diff --git a/libretro-common/encodings/encoding_utf.c b/libretro-common/encodings/encoding_utf.c index f130f15a3a..e6ab4a81f8 100644 --- a/libretro-common/encodings/encoding_utf.c +++ b/libretro-common/encodings/encoding_utf.c @@ -22,8 +22,10 @@ #include #include +#include #include +#include #include static INLINE unsigned leading_ones(uint8_t c) @@ -133,3 +135,76 @@ bool utf16_conv_utf8(uint8_t *out, size_t *out_chars, *out_chars = out_pos; return false; } + +/* Acts mostly like strlcpy. + * + * Copies the given number of UTF-8 characters, + * but at most d_len bytes. + * + * Always NULL terminates. + * Does not copy half a character. + * + * Returns number of bytes. 's' is assumed valid UTF-8. + * Use only if 'chars' is considerably less than 'd_len'. */ +size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars) +{ +#ifdef HAVE_UTF8 + char *d_org = d; + char *d_end = d+d_len; + const uint8_t *sb = (const uint8_t*)s; + const uint8_t *sb_org = sb; + + while (*sb && chars-- > 0) + { + sb++; + while ((*sb&0xC0) == 0x80) sb++; + } + + if (sb - sb_org > d_len-1 /* NUL */) + { + sb = sb_org + d_len-1; + while ((*sb&0xC0) == 0x80) sb--; + } + + memcpy(d, sb_org, sb-sb_org); + d[sb-sb_org] = '\0'; + + return sb-sb_org; +#else + return strlcpy(d, s, chars + 1); +#endif +} + +const char *utf8skip(const char *str, size_t chars) +{ +#ifdef HAVE_UTF8 + const uint8_t *strb = (const uint8_t*)str; + if (!chars) + return str; + do + { + strb++; + while ((*strb&0xC0)==0x80) strb++; + chars--; + } while(chars); + return (const char*)strb; +#else + return str + chars; +#endif +} + +size_t utf8len(const char *string) +{ +#ifdef HAVE_UTF8 + size_t ret = 0; + while (*string) + { + if ((*string & 0xC0) != 0x80) + ret++; + string++; + } + return ret; +#else + return strlen(string); +#endif +} diff --git a/libretro-common/include/encodings/utf.h b/libretro-common/include/encodings/utf.h index 200892457c..a3c630c783 100644 --- a/libretro-common/include/encodings/utf.h +++ b/libretro-common/include/encodings/utf.h @@ -28,10 +28,24 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + size_t utf8_conv_utf32(uint32_t *out, size_t out_chars, const char *in, size_t in_size); bool utf16_conv_utf8(uint8_t *out, size_t *out_chars, const uint16_t *in, size_t in_size); +size_t utf8len(const char *string); + +size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars); + +const char *utf8skip(const char *str, size_t chars); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index ac3637f16a..f544b96b3d 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -193,19 +194,8 @@ static uint32_t string_walk(const char **string) return ret | (first&7)<<6; } -size_t utf8len(const char *string) -{ - size_t ret = 0; - while (*string) - { - if ((*string & 0xC0) != 0x80) ret++; - string++; - } - return ret; -} #else #define string_walk string_walkbyte -#define utf8len strlen #endif static void blit_line(int x, int y, diff --git a/menu/menu_animation.c b/menu/menu_animation.c index 9120c6e1ea..821ce991de 100644 --- a/menu/menu_animation.c +++ b/menu/menu_animation.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "menu_animation.h" @@ -587,54 +588,6 @@ bool menu_animation_push(float duration, float target_value, float* subject, return true; } -#ifdef HAVE_UTF8 -size_t utf8len(const char *string); /* rgui.c */ - -/* Acts mostly like strlcpy. Copies the given number of UTF-8 characters, but at most d_len bytes. - * Always NUL terminates. Does not copy half a character. Returns number of bytes. 's' is assumed valid UTF-8. - * Use only if 'chars' is considerably less than 'd_len'. */ -size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars) -{ - char *d_org = d; - char *d_end = d+d_len; - const uint8_t *sb = (const uint8_t*)s; - const uint8_t *sb_org = sb; - - while (*sb && chars-- > 0) - { - sb++; - while ((*sb&0xC0) == 0x80) sb++; - } - - if (sb - sb_org > d_len-1 /* NUL */) - { - sb = sb_org + d_len-1; - while ((*sb&0xC0) == 0x80) sb--; - } - - memcpy(d, sb_org, sb-sb_org); - d[sb-sb_org] = '\0'; - - return sb-sb_org; -} - -const char *utf8skip(const char *str, size_t chars) -{ - const uint8_t *strb = (const uint8_t*)str; - if (!chars) return str; - do { - strb++; - while ((*strb&0xC0)==0x80) strb++; - chars--; - } while(chars); - return (const char*)strb; -} -#else -#define utf8len strlen -#define utf8cpy(d,dl,s,sl) strlcpy((d),(s),(sl)+1) -#define utf8skip(str, chars) ((str)+(chars)) -#endif - /** * menu_animation_ticker_str: * @s : buffer to write new message line to.