aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2011-05-21 17:22:14 +0300
committerEli Zaretskii2011-05-21 17:22:14 +0300
commitfc6f18ceeaae3c3eb4d68120899e16c2fc73ea86 (patch)
treedbbc17ffa38f01c0fe0184605569c1051f6eec8d
parent683a44f77c8c83febe1ab7ebe7fc32d26fc71bcd (diff)
downloademacs-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.
-rw-r--r--src/ChangeLog23
-rw-r--r--src/bidi.c22
-rw-r--r--src/dispextern.h5
-rw-r--r--src/xdisp.c430
4 files changed, 300 insertions, 180 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index fdb98351672..f7807b90941 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,26 @@
12011-05-21 Eli Zaretskii <eliz@gnu.org>
2
3 * xdisp.c (handle_display_spec): New function, refactored from the
4 last portion of handle_display_prop.
5 (compute_display_string_pos): Accept additional argument
6 FRAME_WINDOW_P. Call handle_display_spec to determine whether the
7 value of a `display' property is a "replacing spec".
8 (handle_single_display_spec): Accept 2 additional arguments BUFPOS
9 and FRAME_WINDOW_P. If IT is NULL, don't set up the iterator from
10 the display property, but just return a value indicating whether
11 the display property will replace the characters it covers.
12 (Fcurrent_bidi_paragraph_direction): Initialize the nchars and
13 frame_window_p members of struct bidi_it.
14
15 * bidi.c (bidi_fetch_char): Accept additional argument
16 FRAME_WINDOW_P and pass it to compute_display_string_pos. All
17 callers changed.
18 (bidi_init_it): Accept additional argument FRAME_WINDOW_P and use
19 it to initialize the frame_window_p member of struct bidi_it.
20
21 * dispextern.h (struct bidi_it): New member frame_window_p.
22 (bidi_init_it, compute_display_string_pos): Update prototypes.
23
12011-05-14 Eli Zaretskii <eliz@gnu.org> 242011-05-14 Eli Zaretskii <eliz@gnu.org>
2 25
3 * xdisp.c (compute_display_string_pos): Non-trivial implementation. 26 * xdisp.c (compute_display_string_pos): Non-trivial implementation.
diff --git a/src/bidi.c b/src/bidi.c
index 742224607e4..17cb1214c73 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -581,7 +581,7 @@ bidi_line_init (struct bidi_it *bidi_it)
581 string. */ 581 string. */
582static INLINE int 582static INLINE int
583bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, 583bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
584 EMACS_INT *ch_len, EMACS_INT *nchars) 584 int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars)
585{ 585{
586 int ch; 586 int ch;
587 587
@@ -589,7 +589,7 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
589 /* If we got past the last known position of display string, compute 589 /* If we got past the last known position of display string, compute
590 the position of the next one. That position could be at BYTEPOS. */ 590 the position of the next one. That position could be at BYTEPOS. */
591 if (charpos < ZV && charpos > *disp_pos) 591 if (charpos < ZV && charpos > *disp_pos)
592 *disp_pos = compute_display_string_pos (charpos); 592 *disp_pos = compute_display_string_pos (charpos, frame_window_p);
593 593
594 /* Fetch the character at BYTEPOS. */ 594 /* Fetch the character at BYTEPOS. */
595 if (bytepos >= ZV_BYTE) 595 if (bytepos >= ZV_BYTE)
@@ -625,7 +625,7 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
625 /* If we just entered a run of characters covered by a display 625 /* If we just entered a run of characters covered by a display
626 string, compute the position of the next display string. */ 626 string, compute the position of the next display string. */
627 if (charpos + *nchars <= ZV && charpos + *nchars > *disp_pos) 627 if (charpos + *nchars <= ZV && charpos + *nchars > *disp_pos)
628 *disp_pos = compute_display_string_pos (charpos + *nchars); 628 *disp_pos = compute_display_string_pos (charpos + *nchars, frame_window_p);
629 629
630 return ch; 630 return ch;
631} 631}
@@ -754,7 +754,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
754 do { 754 do {
755 bytepos = pstartbyte; 755 bytepos = pstartbyte;
756 pos = BYTE_TO_CHAR (bytepos); 756 pos = BYTE_TO_CHAR (bytepos);
757 ch = bidi_fetch_char (bytepos, pos, &disp_pos, &ch_len, &nchars); 757 ch = bidi_fetch_char (bytepos, pos, &disp_pos, bidi_it->frame_window_p,
758 &ch_len, &nchars);
758 type = bidi_get_type (ch, NEUTRAL_DIR); 759 type = bidi_get_type (ch, NEUTRAL_DIR);
759 760
760 for (pos += nchars, bytepos += ch_len; 761 for (pos += nchars, bytepos += ch_len;
@@ -778,7 +779,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
778 break; 779 break;
779 } 780 }
780 /* Fetch next character and advance to get past it. */ 781 /* Fetch next character and advance to get past it. */
781 ch = bidi_fetch_char (bytepos, pos, &disp_pos, &ch_len, &nchars); 782 ch = bidi_fetch_char (bytepos, pos, &disp_pos,
783 bidi_it->frame_window_p, &ch_len, &nchars);
782 pos += nchars; 784 pos += nchars;
783 bytepos += ch_len; 785 bytepos += ch_len;
784 } 786 }
@@ -840,12 +842,14 @@ bidi_set_paragraph_end (struct bidi_it *bidi_it)
840 842
841/* Initialize the bidi iterator from buffer/string position CHARPOS. */ 843/* Initialize the bidi iterator from buffer/string position CHARPOS. */
842void 844void
843bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, struct bidi_it *bidi_it) 845bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p,
846 struct bidi_it *bidi_it)
844{ 847{
845 if (! bidi_initialized) 848 if (! bidi_initialized)
846 bidi_initialize (); 849 bidi_initialize ();
847 bidi_it->charpos = charpos; 850 bidi_it->charpos = charpos;
848 bidi_it->bytepos = bytepos; 851 bidi_it->bytepos = bytepos;
852 bidi_it->frame_window_p = frame_window_p;
849 bidi_it->nchars = -1; /* to be computed in bidi_resolve_explicit_1 */ 853 bidi_it->nchars = -1; /* to be computed in bidi_resolve_explicit_1 */
850 bidi_it->first_elt = 1; 854 bidi_it->first_elt = 1;
851 bidi_set_paragraph_end (bidi_it); 855 bidi_set_paragraph_end (bidi_it);
@@ -996,7 +1000,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
996 display string, treat the entire run of covered characters as 1000 display string, treat the entire run of covered characters as
997 a single character u+FFFC. */ 1001 a single character u+FFFC. */
998 curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, 1002 curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos,
999 &bidi_it->disp_pos, 1003 &bidi_it->disp_pos, bidi_it->frame_window_p,
1000 &bidi_it->ch_len, &bidi_it->nchars); 1004 &bidi_it->ch_len, &bidi_it->nchars);
1001 } 1005 }
1002 bidi_it->ch = curchar; 1006 bidi_it->ch = curchar;
@@ -1674,11 +1678,13 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
1674 EMACS_INT disp_pos = bidi_it->disp_pos; 1678 EMACS_INT disp_pos = bidi_it->disp_pos;
1675 EMACS_INT nc = bidi_it->nchars; 1679 EMACS_INT nc = bidi_it->nchars;
1676 bidi_type_t chtype; 1680 bidi_type_t chtype;
1681 int fwp = bidi_it->frame_window_p;
1677 1682
1678 if (bidi_it->nchars <= 0) 1683 if (bidi_it->nchars <= 0)
1679 abort (); 1684 abort ();
1680 do { 1685 do {
1681 ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &clen, &nc); 1686 ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, fwp,
1687 &clen, &nc);
1682 if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */) 1688 if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */)
1683 chtype = NEUTRAL_B; 1689 chtype = NEUTRAL_B;
1684 else 1690 else
diff --git a/src/dispextern.h b/src/dispextern.h
index f5036169f75..6c09f21a78f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1847,6 +1847,7 @@ struct bidi_it {
1847 int first_elt; /* if non-zero, examine current char first */ 1847 int first_elt; /* if non-zero, examine current char first */
1848 bidi_dir_t paragraph_dir; /* current paragraph direction */ 1848 bidi_dir_t paragraph_dir; /* current paragraph direction */
1849 int new_paragraph; /* if non-zero, we expect a new paragraph */ 1849 int new_paragraph; /* if non-zero, we expect a new paragraph */
1850 int frame_window_p; /* non-zero if displaying on a GUI frame */
1850 EMACS_INT separator_limit; /* where paragraph separator should end */ 1851 EMACS_INT separator_limit; /* where paragraph separator should end */
1851 EMACS_INT disp_pos; /* position of display string after ch */ 1852 EMACS_INT disp_pos; /* position of display string after ch */
1852}; 1853};
@@ -2945,7 +2946,7 @@ enum tool_bar_item_image
2945 2946
2946/* Defined in bidi.c */ 2947/* Defined in bidi.c */
2947 2948
2948extern void bidi_init_it (EMACS_INT, EMACS_INT, struct bidi_it *); 2949extern void bidi_init_it (EMACS_INT, EMACS_INT, int, struct bidi_it *);
2949extern void bidi_move_to_visually_next (struct bidi_it *); 2950extern void bidi_move_to_visually_next (struct bidi_it *);
2950extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int); 2951extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int);
2951extern int bidi_mirror_char (int); 2952extern int bidi_mirror_char (int);
@@ -3006,7 +3007,7 @@ extern void reseat_at_previous_visible_line_start (struct it *);
3006extern Lisp_Object lookup_glyphless_char_display (int, struct it *); 3007extern Lisp_Object lookup_glyphless_char_display (int, struct it *);
3007extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, 3008extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object,
3008 struct font *, int, int *); 3009 struct font *, int, int *);
3009extern EMACS_INT compute_display_string_pos (EMACS_INT); 3010extern EMACS_INT compute_display_string_pos (EMACS_INT, int);
3010extern EMACS_INT compute_display_string_end (EMACS_INT); 3011extern EMACS_INT compute_display_string_end (EMACS_INT);
3011 3012
3012#ifdef HAVE_WINDOW_SYSTEM 3013#ifdef HAVE_WINDOW_SYSTEM
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);
885static int face_before_or_after_it_pos (struct it *, int); 885static int face_before_or_after_it_pos (struct it *, int);
886static EMACS_INT next_overlay_change (EMACS_INT); 886static EMACS_INT next_overlay_change (EMACS_INT);
887static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
888 Lisp_Object, struct text_pos *, EMACS_INT, int);
887static int handle_single_display_spec (struct it *, Lisp_Object, 889static 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);
890static int underlying_face_id (struct it *); 892static int underlying_face_id (struct it *);
891static int in_ellipses_for_invisible_text_p (struct display_pos *, 893static 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. */
3093EMACS_INT 3096EMACS_INT
3094compute_display_string_pos (EMACS_INT charpos) 3097compute_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)
3802static enum prop_handled 3821static enum prop_handled
3803handle_display_prop (struct it *it) 3822handle_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. */
3886static int
3887handle_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
3934static int 3991static int
3935handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, 3992handle_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;