[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 17 of 22] Applied patches from Stanislav Maslovski <stanislav (dot) maslovski (at) gmail (dot) com> to



# HG changeset patch
# User Dan Pascu <dan@ag-projects.com>
# Date 1146009163 25200
# Branch wm_0_92
# Node ID bd0c670bda80aab916c22b627adfe8cc9978d1ab
# Parent  6c6cf07271fc30e7be53e03b9cb6972e812c9ea8
Applied patches from Stanislav Maslovski <stanislav.maslovski@gmail.com> to
fix the 2 problems mentioend below:

- Fixed buggy handling of UTF8 characters in textfields in WINGs.
- Fixed segfault in WPrefs when some font description is missing from the
  configuration file.
(transplanted from 84918d13ba317bfe1de6f734c5e32458de6f61ce)

diff -r 6c6cf07271fc -r bd0c670bda80 ChangeLog
--- a/ChangeLog	Tue Apr 25 13:01:51 2006 -0700
+++ b/ChangeLog	Tue Apr 25 16:52:43 2006 -0700
@@ -33,6 +33,10 @@
 - Improved Info panel layout and fonts.
 - Fixed missing library paths when linking some binaries on certain
   platforms with a recent pkg-config (debian unstable/sid for one)
+- Fixed buggy handling of UTF8 characters in textfields in WINGs.
+  (Stanislav Maslovski <stanislav.maslovski@gmail.com>)
+- Fixed segfault in WPrefs when some font description is missing from the 
+  configuration file (Stanislav Maslovski <stanislav.maslovski@gmail.com>)
 
 
 
diff -r 6c6cf07271fc -r bd0c670bda80 WINGs/wtextfield.c
--- a/WINGs/wtextfield.c	Tue Apr 25 13:01:51 2006 -0700
+++ b/WINGs/wtextfield.c	Tue Apr 25 16:52:43 2006 -0700
@@ -30,15 +30,15 @@
 #endif
 
     char *text;
-    int textLen;		       /* size of text */
-    int bufferSize;		       /* memory allocated for text */
+    int textLen;                       /* size of text */
+    int bufferSize;                    /* memory allocated for text */
 
-    int viewPosition;		       /* position of text being shown */
+    int viewPosition;                  /* position of text being shown */
 
-    int cursorPosition;		       /* position of the insertion cursor */
+    int cursorPosition;                /* position of the insertion cursor */
 
     short usableWidth;
-    short offsetWidth;		       /* offset of text from border */
+    short offsetWidth;                 /* offset of text from border */
 
     WMRange selection;
 
@@ -47,7 +47,7 @@
     WMTextFieldDelegate *delegate;
 
 #if 0
-    WMHandlerID	timerID;	       /* for cursor blinking */
+    WMHandlerID timerID;               /* for cursor blinking */
 #endif
     struct {
         WMAlignment alignment:2;
@@ -62,7 +62,7 @@
 
         unsigned int cursorOn:1;
 
-        unsigned int secure:1;	       /* password entry style */
+        unsigned int secure:1;         /* password entry style */
 
         unsigned int pointerGrabbed:1;
 
@@ -77,7 +77,7 @@
 } TextField;
 
 
-#define NOTIFY(T,C,N,A)	{ WMNotification *notif = WMCreateNotification(N,T,A);\
+#define NOTIFY(T,C,N,A) { WMNotification *notif = WMCreateNotification(N,T,A);\
     if ((T)->delegate && (T)->delegate->C)\
     (*(T)->delegate->C)((T)->delegate,notif);\
     WMPostNotification(notif);\
@@ -136,11 +136,45 @@
 };
 
 
-#define TEXT_WIDTH(tPtr, start)	(WMWidthOfString((tPtr)->font, \
-    &((tPtr)->text[(start)]), (tPtr)->textLen - (start) + 1))
+#define TEXT_WIDTH(tPtr, start) (WMWidthOfString((tPtr)->font, \
+    &((tPtr)->text[(start)]), (tPtr)->textLen - (start)))
 
 #define TEXT_WIDTH2(tPtr, start, end) (WMWidthOfString((tPtr)->font, \
