From d2a9b31e61e85af8a19ef44cac79067be932370f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 3 Jan 2007 23:05:36 +0000 Subject: [PATCH] Take zerowidth and double-width chars into consideration when computing 2007-01-03 Behdad Esfahbod * glib/goption.c (_g_unichar_get_width), (_g_utf8_strwidth), (calculate_max_length), (print_entry), (print_help): Take zerowidth and double-width chars into consideration when computing width of a string. Also fix another bug in width computation. * glib/guniprop.c (g_unichar_iszerowidth): Fix typo. It was not working correctly. svn path=/trunk/; revision=5204 --- ChangeLog | 10 +++++++++ glib/goption.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++------ glib/guniprop.c | 2 +- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 24e9384..2696785 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2007-01-03 Behdad Esfahbod + * glib/goption.c (_g_unichar_get_width), (_g_utf8_strwidth), + (calculate_max_length), (print_entry), (print_help): Take zerowidth + and double-width chars into consideration when computing width of a + string. Also fix another bug in width computation. + + * glib/guniprop.c (g_unichar_iszerowidth): Fix typo. It was not + working correctly. + +2007-01-03 Behdad Esfahbod + * glib/glib.symbols: * glib/gunicode.h: * glib/guniprop.c: Add g_unichar_iszerowidth(). (#347645) diff --git a/glib/goption.c b/glib/goption.c index 8b5139a..e75e576 100644 --- a/glib/goption.c +++ b/glib/goption.c @@ -122,6 +122,59 @@ static void free_changes_list (GOptionContext *context, static void free_pending_nulls (GOptionContext *context, gboolean perform_nulls); + +static int +_g_unichar_get_width (gunichar c) +{ + if (G_UNLIKELY (g_unichar_iszerowidth (c))) + return 0; + + /* we ignore the fact that we should call g_unichar_iswide_cjk() under + * some locales (legacy East Asian ones) */ + if (g_unichar_iswide (c)) + return 2; + + return 1; +} + +static glong +_g_utf8_strwidth (const gchar *p, + gssize max) +{ + glong len = 0; + const gchar *start = p; + g_return_val_if_fail (p != NULL || max == 0, 0); + max = strlen (p); + + if (max < 0) + { + while (*p) + { + len += _g_unichar_get_width (g_utf8_get_char (p)); + p = g_utf8_next_char (p); + } + } + else + { + if (max == 0 || !*p) + return 0; + + /* this case may not be quite correct */ + + len += _g_unichar_get_width (g_utf8_get_char (p)); + p = g_utf8_next_char (p); + + while (p - start < max && *p) + { + len += _g_unichar_get_width (g_utf8_get_char (p)); + p = g_utf8_next_char (p); + } + } + + return len; +} + + GQuark g_option_error_quark (void) { @@ -421,13 +474,13 @@ calculate_max_length (GOptionGroup *group) if (entry->flags & G_OPTION_FLAG_HIDDEN) continue; - len = g_utf8_strlen (entry->long_name, -1); + len = _g_utf8_strwidth (entry->long_name, -1); if (entry->short_name) len += 4; if (!NO_ARG (entry) && entry->arg_description) - len += 1 + g_utf8_strlen (TRANSLATE (group, entry->arg_description), -1); + len += 1 + _g_utf8_strwidth (TRANSLATE (group, entry->arg_description), -1); max_length = MAX (max_length, len); } @@ -458,7 +511,8 @@ print_entry (GOptionGroup *group, if (entry->arg_description) g_string_append_printf (str, "=%s", TRANSLATE (group, entry->arg_description)); - g_print ("%-*s %s\n", max_length + 4, str->str, + g_print ("%s%*s %s\n", str->str, + (int) (max_length + 4 - _g_utf8_strwidth (str->str, -1)), "", entry->description ? TRANSLATE (group, entry->description) : ""); g_string_free (str, TRUE); } @@ -546,11 +600,11 @@ print_help (GOptionContext *context, list = context->groups; - max_length = g_utf8_strlen ("-?, --help", -1); + max_length = _g_utf8_strwidth ("-?, --help", -1); if (list) { - len = g_utf8_strlen ("--help-all", -1); + len = _g_utf8_strwidth ("--help-all", -1); max_length = MAX (max_length, len); } @@ -565,7 +619,7 @@ print_help (GOptionContext *context, GOptionGroup *group = list->data; /* First, we check the --help- options */ - len = g_utf8_strlen ("--help-", -1) + g_utf8_strlen (group->name, -1); + len = _g_utf8_strwidth ("--help-", -1) + _g_utf8_strwidth (group->name, -1); max_length = MAX (max_length, len); /* Then we go through the entries */ diff --git a/glib/guniprop.c b/glib/guniprop.c index 2292e76..908d3fe 100644 --- a/glib/guniprop.c +++ b/glib/guniprop.c @@ -380,7 +380,7 @@ g_unichar_iszerowidth (gunichar c) if (G_UNLIKELY (c == 0x00AD)) return FALSE; - if (G_UNLIKELY (ISZEROWIDTHTYPE (c))) + if (G_UNLIKELY (ISZEROWIDTHTYPE (TYPE (c)))) return TRUE; if (G_UNLIKELY ((c >= 0x1160 && c < 0x1200) || -- 2.7.4