From: notting Date: Thu, 15 Aug 2002 20:13:40 +0000 (+0000) Subject: UTF-8 changes X-Git-Tag: r0-51-0~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=349586bb531fa8caebeeaf225e817dab01648d0e;p=thirdparty%2Fnewt.git UTF-8 changes - changes for computing widths of various elements - rewrite of wrap code - no longer uses specific kanji handling; uses glibc mb/wc routines --- diff --git a/button.c b/button.c index 1ff360d..c933aad 100644 --- a/button.c +++ b/button.c @@ -30,6 +30,7 @@ static struct componentOps buttonOps = { static newtComponent createButton(int left, int row, const char * text, int compact) { newtComponent co; struct button * bu; + int width = wstrlen(text,-1); co = malloc(sizeof(*co)); bu = malloc(sizeof(struct button)); @@ -41,10 +42,10 @@ static newtComponent createButton(int left, int row, const char * text, int comp if (bu->compact) { co->height = 1; - co->width = strlen(text) + 3; + co->width = width + 3; } else { co->height = 4; - co->width = strlen(text) + 5; + co->width = width + 5; } co->top = row; diff --git a/checkbox.c b/checkbox.c index eee514c..ff49b65 100644 --- a/checkbox.c +++ b/checkbox.c @@ -117,7 +117,7 @@ newtComponent newtCheckbox(int left, int top, const char * text, char defValue, co->callback = NULL; co->height = 1; - co->width = strlen(text) + 4; + co->width = wstrlen(text, -1) + 4; co->top = top; co->left = left; co->takesFocus = 1; diff --git a/checkboxtree.c b/checkboxtree.c index 2c8df85..488ce92 100644 --- a/checkboxtree.c +++ b/checkboxtree.c @@ -169,7 +169,7 @@ int newtCheckboxTreeAddArray(newtComponent co, int flags, int * indexes) { struct items * curList, * newNode, * item; struct items ** listPtr = NULL; - int i, index, numIndexes; + int i, index, numIndexes, width; struct CheckboxTree * ct = co->data; numIndexes = 0; @@ -243,9 +243,10 @@ int newtCheckboxTreeAddArray(newtComponent co, item->depth = numIndexes - 1; i = 4 + (3 * item->depth); + width = wstrlen(text, -1); - if ((ct->userHasSetWidth == 0) && ((strlen(text) + i + ct->sbAdjust) > co->width)) { - updateWidth(co, ct, strlen(text) + i); + if ((ct->userHasSetWidth == 0) && ((width + i + ct->sbAdjust) > co->width)) { + updateWidth(co, ct, width + i); } return 0; @@ -695,7 +696,7 @@ void newtCheckboxTreeSetEntry(newtComponent co, const void * data, const char * { struct CheckboxTree * ct; struct items * item; - int i; + int i, width; if (!co) return; ct = co->data; @@ -707,8 +708,9 @@ void newtCheckboxTreeSetEntry(newtComponent co, const void * data, const char * i = 4 + (3 * item->depth); - if ((ct->userHasSetWidth == 0) && ((strlen(text) + i + ct->sbAdjust) > co->width)) { - updateWidth(co, ct, strlen(text) + i); + width = wstrlen(text, -1); + if ((ct->userHasSetWidth == 0) && ((width + i + ct->sbAdjust) > co->width)) { + updateWidth(co, ct, width + i); } ctDraw(co); diff --git a/configure.in b/configure.in index ee2129a..8a569d2 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_CONFIG_HEADER(config.h) VERSION=$(awk '/^%define version/ {print $3}' $srcdir/newt.spec) -VERSION=0.50.38 +VERSION=0.50.39 SONAME=0.50 AC_SUBST(VERSION) AC_SUBST(SONAME) diff --git a/dialogboxes.c b/dialogboxes.c index 4144009..0ac7727 100644 --- a/dialogboxes.c +++ b/dialogboxes.c @@ -8,6 +8,7 @@ #include "dialogboxes.h" #include "newt.h" +#include "newt_pr.h" #include "popt.h" /* globals -- ick */ @@ -193,10 +194,10 @@ int listBox(const char * text, int height, int width, poptContext optCon, } else itemInfo[numItems].text = ""; - if (strlen(itemInfo[numItems].text) > (unsigned int)maxTextWidth) - maxTextWidth = strlen(itemInfo[numItems].text); - if (strlen(itemInfo[numItems].tag) > (unsigned int)maxTagWidth) - maxTagWidth = strlen(itemInfo[numItems].tag); + if (wstrlen(itemInfo[numItems].text,-1) > (unsigned int)maxTextWidth) + maxTextWidth = wstrlen(itemInfo[numItems].text,-1); + if (wstrlen(itemInfo[numItems].tag,-1) > (unsigned int)maxTagWidth) + maxTagWidth = wstrlen(itemInfo[numItems].tag,-1); numItems++; } @@ -287,8 +288,8 @@ int checkList(const char * text, int height, int width, poptContext optCon, else cbStates[numBoxes] = ' '; - if (strlen(cbInfo[numBoxes].tag) > (unsigned int)maxWidth) - maxWidth = strlen(cbInfo[numBoxes].tag); + if (wstrlen(cbInfo[numBoxes].tag,-1) > (unsigned int)maxWidth) + maxWidth = wstrlen(cbInfo[numBoxes].tag,-1); numBoxes++; } diff --git a/entry.c b/entry.c index 94c77ef..7bce7ff 100644 --- a/entry.c +++ b/entry.c @@ -90,8 +90,8 @@ newtComponent newtEntry(int left, int top, const char * initialValue, int width, else co->takesFocus = 0; - if (initialValue && strlen(initialValue) > (unsigned int)width) { - en->bufAlloced = strlen(initialValue) + 1; + if (initialValue && wstrlen(initialValue,-1) > (unsigned int)width) { + en->bufAlloced = wstrlen(initialValue,-1) + 1; } en->buf = malloc(en->bufAlloced); en->resultPtr = resultPtr; diff --git a/grid.c b/grid.c index 038b7c1..bedd02a 100644 --- a/grid.c +++ b/grid.c @@ -245,12 +245,13 @@ void newtGridGetSize(newtGrid grid, int * width, int * height) { } void newtGridWrappedWindow(newtGrid grid, char * title) { - int width, height, offset = 0; + int w, width, height, offset = 0; newtGridGetSize(grid, &width, &height); - if (width < strlen(title) + 2) { - offset = ((strlen(title) + 2) - width) / 2; - width = strlen(title) + 2; + w = wstrlen(title,-1); + if (width < w + 2) { + offset = ((w + 2) - width) / 2; + width = w + 2; } newtCenteredWindow(width + 2, height + 2, title); newtGridPlace(grid, 1 + offset, 1); diff --git a/label.c b/label.c index f1a9ceb..3d81935 100644 --- a/label.c +++ b/label.c @@ -32,7 +32,7 @@ newtComponent newtLabel(int left, int top, const char * text) { co->ops = &labelOps; co->height = 1; - co->width = strlen(text); + co->width = wstrlen(text, -1); co->top = top; co->left = left; co->takesFocus = 0; @@ -55,7 +55,7 @@ void newtLabelSetText(newtComponent co, const char * text) { free(la->text); la->text = strdup(text); la->length = newLength; - co->width = newLength; + co->width = wstrlen(text,-1); } labelDraw(co); diff --git a/listbox.c b/listbox.c index 259c5cc..a05f6b3 100644 --- a/listbox.c +++ b/listbox.c @@ -297,8 +297,8 @@ void newtListboxSetEntry(newtComponent co, int num, const char * text) { free(item->text); item->text = strdup(text); } - if (li->userHasSetWidth == 0 && strlen(text) > li->curWidth) { - updateWidth(co, li, strlen(text)); + if (li->userHasSetWidth == 0 && wstrlen(text,-1) > li->curWidth) { + updateWidth(co, li, wstrlen(text,-1)); } if (num >= li->startShowItem && num <= li->startShowItem + co->height) @@ -329,8 +329,8 @@ int newtListboxAppendEntry(newtComponent co, const char * text, item = li->boxItems = malloc(sizeof(struct items)); } - if (!li->userHasSetWidth && text && (strlen(text) > li->curWidth)) - updateWidth(co, li, strlen(text)); + if (!li->userHasSetWidth && text && (wstrlen(text,-1) > li->curWidth)) + updateWidth(co, li, wstrlen(text,-1)); item->text = strdup(text); item->data = data; item->next = NULL; item->isSelected = 0; @@ -369,8 +369,8 @@ int newtListboxInsertEntry(newtComponent co, const char * text, item->next = NULL; } - if (!li->userHasSetWidth && text && (strlen(text) > li->curWidth)) - updateWidth(co, li, strlen(text)); + if (!li->userHasSetWidth && text && (wstrlen(text,-1) > li->curWidth)) + updateWidth(co, li, wstrlen(text,-1)); item->text = strdup(text?text:"(null)"); item->data = data; item->isSelected = 0; @@ -417,7 +417,7 @@ int newtListboxDeleteEntry(newtComponent co, void * key) { if (!li->userHasSetWidth) { widest = 0; for (item = li->boxItems; item != NULL; item = item->next) - if ((t = strlen(item->text)) > widest) widest = t; + if ((t = wstrlen(item->text,-1)) > widest) widest = t; } if (li->currItem >= num) diff --git a/newt.c b/newt.c index 56b4e1a..f868cdf 100644 --- a/newt.c +++ b/newt.c @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef HAVE_ALLOCA_H #include @@ -145,6 +146,29 @@ static int getkeyInterruptHook(void) { return -1; } +int wstrlen(const char *str, int len) { + mbstate_t ps; + wchar_t tmp; + int nchars = 0; + + if (!str) return 0; + if (!len) return 0; + if (len < 0) len = strlen(str); + memset(&ps,0,sizeof(mbstate_t)); + while (len > 0) { + int x,y; + + x = mbrtowc(&tmp,str,len,&ps); + if (x >0) { + len -= x; + y = wcwidth(tmp); + if (y>0) + nchars+=y; + } else break; + } + return nchars; +} + void newtFlushInput(void) { while (SLang_input_pending(0)) { SLang_getkey(); @@ -429,7 +453,7 @@ int newtOpenWindow(int left, int top, int width, int height, SLsmg_draw_box(top - 1, left - 1, height + 2, width + 2); if (currentWindow->title) { - i = strlen(currentWindow->title) + 4; + i = wstrlen(currentWindow->title,-1) + 4; i = ((width - i) / 2) + left; SLsmg_gotorc(top - 1, i); SLsmg_set_char_set(1); diff --git a/newt_pr.h b/newt_pr.h index 258322d..911898c 100644 --- a/newt_pr.h +++ b/newt_pr.h @@ -80,4 +80,6 @@ void newtDefaultMappedHandler(newtComponent c, int isMapped); struct eventResult newtDefaultEventHandler(newtComponent c, struct event ev); +int wstrlen(const char *str, int len); + #endif /* H_NEWT_PR */ diff --git a/textbox.c b/textbox.c index dc42dc5..8387185 100644 --- a/textbox.c +++ b/textbox.c @@ -1,7 +1,10 @@ + #include #include #include #include +#include +#include #include "newt.h" #include "newt_pr.h" @@ -9,6 +12,7 @@ struct textbox { char ** lines; int numLines; + char *blankline; int linesAlloced; int doWrap; newtComponent sb; @@ -101,6 +105,9 @@ newtComponent newtTextbox(int left, int top, int width, int height, int flags) { tb->lines = NULL; tb->topLine = 0; tb->textWidth = width; + tb->blankline = malloc(width+1); + memset(tb->blankline,' ',width); + tb->blankline[width] = '\0'; if (flags & NEWT_FLAG_SCROLL) { co->width += 2; @@ -147,8 +154,6 @@ static char * expandTabs(const char * text) { return buf; } -#define iseuckanji(c) (0xa1 <= (unsigned char)(c&0xff) && (unsigned char)(c&0xff) <= 0xfe) - static void doReflow(const char * text, char ** resultPtr, int width, int * badness, int * heightPtr) { char * result = NULL; @@ -156,73 +161,79 @@ static void doReflow(const char * text, char ** resultPtr, int width, int i; int howbad = 0; int height = 0; - int kanji = 0; + wchar_t tmp; + mbstate_t ps; if (resultPtr) { /* XXX I think this will work */ result = malloc(strlen(text) + (strlen(text) / width) + 2); *result = '\0'; } - + + memset(&ps,0,sizeof(mbstate_t)); while (*text) { - kanji = 0; end = strchr(text, '\n'); if (!end) end = text + strlen(text); while (*text && text <= end) { - if (end - text < width) { + int len; + + len = wstrlen(text, end - text); + if (len < width) { if (result) { strncat(result, text, end - text); strcat(result, "\n"); height++; } - if (end - text < (width / 2)) - howbad += ((width / 2) - (end - text)) / 2; + if (len < (width / 2)) { +#ifdef DEBUG_WRAP + fprintf(stderr,"adding %d\n",((width / 2) - (len)) / 2); +#endif + howbad += ((width / 2) - (len)) / 2; + } text = end; if (*text) text++; } else { + char *spcptr = NULL; + int spc =0,w2, x; + chptr = text; - kanji = 0; - for ( i = 0; i < width - 1; i++ ) { - if ( !iseuckanji(*chptr)) { - kanji = 0; - } else if ( kanji == 1 ) { - kanji = 2; - } else { - kanji = 1; - } - chptr++; - } - if (kanji == 0) { - while (chptr > text && !isspace(*chptr)) chptr--; - while (chptr > text && isspace(*chptr)) chptr--; - chptr++; + w2 = 0; + for (i = 0; i < width - 1;) { + if ((x=mbrtowc(&tmp,chptr,end-chptr,&ps))<=0) + break; + if (spc && !iswspace(tmp)) + spc = 0; + else if (!spc && iswspace(tmp)) { + spc = 1; + spcptr = chptr; + w2 = i; + } + chptr += x; + x = wcwidth(tmp); + if (x>0) + i+=x; } - - if (chptr-text == 1 && !isspace(*chptr)) - chptr = text + width - 1; - - if (chptr > text) - howbad += width - (chptr - text) + 1; + howbad += width - w2 + 1; +#ifdef DEBUG_WRAP + fprintf(stderr,"adding %d\n",width - w2 + 1, chptr); +#endif + if (spcptr) chptr = spcptr; if (result) { - if (kanji == 1) { - strncat(result, text, chptr - text + 1 ); - chptr++; - kanji = 0; - } else { strncat(result, text, chptr - text ); - } strcat(result, "\n"); height++; } - if (isspace(*chptr)) - text = chptr + 1; - else - text = chptr; - while (isspace(*text)) text++; + text = chptr; + while (1) { + if ((x=mbrtowc(&tmp,text,end-text,NULL))<=0) + break; + if (!iswspace(tmp)) break; + text += x; + } } } } @@ -230,6 +241,9 @@ static void doReflow(const char * text, char ** resultPtr, int width, if (badness) *badness = howbad; if (resultPtr) *resultPtr = result; if (heightPtr) *heightPtr = height; +#ifdef DEBUG_WRAP + fprintf(stderr, "width %d, badness %d, height %d\n",width, howbad, height); +#endif } char * newtReflowText(char * text, int width, int flexDown, int flexUp, @@ -311,12 +325,12 @@ void newtTextboxSetText(newtComponent co, const char * text) { static void addLine(newtComponent co, const char * s, int len) { struct textbox * tb = co->data; - if (len > tb->textWidth) len = tb->textWidth; - - tb->lines[tb->numLines] = malloc(tb->textWidth + 1); - memset(tb->lines[tb->numLines], ' ', tb->textWidth); + while (wstrlen(s,len) > tb->textWidth) { + len--; + } + tb->lines[tb->numLines] = malloc(len + 1); memcpy(tb->lines[tb->numLines], s, len); - tb->lines[tb->numLines++][tb->textWidth] = '\0'; + tb->lines[tb->numLines++][len] = '\0'; } static void textboxDraw(newtComponent c) { @@ -333,6 +347,8 @@ static void textboxDraw(newtComponent c) { SLsmg_set_color(NEWT_COLORSET_TEXTBOX); for (i = 0; (i + tb->topLine) < tb->numLines && i < c->height; i++) { + newtGotorc(c->top + i, c->left); + SLsmg_write_string(tb->blankline); newtGotorc(c->top + i, c->left); SLsmg_write_string(tb->lines[i + tb->topLine]); } @@ -405,6 +421,7 @@ static void textboxDestroy(newtComponent co) { for (i = 0; i < tb->numLines; i++) free(tb->lines[i]); free(tb->lines); + free(tb->blankline); free(tb); free(co); }