changeset 90638:1b46574c9f5d

Include "composite.h". (encode_terminal_code): Output all components of composition. Check the size of encode_terminal_src. (produce_glyphs): For compostion, call produce_composite_glyph. (append_composite_glyph, produce_composite_glyph): New functions.
author Kenichi Handa <handa@m17n.org>
date Thu, 26 Oct 2006 12:00:50 +0000
parents 042336f13176
children 5a93997128bf
files src/term.c
diffstat 1 files changed, 106 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/term.c	Thu Oct 26 11:34:09 2006 +0000
+++ b/src/term.c	Thu Oct 26 12:00:50 2006 +0000
@@ -33,6 +33,7 @@
 #include "character.h"
 #include "charset.h"
 #include "coding.h"
+#include "composite.h"
 #include "keyboard.h"
 #include "frame.h"
 #include "disptab.h"
@@ -835,7 +836,8 @@
 
   /* 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.  */
+     Vglyph_table contains a string or a composite glyph is
+     encountered.  */
   required = MAX_MULTIBYTE_LENGTH * src_len;
   if (encode_terminal_src_size < required)
     {
@@ -852,8 +854,40 @@
   nchars = 0;
   while (src < src_end)
     {
+      if (src->type == COMPOSITE_GLYPH)
+	{
+	  struct composition *cmp = composition_table[src->u.cmp_id];
+	  int i;
+
+	  nbytes = buf - encode_terminal_src;
+	  required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len;
+
+	  if (encode_terminal_src_size < nbytes + required)
+	    {
+	      encode_terminal_src_size = nbytes + required;
+	      encode_terminal_src = xrealloc (encode_terminal_src,
+					      encode_terminal_src_size);
+	      buf = encode_terminal_src + nbytes;
+	    }
+
+	  for (i = 0; i < cmp->glyph_len; i++)
+	    {
+	      int c = COMPOSITION_GLYPH (cmp, i);
+	      
+	      if (! char_charset (c, charset_list, NULL))
+		break;
+	      buf += CHAR_STRING (c, buf);
+	      nchars++;
+	    }
+	  if (i == 0)
+	    {
+	      /* The first character of the composition is not encodable.  */
+	      *buf++ = '?';
+	      nchars++;
+	    }
+	}
       /* We must skip glyphs to be padded for a wide character.  */
-      if (! CHAR_GLYPH_PADDING_P (*src))
+      else if (! CHAR_GLYPH_PADDING_P (*src))
 	{
 	  int c;
 	  Lisp_Object string;
@@ -883,6 +917,14 @@
 
 	  if (NILP (string))
 	    {
+	      nbytes = buf - encode_terminal_src;
+	      if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH)
+		{
+		  encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH;
+		  encode_terminal_src = xrealloc (encode_terminal_src,
+						  encode_terminal_src_size);
+		  buf = encode_terminal_src + nbytes;
+		}
 	      if (char_charset (c, charset_list, NULL))
 		{
 		  /* Store the multibyte form of C at BUF.  */
@@ -1658,11 +1700,14 @@
 #ifdef static
 #define append_glyph append_glyph_term
 #define produce_stretch_glyph produce_stretch_glyph_term
+#define append_composite_glyph append_composite_glyph_term
+#define produce_composite_glyph produce_composite_glyph_term
 #endif
 
 static void append_glyph P_ ((struct it *));
 static void produce_stretch_glyph P_ ((struct it *));
-
+static void append_composite_glyph P_ ((struct it *));
+static void produce_composite_glyph P_ ((struct it *));
 
 /* Append glyphs to IT's glyph_row.  Called from produce_glyphs for
    terminal frames if IT->glyph_row != NULL.  IT->char_to_display is
@@ -1723,6 +1768,8 @@
      struct it *it;
 {
   /* If a hook is installed, let it do the work.  */
+
+  /* Nothing but characters are supported on terminal frames.  */
   xassert (it->what == IT_CHARACTER
 	   || it->what == IT_COMPOSITION
 	   || it->what == IT_STRETCH);
@@ -1733,11 +1780,11 @@
       goto done;
     }
 
-  /* Nothing but characters are supported on terminal frames.  For a
-     composition sequence, it->c is the first character of the
-     sequence.  */
-  xassert (it->what == IT_CHARACTER
-	   || it->what == IT_COMPOSITION);
+  if (it->what == IT_COMPOSITION)
+    {
+      produce_composite_glyph (it);
+      goto done;
+    }
 
   /* Maybe translate single-byte characters to multibyte.  */
   it->char_to_display = it->c;
@@ -1896,6 +1943,57 @@
 }
 
 
+/* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
+   Called from produce_composite_glyph for terminal frames if
+   IT->glyph_row != NULL.  IT->face_id contains the character's
+   face.  */
+
+static void
+append_composite_glyph (it)
+     struct it *it;
+{
+  struct glyph *glyph;
+
+  xassert (it->glyph_row);
+  glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
+  if (glyph < it->glyph_row->glyphs[1 + it->area])
+    {
+      glyph->type = COMPOSITE_GLYPH;
+      glyph->pixel_width = it->pixel_width;
+      glyph->u.cmp_id = it->cmp_id;
+      glyph->face_id = it->face_id;
+      glyph->padding_p = 0;
+      glyph->charpos = CHARPOS (it->position);
+      glyph->object = it->object;
+
+      ++it->glyph_row->used[it->area];
+      ++glyph;
+    }
+}
+
+
+/* Produce a composite glyph for iterator IT.  IT->cmp_id is the ID of
+   the composition.  We simply produces components of the composition
+   assuming that that the terminal has a capability to layout/render
+   it correctly.  */
+
+static void
+produce_composite_glyph (it)
+     struct it *it;
+{
+  struct composition *cmp = composition_table[it->cmp_id];
+  int c;
+
+  xassert (cmp->glyph_len > 0);
+  c = COMPOSITION_GLYPH (cmp, 0);
+  it->pixel_width = CHAR_WIDTH (it->c);
+  it->nglyphs = 1;
+
+  if (it->glyph_row)
+    append_composite_glyph (it);
+}
+
+
 /* Get information about special display element WHAT in an
    environment described by IT.  WHAT is one of IT_TRUNCATION or
    IT_CONTINUATION.  Maybe produce glyphs for WHAT if IT has a