summaryrefslogtreecommitdiff
path: root/glib/goption.c
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@gnome.org>2007-01-03 23:05:36 +0000
committerBehdad Esfahbod <behdad@src.gnome.org>2007-01-03 23:05:36 +0000
commitd2a9b31e61e85af8a19ef44cac79067be932370f (patch)
treeaca3a0ad32df5dabca0ebdb9059447dc54d5a825 /glib/goption.c
parenta0c60a62d6598be7f5ed00b87ba958c4f1301140 (diff)
downloadglib-d2a9b31e61e85af8a19ef44cac79067be932370f.tar.gz
Take zerowidth and double-width chars into consideration when computing
2007-01-03 Behdad Esfahbod <behdad@gnome.org> * 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
Diffstat (limited to 'glib/goption.c')
-rw-r--r--glib/goption.c66
1 files changed, 60 insertions, 6 deletions
diff --git a/glib/goption.c b/glib/goption.c
index 8b5139ad0..e75e576af 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-<groupname> 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 */