changeset 90059:9b0bfaaaec9c

Sync to the change in HEAD on 2004-11-30.
author Kenichi Handa <handa@m17n.org>
date Sat, 11 Dec 2004 02:11:33 +0000
parents 48f163b71dbf
children 637c6bc8a26f
files src/term.c
diffstat 1 files changed, 129 insertions(+), 111 deletions(-) [+]
line wrap: on
line diff
--- a/src/term.c	Thu Dec 09 12:37:05 2004 +0000
+++ b/src/term.c	Sat Dec 11 02:11:33 2004 +0000
@@ -793,75 +793,64 @@
     }
 }
 
-/* Buffer to store the result of terminal codes.  It is initialized in
-   term_init and, if necessary, enlarged in encode_terminal_code.  */
-unsigned char *terminal_encode_buffer;
-/* Size of terminal_encode_buffer.  */
-static int terminal_encode_buf_size;
-
-/* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
-   store them in terminal_encode_buffer.
-
-   We store the number of glyphs actually converted in *CONSUMED.  The
-   return value is the number of bytes stored in
-   terminal_encode_buffer.
-
-   This function will stop before encoding all glyphs in these two
-   cases.
-
-   (1) If the first glyph doesn't have a string entry in Vglyph_table,
-       it stops at encountering a glyph that has a string entry in
-       Vglyph_table.n
-
-   (2) If the first has a string entry in Vglyph_table, it stops after
-       encoding that string.
-*/
-
-int
-encode_terminal_code (src, src_len, consumed)
+/* Buffers to store the source and result of code conversion for terminal.  */
+static unsigned char *encode_terminal_src;
+static unsigned char *encode_terminal_dst;
+/* Allocated sizes of the above buffers.  */
+static int encode_terminal_src_size;
+static int encode_terminal_dst_size;
+
+/* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
+   Set CODING->produced to the byte-length of the resulting byte
+   sequence, and return a pointer to that byte sequence.  */
+
+unsigned char *
+encode_terminal_code (src, src_len, coding)
      struct glyph *src;
      int src_len;
