X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fcharset.c;h=61a34cbcf449a6dd0eb870cfc9dd239d83109cf5;hb=3af5c3a185fc23b8fb9d528a9c0a14f70093ac70;hp=b948636f03c57e4ab31789ab42c02c535bb1058a;hpb=c39eb2cdf399c740c24884997364cf84c64fd46b;p=ncmpc.git diff --git a/src/charset.c b/src/charset.c index b948636..61a34cb 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1,6 +1,6 @@ -/* - * (c) 2006 by Kalle Wallin - * Copyright (C) 2008 Max Kellermann +/* ncmpc (Ncurses MPD Client) + * (c) 2004-2017 The Music Player Daemon Project + * Project homepage: http://musicpd.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -11,10 +11,10 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "charset.h" @@ -32,16 +32,32 @@ charset_init(void) { noconvert = g_get_charset(&charset); return charset; - return NULL; } #endif +#ifdef HAVE_CURSES_ENHANCED +static inline unsigned +unicode_char_width(gunichar ch) +{ + if (g_unichar_iszerowidth(ch)) + return 0; + + if (g_unichar_iswide(ch)) + return 2; + + return 1; +} +#endif /* HAVE_CURSES_ENHANCED */ + unsigned utf8_width(const char *str) { assert(str != NULL); -#ifdef ENABLE_WIDE +#if defined(ENABLE_MULTIBYTE) && !defined(HAVE_CURSES_ENHANCED) + return g_utf8_strlen(str, -1); +#else +#ifdef HAVE_CURSES_ENHANCED if (g_utf8_validate(str, -1, NULL)) { size_t len = g_utf8_strlen(str, -1); unsigned width = 0; @@ -49,7 +65,7 @@ utf8_width(const char *str) while (len--) { c = g_utf8_get_char(str); - width += g_unichar_iswide(c) ? 2 : 1; + width += unicode_char_width(c); str += g_unichar_to_utf8(c, NULL); } @@ -57,22 +73,105 @@ utf8_width(const char *str) } else #endif return strlen(str); +#endif +} + +unsigned +locale_width(const char *p) +{ +#if defined(ENABLE_LOCALE) && defined(ENABLE_MULTIBYTE) + char *utf8; + unsigned width; + + if (noconvert) + return utf8_width(p); + + utf8 = locale_to_utf8(p); + width = utf8_width(utf8); + g_free(utf8); + + return width; +#else + return strlen(p); +#endif +} + +gcc_unused +static 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; +} + +gcc_unused +static 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; +} + +gcc_unused +static unsigned +wide_cut_width(char *p, unsigned max_width) +{ + size_t length = g_utf8_strlen(p, -1); + unsigned width = 0, prev_width; + + while (length-- > 0) { + gunichar 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 HAVE_CURSES_ENHANCED + 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(HAVE_CURSES_ENHANCED) + return narrow_cut_width(p, max_width); +#else + return ascii_cut_width(p, max_width); +#endif } char * utf8_to_locale(const char *utf8str) { #ifdef ENABLE_LOCALE - gchar *str; - assert(utf8str != NULL); if (noconvert) return g_strdup(utf8str); - str = g_convert_with_fallback(utf8str, -1, - charset, "utf-8", - NULL, NULL, NULL, NULL); + gchar *str = g_convert_with_fallback(utf8str, -1, + charset, "utf-8", + NULL, NULL, NULL, NULL); if (str == NULL) return g_strdup(utf8str); @@ -86,16 +185,14 @@ char * locale_to_utf8(const char *localestr) { #ifdef ENABLE_LOCALE - gchar *str; - assert(localestr != NULL); if (noconvert) return g_strdup(localestr); - str = g_convert_with_fallback(localestr, -1, - "utf-8", charset, - NULL, NULL, NULL, NULL); + gchar *str = g_convert_with_fallback(localestr, -1, + "utf-8", charset, + NULL, NULL, NULL, NULL); if (str == NULL) return g_strdup(localestr); @@ -104,3 +201,34 @@ locale_to_utf8(const char *localestr) return g_strdup(localestr); #endif } + +char * +replace_utf8_to_locale(char *src) +{ +#ifdef ENABLE_LOCALE + assert(src != NULL); + + if (noconvert) + return src; + + return utf8_to_locale(src); +#else + return src; +#endif +} + + +char * +replace_locale_to_utf8(char *src) +{ +#ifdef ENABLE_LOCALE + assert(src != NULL); + + if (noconvert) + return src; + + return locale_to_utf8(src); +#else + return src; +#endif +}