emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] emacs/src msdos.c


From: Eli Zaretskii
Subject: [Emacs-diffs] emacs/src msdos.c
Date: Sat, 14 Feb 2009 10:49:43 +0000

CVSROOT:        /cvsroot/emacs
Module name:    emacs
Changes by:     Eli Zaretskii <eliz>    09/02/14 10:49:43

Modified files:
        src            : msdos.c 

Log message:
        (MAX_SCREEN_BUF): New macro.
        (IT_write_glyphs): Make screen_buf[] always be MAX_SCREEN_BUF-long.
        Encode the entire run of glyphs sharing the same face, instead of
        doing that one glyph at a time (fixes a bug with displaying
        double-size characters).

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/emacs/src/msdos.c?cvsroot=emacs&r1=1.230&r2=1.231

Patches:
Index: msdos.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/msdos.c,v
retrieving revision 1.230
retrieving revision 1.231
diff -u -b -r1.230 -r1.231
--- msdos.c     29 Jan 2009 19:22:54 -0000      1.230
+++ msdos.c     14 Feb 2009 10:49:42 -0000      1.231
@@ -957,19 +957,20 @@
     }
 }
 
+/* According to RBIL (INTERRUP.A, V-1000), 160 is the maximum possible
+   width of a DOS display in any known text mode.  We multiply by 2 to
+   accomodate the screen attribute byte.  */
+#define MAX_SCREEN_BUF 160*2
+
 Lisp_Object Vdos_unsupported_char_glyph;
 extern unsigned char *encode_terminal_code (struct glyph *, int,
                                            struct coding_system *);
 static void
 IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
 {
-  unsigned char *screen_buf, *screen_bp, *screen_buf_end, *bp;
-  int unsupported_face = 0;
-  unsigned unsupported_char = '\177';
+  unsigned char screen_buf[MAX_SCREEN_BUF], *screen_bp, *bp;
   int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y);
   register int sl = str_len;
-  register int tlen = GLYPH_TABLE_LENGTH;
-  register Lisp_Object *tbase = GLYPH_TABLE_BASE;
   struct tty_display_info *tty = FRAME_TTY (f);
   struct frame *sf;
   unsigned char *conversion_buffer;
@@ -990,8 +991,6 @@
 
   if (str_len <= 0) return;
 
-  screen_buf = screen_bp = alloca (str_len * 2);
-  screen_buf_end = screen_buf + str_len * 2;
   sf = SELECTED_FRAME();
 
   /* Since faces get cached and uncached behind our back, we can't
@@ -1004,73 +1003,50 @@
   /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
      the tail.  */
   coding->mode &= ~CODING_MODE_LAST_BLOCK;
+  screen_bp = &screen_buf[0];
   while (sl > 0)
     {
       int cf;
+      int n;
 
-      /* Glyphs with GLYPH_MASK_PADDING bit set are actually there
-        only for the redisplay code to know how many columns does
-         this character occupy on the screen.  Skip padding glyphs.  */
-      if (CHAR_GLYPH_PADDING_P (*str))
-       {
-         str++;
-         sl--;
-       }
-      else
-       {
          /* If the face of this glyph is different from the current
             screen face, update the screen attribute byte.  */
          cf = str->face_id;
          if (cf != screen_face)
            IT_set_face (cf);   /* handles invalid faces gracefully */
 
-         if (sl <= 1)
+      /* Identify a run of glyphs with the same face.  */
+      for (n = 1; n < sl; ++n)
+       if (str[n].face_id != cf)
+         break;
+
+      if (n >= sl)
            /* This is the last glyph.  */
            coding->mode |= CODING_MODE_LAST_BLOCK;
 
-         conversion_buffer = encode_terminal_code (str, 1, coding);
+      conversion_buffer = encode_terminal_code (str, n, coding);
          if (coding->produced > 0)
            {
-             if (2*coding->produced > screen_buf_end - screen_bp)
-               {
-                 /* The allocated buffer for screen writes is too small.
-                    Flush it and loop again without incrementing STR, so
-                    that the next loop will begin with the same glyph.  */
-                 int nbytes = screen_bp - screen_buf;
-
-                 mouse_off_maybe ();
-                 dosmemput (screen_buf, nbytes, (int)ScreenPrimary + offset);
-                 if (screen_virtual_segment)
-                   dosv_refresh_virtual_screen (offset, nbytes / 2);
-                 new_pos_X += nbytes / 2;
-                 offset += nbytes;
-
-                 /* Prepare to reuse the same buffer again.  */
-                 screen_bp = screen_buf;
-                 continue;
-               }
-             else
-               {
-                 /* There's enough place in the allocated buffer to add
-                    the encoding of this glyph.  */
-
-                 /* Copy the encoded bytes to the allocated buffer.  */
+         /* Copy the encoded bytes to the screen buffer.  */
                  for (bp = conversion_buffer; coding->produced--; bp++)
                    {
+             /* Paranoia: discard bytes that would overrun the end of
+                the screen buffer.  */
+             if (screen_bp - screen_buf <= MAX_SCREEN_BUF - 2)
+               {
                      *screen_bp++ = (unsigned char)*bp;
                      *screen_bp++ = ScreenAttrib;
+               }
                      if (tty->termscript)
                        fputc (*bp, tty->termscript);
                    }
                }
-           }
          /* Update STR and its remaining length.  */
-         str++;
-         sl--;
-       }
+      str += n;
+      sl -= n;
     }
 
-  /* Dump whatever is left in the screen buffer.  */
+  /* Dump whatever we have in the screen buffer.  */
   mouse_off_maybe ();
   dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset);
   if (screen_virtual_segment)




reply via email to

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