changeset 79337:c81a71ff50d9

(handle_face_prop): Test for strings that came from overlays, not just for after-strings and before-strings. Call face_for_overlay_string and pass the overlay to it. (handle_display_prop): Determine whether property came from an overlay. Pass OVERLAY arg to handle_single_display_spec. (handle_single_display_spec): New arg OVERLAY sets it->from_overlay. (load_overlay_strings): Fill in it->string_overlays. (get_overlay_strings_1, push_it, pop_it): Handle it->from_overlays.
author Richard M. Stallman <rms@gnu.org>
date Sun, 04 Nov 2007 07:42:21 +0000
parents 6c386e3cec2a
children c58c35c1d5f9
files src/xdisp.c
diffstat 1 files changed, 62 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/xdisp.c	Sun Nov 04 07:32:41 2007 +0000
+++ b/src/xdisp.c	Sun Nov 04 07:42:21 2007 +0000
@@ -967,8 +967,8 @@
 static int face_before_or_after_it_pos P_ ((struct it *, int));
 static int next_overlay_change P_ ((int));
 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
-					   Lisp_Object, struct text_pos *,
-					   int));
+					   Lisp_Object, Lisp_Object,
+					   struct text_pos *, int));
 static int underlying_face_id P_ ((struct it *));
 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
 						 struct window *));