-    &((tPtr)->text[(start)]), (end) - (start) + 1))
+    &((tPtr)->text[(start)]), (end) - (start)))
+
+
+static INLINE int
+oneUTF8CharBackward(char *str, int len)
+{
+    unsigned char* ustr = (unsigned char*) str;
+    int pos = 0;
+
+    while (len-- > 0 && ustr[--pos] >= 0x80 && ustr[pos] <= 0xbf);
+    return pos;
+}
+
+
+static INLINE int
+oneUTF8CharForward(char *str, int len)
+{
+    unsigned char* ustr = (unsigned char*) str;
+    int pos = 0;
+
+    while (len-- > 0 && ustr[++pos] >= 0x80 && ustr[pos] <= 0xbf);
+    return pos;
+}
+
+
+// find the beginning of the UTF8 char pointed by str
+static INLINE int
+seekUTF8CharStart(char *str, int len)
+{
+    unsigned char* ustr = (unsigned char*) str;
+    int pos = 0;
+
+    while (len-- > 0 && ustr[pos] >= 0x80 && ustr[pos] <= 0xbf) --pos;
+    return pos;
+}
 
 
 static void
@@ -177,6 +211,7 @@
         range->count = tPtr->textLen - range->position;
 }
 
+
 static void
 memmv(char *dest, char *src, int size)
 {
@@ -200,7 +235,8 @@
     int vp = tPtr->viewPosition;
 
     while (TEXT_WIDTH(tPtr, tPtr->viewPosition) > tPtr->usableWidth) {
-        tPtr->viewPosition++;
+        tPtr->viewPosition += oneUTF8CharForward(&tPtr->text[tPtr->viewPosition],
+                                                 tPtr->textLen - tPtr->viewPosition);
     }
     return vp!=tPtr->viewPosition;
 }
@@ -210,11 +246,11 @@
 incrToFit2(TextField *tPtr)
 {
     int vp = tPtr->viewPosition;
+
     while (TEXT_WIDTH2(tPtr, tPtr->viewPosition, tPtr->cursorPosition)
            >= tPtr->usableWidth)
-        tPtr->viewPosition++;
-
-
+        tPtr->viewPosition += oneUTF8CharForward(&tPtr->text[tPtr->viewPosition],
+                                                 tPtr->cursorPosition - tPtr->viewPosition);
     return vp!=tPtr->viewPosition;
 }
 
@@ -222,14 +258,16 @@
 static void
 decrToFit(TextField *tPtr)
 {
-    while (TEXT_WIDTH(tPtr, tPtr->viewPosition-1) < tPtr->usableWidth
-           && tPtr->viewPosition>0)
-        tPtr->viewPosition--;
+    int vp = tPtr->viewPosition;
+
+    while (vp > 0 && (vp += oneUTF8CharBackward(&tPtr->text[vp], vp),
+                      TEXT_WIDTH(tPtr, vp)) < tPtr->usableWidth) {
+        tPtr->viewPosition = vp;
+    }
 }
 
 #undef TEXT_WIDTH
 #undef TEXT_WIDTH2
-
 
 
 static WMData*
