Code

charset: added function utf8_cut_width()
authorMax Kellermann <max@duempel.org>
Tue, 20 Oct 2009 06:00:09 +0000 (08:00 +0200)
committerMax Kellermann <max@duempel.org>
Tue, 20 Oct 2009 06:00:09 +0000 (08:00 +0200)
This function helps printing UTF-8 strings on limited screen space.

src/charset.c
src/charset.h

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)
 {
index a08054b70be361c8c0b5cdbb2613320f7b53c72b..e64eb19adad66c0fdf0d70959b903215600e6b94 100644 (file)
@@ -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);