From: Max Kellermann Date: Tue, 20 Oct 2009 06:00:09 +0000 (+0200) Subject: charset: added function utf8_cut_width() X-Git-Tag: release-0.16~68 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=5560a99873b1a77021e4050c0aac7e8277e0e329;p=ncmpc.git charset: added function utf8_cut_width() This function helps printing UTF-8 strings on limited screen space. --- diff --git a/src/charset.c b/src/charset.c index 59d1a26..8e7ed0f 100644 --- a/src/charset.c +++ b/src/charset.c @@ -62,6 +62,68 @@ utf8_width(const char *str) #endif } +static inline unsigned +ascii_cut_width(char *p, unsigned max_width) +{ + size_t length = strlen(p); + if (length <= (size_t)max_width) + return (unsigned)length; + + p[max_width] = 0; + return max_width; +} + +static inline unsigned +narrow_cut_width(char *p, unsigned max_width) +{ + size_t length = g_utf8_strlen(p, -1); + if (length <= (size_t)max_width) + return (unsigned)length; + + *g_utf8_offset_to_pointer(p, max_width) = 0; + return max_width; +} + +static inline unsigned +wide_cut_width(char *p, unsigned max_width) +{ + size_t length = g_utf8_strlen(p, -1); + unsigned width = 0, prev_width; + gunichar c; + + while (length-- > 0) { + c = g_utf8_get_char(p); + prev_width = width; + width += g_unichar_iswide(c) ? 2 : 1; + if (width > max_width) { + /* too wide - cut the rest off */ + *p = 0; + return prev_width; + } + + p += g_unichar_to_utf8(c, NULL); + } + + return width; +} + +unsigned +utf8_cut_width(char *p, unsigned max_width) +{ + assert(p != NULL); + +#ifdef ENABLE_WIDE + if (!g_utf8_validate(p, -1, NULL)) + return ascii_cut_width(p, max_width); + + return wide_cut_width(p, max_width); +#elif defined(ENABLE_MULTIBYTE) && !defined(ENABLE_WIDE) + return narrow_cut_width(p, max_width); +#else + return ascii_cut_width(p, max_width); +#endif +} + char * utf8_to_locale(const char *utf8str) { diff --git a/src/charset.h b/src/charset.h index a08054b..e64eb19 100644 --- a/src/charset.h +++ b/src/charset.h @@ -38,6 +38,15 @@ G_GNUC_PURE unsigned utf8_width(const char *str); +/** + * Limits the width of the specified string. Cuts it off before the + * specified width is exceeded. + * + * @return the resulting width of the string + */ +unsigned +utf8_cut_width(char *p, unsigned max_width); + char *utf8_to_locale(const char *str); char *locale_to_utf8(const char *str);