bug-texinfo
[Top][All Lists]
Advanced

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

[PATCH] info: display of multibyte modeline is currently partially broke


From: Andrey Borzenkov
Subject: [PATCH] info: display of multibyte modeline is currently partially broken
Date: Sun, 15 Mar 2009 20:22:44 +0300
User-agent: KMail/1.11.1 (Linux/2.6.29-rc8-1avb; KDE/4.2.1; i686; ; )

On 15 марта 2009 11:28:35 Andrey Borzenkov wrote:
> Texinfo 4.13 as shipped in Mandriva cooker.
>
> Display of translated multibyte characters in modeline is currently
> broken. Screen size of displayed text is computed using plain
> strlen(); also when modeline needs to be truncated it is truncated on
> byte boundary instead of on (mb)character boundary. The effect is, in
> the best case tail of modeline simply displays garbage; in the worst
> case, resetting inverse display is lost so main window suddenly
> starts to be displayed inverse. I also have seen strange window
> corruption that can well be attributed to incorrect line break
> computation.
>

Attached patch seems to have fixed it for me. Comments?
--- texinfo-4.13/info/display.c.mb_modeline     2009-03-15 12:43:46.000000000 
+0300
+++ texinfo-4.13/info/display.c 2009-03-15 20:12:22.000000000 +0300
@@ -308,6 +308,9 @@ display_update_one_window (WINDOW *win)
           terminal_begin_inverse ();
           terminal_put_text (win->modeline);
           terminal_end_inverse ();
+         /* line length can change when using multibyte characters */
+         display[line_index]->text = xrealloc (display[line_index]->text,
+                                               1 + strlen (win->modeline));
           strcpy (display[line_index]->text, win->modeline);
           display[line_index]->inverse = 1;
           display[line_index]->textlen = strlen (win->modeline);
--- texinfo-4.13/info/window.c.mb_modeline      2009-03-15 12:17:35.000000000 
+0300
+++ texinfo-4.13/info/window.c  2009-03-15 20:15:46.000000000 +0300
@@ -1007,6 +1007,8 @@ window_make_modeline (WINDOW *window)
     char *nodename = "*no node*";
     const char *update_message = NULL;
     NODE *node = window->node;
+    mbi_iterator_t iter;
+    int w;
 
     if (node)
       {
@@ -1016,7 +1018,9 @@ window_make_modeline (WINDOW *window)
         if (node->parent)
           {
             parent = filename_non_directory (node->parent);
-            modeline_len += strlen ("Subfile: ") + strlen (node->filename);
+           /* FIXME: currently message catalog lacks plain "Subfile:"; so
+            * just allocate a couple if characters more */
+            modeline_len += strlen (_("Subfile: %s")) + strlen 
(node->filename);
           }
 
         if (node->filename)
@@ -1057,17 +1061,28 @@ window_make_modeline (WINDOW *window)
     if (update_message)
       sprintf (modeline + strlen (modeline), "%s", update_message);
 
-    i = strlen (modeline);
-
-    if (i >= window->width)
-      modeline[window->width] = '\0';
-    else
+    /* truncate line on screen width making sure we do not leave
+     * partial multibyte characters */
+    for (mbi_init (iter, modeline, strlen (modeline)), i = 0, w = 0;
+         mbi_avail (iter); mbi_advance (iter))
       {
-        while (i < window->width)
-          modeline[i++] = '-';
-        modeline[i] = '\0';
+       size_t cur_len = mb_len (mbi_cur (iter));
+       int cur_width = mb_width (mbi_cur (iter));
+
+       if (w + cur_width > window->width || i + cur_len > modeline_len)
+         break;
+       else
+         {
+           i += cur_len;
+           w += cur_width;
+         }
       }
 
+      while (w++ < window->width && i < modeline_len)
+       modeline[i++] = '-';
+      modeline[i] = '\0';
+
+    window->modeline = xrealloc (window->modeline, 1 + strlen (modeline));
     strcpy (window->modeline, modeline);
     free (modeline);
   }

Attachment: signature.asc
Description: This is a digitally signed message part.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]