changeset 26874:e45f9a84fca0

(it_props): Add an entry for composition. (face_before_or_after_it_pos): For composition, check face of a character after the composition. (handle_composition_prop): New function. (get_next_display_element): Adjusted for the change of CHAR_STRING. (set_iterator_to_next): Handle the case that it->method == next_element_from_composition. (next_element_from_composition): New function. (message_dolog): Adjusted for the change of CHAR_STRING. (set_message_1): Likewise. (check_point_in_composition): New function. (reconsider_clip_changes): If point moved into or out of composition, set b->clip_changed to 1 to force updating of the screen. (disp_char_vector): Delete codes for a composite character. (decode_mode_spec_coding): Adjusted for the change of CHAR_STRING.
author Kenichi Handa <handa@m17n.org>
date Wed, 15 Dec 1999 00:23:27 +0000
parents 5281eb29603f
children d6aa11f2a4af
files src/xdisp.c
diffstat 1 files changed, 181 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/xdisp.c	Wed Dec 15 00:22:26 1999 +0000
+++ b/src/xdisp.c	Wed Dec 15 00:23:27 1999 +0000
@@ -533,6 +533,7 @@
 static enum prop_handled handle_face_prop P_ ((struct it *));
 static enum prop_handled handle_invisible_prop P_ ((struct it *));
 static enum prop_handled handle_display_prop P_ ((struct it *));
+static enum prop_handled handle_composition_prop P_ ((struct it *));
 static enum prop_handled handle_overlay_change P_ ((struct it *));
 static enum prop_handled handle_fontified_prop P_ ((struct it *));
 
@@ -546,6 +547,7 @@
   {&Qface,		FACE_PROP_IDX,		handle_face_prop},
   {&Qdisplay,		DISPLAY_PROP_IDX,	handle_display_prop},
   {&Qinvisible,		INVISIBLE_PROP_IDX,	handle_invisible_prop},
+  {&Qcomposition,	COMPOSITION_PROP_IDX,	handle_composition_prop},
   {NULL,		0,			NULL}
 };
 
@@ -646,6 +648,7 @@
 static int next_element_from_string P_ ((struct it *));
 static int next_element_from_c_string P_ ((struct it *));
 static int next_element_from_buffer P_ ((struct it *));
+static int next_element_from_composition P_ ((struct it *));
 static int next_element_from_image P_ ((struct it *));
 static int next_element_from_stretch P_ ((struct it *));
 static void load_overlay_strings P_ ((struct it *));
@@ -1943,7 +1946,11 @@
       if (before_p)
 	pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
       else
