Enlightenment CVS committal

Author  : kwo
Project : e16
Module  : e

Dir     : e16/e/src


Modified Files:
        lang.c lang.h tclass.h text.c ttfont.c 


Log Message:
Fix shortening text to fit available space in certain combinations of locale 
and font type.

===================================================================
RCS file: /cvs/e/e16/e/src/lang.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -3 -r1.12 -r1.13
--- lang.c      18 Oct 2006 18:19:14 -0000      1.12
+++ lang.c      12 Nov 2006 00:39:19 -0000      1.13
@@ -143,6 +143,125 @@
 #endif
 }
 
+/*
+ * Stuff to do mb/utf8 <-> wc conversions.
+ */
+#if HAVE_ICONV
+static iconv_t      iconv_cd_str2wcs = NULL;
+static iconv_t      iconv_cd_wcs2str = NULL;
+#endif
+
+int
+EwcOpen(int utf8)
+{
+#if HAVE_ICONV
+   const char         *enc;
+
+   if (utf8)
+      enc = "UTF-8";
+   else
+      enc = nl_langinfo(CODESET);
+
+   iconv_cd_str2wcs = iconv_open("WCHAR_T", enc);
+   iconv_cd_wcs2str = iconv_open(enc, "WCHAR_T");
+
+   if (iconv_cd_str2wcs && iconv_cd_wcs2str)
+      return 0;
+
+   EwcClose();
+   return -1;
+#else
+   /* NB! This case will not work properly if needed MB encoding is utf8
+    * but locale isn't */
+   utf8 = 0;
+   return 0;
+#endif
+}
+
+void
+EwcClose(void)
+{
+#if HAVE_ICONV
+   if (iconv_cd_str2wcs)
+      iconv_close(iconv_cd_str2wcs);
+   iconv_cd_str2wcs = NULL;
+   if (iconv_cd_wcs2str)
+      iconv_close(iconv_cd_wcs2str);
+   iconv_cd_wcs2str = NULL;
+#endif
+}
+
+int
+EwcStrToWcs(const char *str, int len, wchar_t * wcs, int wcl)
+{
+#if HAVE_ICONV
+   size_t              ni, no, rc;
+
+   if (!wcs)
+     {
+       char                buf[4096], *po;
+
+       ni = len;
+       no = 4096;
+       po = buf;
+       rc = iconv(iconv_cd_str2wcs, (char **)(&str), &ni, &po, &no);
+       if (rc == (size_t) (-1) || no == 0)
+          return -1;
+       wcl = (4096 - no) / sizeof(wchar_t);
+       return wcl;
+     }
+
+   ni = len;
+   no = wcl * sizeof(wchar_t);
+   rc = iconv(iconv_cd_str2wcs, (char **)(&str), &ni, (char **)(&wcs), &no);
+   if (rc == (size_t) (-1))
+      return 0;
+   return wcl - no / sizeof(wchar_t);
+#else
+   if (!wcs)
+      return mbstowcs(NULL, str, 0);
+
+   mbstowcs(wcs, str, wcl);
+   wcs[wcl] = (wchar_t) '\0';
+
+   len = 0;
+   return wcl;
+#endif
+}
+
+int
+EwcWcsToStr(const wchar_t * wcs, int wcl, char *str, int len)
+{
+#if HAVE_ICONV
+   size_t              ni, no, rc;
+
+   ni = wcl * sizeof(wchar_t);
+   no = len;
+   rc = iconv(iconv_cd_wcs2str, (char **)(&wcs), &ni, &str, &no);
+   if (rc == (size_t) (-1))
+      return 0;
+   return len - no;
+#else
+   int                 i, j, n;
+
+   j = 0;
+   for (i = 0; i < wcl; i++)
+     {
+       if (j + (int)MB_CUR_MAX > len)
+          break;
+       n = wctomb(str + j, wcs[i]);
+       if (n > 0)
+          j += n;
+     }
+   str[j] = '\0';
+   return j;
+#endif
+}
+
+/*
+ * Setup
+ */
+
 static struct
 {
    char               *internal;
===================================================================
RCS file: /cvs/e/e16/e/src/lang.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -3 -r1.2 -r1.3
--- lang.h      21 Apr 2006 23:47:30 -0000      1.2
+++ lang.h      12 Nov 2006 00:39:19 -0000      1.3
@@ -24,6 +24,8 @@
 #ifndef _LANG_H_
 #define _LANG_H_
 
+#include <stdlib.h>
+
 #include "config.h"
 
 #ifdef ENABLE_NLS
@@ -48,5 +50,12 @@
 char               *EstrUtf82Int(const char *str, int len);
 const char         *EstrInt2Enc(const char *str, int want_utf8);
 void                EstrInt2EncFree(const char *str, int want_utf8);
+
+int                 EwcOpen(int utf8);
+void                EwcClose(void);
+int                 EwcStrToWcs(const char *str, int len, wchar_t * wcs,
+                               int wcl);
+int                 EwcWcsToStr(const wchar_t * wcs, int wcl, char *str,
+                               int len);
 
 #endif /* _LANG_H_ */
===================================================================
RCS file: /cvs/e/e16/e/src/tclass.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -3 -r1.17 -r1.18
--- tclass.h    22 Oct 2006 14:09:50 -0000      1.17
+++ tclass.h    12 Nov 2006 00:39:19 -0000      1.18
@@ -101,8 +101,8 @@
 /* text.c */
 TextState          *TextclassGetTextState(TextClass * tclass, int state,
                                          int active, int sticky);
-void                TextstateTextFitMB(TextState * ts, char **ptext, int *pw,
-                                      int textwidth_limit);
+void                TextstateTextFit(TextState * ts, char **ptext, int *pw,
+                                    int textwidth_limit);
 void                TextstateTextDraw(TextState * ts, Win win, Drawable draw,
                                      const char *text, int x, int y, int w,
                                      int h, const EImageBorder * pad,
===================================================================
RCS file: /cvs/e/e16/e/src/text.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -3 -r1.79 -r1.80
--- text.c      30 Oct 2006 21:06:01 -0000      1.79
+++ text.c      12 Nov 2006 00:39:19 -0000      1.80
@@ -258,6 +258,151 @@
    return NULL;
 }
 
+static void
+TextstateTextFit1(TextState * ts, char **ptext, int *pw, int textwidth_limit)
+{
+   char               *text = *ptext;
+   int                 hh, ascent;
+   char               *new_line;
+   int                 nuke_count = 0, nc2;
+   int                 len;
+
+   len = strlen(text);
+   if (len <= 1)
+      return;
+   new_line = Emalloc(len + 10);
+   if (!new_line)
+      return;
+
+   while (*pw > textwidth_limit)
+     {
+       nuke_count++;
+
+       if (nuke_count >= len - 1)
+         {
+            new_line[0] = text[0];
+            memcpy(new_line + 1, "...", 4);
+            break;
+         }
+
+       nc2 = (len - nuke_count) / 2;
+       memcpy(new_line, text, nc2);
+       memcpy(new_line + nc2, "...", 3);
+       strcpy(new_line + nc2 + 3, text + nc2 + nuke_count);
+
+       ts->ops->TextSize(ts, new_line, 0, pw, &hh, &ascent);
+     }
+
+   Efree(text);
+   *ptext = new_line;
+}
+
+#if FONT_TYPE_XFONT
+static void
+TextstateTextFit2(TextState * ts, char **ptext, int *pw, int textwidth_limit)
+{
+   char               *text = *ptext;
+   int                 hh, ascent;
+   char               *new_line;
+   int                 nuke_count = 0;
+   int                 len;
+
+   len = strlen(text);
+   new_line = Emalloc(len + 20);
+   if (!new_line)
+      return;
+
+   while (*pw > textwidth_limit)
+     {
+       nuke_count += 2;
+
+       if (nuke_count > len)
+         {
+            memcpy(new_line, text, 2);
+            memcpy(new_line + 2, ". . . ", 7);
+            break;
+         }
+
+       new_line[0] = 0;
+       strncat(new_line, text, (len - nuke_count) / 4);
+       strcat(new_line, ". . . ");
+       strcat(new_line, text + ((len - nuke_count) / 4) + nuke_count);
+
+       ts->ops->TextSize(ts, new_line, 0, pw, &hh, &ascent);
+     }
+
+   Efree(text);
+   *ptext = new_line;
+}
+#endif /* FONT_TYPE_XFONT */
+
+static void
+TextstateTextFitMB(TextState * ts, char **ptext, int *pw, int textwidth_limit)
+{
+   char               *text = *ptext;
+   int                 hh, ascent;
+   char               *new_line;
+   int                 nuke_count = 0, nc2;
+   int                 len;
+   wchar_t            *wc_line = NULL;
+   int                 wc_len;
+
+   if (EwcOpen(ts->need_utf8 || Mode.locale.utf8_int))
+      return;
+
+   len = strlen(text);
+   wc_len = EwcStrToWcs(text, len, NULL, 0);
+   if (wc_len <= 1)
+      goto done;
+
+   wc_line = (wchar_t *) Emalloc((wc_len + 1) * sizeof(wchar_t));
+   if (!wc_line)
+      goto done;
+
+   if (EwcStrToWcs(text, len, wc_line, wc_len) <= 0)
+      goto done;
+
+   new_line = Emalloc(len + 10);
+   if (!new_line)
+      goto done;
+
+   while (*pw > textwidth_limit)
+     {
+       nuke_count++;
+       int                 len_mb;
+
+       if (nuke_count >= wc_len - 1)
+         {
+            int                 mlen;
+
+            mlen = mblen(text, MB_CUR_MAX);
+            if (mlen < 0)
+               mlen = 1;
+
+            memcpy(new_line, text, mlen);
+            strcpy(new_line + mlen, "...");
+            break;
+         }
+
+       nc2 = (wc_len - nuke_count) / 2;
+       len_mb = EwcWcsToStr(wc_line, nc2, new_line, len + 10);
+       memcpy(new_line + len_mb, "...", 3);
+       len_mb += 3;
+       len_mb += EwcWcsToStr(wc_line + nc2 + nuke_count,
+                             wc_len - nc2 - nuke_count,
+                             new_line + len_mb, len + 10 - len_mb);
+       new_line[len_mb] = '\0';
+
+       ts->ops->TextSize(ts, new_line, 0, pw, &hh, &ascent);
+     }
+   Efree(text);
+   *ptext = new_line;
+ done:
+   if (wc_line)
+      Efree(wc_line);
+   EwcClose();
+}
+
 #if FONT_TYPE_XFT
 /*
  * Xft
@@ -397,7 +542,7 @@
 }
 
 const FontOps       FontOpsXft = {
-   _xft_Load, _xft_Unload, _xft_TextSize, TextstateTextFitMB, _xft_TextDraw,
+   _xft_Load, _xft_Unload, _xft_TextSize, TextstateTextFit, _xft_TextDraw,
    _xft_FdcInit, _xft_FdcFini, _xft_FdcSetDrawable, _xft_FdcSetColor
 };
 #endif /* FONT_TYPE_XFT */
@@ -525,7 +670,7 @@
 }
 
 const FontOps       FontOpsXfs = {
-   _xfs_Load, _xfs_Unload, _xfs_TextSize, TextstateTextFitMB, _xfs_TextDraw,
+   _xfs_Load, _xfs_Unload, _xfs_TextSize, TextstateTextFit, _xfs_TextDraw,
    _xfs_FdcInit, NULL, _xfs_FdcSetDrawable, _xfs_FdcSetColor
 };
 #endif /* FONT_TYPE_XFS */