@@ -3365,21 +3365,46 @@
   else
     {
       int base_face_id, bufpos;
-
-      if (it->current.overlay_string_index >= 0)
+      int i;
+      Lisp_Object from_overlay
+	= (it->current.overlay_string_index >= 0
+	   ? it->string_overlays[it->current.overlay_string_index]
+	   : from_overlay);
+
+      /* See we got to this string directly or indirectly from
+	 an overlay property.  That includes the before-string or
+	 after-string of an overlay, strings in display properties
+	 provided by an overlay, their text properties, etc.
+
+	 FROM_OVERLAY is the overlay that brought us here, or nil if none.  */
+      if (! NILP (from_overlay))
+	for (i = it->sp - 1; i >= 0; i--)
+	  {
+	    if (it->stack[i].current.overlay_string_index >= 0)
+	      from_overlay
+		= it->string_overlays[it->stack[i].current.overlay_string_index];
+	    else if (! NILP (it->stack[i].from_overlay))
+	      from_overlay = it->stack[i].from_overlay;
+
+	    if (!NILP (from_overlay))
+	      break;
+	  }
+
+      if (! NILP (from_overlay))
 	{
 	  bufpos = IT_CHARPOS (*it);
-	  /* For an overlay face, the base face depends
+	  /* For a string from an overlay, the base face depends
 	     only on text properties and ignores overlays.  */
 	  base_face_id
-	    = face_at_buffer_position_no_overlays (it->w,
-						   IT_CHARPOS (*it),
-						   it->region_beg_charpos,
-						   it->region_end_charpos,
-						   &next_stop,
-						   (IT_CHARPOS (*it)
-						    + TEXT_PROP_DISTANCE_LIMIT),
-						   0);
+	    = face_for_overlay_string (it->w,
+				       IT_CHARPOS (*it),
+				       it->region_beg_charpos,
+				       it->region_end_charpos,
+				       &next_stop,
+				       (IT_CHARPOS (*it)
+					+ TEXT_PROP_DISTANCE_LIMIT),
+				       0,
+				       from_overlay);
 	}
       else
 	{
@@ -3801,7 +3826,7 @@
 handle_display_prop (it)
      struct it *it;
 {
-  Lisp_Object prop, object;
+  Lisp_Object prop, object, overlay;
   struct text_pos *position;
   /* Nonzero if some property replaces the display of the text itself.  */
   int display_replaced_p = 0;
@@ -3829,10 +3854,12 @@
   if (!it->string_from_display_prop_p)
     it->area = TEXT_AREA;
 
-  prop = Fget_char_property (make_number (position->charpos),
-			     Qdisplay, object);
+  prop = get_char_property_and_overlay (make_number (position->charpos),
+					Qdisplay, object, &overlay);
   if (NILP (prop))
     return HANDLED_NORMALLY;
+  /* Now OVERLAY is the overlay that gave us this property, or nil
+     if it was a text property.  */
 
   if (!STRINGP (it->string))
     object = it->w->buffer;
@@ -3854,7 +3881,7 @@
     {
       for (; CONSP (prop); prop = XCDR (prop))
 	{
-	  if (handle_single_display_spec (it, XCAR (prop), object,
+	  if (handle_single_display_spec (it, XCAR (prop), object, overlay,
 					  position, display_replaced_p))
 	    {
 	      display_replaced_p = 1;
@@ -3869,7 +3896,7 @@
     {
       int i;
       for (i = 0; i < ASIZE (prop); ++i)
-	if (handle_single_display_spec (it, AREF (prop, i), object,
+	if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
 					position, display_replaced_p))
 	  {
 	    display_replaced_p = 1;
@@ -3881,7 +3908,8 @@
     }
   else
     {
-      int ret = handle_single_display_spec (it, prop, object, position, 0);
+      int ret = handle_single_display_spec (it, prop, object, overlay,
+					    position, 0);
       if (ret < 0)  /* Replaced by "", i.e. nothing. */
 	return HANDLED_RECOMPUTE_PROPS;
       if (ret)
@@ -3923,6 +3951,9 @@
    replaced text display with something else, for example an image;
    we ignore such properties after the first one has been processed.
 
+   OVERLAY is the overlay this `display' property came from,
+   or nil if it was a text property.
+
    If PROP is a `space' or `image' specification, and in some other
    cases too, set *POSITION to the position where the `display'
    property ends.
@@ -3932,11 +3963,12 @@
    "something" is "nothing". */
 
 static int
-handle_single_display_spec (it, spec, object, position,
+handle_single_display_spec (it, spec, object, overlay, position,
 			    display_replaced_before_p)
      struct it *it;
      Lisp_Object spec;
      Lisp_Object object;
+     Lisp_Object overlay;
      struct text_pos *position;
      int display_replaced_before_p;
 {
@@ -4046,7 +4078,7 @@
       return 0;
     }
 
-  /* Handle `(space_width WIDTH)'.  */
+  /* Handle `(space-width WIDTH)'.  */
   if (CONSP (spec)
       && EQ (XCAR (spec), Qspace_width)
       && CONSP (XCDR (spec)))
@@ -4170,6 +4202,7 @@
       it->position = start_pos;
       it->object = NILP (object) ? it->w->buffer : object;
       it->method = GET_FROM_IMAGE;
+      it->from_overlay = Qnil;
       it->face_id = face_id;
 
       /* Say that we haven't consumed the characters with
@@ -4240,6 +4273,7 @@
       it->position = *position;
       push_it (it);
       it->position = save_pos;
+      it->from_overlay = overlay;
 
       if (NILP (location))
 	it->area = TEXT_AREA;
@@ -4883,7 +4917,10 @@
   i = 0;
   j = it->current.overlay_string_index;
   while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
-    it->overlay_strings[i++] = entries[j++].string;
+    {
+      it->overlay_strings[i++] = entries[j++].string;
+      it->string_overlays[i++] = entries[j++].overlay;
+    }
 
   CHECK_IT (it);
 }
@@ -4929,6 +4966,7 @@
 	 string.  */
       IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
       it->string = it->overlay_strings[0];
+      it->from_overlay = Qnil;
       it->stop_charpos = 0;
       xassert (STRINGP (it->string));
       it->end_charpos = SCHARS (it->string);
@@ -4982,6 +5020,7 @@
   p->face_id = it->face_id;
   p->string = it->string;
   p->method = it->method;
+  p->from_overlay = it->from_overlay;
   switch (p->method)
     {
     case GET_FROM_IMAGE:
@@ -5035,6 +5074,7 @@
   it->current = p->current;
   it->position = p->position;
   it->string = p->string;
+  it->from_overlay = p->from_overlay;
   if (NILP (it->string))
     SET_TEXT_POS (it->current.string_pos, -1, -1);
   it->method = p->method;