-	pos = string_pos (IT_STRING_CHARPOS (*it) + 1, it->string);
+	/* For composition, we must check the character after the
+           composition.  */
+	pos = (it->what == IT_COMPOSITION
+	       ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
+	       : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
 
       /* Get the face for ASCII, or unibyte.  */
       face_id
@@ -1985,8 +1992,14 @@
       if (before_p)
 	DEC_TEXT_POS (pos);
       else
-	INC_TEXT_POS (pos);
-
+	{
+	  if (it->what == IT_COMPOSITION)
+	    /* For composition, we must check the position after the
+	       composition.  */
+	    pos.charpos += it->cmp_len, pos.bytepos += it->len;
+	  else
+	    INC_TEXT_POS (pos);
+	}
       /* Determine face for CHARSET_ASCII, or unibyte.  */
       face_id = face_at_buffer_position (it->w,
 					 CHARPOS (pos),
@@ -2534,6 +2547,64 @@
 
 
 /***********************************************************************
+			`composition' property
+ ***********************************************************************/
+
+/* Set up iterator IT from `composition' property at its current
+   position.  Called from handle_stop.  */
+
+static enum prop_handled
+handle_composition_prop (it)
+     struct it *it;
+{
+  Lisp_Object prop, string;
+  int pos, pos_byte, end;
+  enum prop_handled handled = HANDLED_NORMALLY;
+
+  if (STRINGP (it->string))
+    {
+      pos = IT_STRING_CHARPOS (*it);
+      pos_byte = IT_STRING_BYTEPOS (*it);
+      string = it->string;
+    }
+  else
+    {
+      pos = IT_CHARPOS (*it);
+      pos_byte = IT_BYTEPOS (*it);
+      string = Qnil;
+    }
+
+  /* If there's a valid composition and point is not inside of the
+     composition (in the case that the composition is from the current
+     buffer), draw a glyph composed from the composition components.  */
+  if (find_composition (pos, -1, &pos, &end, &prop, string)
+      && COMPOSITION_VALID_P (pos, end, prop)
+      && (STRINGP (it->string) || (PT <= pos || PT >= end)))
+    {
+      int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
+
+      if (id >= 0)
+	{
+	  it->method = next_element_from_composition;
+	  it->cmp_id = id;
+	  it->cmp_len = COMPOSITION_LENGTH (prop);
+	  /* For a terminal, draw only the first character of the
+             components.  */
+	  it->c = COMPOSITION_GLYPH (composition_table[id], 0);
+	  it->len = (STRINGP (it->string)
+		     ? string_char_to_byte (it->string, end)
+		     : CHAR_TO_BYTE (end)) - pos_byte;
+	  it->stop_charpos = end;
+	  handled = HANDLED_RETURN;
+	}
+    }
+
+  return handled;
+}
+
+
+
+/***********************************************************************
 			   Overlay strings
  ***********************************************************************/
 
@@ -3340,8 +3411,8 @@
 		}
 	      else
 		{
-		  unsigned char work[4], *str;
-		  int len = CHAR_STRING (it->c, work, str);
+		  unsigned char str[MAX_MULTIBYTE_LENGTH];
+		  int len = CHAR_STRING (it->c, str);
 		  int i;
 		  GLYPH escape_glyph;
 
@@ -3442,6 +3513,23 @@
 	  xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
 	}
     }
+  else if (it->method == next_element_from_composition)
+    {
+      xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
+      if (STRINGP (it->string))
+	{
+	  IT_STRING_BYTEPOS (*it) += it->len;
+	  IT_STRING_CHARPOS (*it) += it->cmp_len;
+	  it->method = next_element_from_string;
+	  goto consider_string_end;
+	}
+      else
+	{
+	  IT_BYTEPOS (*it) += it->len;
+	  IT_CHARPOS (*it) += it->cmp_len;
+	  it->method = next_element_from_buffer;
+	}
+    }
   else if (it->method == next_element_from_c_string)
     {
       /* Current display element of IT is from a C string.  */
@@ -3862,7 +3950,7 @@
 
       /* Get the next character, maybe multibyte.  */
       p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
-      if (it->multibyte_p)
+      if (it->multibyte_p && !ASCII_BYTE_P (*p))
 	{
 	  int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
 			- IT_BYTEPOS (*it));
@@ -3939,6 +4027,22 @@
 }
 
 
+/* Deliver a composition display element.  The iterator IT is already
+   filled with composition information (done in
+   handle_composition_prop).  Value is always 1.  */
+
+static int
+next_element_from_composition (it)
+     struct it *it;
+{
+  it->what = IT_COMPOSITION;
+  it->position = (STRINGP (it->string)
+		  ? it->current.string_pos
+		  : it->current.pos);
+  return 1;
+}
+
+
 
 /***********************************************************************
 	     Moving an iterator without producing glyphs
@@ -4673,14 +4777,14 @@
 	{
 	  int i, c, nbytes;
 	  unsigned char *msg = (unsigned char *) m;
-	  unsigned char *str, work[4];
+	  unsigned char str[MAX_MULTIBYTE_LENGTH];
 	  /* Convert a single-byte string to multibyte
 	     for the *Message* buffer.  */
 	  for (i = 0; i < len; i++)
 	    {
 	      c = unibyte_char_to_multibyte (msg[i]);
-	      nbytes = CHAR_STRING (c, work, str);
-	      insert_1_both (work, 1, nbytes, 1, 0, 0);
+	      nbytes = CHAR_STRING (c, str);
+	      insert_1_both (str, 1, nbytes, 1, 0, 0);
 	    }
 	}
       else if (len)