@@ -642,62 +787,11 @@
 _xfont_TextFit(TextState * ts, char **ptext, int *pw, int textwidth_limit)
 {
    FontCtxXfont       *fdc = (FontCtxXfont *) ts->fdc;
-   char               *text = *ptext;
-   int                 hh, ascent;
-   char               *new_line;
-   int                 nuke_count = 0;
-   int                 len;
 
    if (fdc->font->min_byte1 == 0 && fdc->font->max_byte1 == 0)
-     {
-       len = strlen(text);
-       new_line = Emalloc(len + 10);
-       if (!new_line)
-          return;
-
-       while (*pw > textwidth_limit)
-         {
-            nuke_count++;
-            if (nuke_count > len)
-              {
-                 new_line[0] = 0;
-                 strncat(new_line, text, 1);
-                 strcat(new_line, "...");
-                 break;
-              }
-            new_line[0] = 0;
-            strncat(new_line, text, (len - nuke_count) / 2);
-            strcat(new_line, "...");
-            strcat(new_line, text + ((len - nuke_count) / 2) + nuke_count);
-            ts->ops->TextSize(ts, new_line, 0, pw, &hh, &ascent);
-         }
-     }
+      TextstateTextFit1(ts, ptext, pw, textwidth_limit);
    else
-     {
-       len = strlen(text);
-       new_line = Emalloc(len + 20);
-       if (!new_line)
-          return;
-
-       while (*pw > textwidth_limit)
-         {
-            nuke_count += 2;
-            if (nuke_count > len)
-              {
-                 new_line[0] = 0;
-                 strncat(new_line, text, 1);
-                 strcat(new_line, ". . . ");
-                 break;
-              }
-            new_line[0] = 0;
-            strncat(new_line, text, (len - nuke_count) / 4);
-            strcat(new_line, ". . . ");
-            strcat(new_line, text + ((len - nuke_count) / 4) + nuke_count);
-            ts->ops->TextSize(ts, new_line, 0, pw, &hh, &ascent);
-         }
-     }
-   Efree(text);
-   *ptext = new_line;
+      TextstateTextFit2(ts, ptext, pw, textwidth_limit);
 }
 
 const FontOps       FontOpsXfont = {
@@ -809,83 +903,12 @@
 }
 
 void
