]> git.ipfire.org Git - thirdparty/newt.git/commitdiff
UTF-8 changes
authornotting <notting>
Thu, 15 Aug 2002 20:13:40 +0000 (20:13 +0000)
committernotting <notting>
Thu, 15 Aug 2002 20:13:40 +0000 (20:13 +0000)
- changes for computing widths of various elements
- rewrite of wrap code
  - no longer uses specific kanji handling; uses glibc mb/wc routines

12 files changed:
button.c
checkbox.c
checkboxtree.c
configure.in
dialogboxes.c
entry.c
grid.c
label.c
listbox.c
newt.c
newt_pr.h
textbox.c

index 1ff360dc58776addb85d3a85b04b8380e4e5f5c3..c933aad507843fafe8aab82f175a6b979c36956e 100644 (file)
--- 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;
index eee514c98c4c086ee5f855e80961e697814a4178..ff49b65c3b876a1505a07cc26e378087b0e02aa8 100644 (file)
@@ -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;
index 2c8df85ccb695eaea0b679ff1b996835302c8d09..488ce92b100d62dd93e59ebbf5bc8c98805aec9e 100644 (file)
@@ -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);
index ee2129a805fb21d2125ed1604814d7b430eb1d11..8a569d2c4d5daa1edef8b9ac59d1b1337e239c55 100644 (file)
@@ -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)
index 41440094a570b2e1aa3697442cc598562a942913..0ac7727900951d417a8fcfc4db2cc272cdab0e0d 100644 (file)
@@ -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 94c77ef5e38fbf6f78cf73827bf963206cc81318..7bce7ffb40ef11a2073600f1dcbfabaf827a8d3e 100644 (file)
--- 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 038b7c1721f23eb171bef9abab2464835ac5c404..bedd02a5267cce15a71c5a3e7ec4c8f874da1ad8 100644 (file)
--- 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 f1a9cebbf965c2ac72787f2a69058967ffef7d1f..3d81935437a3e67a19c6591c95652be60bbeb0fd 100644 (file)
--- 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);
index 259c5ccfb751b12091d2c559d4036e0920d7fc98..a05f6b30e4a8d907d7ff78ba8b289496a19676e7 100644 (file)
--- 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 56b4e1aba0cb05d1d2c60f5c1f8bc09f141d488c..f868cdf4fd72665fcc8d9e22cf380e7972516a20 100644 (file)
--- a/newt.c
+++ b/newt.c
@@ -9,6 +9,7 @@
 #include <sys/types.h>
 #include <termios.h>
 #include <unistd.h>
+#include <wchar.h>
 
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
@@ -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);
index 258322d1eba6badbf8be8ae126311f5575ecc730..911898cfb38fc0fc7f6c7fe65cfc0df0fe43ad61 100644 (file)
--- 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 */
index dc42dc558f77bc2ead32a6aee872e286fa929904..8387185e265d0d2072cc7133d501031850126a93 100644 (file)
--- a/textbox.c
+++ b/textbox.c
@@ -1,7 +1,10 @@
+
 #include <ctype.h>
 #include <slang.h>
 #include <stdlib.h>
 #include <string.h>
+#include <wchar.h>
+#include <wctype.h>
 
 #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);
 }