@@ -5780,14 +5884,14 @@
 	  /* Convert from single-byte to multi-byte.  */
 	  int i, c, n;
 	  unsigned char *msg = (unsigned char *) s;
-	  unsigned char *str, work[4];
+	  unsigned char str[MAX_MULTIBYTE_LENGTH];
       
 	  /* Convert a single-byte string to multibyte.  */
 	  for (i = 0; i < nbytes; i++)
 	    {
 	      c = unibyte_char_to_multibyte (msg[i]);
-	      n = CHAR_STRING (c, work, str);
-	      insert_1_both (work, 1, n, 1, 0, 0);
+	      n = CHAR_STRING (c, str);
+	      insert_1_both (str, 1, n, 1, 0, 0);
 	    }
 	}
       else
@@ -6953,6 +7057,43 @@
   redisplay_internal (0);
 }
 
+/* Return 1 if point moved out of or into a composition.  Otherwise
+   return 0.  PREV_BUF and PREV_PT are the last point buffer and
+   position.  BUF and PT are the current point buffer and position.  */
+
+int
+check_point_in_composition (prev_buf, prev_pt, buf, pt)
+     struct buffer *prev_buf, *buf;
+     int prev_pt, pt;
+{
+  int start, end;
+  Lisp_Object prop;
+  Lisp_Object buffer;
+
+  XSETBUFFER (buffer, buf);
+  /* Check a composition at the last point if point moved within the
+     same buffer.  */
+  if (prev_buf == buf)
+    {
+      if (prev_pt == pt)
+	/* Point didn't move.  */
+	return 0;
+    
+      if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
+	  && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
+	  && COMPOSITION_VALID_P (start, end, prop)
+	  && start < prev_pt && end > prev_pt)
+	/* The last point was within the composition.  Return 1 iff
+            point moved out of the composition.  */
+	return (pt <= start || pt >= end);
+    }
+
+  /* Check a composition at the current point.  */
+  return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
+	  && find_composition (pt, -1, &start, &end, &prop, buffer)
+	  && COMPOSITION_VALID_P (start, end, prop)
+	  && start < pt && end > pt);
+}
 
 /* Reconsider the setting of B->clip_changed which is displayed
    in window W.  */
@@ -6970,6 +7111,29 @@
 	   && w->current_matrix->zv == BUF_ZV (b)
 	   && w->current_matrix->begv == BUF_BEGV (b))
     b->clip_changed = 0;
+
+  /* If display wasn't paused, and W is not a tool bar window, see if
+     point has been moved into or out of a composition.  In that case,
+     we set b->clip_changed to 1 to force updating the screen.  If
+     b->clip_changed has already been set to 1, we can skip this
+     check.  */
+  if (!b->clip_changed
+      && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
+    {
+      int pt;
+
+      if (w == XWINDOW (selected_window))
+	pt = BUF_PT (current_buffer);
+      else
+	pt = marker_position (w->pointm);
+
+      if ((w->current_matrix->buffer != XBUFFER (w->buffer)
+	   || pt != w->last_point)
+	  && check_point_in_composition (w->current_matrix->buffer,
+					 w->last_point,
+					 XBUFFER (w->buffer), pt))
+	b->clip_changed = 1;
+    }
 }
 
 
@@ -7790,13 +7954,10 @@
     return (dp->contents[c]);
   
   SPLIT_NON_ASCII_CHAR (c, code[0], code[1], code[2]);
-  if (code[0] != CHARSET_COMPOSITION)
-    {
-      if (code[1] < 32)
-	code[1] = -1;
-      else if (code[2] < 32)
-	code[2] = -1;
-    }
+  if (code[1] < 32)
+    code[1] = -1;
+  else if (code[2] < 32)
+    code[2] = -1;
   
   /* Here, the possible range of code[0] (== charset ID) is
      128..max_charset.  Since the top level char table contains data
@@ -11864,9 +12025,7 @@
       else if (INTEGERP (eoltype)
 	       && CHAR_VALID_P (XINT (eoltype), 0))
 	{
-	  unsigned char work[4];
-
-	  eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str);
+	  eol_str_len = CHAR_STRING (XINT (eoltype), eol_str);
 	}
       else
 	{