-TextstateTextFitMB(TextState * ts, char **ptext, int *pw, int textwidth_limit)
+TextstateTextFit(TextState * ts, char **ptext, int *pw, int textwidth_limit)
 {
-   char               *text = *ptext;
-   int                 hh, ascent;
-   char               *new_line;
-   int                 nuke_count = 0;
-   int                 len;
-   wchar_t            *wc_line = NULL;
-   int                 wc_len;
-
-   len = strlen(text);
-   new_line = Emalloc(len + 10);
-   if (!new_line)
-      return;
-
-   wc_len = mbstowcs(NULL, text, 0);
-   if (wc_len > 0)
-     {
-       wc_line = (wchar_t *) Emalloc((wc_len + 1) * sizeof(wchar_t));
-       mbstowcs(wc_line, text, len);
-       wc_line[wc_len] = (wchar_t) '\0';
-     }
-
-   while (*pw > textwidth_limit)
-     {
-       nuke_count++;
-       if (nuke_count > wc_len)
-         {
-            int                 mlen;
-
-            new_line[0] = 0;
-            if (MB_CUR_MAX > 1 && wc_len > 0)
-              {                /* if multibyte locale,... */
-                 mlen = mblen(text, MB_CUR_MAX);
-                 if (mlen < 0)
-                    mlen = 1;
-              }
-            else
-               mlen = 1;
-
-            strncat(new_line, text, mlen);
-            strcat(new_line, "...");
-            break;
-         }
-       new_line[0] = 0;
-       if (MB_CUR_MAX > 1 && wc_len > 0)
-         {
-            int                 j, k, len_mb;
-
-            for (j = k = 0; k < (wc_len - nuke_count) / 2; k++)
-              {
-                 len_mb = wctomb(new_line + j, wc_line[k]);
-                 if (len_mb > 0)
-                    j += len_mb;
-              }
-            new_line[j] = '\0';
-            strcat(new_line, "...");
-            j += 3;
-            len_mb = wcstombs(new_line + j,
-                              wc_line + (wc_len - nuke_count) / 2 +
-                              nuke_count, len + 10 - j);
-            if (len_mb > 0)
-               j += len_mb;
-            new_line[j] = '\0';
-         }
-       else
-         {
-            strncat(new_line, text, (len - nuke_count) / 2);
-            strcat(new_line, "...");
-            strcat(new_line, text + ((len - nuke_count) / 2) + nuke_count);
-         }
-       ts->ops->TextSize(ts, new_line, 0, pw, &hh, &ascent);
-     }
-   Efree(text);
-   *ptext = new_line;
-   if (wc_line)
-      Efree(wc_line);
+   if (ts->need_utf8 || MB_CUR_MAX > 1)
+      TextstateTextFitMB(ts, ptext, pw, textwidth_limit);
+   else
+      TextstateTextFit1(ts, ptext, pw, textwidth_limit);
 }
 
 void
===================================================================
RCS file: /cvs/e/e16/e/src/ttfont.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -3 -r1.56 -r1.57
--- ttfont.c    22 Oct 2006 14:09:50 -0000      1.56
+++ ttfont.c    12 Nov 2006 00:39:19 -0000      1.57
@@ -194,7 +194,7 @@
 }
 
 const FontOps       FontOpsIft = {
-   _ift_Load, _ift_Unload, _ift_TextSize, TextstateTextFitMB, _ift_TextDraw,
+   _ift_Load, _ift_Unload, _ift_TextSize, TextstateTextFit, _ift_TextDraw,
    _ift_FdcInit, NULL, _ift_FdcSetDrawable, _ift_FdcSetColor
 };
 



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to