-     int *consumed;
+     struct coding_system *coding;
 {
   struct glyph *src_start = src, *src_end = src + src_len;
   register GLYPH g;
-  register int c;
-  Lisp_Object string;
-  unsigned char *workbuf, *buf;
-  int nchars;
+  unsigned char *buf;
+  int nchars, nbytes, required;
   register int tlen = GLYPH_TABLE_LENGTH;
   register Lisp_Object *tbase = GLYPH_TABLE_BASE;
-  struct coding_system *coding;
-  Lisp_Object attrs, charset_list;
-
-#if 1
-  /* GLYPH-TABLE is not supported anymore in xdisp.c.  */
-  tlen = 0;
-#endif
-
-  /* If terminal_coding does any conversion, use it, otherwise use
-     safe_terminal_coding.  We can't use CODING_REQUIRE_ENCODING here
-     because it always return 1 if the member src_multibyte is 1.  */
-  coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
-	    ? &terminal_coding
-	    : &safe_terminal_coding);
-  coding->destination = terminal_encode_buffer;
-  coding->dst_bytes = terminal_encode_buf_size;
-  coding->mode |= CODING_MODE_LAST_BLOCK;
-  attrs = CODING_ID_ATTRS (coding->id);
-  charset_list = CODING_ATTR_CHARSET_LIST (attrs);
-
-  workbuf = buf = alloca (MAX_MULTIBYTE_LENGTH * src_len);
-  for (nchars = 0; src < src_end; src++)
+  Lisp_Object charset_list;
+
+  /* Allocate sufficient size of buffer to store all characters in
+     multibyte-form.  But, it may be enlarged on demand if
+     Vglyph_table contains a string.  */
+  required = MAX_MULTIBYTE_LENGTH * src_len;
+  if (encode_terminal_src_size < required)
+    {
+      if (encode_terminal_src_size == 0)
+	encode_terminal_src = xmalloc (required);
+      else
+	encode_terminal_src = xrealloc (encode_terminal_src, required);
+      encode_terminal_src_size = required;
+    }
+
+  charset_list = coding_charset_list (coding);
+
+  buf = encode_terminal_src;
+  nchars = 0;
+  while (src < src_end)
     {
       /* We must skip glyphs to be padded for a wide character.  */
       if (! CHAR_GLYPH_PADDING_P (*src))
 	{
+	  int c;
+	  Lisp_Object string;
+
+	  string = Qnil;
 	  g = GLYPH_FROM_CHAR_GLYPH (src[0]);
-	  string = Qnil;
 
 	  if (g < 0 || g >= tlen)
-	    c = src->u.ch;
+	    {
+	      /* This glyph doesn't has an entry in Vglyph_table.  */
+	      c = src->u.ch;
+	    }
 	  else
 	    {
 	      /* This glyph has an entry in Vglyph_table,
@@ -879,47 +868,68 @@
 
 	  if (NILP (string))
 	    {
-	      if (! char_charset (c, charset_list, NULL))
-		{
-		  /* C is not encodable.  */
-		  int i;
-
-		  for (i = CHAR_WIDTH (c) - 1; i >= 0; i--, nchars++)
-		    *buf++ = '?';
-		}
-	      else
+	      if (char_charset (c, charset_list, NULL))
 		{
 		  /* Store the multibyte form of C at BUF.  */
 		  buf += CHAR_STRING (c, buf);
 		  nchars++;
 		}
+	      else
+		{
+		  /* C is not encodable.  */
+		  *buf++ = '?';
+		  nchars++;
+		  while (src + 1 < src_end && CHAR_GLYPH_PADDING_P (src[1]))
+		    {
+		      *buf++ = '?';
+		      nchars++;
+		      src++;
+		    }
+		}
 	    }
 	  else
 	    {
-	      if (nchars == 0)
+	      unsigned char *p = SDATA (string), *pend = p + SBYTES (string);
+
+	      if (! STRING_MULTIBYTE (string))
+		string = string_to_multibyte (string);
+	      nbytes = buf - encode_terminal_src;
+	      if (nbytes + SBYTES (string) < encode_terminal_src_size)
 		{
-		  encode_coding_object (coding, string, 0, 0, SCHARS (string),
-					SBYTES (string), Qnil);
-		  src++;
+		  encode_terminal_src_size = nbytes + SBYTES (string);
+		  encode_terminal_src = xrealloc (encode_terminal_src,
+						  encode_terminal_src_size);
+		  buf = encode_terminal_src + nbytes;
 		}
-	      break;
+	      bcopy (SDATA (string), buf, SBYTES (string));
+	      buf += SBYTES (string);
+	      nchars += SCHARS (string);
 	    }
 	}
+      src++;
     }
 
-  if (nchars > 0)
+  if (nchars == 0)
     {
-      coding->source = workbuf;
-      encode_coding_object (coding, Qnil, 0, 0, nchars,
-			    buf - workbuf, Qnil);
+      coding->produced = 0;
+      return NULL;
     }
+
+  nbytes = buf - encode_terminal_src;
+  coding->source = encode_terminal_src;
+  if (encode_terminal_dst_size == 0)
+    {
+      encode_terminal_dst_size = encode_terminal_src_size;
+      encode_terminal_dst = xmalloc (encode_terminal_dst_size);
+    }
+  coding->destination = encode_terminal_dst;
+  coding->dst_bytes = encode_terminal_dst_size;
+  encode_coding_object (coding, Qnil, 0, 0, nchars, nbytes, Qnil);
   /* coding->destination may have been reallocated.  */
-  terminal_encode_buffer = coding->destination;
-  if (terminal_encode_buf_size < coding->dst_bytes)
-    terminal_encode_buf_size = coding->dst_bytes;
-
-  *consumed = src - src_start;
-  return (coding->produced);
+  encode_terminal_dst = coding->destination;
+  encode_terminal_dst_size = coding->dst_bytes;
+
+  return (encode_terminal_dst);
 }
 
 
@@ -931,6 +941,8 @@
   int produced, consumed;
   struct frame *sf = XFRAME (selected_frame);
   struct frame *f = updating_frame ? updating_frame : sf;
