diff src/redisplay.c @ 361:7347b34c275b r21-1-10

Import from CVS: tag r21-1-10
author cvs
date Mon, 13 Aug 2007 10:58:40 +0200
parents 8bec6624d99b
children a4f53d9b3154
line wrap: on
line diff
--- a/src/redisplay.c	Mon Aug 13 10:57:57 2007 +0200
+++ b/src/redisplay.c	Mon Aug 13 10:58:40 2007 +0200
@@ -1232,66 +1232,12 @@
     }
 }
 
-/* Given a display table entry, call the appropriate functions to
-   display each element of the entry. */
-
 static prop_block_dynarr *
-add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
+add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
 {
   prop_block_dynarr *prop = NULL;
 
-  if (VECTORP (entry))
-    {
-      struct Lisp_Vector *de = XVECTOR (entry);
-      long len = vector_length (de);
-      int elt;
-
-      for (elt = 0; elt < len; elt++)
-	{
-	  if (NILP (de->contents[elt]))
-	    continue;
-	  else if (STRINGP (de->contents[elt]))
-	    {
-	      prop =
-		add_bufbyte_string_runes
-		  (data,
-		   XSTRING_DATA   (de->contents[elt]),
-		   XSTRING_LENGTH (de->contents[elt]),
-		   0);
-	    }
-	  else if (GLYPHP (de->contents[elt]))
-	    {
-	      if (data->start_col)
-		data->start_col--;
-
-	      if (!data->start_col && data->bi_start_col_enabled)
-		{
-		  prop = add_hscroll_rune (data);
-		}
-	      else
-		{
-		  struct glyph_block gb;
-
-		  gb.glyph = de->contents[elt];
-		  gb.extent = Qnil;
-		  prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
-		}
-	    }
-	  else if (CHAR_OR_CHAR_INTP (de->contents[elt]))
-	    {
-	      data->ch = XCHAR_OR_CHAR_INT (de->contents[elt]);
-	      prop = add_emchar_rune (data);
-	    }
-	  /* Else blow it off because someone added a bad entry and we
-             don't have any safe way of signaling an error. */
-
-	  /* #### Still need to add any remaining elements to the
-             propagation information. */
-	  if (prop)
-	    return prop;
-	}
-    }
-  else if (STRINGP (entry))
+  if (STRINGP (entry))
     {
       prop = add_bufbyte_string_runes (data,
 				       XSTRING_DATA   (entry),
@@ -1321,10 +1267,79 @@
       data->ch = XCHAR_OR_CHAR_INT (entry);
       prop = add_emchar_rune (data);
     }
+  else if (CONSP (entry))
+    {
+      if (EQ (XCAR (entry), Qformat)
+	  && CONSP (XCDR (entry))
+	  && STRINGP (XCAR (XCDR (entry))))
+	{
+	  Lisp_Object format = XCAR (XCDR (entry));
+	  Bytind len = XSTRING_LENGTH (format);
+	  Bufbyte *src = XSTRING_DATA (format), *end = src + len;
+	  Bufbyte *result = alloca_array (Bufbyte, len);
+	  Bufbyte *dst = result;
+
+	  while (src < end)
+	    {
+	      Emchar c = charptr_emchar (src);
+	      INC_CHARPTR (src);
+	      if (c != '%' || src == end)
+		dst += set_charptr_emchar (dst, c);
+	      else
+		{
+		  c = charptr_emchar (src);
+		  INC_CHARPTR (src);
+		  switch (c)
+		    {
+		      /*case 'x':
+			dst += long_to_string_base ((char *)dst, data->ch, 16);
+			break;*/
+		    case '%':
+		      dst += set_charptr_emchar (dst, '%');
+		      break;
+		    }
+		}
+	    }
+	  prop = add_bufbyte_string_runes (data, result, dst - result, 0);
+	}
+    }
 
   /* Else blow it off because someone added a bad entry and we don't
-     have any safe way of signaling an error.  Hey, this comment
-     sounds familiar. */
+     have any safe way of signaling an error. */
+  return prop;
+}
+
+/* Given a display table entry, call the appropriate functions to
+   display each element of the entry. */
+
+static prop_block_dynarr *
+add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
+{
+  prop_block_dynarr *prop = NULL;
+  if (VECTORP (entry))
+    {
+      struct Lisp_Vector *de = XVECTOR (entry);
+      EMACS_INT len = vector_length (de);
+      int elt;
+
+      for (elt = 0; elt < len; elt++)
+	{
+	  if (NILP (vector_data (de)[elt]))
+	    continue;
+	  else
+	    prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
+	  /* Else blow it off because someone added a bad entry and we
+	     don't have any safe way of signaling an error.  Hey, this
+	     comment sounds familiar. */
+
+	  /* #### Still need to add any remaining elements to the
+	     propagation information. */
+	  if (prop)
+	    return prop;
+	}
+    }
+  else
+    prop = add_disp_table_entry_runes_1 (data, entry);
   return prop;
 }
 
@@ -1750,7 +1765,6 @@
   struct device *d = XDEVICE (f->device);
 
   pos_data data;
-  struct Lisp_Vector *dt = 0;
 
   /* Don't display anything in the minibuffer if this window is not on
      a selected frame.  We consider all other windows to be active
@@ -1823,6 +1837,8 @@
 			  : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
 			     ? 255 : 160));
 
+  Lisp_Object face_dt, window_dt;
+
   /* The text display block for this display line. */
   struct display_block *db = get_display_block_from_line (dl, TEXT);
 
@@ -1961,10 +1977,10 @@
 	    /* Remember that the extent-fragment routines deal in Bytind's. */
 	    extent_fragment_update (w, data.ef, data.bi_bufpos);
 
+	  get_display_tables (w, data.findex, &face_dt, &window_dt);
+
 	  if (data.bi_bufpos == data.ef->end)
 	    no_more_frags = 1;
-
-	  dt = get_display_table (w, data.findex);
 	}
       initial = 0;
 
