X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fcharset.c;h=34381adfcdc3f195a5d7ac6fa139d2c95b70af89;hb=473cfa9b9feef4348873865fd9503690b3207c0c;hp=a0e8bbda4dca3fb07ff55f05d622274502361f6a;hpb=e67c9454f910f1d202da8d84dc33adec689ae815;p=ncmpc.git diff --git a/src/charset.c b/src/charset.c index a0e8bbd..34381ad 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1,21 +1,21 @@ -/* - * (c) 2006 by Kalle Wallin - * Copyright (C) 2008 Max Kellermann - * +/* ncmpc (Ncurses MPD Client) + * (c) 2004-2010 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * This program is distributed in the hope that it will be useful, * 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" @@ -23,7 +23,7 @@ #include #include -#ifdef HAVE_LOCALE_H +#ifdef ENABLE_LOCALE static bool noconvert = true; static const char *charset; @@ -32,16 +32,34 @@ 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 GLIB_CHECK_VERSION(2,14,0) + if (g_unichar_iszerowidth(ch)) + return 0; +#endif + + 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 +67,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,12 +75,95 @@ 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 +} + +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 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 HAVE_LOCALE_H +#ifdef ENABLE_LOCALE gchar *str; assert(utf8str != NULL); @@ -85,7 +186,7 @@ utf8_to_locale(const char *utf8str) char * locale_to_utf8(const char *localestr) { -#ifdef HAVE_LOCALE_H +#ifdef ENABLE_LOCALE gchar *str; assert(localestr != NULL); @@ -104,3 +205,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 +}