+  unsigned char *conversion_buffer;
+  struct coding_system *coding;
 
   if (write_glyphs_hook
       && ! FRAME_TERMCAP_P (f))
@@ -977,21 +989,20 @@
       highlight_if_desired ();
       turn_on_face (f, face_id);
 
-      while (n > 0)
+      if (n == len)
+	/* This is the last run.  */
+	coding->mode |= CODING_MODE_LAST_BLOCK;
+      conversion_buffer = encode_terminal_code (string, n, coding);
+      if (coding->produced > 0)
 	{
-	  produced = encode_terminal_code (string, n, &consumed);
-	  if (produced > 0)
-	    {
-	      fwrite (terminal_encode_buffer, 1, produced, stdout);
-	      if (ferror (stdout))
-		clearerr (stdout);
-	      if (termscript)
-		fwrite (terminal_encode_buffer, 1, produced, termscript);
-	    }
-	  len -= consumed;
-	  n -= consumed;
-	  string += consumed;
+	  fwrite (conversion_buffer, 1, coding->produced, stdout);
+	  if (ferror (stdout))
+	    clearerr (stdout);
+	  if (termscript)
+	    fwrite (conversion_buffer, 1, coding->produced, termscript);
 	}
+      len -= n;
+      string += n;
 
       /* Turn appearance modes off.  */
       turn_off_face (f, face_id);
@@ -1039,17 +1050,26 @@
 
   turn_on_insert ();
   cmplus (len);
-  /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail.  */
-  terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
+
+  if (! start)
+    space[0] = SPACEGLYPH;
+
+  /* If terminal_coding does any conversion, use it, otherwise use
+     safe_terminal_coding.  We can't use CODING_REQUIRE_ENCODING here
+     because it always return 1 if the member src_multibyte is 1.  */
+  coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
+	    ? &terminal_coding : &safe_terminal_coding);
+  /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
+     the tail.  */
+  coding->mode &= ~CODING_MODE_LAST_BLOCK;
+
   while (len-- > 0)
     {
-      int produced, consumed;
-
       OUTPUT1_IF (TS_ins_char);
       if (!start)
 	{
-	  terminal_encode_buffer[0] = SPACEGLYPH;
-	  produced = 1;
+	  conversion_buffer = space;
+	  coding->produced = 1;
 	}
       else
 	{
@@ -1064,16 +1084,21 @@
 	      OUTPUT1_IF (TS_ins_char);
 	      start++, len--;
 	    }
-	  produced = encode_terminal_code (glyph, 1, &consumed);
+
+	  if (len <= 0)
+	    /* This is the last glyph.  */
+	    coding->mode |= CODING_MODE_LAST_BLOCK;
+
+	  conversion_buffer = encode_terminal_code (glyph, 1, coding);
 	}
 
-      if (produced > 0)
+      if (coding->produced > 0)
 	{
-	  fwrite (terminal_encode_buffer, 1, produced, stdout);
+	  fwrite (conversion_buffer, 1, coding->produced, stdout);
 	  if (ferror (stdout))
 	    clearerr (stdout);
 	  if (termscript)
-	    fwrite (terminal_encode_buffer, 1, produced, termscript);
+	    fwrite (conversion_buffer, 1, coding->produced, termscript);
 	}
 
       OUTPUT1_IF (TS_pad_inserted_char);
@@ -2247,7 +2272,8 @@
   int status;
   struct frame *sf = XFRAME (selected_frame);
 
-  encode_terminal_bufsize = 0;
+  encode_terminal_src_size = 0;
+  encode_terminal_dst_size = 0;
 
 #ifdef WINDOWSNT
   initialize_w32_display ();
@@ -2642,14 +2668,6 @@
 
   FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
   FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
-
-  if (! terminal_encode_buffer)
-    {
-      terminal_encode_buffer = xmalloc (1024);
-      if (! terminal_encode_buffer)
-	abort ();
-      terminal_encode_buf_size = 1024;
-    }
 #endif /* WINDOWSNT */
 
   xfree (buffer);