@@ -2076,16 +2092,17 @@
 
       else
 	{
+	  Lisp_Object entry = Qnil;
 	  /* Get the character at the current buffer position. */
 	  data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
+	  if (!NILP (face_dt) || !NILP (window_dt))
+	    entry = display_table_entry (data.ch, face_dt, window_dt);
 
 	  /* If there is a display table entry for it, hand it off to
              add_disp_table_entry_runes and let it worry about it. */
-	  if (dt && !NILP (DISP_CHAR_ENTRY (dt, data.ch)))
+	  if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
 	    {
-	      *prop =
-		add_disp_table_entry_runes (&data,
-					    DISP_CHAR_ENTRY (dt, data.ch));
+	      *prop = add_disp_table_entry_runes (&data, entry);
 
 	      if (*prop)
 		goto done;
@@ -4230,6 +4247,9 @@
   else
     prop = 0;
 
+  /* Make sure this is set always */
+  /* Note the conversion at end */
+  w->window_end_pos[type] = start_pos;
   while (ypos < yend)
     {
       struct display_line dl;
@@ -4312,10 +4332,14 @@
       Dynarr_free (prop);
 
   /* #### More not quite right, but close enough. */
-  /* #### Ben sez: apparently window_end_pos[] is measured
+  /* Ben sez: apparently window_end_pos[] is measured
      as the number of characters between the window end and the
      end of the buffer?  This seems rather weirdo.  What's
-     the justification for this? */
+     the justification for this?
+
+     JV sez: Because BUF_Z (b) would be a good initial value, however
+     that can change. This representation allows initalizing with 0.
+  */
   w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
 
   if (need_modeline)
@@ -6592,11 +6616,22 @@
    displayed.  The end of the last line is also know as the window end
    position.
 
+   WARNING: Under some circumstances it is possible that rediplay failed
+   to layout any lines for the windows. In that case this function returns
+   0 as an error condition when may_error is non-zero and a normalized
+   value of startp otherwise.
+   Under normal circumstances this is rare. However it seems that it does
+   occur in the following situation: A mouse event has come in and we need
+   to compute its location in a window. That code (in
+   pixel_to_glyph_translation) already can handle 0 as an error return
+   value. 
+
    #### With a little work this could probably be reworked as just a
    call to start_with_line_at_pixpos. */
 
 static Bufpos
-start_end_of_last_line (struct window *w, Bufpos startp, int end)
+start_end_of_last_line (struct window *w, Bufpos startp, int end,
+                        int may_error)
 {
   struct buffer *b = XBUFFER (w->buffer);
   line_start_cache_dynarr *cache = w->line_start_cache;
@@ -6616,8 +6651,8 @@
 
   start_elt = point_in_line_start_cache (w, cur_start, 0);
   if (start_elt == -1)
-    abort ();	/* this had better never happen */
-
+      return may_error ? 0 : startp;
+  
   while (1)
     {
       int height = Dynarr_atp (cache, start_elt)->height;
@@ -6680,7 +6715,7 @@
 Bufpos
 start_of_last_line (struct window *w, Bufpos startp)
 {
-  return start_end_of_last_line (w, startp, 0);
+  return start_end_of_last_line (w, startp, 0 , 0);
 }
 
 /* For the given window W, if display starts at STARTP, what will be
@@ -6690,9 +6725,16 @@
 Bufpos
 end_of_last_line (struct window *w, Bufpos startp)
 {
-  return start_end_of_last_line (w, startp, 1);
+  return start_end_of_last_line (w, startp, 1, 0);
 }
 
+static Bufpos
+end_of_last_line_may_error (struct window *w, Bufpos startp)
+{
+  return start_end_of_last_line (w, startp, 1, 1);
+}
+
+
 /* For window W, what does the starting position have to be so that
    the line containing POINT will cover pixel position PIXPOS. */
 
@@ -7833,7 +7875,7 @@
   if (!MARKERP ((*w)->start[CURRENT_DISP]))
     *closest = 0;
   else
-    *closest = end_of_last_line (*w,
+    *closest = end_of_last_line_may_error (*w,
 				 marker_position ((*w)->start[CURRENT_DISP]));
   *col = 0;
   UPDATE_CACHE_RETURN;