# HG changeset patch # User Sadrul Habib Chowdhury # Date 1156340811 0 # Node ID fda9dc44807dc108e7eb88e32fce5d4c29aea8c5 # Parent a766441af5ea61f59bba774e03d877b240ef5f6c [gaim-migrate @ 17001] Wide-characters should no longer eat characters at the end of the line in textview. committer: Tailor Script diff -r a766441af5ea -r fda9dc44807d console/libgnt/gntentry.c --- a/console/libgnt/gntentry.c Wed Aug 23 12:29:08 2006 +0000 +++ b/console/libgnt/gntentry.c Wed Aug 23 13:46:51 2006 +0000 @@ -1,11 +1,10 @@ #include -#include #include -#include #include "gntbox.h" #include "gntentry.h" #include "gnttree.h" +#include "gntutils.h" enum { @@ -15,25 +14,6 @@ static GntWidgetClass *parent_class = NULL; static guint signals[SIGS] = { 0 }; -static int -get_onscreen_width(const char *start, const char *end) -{ - wchar_t wch; - int size; - int width = 0; - - while (start < end) { - if ((size = mbtowc(&wch, start, end - start)) > 0) { - start += size; - width += wcwidth(wch); - } else { - ++width; - ++start; - } - } - return width; -} - static void destroy_suggest(GntEntry *entry) { @@ -72,7 +52,7 @@ char *s = get_beginning_of_word(entry); suggest = g_strndup(s, entry->cursor - s); if (entry->scroll < s) - offset = get_onscreen_width(entry->scroll, s); + offset = gnt_util_onscreen_width(entry->scroll, s); } else suggest = g_strdup(entry->start); @@ -141,12 +121,12 @@ else mvwprintw(widget->window, 0, 0, "%s", entry->scroll); - stop = get_onscreen_width(entry->scroll, entry->end); + stop = gnt_util_onscreen_width(entry->scroll, entry->end); if (stop < widget->priv.width) whline(widget->window, ENTRY_CHAR, widget->priv.width - stop); if (focus) - mvwchgat(widget->window, 0, get_onscreen_width(entry->scroll, entry->cursor), + mvwchgat(widget->window, 0, gnt_util_onscreen_width(entry->scroll, entry->cursor), 1, A_REVERSE, COLOR_PAIR(GNT_COLOR_TEXT_NORMAL), NULL); DEBUG; @@ -194,7 +174,7 @@ if (entry->cursor >= entry->end) return; entry->cursor = g_utf8_find_next_char(entry->cursor, NULL); - while (get_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width) + while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width) entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); entry_redraw(GNT_WIDGET(entry)); } @@ -249,7 +229,7 @@ { entry->cursor = entry->end; /* This should be better than this */ - while (get_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width) + while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width) entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); entry_redraw(GNT_WIDGET(entry)); } @@ -410,7 +390,7 @@ str++; } - while (get_onscreen_width(entry->scroll, entry->cursor) >= widget->priv.width) + while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= widget->priv.width) entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); if (entry->ddown) diff -r a766441af5ea -r fda9dc44807d console/libgnt/gnttextview.c --- a/console/libgnt/gnttextview.c Wed Aug 23 12:29:08 2006 +0000 +++ b/console/libgnt/gnttextview.c Wed Aug 23 13:46:51 2006 +0000 @@ -1,4 +1,5 @@ #include "gnttextview.h" +#include "gntutils.h" enum { @@ -14,7 +15,7 @@ typedef struct { GList *segments; /* A list of GntTextSegments */ - int length; /* The current length of the line so far */ + int length; /* The current length of the line so far (ie. onscreen width) */ } GntTextLine; static GntWidgetClass *parent_class = NULL; @@ -236,18 +237,23 @@ while (iter && *iter) { - GntTextSegment *seg = g_new0(GntTextSegment, 1); - int len = g_utf8_offset_to_pointer(iter, widget->priv.width - line->length - 1) - iter; - seg->flags = fl; - seg->text = g_new0(char, len + 1); - g_utf8_strncpy(seg->text, iter, widget->priv.width - line->length - 1); - line->segments = g_list_append(line->segments, seg); + int len; - prev = g_utf8_strlen(seg->text, -1); - line->length += prev; - iter = g_utf8_offset_to_pointer(iter, prev); - if (line->length >= widget->priv.width - 1 && *iter) - { + len = gnt_util_onscreen_width_to_pointer(iter, widget->priv.width - line->length - 1, &prev) - iter; + if (len) { + GntTextSegment *seg = g_new0(GntTextSegment, 1); + seg->flags = fl; + seg->text = g_new0(char, len + 1); + g_utf8_strncpy(seg->text, iter, g_utf8_pointer_to_offset(iter, iter + len)); + line->segments = g_list_append(line->segments, seg); + + line->length += prev; + iter += len; + if (line->length >= widget->priv.width - 1 && *iter) { + line = g_new0(GntTextLine, 1); + view->list = g_list_prepend(g_list_first(view->list), line); + } + } else { line = g_new0(GntTextLine, 1); view->list = g_list_prepend(g_list_first(view->list), line); } diff -r a766441af5ea -r fda9dc44807d console/libgnt/gntutils.c --- a/console/libgnt/gntutils.c Wed Aug 23 12:29:08 2006 +0000 +++ b/console/libgnt/gntutils.c Wed Aug 23 13:46:51 2006 +0000 @@ -1,5 +1,9 @@ #include "gntutils.h" +#include +#include +#include + void gnt_util_get_text_bound(const char *text, int *width, int *height) { const char *s = text, *last; @@ -34,3 +38,49 @@ *width = max + (count > 1); } +int gnt_util_onscreen_width(const char *start, const char *end) +{ + wchar_t wch; + int size; + int width = 0; + + while (start < end) { + if ((size = mbtowc(&wch, start, end - start)) > 0) { + start += size; + width += wcwidth(wch); + } else { + ++width; + ++start; + } + } + return width; +} + +char *gnt_util_onscreen_width_to_pointer(const char *string, int len, int *w) +{ + wchar_t wch; + int size; + int width = 0; + char *str = (char*)string; + int slen = strlen(string); /* Yeah, no. of bytes */ + + while (width < len && *str) { + if ((size = mbtowc(&wch, str, slen)) > 0) { + if (width + wcwidth(wch) > len) + break; + str += size; + width += wcwidth(wch); + slen -= size; + } else { + ++str; + ++width; + --slen; + } + } + + if (w) + *w = width; + + return str; +} + diff -r a766441af5ea -r fda9dc44807d console/libgnt/gntutils.h --- a/console/libgnt/gntutils.h Wed Aug 23 12:29:08 2006 +0000 +++ b/console/libgnt/gntutils.h Wed Aug 23 13:46:51 2006 +0000 @@ -4,3 +4,7 @@ #include "gntwidget.h" void gnt_util_get_text_bound(const char *text, int *width, int *height); + +int gnt_util_onscreen_width(const char *start, const char *end); + +char *gnt_util_onscreen_width_to_pointer(const char *str, int len, int *w);