@@ -419,11 +457,9 @@
     if (position < 0 || position >= tPtr->textLen) {
         /* append the text at the end */
         strcat(tPtr->text, text);
-
-        incrToFit(tPtr);
-
         tPtr->textLen += len;
         tPtr->cursorPosition += len;
+        incrToFit(tPtr);
     } else {
         /* insert text at position */
         memmv(&(tPtr->text[position+len]), &(tPtr->text[position]),
@@ -456,12 +492,11 @@
     memmv(&(tPtr->text[range.position]), &(tPtr->text[range.position+range.count]),
           tPtr->textLen - (range.position+range.count) + 1);
 
+    /* better than nothing ;) */
+    if (tPtr->cursorPosition > range.position)
+        tPtr->viewPosition += oneUTF8CharBackward(&tPtr->text[tPtr->viewPosition],
+                                                  tPtr->viewPosition);
     tPtr->textLen -= range.count;
-
-    /* try to keep cursorPosition at the same place */
-    tPtr->viewPosition -= range.count;
-    if (tPtr->viewPosition < 0)
-        tPtr->viewPosition = 0;
     tPtr->cursorPosition = range.position;
 
     decrToFit(tPtr);
@@ -1096,16 +1131,18 @@
 #endif
     case XK_Left:
         if (tPtr->cursorPosition > 0) {
+            int i;
             paintCursor(tPtr);
+
+            i = tPtr->cursorPosition;
+            i += oneUTF8CharBackward(&tPtr->text[i], i);
             if (controled) {
-                int i = tPtr->cursorPosition - 1;
-
                 while (i > 0 && tPtr->text[i] != ' ') i--;
                 while (i > 0 && tPtr->text[i] == ' ') i--;
 
                 tPtr->cursorPosition = (i > 0) ? i + 1 : 0;
             } else
-                tPtr->cursorPosition--;
+                tPtr->cursorPosition = i;
 
             if (tPtr->cursorPosition < tPtr->viewPosition) {
                 tPtr->viewPosition = tPtr->cursorPosition;
@@ -1131,24 +1168,20 @@
 #endif
     case XK_Right:
         if (tPtr->cursorPosition < tPtr->textLen) {
+            int i;
             paintCursor(tPtr);
+
+            i = tPtr->cursorPosition;
             if (controled) {
-                int i = tPtr->cursorPosition;
-
                 while (tPtr->text[i] && tPtr->text[i] != ' ') i++;
                 while (tPtr->text[i] == ' ') i++;
+            } else {
+                i += oneUTF8CharForward(&tPtr->text[i], tPtr->textLen - i);
+            }
+            tPtr->cursorPosition = i;
 
-                tPtr->cursorPosition = i;
-            } else {
-                tPtr->cursorPosition++;
-            }
-            while (WMWidthOfString(tPtr->font,
-                                   &(tPtr->text[tPtr->viewPosition]),
-                                   tPtr->cursorPosition-tPtr->viewPosition)
-                   > tPtr->usableWidth) {
-                tPtr->viewPosition++;
-                refresh = 1;
-            }
+            refresh = incrToFit2(tPtr);
+
             if (!refresh)
                 paintCursor(tPtr);
         }
@@ -1201,13 +1234,9 @@
                 paintCursor(tPtr);
                 tPtr->cursorPosition = tPtr->textLen;
                 tPtr->viewPosition = 0;
-                while (WMWidthOfString(tPtr->font,
-                                       &(tPtr->text[tPtr->viewPosition]),
-                                       tPtr->textLen-tPtr->viewPosition)
-                       > tPtr->usableWidth) {
-                    tPtr->viewPosition++;
-                    refresh = 1;
-                }
+
+                refresh = incrToFit(tPtr);
+
                 if (!refresh)
                     paintCursor(tPtr);
             }
@@ -1231,9 +1260,11 @@
                 data = (void*)WMDeleteTextEvent;
                 textEvent = WMTextDidChangeNotification;
             } else if (tPtr->cursorPosition > 0) {
+                int i = oneUTF8CharBackward(&tPtr->text[tPtr->cursorPosition],
+                                            tPtr->cursorPosition);
                 WMRange range;
-                range.position = tPtr->cursorPosition - 1;
-                range.count = 1;
+                range.position = tPtr->cursorPosition + i;
+                range.count = -i;
                 WMDeleteTextFieldRange(tPtr, range);
                 data = (void*)WMDeleteTextEvent;
                 textEvent = WMTextDidChangeNotification;
@@ -1261,7 +1292,8 @@
             } else if (tPtr->cursorPosition < tPtr->textLen) {
                 WMRange range;
                 range.position = tPtr->cursorPosition;
-                range.count = 1;
+                range.count = oneUTF8CharForward(&tPtr->text[tPtr->cursorPosition],
+                                                 tPtr->textLen - tPtr->cursorPosition);
                 WMDeleteTextFieldRange(tPtr, range);
                 data = (void*)WMDeleteTextEvent;
                 textEvent = WMTextDidChangeNotification;
@@ -1356,21 +1388,24 @@
     a = tPtr->viewPosition;
     b = tPtr->textLen;
 
-    while (a < b && b-a>1) {
+    while (a < b) {
         mid = (a+b)/2;
+        mid += seekUTF8CharStart(&tPtr->text[mid], mid - a);
         tw = WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]),
-                             mid - tPtr->viewPosition);
-        if (tw > x)
+                             mid - tPtr->viewPosition + 1);
+        if (tw > x) {
             b = mid;
-        else if (tw < x)
-            a = mid;
-        else
+        } else if (tw < x) {
+            if (a == mid)
+                a += oneUTF8CharForward(&tPtr->text[mid], b - a);
+            else
+                a = mid;
+        } else {
             return mid;
+        }
     }
