diff options
| author | Eli Zaretskii | 2011-05-21 17:22:14 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-05-21 17:22:14 +0300 |
| commit | fc6f18ceeaae3c3eb4d68120899e16c2fc73ea86 (patch) | |
| tree | dbbc17ffa38f01c0fe0184605569c1051f6eec8d /src/xdisp.c | |
| parent | 683a44f77c8c83febe1ab7ebe7fc32d26fc71bcd (diff) | |
| download | emacs-fc6f18ceeaae3c3eb4d68120899e16c2fc73ea86.tar.gz emacs-fc6f18ceeaae3c3eb4d68120899e16c2fc73ea86.zip | |
Discovery of replacing display properties now uses the same code
as the display engine. Tested OK with display properties whose
value is a list.
src/dispextern.h (struct bidi_it): New member frame_window_p.
(bidi_init_it, compute_display_string_pos): Update prototypes.
src/bidi.c (bidi_fetch_char): Accept additional argument
FRAME_WINDOW_P and pass it to compute_display_string_pos. All
callers changed.
(bidi_init_it): Accept additional argument FRAME_WINDOW_P and use
it to initialize the frame_window_p member of struct bidi_it.
src/xdisp.c (handle_display_spec): New function, refactored from the
last portion of handle_display_prop.
(compute_display_string_pos): Accept additional argument
FRAME_WINDOW_P. Call handle_display_spec to determine whether the
value of a `display' property is a "replacing spec".
(handle_single_display_spec): Accept 2 additional arguments BUFPOS
and FRAME_WINDOW_P. If IT is NULL, don't set up the iterator from
the display property, but just return a value indicating whether
the display property will replace the characters it covers.
(Fcurrent_bidi_paragraph_direction): Initialize the nchars and
frame_window_p members of struct bidi_it.
Diffstat (limited to 'src/xdisp.c')
| -rw-r--r-- | src/xdisp.c | 430 |
1 files changed, 260 insertions, 170 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 6ea6f92a3f7..8665acf8fdd 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -884,9 +884,11 @@ static void compute_string_pos (struct text_pos *, struct text_pos, | |||
| 884 | Lisp_Object); | 884 | Lisp_Object); |
| 885 | static int face_before_or_after_it_pos (struct it *, int); | 885 | static int face_before_or_after_it_pos (struct it *, int); |
| 886 | static EMACS_INT next_overlay_change (EMACS_INT); | 886 | static EMACS_INT next_overlay_change (EMACS_INT); |
| 887 | static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object, | ||
| 888 | Lisp_Object, struct text_pos *, EMACS_INT, int); | ||
| 887 | static int handle_single_display_spec (struct it *, Lisp_Object, | 889 | static int handle_single_display_spec (struct it *, Lisp_Object, |
| 888 | Lisp_Object, Lisp_Object, | 890 | Lisp_Object, Lisp_Object, |
| 889 | struct text_pos *, int); | 891 | struct text_pos *, EMACS_INT, int, int); |
| 890 | static int underlying_face_id (struct it *); | 892 | static int underlying_face_id (struct it *); |
| 891 | static int in_ellipses_for_invisible_text_p (struct display_pos *, | 893 | static int in_ellipses_for_invisible_text_p (struct display_pos *, |
| 892 | struct window *); | 894 | struct window *); |
| @@ -2564,7 +2566,7 @@ init_iterator (struct it *it, struct window *w, | |||
| 2564 | it->paragraph_embedding = R2L; | 2566 | it->paragraph_embedding = R2L; |
| 2565 | else | 2567 | else |
| 2566 | it->paragraph_embedding = NEUTRAL_DIR; | 2568 | it->paragraph_embedding = NEUTRAL_DIR; |
| 2567 | bidi_init_it (charpos, bytepos, &it->bidi_it); | 2569 | bidi_init_it (charpos, bytepos, FRAME_WINDOW_P (it->f), &it->bidi_it); |
| 2568 | } | 2570 | } |
| 2569 | 2571 | ||
| 2570 | /* If a buffer position was specified, set the iterator there, | 2572 | /* If a buffer position was specified, set the iterator there, |
| @@ -3086,37 +3088,54 @@ next_overlay_change (EMACS_INT pos) | |||
| 3086 | } | 3088 | } |
| 3087 | 3089 | ||
| 3088 | /* Return the character position of a display string at or after CHARPOS. | 3090 | /* Return the character position of a display string at or after CHARPOS. |
| 3089 | If no display string exist at or after CHARPOS, return ZV. A | 3091 | If no display string exists at or after CHARPOS, return ZV. A |
| 3090 | display string is either an overlay with `display' property whose | 3092 | display string is either an overlay with `display' property whose |
| 3091 | value is a string or a `display' text property whose value is a | 3093 | value is a string, or a `display' text property whose value is a |
| 3092 | string. */ | 3094 | string. FRAME_WINDOW_P is non-zero when we are displaying a window |
| 3095 | on a GUI frame. */ | ||
| 3093 | EMACS_INT | 3096 | EMACS_INT |
| 3094 | compute_display_string_pos (EMACS_INT charpos) | 3097 | compute_display_string_pos (EMACS_INT charpos, int frame_window_p) |
| 3095 | { | 3098 | { |
| 3096 | /* FIXME: Support display properties on strings (object = Qnil means | 3099 | /* FIXME: Support display properties on strings (object = Qnil means |
| 3097 | current buffer). */ | 3100 | current buffer). */ |
| 3098 | Lisp_Object object = Qnil; | 3101 | Lisp_Object object = Qnil; |
| 3099 | Lisp_Object pos = make_number (charpos); | 3102 | Lisp_Object pos, spec; |
| 3103 | struct text_pos position; | ||
| 3104 | EMACS_INT bufpos; | ||
| 3100 | 3105 | ||
| 3101 | if (charpos >= ZV) | 3106 | if (charpos >= ZV) |
| 3102 | return ZV; | 3107 | return ZV; |
| 3103 | 3108 | ||
| 3104 | /* If the character at CHARPOS is where the display string begins, | 3109 | /* If the character at CHARPOS is where the display string begins, |
| 3105 | return CHARPOS. */ | 3110 | return CHARPOS. */ |
| 3106 | if (!NILP (Fget_char_property (pos, Qdisplay, object)) | 3111 | pos = make_number (charpos); |
| 3112 | CHARPOS (position) = charpos; | ||
| 3113 | BYTEPOS (position) = CHAR_TO_BYTE (charpos); | ||
| 3114 | bufpos = charpos; /* FIXME! support strings as well */ | ||
| 3115 | if (!NILP (spec = Fget_char_property (pos, Qdisplay, object)) | ||
| 3107 | && (charpos <= BEGV | 3116 | && (charpos <= BEGV |
| 3108 | || NILP (Fget_char_property (make_number (charpos - 1), Qdisplay, | 3117 | || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay, |
| 3109 | object)))) | 3118 | object), |
| 3119 | spec))) | ||
| 3120 | && handle_display_spec (NULL, spec, object, Qnil, &position, bufpos, | ||
| 3121 | frame_window_p)) | ||
| 3110 | return charpos; | 3122 | return charpos; |
| 3111 | 3123 | ||
| 3112 | /* Look forward for the first character where the `display' property | 3124 | /* Look forward for the first character with a `display' property |
| 3113 | changes from nil to non-nil. */ | 3125 | that will replace the underlying text when displayed. */ |
| 3114 | do { | 3126 | do { |
| 3115 | pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil); | 3127 | pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil); |
| 3116 | } while (XFASTINT (pos) < ZV | 3128 | CHARPOS (position) = XFASTINT (pos); |
| 3117 | && NILP (Fget_char_property (pos, Qdisplay, object))); | 3129 | BYTEPOS (position) = CHAR_TO_BYTE (CHARPOS (position)); |
| 3130 | if (CHARPOS (position) >= ZV) | ||
| 3131 | break; | ||
| 3132 | spec = Fget_char_property (pos, Qdisplay, object); | ||
| 3133 | bufpos = CHARPOS (position); /* FIXME! support strings as well */ | ||
| 3134 | } while (NILP (spec) | ||
| 3135 | || !handle_display_spec (NULL, spec, object, Qnil, &position, bufpos, | ||
| 3136 | frame_window_p)); | ||
| 3118 | 3137 | ||
| 3119 | return XFASTINT (pos); | 3138 | return CHARPOS (position); |
| 3120 | } | 3139 | } |
| 3121 | 3140 | ||
| 3122 | /* Return the character position of the end of the display string that | 3141 | /* Return the character position of the end of the display string that |
| @@ -3802,8 +3821,9 @@ setup_for_ellipsis (struct it *it, int len) | |||
| 3802 | static enum prop_handled | 3821 | static enum prop_handled |
| 3803 | handle_display_prop (struct it *it) | 3822 | handle_display_prop (struct it *it) |
| 3804 | { | 3823 | { |
| 3805 | Lisp_Object prop, object, overlay; | 3824 | Lisp_Object propval, object, overlay; |
| 3806 | struct text_pos *position; | 3825 | struct text_pos *position; |
| 3826 | EMACS_INT bufpos; | ||
| 3807 | /* Nonzero if some property replaces the display of the text itself. */ | 3827 | /* Nonzero if some property replaces the display of the text itself. */ |
| 3808 | int display_replaced_p = 0; | 3828 | int display_replaced_p = 0; |
| 3809 | 3829 | ||
| @@ -3811,11 +3831,13 @@ handle_display_prop (struct it *it) | |||
| 3811 | { | 3831 | { |
| 3812 | object = it->string; | 3832 | object = it->string; |
| 3813 | position = &it->current.string_pos; | 3833 | position = &it->current.string_pos; |
| 3834 | bufpos = CHARPOS (it->current.pos); | ||
| 3814 | } | 3835 | } |
| 3815 | else | 3836 | else |
| 3816 | { | 3837 | { |
| 3817 | XSETWINDOW (object, it->w); | 3838 | XSETWINDOW (object, it->w); |
| 3818 | position = &it->current.pos; | 3839 | position = &it->current.pos; |
| 3840 | bufpos = CHARPOS (*position); | ||
| 3819 | } | 3841 | } |
| 3820 | 3842 | ||
| 3821 | /* Reset those iterator values set from display property values. */ | 3843 | /* Reset those iterator values set from display property values. */ |
| @@ -3830,9 +3852,9 @@ handle_display_prop (struct it *it) | |||
| 3830 | if (!it->string_from_display_prop_p) | 3852 | if (!it->string_from_display_prop_p) |
| 3831 | it->area = TEXT_AREA; | 3853 | it->area = TEXT_AREA; |
| 3832 | 3854 | ||
| 3833 | prop = get_char_property_and_overlay (make_number (position->charpos), | 3855 | propval = get_char_property_and_overlay (make_number (position->charpos), |
| 3834 | Qdisplay, object, &overlay); | 3856 | Qdisplay, object, &overlay); |
| 3835 | if (NILP (prop)) | 3857 | if (NILP (propval)) |
| 3836 | return HANDLED_NORMALLY; | 3858 | return HANDLED_NORMALLY; |
| 3837 | /* Now OVERLAY is the overlay that gave us this property, or nil | 3859 | /* Now OVERLAY is the overlay that gave us this property, or nil |
| 3838 | if it was a text property. */ | 3860 | if it was a text property. */ |
| @@ -3840,59 +3862,88 @@ handle_display_prop (struct it *it) | |||
| 3840 | if (!STRINGP (it->string)) | 3862 | if (!STRINGP (it->string)) |
| 3841 | object = it->w->buffer; | 3863 | object = it->w->buffer; |
| 3842 | 3864 | ||
| 3843 | if (CONSP (prop) | 3865 | display_replaced_p = handle_display_spec (it, propval, object, overlay, |
| 3844 | /* Simple properties. */ | 3866 | position, bufpos, |
| 3845 | && !EQ (XCAR (prop), Qimage) | 3867 | FRAME_WINDOW_P (it->f)); |
| 3846 | && !EQ (XCAR (prop), Qspace) | 3868 | |
| 3847 | && !EQ (XCAR (prop), Qwhen) | 3869 | return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY; |
| 3848 | && !EQ (XCAR (prop), Qslice) | 3870 | } |
| 3849 | && !EQ (XCAR (prop), Qspace_width) | 3871 | |
| 3850 | && !EQ (XCAR (prop), Qheight) | 3872 | /* Subroutine of handle_display_prop. Returns non-zero if the display |
| 3851 | && !EQ (XCAR (prop), Qraise) | 3873 | specification in SPEC is a replacing specification, i.e. it would |
| 3874 | replace the text covered by `display' property with something else, | ||
| 3875 | such as an image or a display string. | ||
| 3876 | |||
| 3877 | See handle_single_display_spec for documentation of arguments. | ||
| 3878 | frame_window_p is non-zero if the window being redisplayed is on a | ||
| 3879 | GUI frame; this argument is used only if IT is NULL, see below. | ||
| 3880 | |||
| 3881 | IT can be NULL, if this is called by the bidi reordering code | ||
| 3882 | through compute_display_string_pos, which see. In that case, this | ||
| 3883 | function only examines SPEC, but does not otherwise "handle" it, in | ||
| 3884 | the sense that it doesn't set up members of IT from the display | ||
| 3885 | spec. */ | ||
| 3886 | static int | ||
| 3887 | handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | ||
| 3888 | Lisp_Object overlay, struct text_pos *position, | ||
| 3889 | EMACS_INT bufpos, int frame_window_p) | ||
| 3890 | { | ||
| 3891 | int replacing_p = 0; | ||
| 3892 | |||
| 3893 | if (CONSP (spec) | ||
| 3894 | /* Simple specerties. */ | ||
| 3895 | && !EQ (XCAR (spec), Qimage) | ||
| 3896 | && !EQ (XCAR (spec), Qspace) | ||
| 3897 | && !EQ (XCAR (spec), Qwhen) | ||
| 3898 | && !EQ (XCAR (spec), Qslice) | ||
| 3899 | && !EQ (XCAR (spec), Qspace_width) | ||
| 3900 | && !EQ (XCAR (spec), Qheight) | ||
| 3901 | && !EQ (XCAR (spec), Qraise) | ||
| 3852 | /* Marginal area specifications. */ | 3902 | /* Marginal area specifications. */ |
| 3853 | && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin)) | 3903 | && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin)) |
| 3854 | && !EQ (XCAR (prop), Qleft_fringe) | 3904 | && !EQ (XCAR (spec), Qleft_fringe) |
| 3855 | && !EQ (XCAR (prop), Qright_fringe) | 3905 | && !EQ (XCAR (spec), Qright_fringe) |
| 3856 | && !NILP (XCAR (prop))) | 3906 | && !NILP (XCAR (spec))) |
| 3857 | { | 3907 | { |
| 3858 | for (; CONSP (prop); prop = XCDR (prop)) | 3908 | for (; CONSP (spec); spec = XCDR (spec)) |
| 3859 | { | 3909 | { |
| 3860 | if (handle_single_display_spec (it, XCAR (prop), object, overlay, | 3910 | if (handle_single_display_spec (it, XCAR (spec), object, overlay, |
| 3861 | position, display_replaced_p)) | 3911 | position, bufpos, replacing_p, |
| 3912 | frame_window_p)) | ||
| 3862 | { | 3913 | { |
| 3863 | display_replaced_p = 1; | 3914 | replacing_p = 1; |
| 3864 | /* If some text in a string is replaced, `position' no | 3915 | /* If some text in a string is replaced, `position' no |
| 3865 | longer points to the position of `object'. */ | 3916 | longer points to the position of `object'. */ |
| 3866 | if (STRINGP (object)) | 3917 | if (!it || STRINGP (object)) |
| 3867 | break; | 3918 | break; |
| 3868 | } | 3919 | } |
| 3869 | } | 3920 | } |
| 3870 | } | 3921 | } |
| 3871 | else if (VECTORP (prop)) | 3922 | else if (VECTORP (spec)) |
| 3872 | { | 3923 | { |
| 3873 | int i; | 3924 | int i; |
| 3874 | for (i = 0; i < ASIZE (prop); ++i) | 3925 | for (i = 0; i < ASIZE (spec); ++i) |
| 3875 | if (handle_single_display_spec (it, AREF (prop, i), object, overlay, | 3926 | if (handle_single_display_spec (it, AREF (spec, i), object, overlay, |
| 3876 | position, display_replaced_p)) | 3927 | position, bufpos, replacing_p, |
| 3928 | frame_window_p)) | ||
| 3877 | { | 3929 | { |
| 3878 | display_replaced_p = 1; | 3930 | replacing_p = 1; |
| 3879 | /* If some text in a string is replaced, `position' no | 3931 | /* If some text in a string is replaced, `position' no |
| 3880 | longer points to the position of `object'. */ | 3932 | longer points to the position of `object'. */ |
| 3881 | if (STRINGP (object)) | 3933 | if (!it || STRINGP (object)) |
| 3882 | break; | 3934 | break; |
| 3883 | } | 3935 | } |
| 3884 | } | 3936 | } |
| 3885 | else | 3937 | else |
| 3886 | { | 3938 | { |
| 3887 | if (handle_single_display_spec (it, prop, object, overlay, | 3939 | if (handle_single_display_spec (it, spec, object, overlay, |
| 3888 | position, 0)) | 3940 | position, bufpos, 0, frame_window_p)) |
| 3889 | display_replaced_p = 1; | 3941 | replacing_p = 1; |
| 3890 | } | 3942 | } |
| 3891 | 3943 | ||
| 3892 | return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY; | 3944 | return replacing_p; |
| 3893 | } | 3945 | } |
| 3894 | 3946 | ||
| 3895 | |||
| 3896 | /* Value is the position of the end of the `display' property starting | 3947 | /* Value is the position of the end of the `display' property starting |
| 3897 | at START_POS in OBJECT. */ | 3948 | at START_POS in OBJECT. */ |
| 3898 | 3949 | ||
| @@ -3916,10 +3967,12 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos) | |||
| 3916 | 3967 | ||
| 3917 | /* Set up IT from a single `display' property specification SPEC. OBJECT | 3968 | /* Set up IT from a single `display' property specification SPEC. OBJECT |
| 3918 | is the object in which the `display' property was found. *POSITION | 3969 | is the object in which the `display' property was found. *POSITION |
| 3919 | is the position at which it was found. DISPLAY_REPLACED_P non-zero | 3970 | is the position in OBJECT at which the `display' property was found. |
| 3920 | means that we previously saw a display specification which already | 3971 | BUFPOS is the buffer position of OBJECT (different from POSITION if |
| 3921 | replaced text display with something else, for example an image; | 3972 | OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we |
| 3922 | we ignore such properties after the first one has been processed. | 3973 | previously saw a display specification which already replaced text |
| 3974 | display with something else, for example an image; we ignore such | ||
| 3975 | properties after the first one has been processed. | ||
| 3923 | 3976 | ||
| 3924 | OVERLAY is the overlay this `display' property came from, | 3977 | OVERLAY is the overlay this `display' property came from, |
| 3925 | or nil if it was a text property. | 3978 | or nil if it was a text property. |
| @@ -3928,17 +3981,22 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos) | |||
| 3928 | cases too, set *POSITION to the position where the `display' | 3981 | cases too, set *POSITION to the position where the `display' |
| 3929 | property ends. | 3982 | property ends. |
| 3930 | 3983 | ||
| 3984 | If IT is NULL, only examine the property specification in SPEC, but | ||
| 3985 | don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC | ||
| 3986 | is intended to be displayed in a window on a GUI frame. | ||
| 3987 | |||
| 3931 | Value is non-zero if something was found which replaces the display | 3988 | Value is non-zero if something was found which replaces the display |
| 3932 | of buffer or string text. */ | 3989 | of buffer or string text. */ |
| 3933 | 3990 | ||
| 3934 | static int | 3991 | static int |
| 3935 | handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | 3992 | handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, |
| 3936 | Lisp_Object overlay, struct text_pos *position, | 3993 | Lisp_Object overlay, struct text_pos *position, |
| 3937 | int display_replaced_p) | 3994 | EMACS_INT bufpos, int display_replaced_p, |
| 3995 | int frame_window_p) | ||
| 3938 | { | 3996 | { |
| 3939 | Lisp_Object form; | 3997 | Lisp_Object form; |
| 3940 | Lisp_Object location, value; | 3998 | Lisp_Object location, value; |
| 3941 | struct text_pos start_pos; | 3999 | struct text_pos start_pos = *position; |
| 3942 | int valid_p; | 4000 | int valid_p; |
| 3943 | 4001 | ||
| 3944 | /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM. | 4002 | /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM. |
| @@ -3962,11 +4020,12 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 3962 | buffer or string. Bind `position' to the position in the | 4020 | buffer or string. Bind `position' to the position in the |
| 3963 | object where the property was found, and `buffer-position' | 4021 | object where the property was found, and `buffer-position' |
| 3964 | to the current position in the buffer. */ | 4022 | to the current position in the buffer. */ |
| 4023 | |||
| 4024 | if (NILP (object)) | ||
| 4025 | XSETBUFFER (object, current_buffer); | ||
| 3965 | specbind (Qobject, object); | 4026 | specbind (Qobject, object); |
| 3966 | specbind (Qposition, make_number (CHARPOS (*position))); | 4027 | specbind (Qposition, make_number (CHARPOS (*position))); |
| 3967 | specbind (Qbuffer_position, | 4028 | specbind (Qbuffer_position, make_number (bufpos)); |
| 3968 | make_number (STRINGP (object) | ||
| 3969 | ? IT_CHARPOS (*it) : CHARPOS (*position))); | ||
| 3970 | GCPRO1 (form); | 4029 | GCPRO1 (form); |
| 3971 | form = safe_eval (form); | 4030 | form = safe_eval (form); |
| 3972 | UNGCPRO; | 4031 | UNGCPRO; |
| @@ -3981,63 +4040,66 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 3981 | && EQ (XCAR (spec), Qheight) | 4040 | && EQ (XCAR (spec), Qheight) |
| 3982 | && CONSP (XCDR (spec))) | 4041 | && CONSP (XCDR (spec))) |
| 3983 | { | 4042 | { |
| 3984 | if (!FRAME_WINDOW_P (it->f)) | 4043 | if (it) |
| 3985 | return 0; | ||
| 3986 | |||
| 3987 | it->font_height = XCAR (XCDR (spec)); | ||
| 3988 | if (!NILP (it->font_height)) | ||
| 3989 | { | 4044 | { |
| 3990 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | 4045 | if (!FRAME_WINDOW_P (it->f)) |
| 3991 | int new_height = -1; | 4046 | return 0; |
| 3992 | 4047 | ||
| 3993 | if (CONSP (it->font_height) | 4048 | it->font_height = XCAR (XCDR (spec)); |
| 3994 | && (EQ (XCAR (it->font_height), Qplus) | 4049 | if (!NILP (it->font_height)) |
| 3995 | || EQ (XCAR (it->font_height), Qminus)) | ||
| 3996 | && CONSP (XCDR (it->font_height)) | ||
| 3997 | && INTEGERP (XCAR (XCDR (it->font_height)))) | ||
| 3998 | { | ||
| 3999 | /* `(+ N)' or `(- N)' where N is an integer. */ | ||
| 4000 | int steps = XINT (XCAR (XCDR (it->font_height))); | ||
| 4001 | if (EQ (XCAR (it->font_height), Qplus)) | ||
| 4002 | steps = - steps; | ||
| 4003 | it->face_id = smaller_face (it->f, it->face_id, steps); | ||
| 4004 | } | ||
| 4005 | else if (FUNCTIONP (it->font_height)) | ||
| 4006 | { | 4050 | { |
| 4007 | /* Call function with current height as argument. | 4051 | struct face *face = FACE_FROM_ID (it->f, it->face_id); |
| 4008 | Value is the new height. */ | 4052 | int new_height = -1; |
| 4009 | Lisp_Object height; | 4053 | |
| 4010 | height = safe_call1 (it->font_height, | 4054 | if (CONSP (it->font_height) |
| 4011 | face->lface[LFACE_HEIGHT_INDEX]); | 4055 | && (EQ (XCAR (it->font_height), Qplus) |
| 4012 | if (NUMBERP (height)) | 4056 | || EQ (XCAR (it->font_height), Qminus)) |
| 4013 | new_height = XFLOATINT (height); | 4057 | && CONSP (XCDR (it->font_height)) |
| 4014 | } | 4058 | && INTEGERP (XCAR (XCDR (it->font_height)))) |
| 4015 | else if (NUMBERP (it->font_height)) | 4059 | { |
| 4016 | { | 4060 | /* `(+ N)' or `(- N)' where N is an integer. */ |
| 4017 | /* Value is a multiple of the canonical char height. */ | 4061 | int steps = XINT (XCAR (XCDR (it->font_height))); |
| 4018 | struct face *f; | 4062 | if (EQ (XCAR (it->font_height), Qplus)) |
| 4063 | steps = - steps; | ||
| 4064 | it->face_id = smaller_face (it->f, it->face_id, steps); | ||
| 4065 | } | ||
| 4066 | else if (FUNCTIONP (it->font_height)) | ||
| 4067 | { | ||
| 4068 | /* Call function with current height as argument. | ||
| 4069 | Value is the new height. */ | ||
| 4070 | Lisp_Object height; | ||
| 4071 | height = safe_call1 (it->font_height, | ||
| 4072 | face->lface[LFACE_HEIGHT_INDEX]); | ||
| 4073 | if (NUMBERP (height)) | ||
| 4074 | new_height = XFLOATINT (height); | ||
| 4075 | } | ||
| 4076 | else if (NUMBERP (it->font_height)) | ||
| 4077 | { | ||
| 4078 | /* Value is a multiple of the canonical char height. */ | ||
| 4079 | struct face *f; | ||
| 4019 | 4080 | ||
| 4020 | f = FACE_FROM_ID (it->f, | 4081 | f = FACE_FROM_ID (it->f, |
| 4021 | lookup_basic_face (it->f, DEFAULT_FACE_ID)); | 4082 | lookup_basic_face (it->f, DEFAULT_FACE_ID)); |
| 4022 | new_height = (XFLOATINT (it->font_height) | 4083 | new_height = (XFLOATINT (it->font_height) |
| 4023 | * XINT (f->lface[LFACE_HEIGHT_INDEX])); | 4084 | * XINT (f->lface[LFACE_HEIGHT_INDEX])); |
| 4024 | } | 4085 | } |
| 4025 | else | 4086 | else |
| 4026 | { | 4087 | { |
| 4027 | /* Evaluate IT->font_height with `height' bound to the | 4088 | /* Evaluate IT->font_height with `height' bound to the |
| 4028 | current specified height to get the new height. */ | 4089 | current specified height to get the new height. */ |
| 4029 | int count = SPECPDL_INDEX (); | 4090 | int count = SPECPDL_INDEX (); |
| 4030 | 4091 | ||
| 4031 | specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]); | 4092 | specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]); |
| 4032 | value = safe_eval (it->font_height); | 4093 | value = safe_eval (it->font_height); |
| 4033 | unbind_to (count, Qnil); | 4094 | unbind_to (count, Qnil); |
| 4034 | 4095 | ||
| 4035 | if (NUMBERP (value)) | 4096 | if (NUMBERP (value)) |
| 4036 | new_height = XFLOATINT (value); | 4097 | new_height = XFLOATINT (value); |
| 4037 | } | 4098 | } |
| 4038 | 4099 | ||
| 4039 | if (new_height > 0) | 4100 | if (new_height > 0) |
| 4040 | it->face_id = face_with_height (it->f, it->face_id, new_height); | 4101 | it->face_id = face_with_height (it->f, it->face_id, new_height); |
| 4102 | } | ||
| 4041 | } | 4103 | } |
| 4042 | 4104 | ||
| 4043 | return 0; | 4105 | return 0; |
| @@ -4048,12 +4110,15 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4048 | && EQ (XCAR (spec), Qspace_width) | 4110 | && EQ (XCAR (spec), Qspace_width) |
| 4049 | && CONSP (XCDR (spec))) | 4111 | && CONSP (XCDR (spec))) |
| 4050 | { | 4112 | { |
| 4051 | if (!FRAME_WINDOW_P (it->f)) | 4113 | if (it) |
| 4052 | return 0; | 4114 | { |
| 4115 | if (!FRAME_WINDOW_P (it->f)) | ||
| 4116 | return 0; | ||
| 4053 | 4117 | ||
| 4054 | value = XCAR (XCDR (spec)); | 4118 | value = XCAR (XCDR (spec)); |
| 4055 | if (NUMBERP (value) && XFLOATINT (value) > 0) | 4119 | if (NUMBERP (value) && XFLOATINT (value) > 0) |
| 4056 | it->space_width = value; | 4120 | it->space_width = value; |
| 4121 | } | ||
| 4057 | 4122 | ||
| 4058 | return 0; | 4123 | return 0; |
| 4059 | } | 4124 | } |
| @@ -4064,20 +4129,23 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4064 | { | 4129 | { |
| 4065 | Lisp_Object tem; | 4130 | Lisp_Object tem; |
| 4066 | 4131 | ||
| 4067 | if (!FRAME_WINDOW_P (it->f)) | 4132 | if (it) |
| 4068 | return 0; | ||
| 4069 | |||
| 4070 | if (tem = XCDR (spec), CONSP (tem)) | ||
| 4071 | { | 4133 | { |
| 4072 | it->slice.x = XCAR (tem); | 4134 | if (!FRAME_WINDOW_P (it->f)) |
| 4073 | if (tem = XCDR (tem), CONSP (tem)) | 4135 | return 0; |
| 4136 | |||
| 4137 | if (tem = XCDR (spec), CONSP (tem)) | ||
| 4074 | { | 4138 | { |
| 4075 | it->slice.y = XCAR (tem); | 4139 | it->slice.x = XCAR (tem); |
| 4076 | if (tem = XCDR (tem), CONSP (tem)) | 4140 | if (tem = XCDR (tem), CONSP (tem)) |
| 4077 | { | 4141 | { |
| 4078 | it->slice.width = XCAR (tem); | 4142 | it->slice.y = XCAR (tem); |
| 4079 | if (tem = XCDR (tem), CONSP (tem)) | 4143 | if (tem = XCDR (tem), CONSP (tem)) |
| 4080 | it->slice.height = XCAR (tem); | 4144 | { |
| 4145 | it->slice.width = XCAR (tem); | ||
| 4146 | if (tem = XCDR (tem), CONSP (tem)) | ||
| 4147 | it->slice.height = XCAR (tem); | ||
| 4148 | } | ||
| 4081 | } | 4149 | } |
| 4082 | } | 4150 | } |
| 4083 | } | 4151 | } |
| @@ -4090,36 +4158,43 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4090 | && EQ (XCAR (spec), Qraise) | 4158 | && EQ (XCAR (spec), Qraise) |
| 4091 | && CONSP (XCDR (spec))) | 4159 | && CONSP (XCDR (spec))) |
| 4092 | { | 4160 | { |
| 4093 | if (!FRAME_WINDOW_P (it->f)) | 4161 | if (it) |
| 4094 | return 0; | 4162 | { |
| 4163 | if (!FRAME_WINDOW_P (it->f)) | ||
| 4164 | return 0; | ||
| 4095 | 4165 | ||
| 4096 | #ifdef HAVE_WINDOW_SYSTEM | 4166 | #ifdef HAVE_WINDOW_SYSTEM |
| 4097 | value = XCAR (XCDR (spec)); | 4167 | value = XCAR (XCDR (spec)); |
| 4098 | if (NUMBERP (value)) | 4168 | if (NUMBERP (value)) |
| 4099 | { | 4169 | { |
| 4100 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | 4170 | struct face *face = FACE_FROM_ID (it->f, it->face_id); |
| 4101 | it->voffset = - (XFLOATINT (value) | 4171 | it->voffset = - (XFLOATINT (value) |
| 4102 | * (FONT_HEIGHT (face->font))); | 4172 | * (FONT_HEIGHT (face->font))); |
| 4103 | } | 4173 | } |
| 4104 | #endif /* HAVE_WINDOW_SYSTEM */ | 4174 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 4175 | } | ||
| 4105 | 4176 | ||
| 4106 | return 0; | 4177 | return 0; |
| 4107 | } | 4178 | } |
| 4108 | 4179 | ||
| 4109 | /* Don't handle the other kinds of display specifications | 4180 | /* Don't handle the other kinds of display specifications |
| 4110 | inside a string that we got from a `display' property. */ | 4181 | inside a string that we got from a `display' property. */ |
| 4111 | if (it->string_from_display_prop_p) | 4182 | if (it && it->string_from_display_prop_p) |
| 4112 | return 0; | 4183 | return 0; |
| 4113 | 4184 | ||
| 4114 | /* Characters having this form of property are not displayed, so | 4185 | /* Characters having this form of property are not displayed, so |
| 4115 | we have to find the end of the property. */ | 4186 | we have to find the end of the property. */ |
| 4116 | start_pos = *position; | 4187 | if (it) |
| 4117 | *position = display_prop_end (it, object, start_pos); | 4188 | { |
| 4189 | start_pos = *position; | ||
| 4190 | *position = display_prop_end (it, object, start_pos); | ||
| 4191 | } | ||
| 4118 | value = Qnil; | 4192 | value = Qnil; |
| 4119 | 4193 | ||
| 4120 | /* Stop the scan at that end position--we assume that all | 4194 | /* Stop the scan at that end position--we assume that all |
| 4121 | text properties change there. */ | 4195 | text properties change there. */ |
| 4122 | it->stop_charpos = position->charpos; | 4196 | if (it) |
| 4197 | it->stop_charpos = position->charpos; | ||
| 4123 | 4198 | ||
| 4124 | /* Handle `(left-fringe BITMAP [FACE])' | 4199 | /* Handle `(left-fringe BITMAP [FACE])' |
| 4125 | and `(right-fringe BITMAP [FACE])'. */ | 4200 | and `(right-fringe BITMAP [FACE])'. */ |
| @@ -4128,12 +4203,16 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4128 | || EQ (XCAR (spec), Qright_fringe)) | 4203 | || EQ (XCAR (spec), Qright_fringe)) |
| 4129 | && CONSP (XCDR (spec))) | 4204 | && CONSP (XCDR (spec))) |
| 4130 | { | 4205 | { |
| 4131 | int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID); | ||
| 4132 | int fringe_bitmap; | 4206 | int fringe_bitmap; |
| 4133 | 4207 | ||
| 4134 | if (!FRAME_WINDOW_P (it->f)) | 4208 | if (it) |
| 4135 | /* If we return here, POSITION has been advanced | 4209 | { |
| 4136 | across the text with this property. */ | 4210 | if (!FRAME_WINDOW_P (it->f)) |
| 4211 | /* If we return here, POSITION has been advanced | ||
| 4212 | across the text with this property. */ | ||
| 4213 | return 0; | ||
| 4214 | } | ||
| 4215 | else if (!frame_window_p) | ||
| 4137 | return 0; | 4216 | return 0; |
| 4138 | 4217 | ||
| 4139 | #ifdef HAVE_WINDOW_SYSTEM | 4218 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -4144,42 +4223,47 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4144 | across the text with this property. */ | 4223 | across the text with this property. */ |
| 4145 | return 0; | 4224 | return 0; |
| 4146 | 4225 | ||
| 4147 | if (CONSP (XCDR (XCDR (spec)))) | 4226 | if (it) |
| 4148 | { | 4227 | { |
| 4149 | Lisp_Object face_name = XCAR (XCDR (XCDR (spec))); | 4228 | int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);; |
| 4150 | int face_id2 = lookup_derived_face (it->f, face_name, | ||
| 4151 | FRINGE_FACE_ID, 0); | ||
| 4152 | if (face_id2 >= 0) | ||
| 4153 | face_id = face_id2; | ||
| 4154 | } | ||
| 4155 | 4229 | ||
| 4156 | /* Save current settings of IT so that we can restore them | 4230 | if (CONSP (XCDR (XCDR (spec)))) |
| 4157 | when we are finished with the glyph property value. */ | 4231 | { |
| 4158 | push_it (it, position); | 4232 | Lisp_Object face_name = XCAR (XCDR (XCDR (spec))); |
| 4233 | int face_id2 = lookup_derived_face (it->f, face_name, | ||
| 4234 | FRINGE_FACE_ID, 0); | ||
| 4235 | if (face_id2 >= 0) | ||
| 4236 | face_id = face_id2; | ||
| 4237 | } | ||
| 4159 | 4238 | ||
| 4160 | it->area = TEXT_AREA; | 4239 | /* Save current settings of IT so that we can restore them |
| 4161 | it->what = IT_IMAGE; | 4240 | when we are finished with the glyph property value. */ |
| 4162 | it->image_id = -1; /* no image */ | 4241 | push_it (it, position); |
| 4163 | it->position = start_pos; | ||
| 4164 | it->object = NILP (object) ? it->w->buffer : object; | ||
| 4165 | it->method = GET_FROM_IMAGE; | ||
| 4166 | it->from_overlay = Qnil; | ||
| 4167 | it->face_id = face_id; | ||
| 4168 | 4242 | ||
| 4169 | /* Say that we haven't consumed the characters with | 4243 | it->area = TEXT_AREA; |
| 4170 | `display' property yet. The call to pop_it in | 4244 | it->what = IT_IMAGE; |
| 4171 | set_iterator_to_next will clean this up. */ | 4245 | it->image_id = -1; /* no image */ |
| 4172 | *position = start_pos; | 4246 | it->position = start_pos; |
| 4247 | it->object = NILP (object) ? it->w->buffer : object; | ||
| 4248 | it->method = GET_FROM_IMAGE; | ||
| 4249 | it->from_overlay = Qnil; | ||
| 4250 | it->face_id = face_id; | ||
| 4173 | 4251 | ||
| 4174 | if (EQ (XCAR (spec), Qleft_fringe)) | 4252 | /* Say that we haven't consumed the characters with |
| 4175 | { | 4253 | `display' property yet. The call to pop_it in |
| 4176 | it->left_user_fringe_bitmap = fringe_bitmap; | 4254 | set_iterator_to_next will clean this up. */ |
| 4177 | it->left_user_fringe_face_id = face_id; | 4255 | *position = start_pos; |
| 4178 | } | 4256 | |
| 4179 | else | 4257 | if (EQ (XCAR (spec), Qleft_fringe)) |
| 4180 | { | 4258 | { |
| 4181 | it->right_user_fringe_bitmap = fringe_bitmap; | 4259 | it->left_user_fringe_bitmap = fringe_bitmap; |
| 4182 | it->right_user_fringe_face_id = face_id; | 4260 | it->left_user_fringe_face_id = face_id; |
| 4261 | } | ||
| 4262 | else | ||
| 4263 | { | ||
| 4264 | it->right_user_fringe_bitmap = fringe_bitmap; | ||
| 4265 | it->right_user_fringe_face_id = face_id; | ||
| 4266 | } | ||
| 4183 | } | 4267 | } |
| 4184 | #endif /* HAVE_WINDOW_SYSTEM */ | 4268 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 4185 | return 1; | 4269 | return 1; |
| @@ -4222,12 +4306,16 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4222 | 4306 | ||
| 4223 | valid_p = (STRINGP (value) | 4307 | valid_p = (STRINGP (value) |
| 4224 | #ifdef HAVE_WINDOW_SYSTEM | 4308 | #ifdef HAVE_WINDOW_SYSTEM |
| 4225 | || (FRAME_WINDOW_P (it->f) && valid_image_p (value)) | 4309 | || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p) |
| 4310 | && valid_image_p (value)) | ||
| 4226 | #endif /* not HAVE_WINDOW_SYSTEM */ | 4311 | #endif /* not HAVE_WINDOW_SYSTEM */ |
| 4227 | || (CONSP (value) && EQ (XCAR (value), Qspace))); | 4312 | || (CONSP (value) && EQ (XCAR (value), Qspace))); |
| 4228 | 4313 | ||
| 4229 | if (valid_p && !display_replaced_p) | 4314 | if (valid_p && !display_replaced_p) |
| 4230 | { | 4315 | { |
| 4316 | if (!it) | ||
| 4317 | return 1; | ||
| 4318 | |||
| 4231 | /* Save current settings of IT so that we can restore them | 4319 | /* Save current settings of IT so that we can restore them |
| 4232 | when we are finished with the glyph property value. */ | 4320 | when we are finished with the glyph property value. */ |
| 4233 | push_it (it, position); | 4321 | push_it (it, position); |
| @@ -18080,6 +18168,8 @@ See also `bidi-paragraph-direction'. */) | |||
| 18080 | bytepos--; | 18168 | bytepos--; |
| 18081 | itb.charpos = pos; | 18169 | itb.charpos = pos; |
| 18082 | itb.bytepos = bytepos; | 18170 | itb.bytepos = bytepos; |
| 18171 | itb.nchars = -1; | ||
| 18172 | itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */ | ||
| 18083 | itb.first_elt = 1; | 18173 | itb.first_elt = 1; |
| 18084 | itb.separator_limit = -1; | 18174 | itb.separator_limit = -1; |
| 18085 | itb.paragraph_dir = NEUTRAL_DIR; | 18175 | itb.paragraph_dir = NEUTRAL_DIR; |