comparison src/xdisp.c @ 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 6afb61db1b95
children 998a04e48f58
comparison
equal deleted inserted replaced
79336:6c386e3cec2a 79337:c81a71ff50d9
965 static void compute_string_pos P_ ((struct text_pos *, struct text_pos, 965 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
966 Lisp_Object)); 966 Lisp_Object));
967 static int face_before_or_after_it_pos P_ ((struct it *, int)); 967 static int face_before_or_after_it_pos P_ ((struct it *, int));
968 static int next_overlay_change P_ ((int)); 968 static int next_overlay_change P_ ((int));
969 static int handle_single_display_spec P_ ((struct it *, Lisp_Object, 969 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
970 Lisp_Object, struct text_pos *, 970 Lisp_Object, Lisp_Object,
971 int)); 971 struct text_pos *, int));
972 static int underlying_face_id P_ ((struct it *)); 972 static int underlying_face_id P_ ((struct it *));
973 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *, 973 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
974 struct window *)); 974 struct window *));
975 975
976 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1) 976 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
3363 } 3363 }
3364 } 3364 }
3365 else 3365 else
3366 { 3366 {
3367 int base_face_id, bufpos; 3367 int base_face_id, bufpos;
3368 3368 int i;
3369 if (it->current.overlay_string_index >= 0) 3369 Lisp_Object from_overlay
3370 = (it->current.overlay_string_index >= 0
3371 ? it->string_overlays[it->current.overlay_string_index]
3372 : from_overlay);
3373
3374 /* See we got to this string directly or indirectly from
3375 an overlay property. That includes the before-string or
3376 after-string of an overlay, strings in display properties
3377 provided by an overlay, their text properties, etc.
3378
3379 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3380 if (! NILP (from_overlay))
3381 for (i = it->sp - 1; i >= 0; i--)
3382 {
3383 if (it->stack[i].current.overlay_string_index >= 0)
3384 from_overlay
3385 = it->string_overlays[it->stack[i].current.overlay_string_index];
3386 else if (! NILP (it->stack[i].from_overlay))
3387 from_overlay = it->stack[i].from_overlay;
3388
3389 if (!NILP (from_overlay))
3390 break;
3391 }
3392
3393 if (! NILP (from_overlay))
3370 { 3394 {
3371 bufpos = IT_CHARPOS (*it); 3395 bufpos = IT_CHARPOS (*it);
3372 /* For an overlay face, the base face depends 3396 /* For a string from an overlay, the base face depends
3373 only on text properties and ignores overlays. */ 3397 only on text properties and ignores overlays. */
3374 base_face_id 3398 base_face_id
3375 = face_at_buffer_position_no_overlays (it->w, 3399 = face_for_overlay_string (it->w,
3376 IT_CHARPOS (*it), 3400 IT_CHARPOS (*it),
3377 it->region_beg_charpos, 3401 it->region_beg_charpos,
3378 it->region_end_charpos, 3402 it->region_end_charpos,
3379 &next_stop, 3403 &next_stop,
3380 (IT_CHARPOS (*it) 3404 (IT_CHARPOS (*it)
3381 + TEXT_PROP_DISTANCE_LIMIT), 3405 + TEXT_PROP_DISTANCE_LIMIT),
3382 0); 3406 0,
3407 from_overlay);
3383 } 3408 }
3384 else 3409 else
3385 { 3410 {
3386 bufpos = 0; 3411 bufpos = 0;
3387 3412
3799 3824
3800 static enum prop_handled 3825 static enum prop_handled
3801 handle_display_prop (it) 3826 handle_display_prop (it)
3802 struct it *it; 3827 struct it *it;
3803 { 3828 {
3804 Lisp_Object prop, object; 3829 Lisp_Object prop, object, overlay;
3805 struct text_pos *position; 3830 struct text_pos *position;
3806 /* Nonzero if some property replaces the display of the text itself. */ 3831 /* Nonzero if some property replaces the display of the text itself. */
3807 int display_replaced_p = 0; 3832 int display_replaced_p = 0;
3808 3833
3809 if (STRINGP (it->string)) 3834 if (STRINGP (it->string))
3827 values that have a string `display' property, that have a string 3852 values that have a string `display' property, that have a string
3828 `display' property etc. */ 3853 `display' property etc. */
3829 if (!it->string_from_display_prop_p) 3854 if (!it->string_from_display_prop_p)
3830 it->area = TEXT_AREA; 3855 it->area = TEXT_AREA;
3831 3856
3832 prop = Fget_char_property (make_number (position->charpos), 3857 prop = get_char_property_and_overlay (make_number (position->charpos),
3833 Qdisplay, object); 3858 Qdisplay, object, &overlay);
3834 if (NILP (prop)) 3859 if (NILP (prop))
3835 return HANDLED_NORMALLY; 3860 return HANDLED_NORMALLY;
3861 /* Now OVERLAY is the overlay that gave us this property, or nil
3862 if it was a text property. */
3836 3863
3837 if (!STRINGP (it->string)) 3864 if (!STRINGP (it->string))
3838 object = it->w->buffer; 3865 object = it->w->buffer;
3839 3866
3840 if (CONSP (prop) 3867 if (CONSP (prop)
3852 && !EQ (XCAR (prop), Qright_fringe) 3879 && !EQ (XCAR (prop), Qright_fringe)
3853 && !NILP (XCAR (prop))) 3880 && !NILP (XCAR (prop)))
3854 { 3881 {
3855 for (; CONSP (prop); prop = XCDR (prop)) 3882 for (; CONSP (prop); prop = XCDR (prop))
3856 { 3883 {
3857 if (handle_single_display_spec (it, XCAR (prop), object, 3884 if (handle_single_display_spec (it, XCAR (prop), object, overlay,
3858 position, display_replaced_p)) 3885 position, display_replaced_p))
3859 { 3886 {
3860 display_replaced_p = 1; 3887 display_replaced_p = 1;
3861 /* If some text in a string is replaced, `position' no 3888 /* If some text in a string is replaced, `position' no
3862 longer points to the position of `object'. */ 3889 longer points to the position of `object'. */
3867 } 3894 }
3868 else if (VECTORP (prop)) 3895 else if (VECTORP (prop))
3869 { 3896 {
3870 int i; 3897 int i;
3871 for (i = 0; i < ASIZE (prop); ++i) 3898 for (i = 0; i < ASIZE (prop); ++i)
3872 if (handle_single_display_spec (it, AREF (prop, i), object, 3899 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
3873 position, display_replaced_p)) 3900 position, display_replaced_p))
3874 { 3901 {
3875 display_replaced_p = 1; 3902 display_replaced_p = 1;
3876 /* If some text in a string is replaced, `position' no 3903 /* If some text in a string is replaced, `position' no
3877 longer points to the position of `object'. */ 3904 longer points to the position of `object'. */
3879 break; 3906 break;
3880 } 3907 }
3881 } 3908 }
3882 else 3909 else
3883 { 3910 {
3884 int ret = handle_single_display_spec (it, prop, object, position, 0); 3911 int ret = handle_single_display_spec (it, prop, object, overlay,
3912 position, 0);
3885 if (ret < 0) /* Replaced by "", i.e. nothing. */ 3913 if (ret < 0) /* Replaced by "", i.e. nothing. */
3886 return HANDLED_RECOMPUTE_PROPS; 3914 return HANDLED_RECOMPUTE_PROPS;
3887 if (ret) 3915 if (ret)
3888 display_replaced_p = 1; 3916 display_replaced_p = 1;
3889 } 3917 }
3921 is the position at which it was found. DISPLAY_REPLACED_P non-zero 3949 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3922 means that we previously saw a display specification which already 3950 means that we previously saw a display specification which already
3923 replaced text display with something else, for example an image; 3951 replaced text display with something else, for example an image;
3924 we ignore such properties after the first one has been processed. 3952 we ignore such properties after the first one has been processed.
3925 3953
3954 OVERLAY is the overlay this `display' property came from,
3955 or nil if it was a text property.
3956
3926 If PROP is a `space' or `image' specification, and in some other 3957 If PROP is a `space' or `image' specification, and in some other
3927 cases too, set *POSITION to the position where the `display' 3958 cases too, set *POSITION to the position where the `display'
3928 property ends. 3959 property ends.
3929 3960
3930 Value is non-zero if something was found which replaces the display 3961 Value is non-zero if something was found which replaces the display
3931 of buffer or string text. Specifically, the value is -1 if that 3962 of buffer or string text. Specifically, the value is -1 if that
3932 "something" is "nothing". */ 3963 "something" is "nothing". */
3933 3964
3934 static int 3965 static int
3935 handle_single_display_spec (it, spec, object, position, 3966 handle_single_display_spec (it, spec, object, overlay, position,
3936 display_replaced_before_p) 3967 display_replaced_before_p)
3937 struct it *it; 3968 struct it *it;
3938 Lisp_Object spec; 3969 Lisp_Object spec;
3939 Lisp_Object object; 3970 Lisp_Object object;
3971 Lisp_Object overlay;
3940 struct text_pos *position; 3972 struct text_pos *position;
3941 int display_replaced_before_p; 3973 int display_replaced_before_p;
3942 { 3974 {
3943 Lisp_Object form; 3975 Lisp_Object form;
3944 Lisp_Object location, value; 3976 Lisp_Object location, value;
4044 } 4076 }
4045 4077
4046 return 0; 4078 return 0;
4047 } 4079 }
4048 4080
4049 /* Handle `(space_width WIDTH)'. */ 4081 /* Handle `(space-width WIDTH)'. */
4050 if (CONSP (spec) 4082 if (CONSP (spec)
4051 && EQ (XCAR (spec), Qspace_width) 4083 && EQ (XCAR (spec), Qspace_width)
4052 && CONSP (XCDR (spec))) 4084 && CONSP (XCDR (spec)))
4053 { 4085 {
4054 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f)) 4086 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
4168 it->what = IT_IMAGE; 4200 it->what = IT_IMAGE;
4169 it->image_id = -1; /* no image */ 4201 it->image_id = -1; /* no image */
4170 it->position = start_pos; 4202 it->position = start_pos;
4171 it->object = NILP (object) ? it->w->buffer : object; 4203 it->object = NILP (object) ? it->w->buffer : object;
4172 it->method = GET_FROM_IMAGE; 4204 it->method = GET_FROM_IMAGE;
4205 it->from_overlay = Qnil;
4173 it->face_id = face_id; 4206 it->face_id = face_id;
4174 4207
4175 /* Say that we haven't consumed the characters with 4208 /* Say that we haven't consumed the characters with
4176 `display' property yet. The call to pop_it in 4209 `display' property yet. The call to pop_it in
4177 set_iterator_to_next will clean this up. */ 4210 set_iterator_to_next will clean this up. */
4238 when we are finished with the glyph property value. */ 4271 when we are finished with the glyph property value. */
4239 save_pos = it->position; 4272 save_pos = it->position;
4240 it->position = *position; 4273 it->position = *position;
4241 push_it (it); 4274 push_it (it);
4242 it->position = save_pos; 4275 it->position = save_pos;
4276 it->from_overlay = overlay;
4243 4277
4244 if (NILP (location)) 4278 if (NILP (location))
4245 it->area = TEXT_AREA; 4279 it->area = TEXT_AREA;
4246 else if (EQ (location, Qleft_margin)) 4280 else if (EQ (location, Qleft_margin))
4247 it->area = LEFT_MARGIN_AREA; 4281 it->area = LEFT_MARGIN_AREA;
4881 that have already been consumed by IT. Copy some of the 4915 that have already been consumed by IT. Copy some of the
4882 remaining overlay strings to IT->overlay_strings. */ 4916 remaining overlay strings to IT->overlay_strings. */
4883 i = 0; 4917 i = 0;
4884 j = it->current.overlay_string_index; 4918 j = it->current.overlay_string_index;
4885 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n) 4919 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4886 it->overlay_strings[i++] = entries[j++].string; 4920 {
4921 it->overlay_strings[i++] = entries[j++].string;
4922 it->string_overlays[i++] = entries[j++].overlay;
4923 }
4887 4924
4888 CHECK_IT (it); 4925 CHECK_IT (it);
4889 } 4926 }
4890 4927
4891 4928
4927 4964
4928 /* Set up IT to deliver display elements from the first overlay 4965 /* Set up IT to deliver display elements from the first overlay
4929 string. */ 4966 string. */
4930 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0; 4967 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4931 it->string = it->overlay_strings[0]; 4968 it->string = it->overlay_strings[0];
4969 it->from_overlay = Qnil;
4932 it->stop_charpos = 0; 4970 it->stop_charpos = 0;
4933 xassert (STRINGP (it->string)); 4971 xassert (STRINGP (it->string));
4934 it->end_charpos = SCHARS (it->string); 4972 it->end_charpos = SCHARS (it->string);
4935 it->multibyte_p = STRING_MULTIBYTE (it->string); 4973 it->multibyte_p = STRING_MULTIBYTE (it->string);
4936 it->method = GET_FROM_STRING; 4974 it->method = GET_FROM_STRING;
4980 p->stop_charpos = it->stop_charpos; 5018 p->stop_charpos = it->stop_charpos;
4981 xassert (it->face_id >= 0); 5019 xassert (it->face_id >= 0);
4982 p->face_id = it->face_id; 5020 p->face_id = it->face_id;
4983 p->string = it->string; 5021 p->string = it->string;
4984 p->method = it->method; 5022 p->method = it->method;
5023 p->from_overlay = it->from_overlay;
4985 switch (p->method) 5024 switch (p->method)
4986 { 5025 {
4987 case GET_FROM_IMAGE: 5026 case GET_FROM_IMAGE:
4988 p->u.image.object = it->object; 5027 p->u.image.object = it->object;
4989 p->u.image.image_id = it->image_id; 5028 p->u.image.image_id = it->image_id;
5033 it->stop_charpos = p->stop_charpos; 5072 it->stop_charpos = p->stop_charpos;
5034 it->face_id = p->face_id; 5073 it->face_id = p->face_id;
5035 it->current = p->current; 5074 it->current = p->current;
5036 it->position = p->position; 5075 it->position = p->position;
5037 it->string = p->string; 5076 it->string = p->string;
5077 it->from_overlay = p->from_overlay;
5038 if (NILP (it->string)) 5078 if (NILP (it->string))
5039 SET_TEXT_POS (it->current.string_pos, -1, -1); 5079 SET_TEXT_POS (it->current.string_pos, -1, -1);
5040 it->method = p->method; 5080 it->method = p->method;
5041 switch (it->method) 5081 switch (it->method)
5042 { 5082 {