-
-    return (a+b)/2;
+    return b;
 }
-
 
 
 static void
@@ -1447,11 +1482,13 @@
                                     &(tPtr->text[tPtr->viewPosition]),
                                     tPtr->cursorPosition-tPtr->viewPosition)
                     > tPtr->usableWidth) {
-                    tPtr->viewPosition++;
+                    tPtr->viewPosition += oneUTF8CharForward(&tPtr->text[tPtr->viewPosition],
+                                                             tPtr->textLen - tPtr->viewPosition);
                 }
             } else if (tPtr->viewPosition > 0 && event->xmotion.x < 0) {
                 paintCursor(tPtr);
-                tPtr->viewPosition--;
+                tPtr->viewPosition += oneUTF8CharBackward(&tPtr->text[tPtr->viewPosition],
+                                                          tPtr->viewPosition);
             }
 
             tPtr->cursorPosition =
diff -r 6c6cf07271fc -r bd0c670bda80 WPrefs.app/FontSimple.c
--- a/WPrefs.app/FontSimple.c	Tue Apr 25 13:01:51 2006 -0700
+++ b/WPrefs.app/FontSimple.c	Tue Apr 25 16:52:43 2006 -0700
@@ -312,9 +312,14 @@
 getSelectedFont(_Panel *panel, FcChar8 *curfont)
 {
     WMListItem *item;
-    FcPattern *pat= FcNameParse(curfont);
+    FcPattern *pat;
     char *name;
     
+    if (curfont)
+        pat= FcNameParse(curfont);
+    else
+        pat= FcPatternCreate();
+
     item= WMGetListSelectedItem(panel->familyL);
     if (item)
     {
@@ -358,12 +363,13 @@
     WMMenuItem *item= WMGetPopUpButtonMenuItem(panel->optionP,
                                            WMGetPopUpButtonSelectedItem(panel->optionP));
     char *fn= WMGetMenuItemRepresentedObject(item);
-    WMFont *font= WMCreateFont(WMWidgetScreen(panel->box), fn);
 
-    if (font)
-    {
-        WMSetTextFieldFont(panel->sampleT, font);
-        WMReleaseFont(font);
+    if (fn) {
+        WMFont *font= WMCreateFont(WMWidgetScreen(panel->box), fn);
+        if (font) {
+            WMSetTextFieldFont(panel->sampleT, font);
+            WMReleaseFont(font);
+        }
     }
 }
 
@@ -451,8 +457,8 @@
 
             ofont= (FcChar8*)WMGetMenuItemRepresentedObject(item);
             nfont= getSelectedFont(panel, ofont);
-            wfree(ofont);
-
+            if (ofont)
+                wfree(ofont);
             WMSetMenuItemRepresentedObject(item, nfont);
         }
         updateSampleFont(panel);
@@ -471,7 +477,8 @@
 
     ofont = (FcChar8*)WMGetMenuItemRepresentedObject(item);
     nfont= getSelectedFont(panel, ofont);
-    wfree(ofont);
+    if (ofont)
+        wfree(ofont);
 
     WMSetMenuItemRepresentedObject(item, nfont);
 


-- 
To unsubscribe, send mail to wmaker-dev-unsubscribe@lists.windowmaker.info.