Code

charset: added function utf8_cut_width()
[ncmpc.git] / src / charset.c
index 59d1a26df3173acbc466024855c88b75c72cfe03..8e7ed0f0bba6efac5f98aefa44467b11a01d50a5 100644 (file)
@@ -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)
 {