aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2011-08-25 13:45:33 +0300
committerEli Zaretskii2011-08-25 13:45:33 +0300
commit0c95fcf739dbfbae70f4e4700fdafedb4497e8df (patch)
treef27c148c083aa9a6d290053b26ac8e45bfdcb07a
parenta2ebe600c947152c10bf657dfb9dfabdb601c766 (diff)
downloademacs-0c95fcf739dbfbae70f4e4700fdafedb4497e8df.tar.gz
emacs-0c95fcf739dbfbae70f4e4700fdafedb4497e8df.zip
Handle `(space ...)' display spec as paragraph separator.
src/xdisp.c (compute_display_string_pos): Return 2 in DISP_PROP when the display spec is of the form `(space ...)'. (handle_display_spec): Return the value returned by handle_single_display_spec, not just 1 or zero. (handle_single_display_spec): If the display spec is of the form `(space ...)', and specifies display in the text area, return 2 rather than 1. src/dispextern.h (struct bidi_it): Rename the disp_prop_p member into disp_prop; all users changed. src/bidi.c (bidi_fetch_char): If compute_display_string_pos returns DISP_PROP = 2, substitute the u+2029 PARAGRAPH SEPARATOR character for the text covered by the display property. lisp/buff-menu.el (Buffer-menu-buffer+size): Remove calls to bidi-string-mark-left-to-right; they are unnecessary now. doc/lispref/display.texi (Specified Space): Mention that `space' specs influence bidi reordering. (Bidirectional Display): Explain how to use `(space . PROPS)' for separating fields with bidirectional content.
-rw-r--r--doc/lispref/ChangeLog7
-rw-r--r--doc/lispref/display.texi17
-rw-r--r--lisp/ChangeLog5
-rw-r--r--lisp/buff-menu.el4
-rw-r--r--src/ChangeLog17
-rw-r--r--src/bidi.c71
-rw-r--r--src/dispextern.h5
-rw-r--r--src/xdisp.c71
8 files changed, 140 insertions, 57 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index 4bf615328b1..ca9c93b563d 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,10 @@
12011-08-25 Eli Zaretskii <eliz@gnu.org>
2
3 * display.texi (Specified Space): Mention that `space' specs
4 influence bidi reordering.
5 (Bidirectional Display): Explain how to use `(space . PROPS)' for
6 separating fields with bidirectional content.
7
12011-08-24 Eli Zaretskii <eliz@gnu.org> 82011-08-24 Eli Zaretskii <eliz@gnu.org>
2 9
3 * display.texi (Bidirectional Display): Document return value in 10 * display.texi (Bidirectional Display): Document return value in
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 0593eba8f05..bf7cd126a26 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -3794,6 +3794,10 @@ with a @dfn{pixel ascent} specification (@pxref{Pixel Specification}).
3794non-graphic terminals, but the other space properties in this section 3794non-graphic terminals, but the other space properties in this section
3795are not. 3795are not.
3796 3796
3797 Note that space properties are treated as paragraph separators for
3798the purposes of reordering bidirectional text for display.
3799@xref{Bidirectional Display}, for the details.
3800
3797@node Pixel Specification 3801@node Pixel Specification
3798@subsection Pixel Specification for Spaces 3802@subsection Pixel Specification for Spaces
3799@cindex spaces, pixel specification 3803@cindex spaces, pixel specification
@@ -6126,8 +6130,8 @@ with bidirectional content can be displayed @emph{to the left} of the
6126preceding field, producing a jumbled display and messing up the 6130preceding field, producing a jumbled display and messing up the
6127expected layout. 6131expected layout.
6128 6132
6129 To countermand this, you can use one of the following techniques for 6133 To countermand this, we recommend that you use one of the following
6130forcing correct order of fields on display: 6134techniques for forcing correct order of fields on display:
6131 6135
6132@itemize @minus 6136@itemize @minus
6133@item 6137@item
@@ -6146,6 +6150,15 @@ Include the tab character in the field separator. The tab character
6146plays the role of @dfn{segment separator} in the @acronym{UBA} 6150plays the role of @dfn{segment separator} in the @acronym{UBA}
6147reordering, whose effect is to make each field a separate segment, and 6151reordering, whose effect is to make each field a separate segment, and
6148thus reorder them separately. 6152thus reorder them separately.
6153
6154@cindex @code{space} display spec, and bidirectional text
6155@item
6156Separate fields with a @code{display} property or overlay with the
6157property value of the form @code{(space . PROPS)} (@pxref{Specified
6158Space}). This display specification is treated by Emacs as a
6159@dfn{paragraph separator}; the text before and after the separator is
6160reordered separately, which avoids the influence of any field on its
6161neighboring fields.
6149@end itemize 6162@end itemize
6150 6163
6151@defun bidi-string-mark-left-to-right string 6164@defun bidi-string-mark-left-to-right string
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index a42711dccc4..064e745d1f5 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,8 @@
12011-08-25 Eli Zaretskii <eliz@gnu.org>
2
3 * buff-menu.el (Buffer-menu-buffer+size): Remove calls to
4 bidi-string-mark-left-to-right; they are unnecessary now.
5
12011-08-25 Deniz Dogan <deniz@dogan.se> 62011-08-25 Deniz Dogan <deniz@dogan.se>
2 7
3 * net/quickurl.el: Documentation typo fixes. 8 * net/quickurl.el: Documentation typo fixes.
diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el
index 2eac33d8157..2be74cf5efb 100644
--- a/lisp/buff-menu.el
+++ b/lisp/buff-menu.el
@@ -681,9 +681,9 @@ For more information, see the function `buffer-menu'."
681 (string-width tail) 681 (string-width tail)
682 2)) 682 2))
683 Buffer-menu-short-ellipsis 683 Buffer-menu-short-ellipsis
684 (bidi-string-mark-left-to-right tail)))) 684 tail)))
685 ;; Don't put properties on (buffer-name). 685 ;; Don't put properties on (buffer-name).
686 (setq name (bidi-string-mark-left-to-right name))) 686 (setq name (copy-sequence name)))
687 (add-text-properties 0 (length name) name-props name) 687 (add-text-properties 0 (length name) name-props name)
688 (add-text-properties 0 (length size) size-props size) 688 (add-text-properties 0 (length size) size-props size)
689 (let ((name+space-width (- Buffer-menu-buffer+size-width 689 (let ((name+space-width (- Buffer-menu-buffer+size-width
diff --git a/src/ChangeLog b/src/ChangeLog
index 431a515def5..b2f2334427c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,20 @@
12011-08-25 Eli Zaretskii <eliz@gnu.org>
2
3 * xdisp.c (compute_display_string_pos): Return 2 in DISP_PROP when
4 the display spec is of the form `(space ...)'.
5 (handle_display_spec): Return the value returned by
6 handle_single_display_spec, not just 1 or zero.
7 (handle_single_display_spec): If the display spec is of the form
8 `(space ...)', and specifies display in the text area, return 2
9 rather than 1.
10
11 * dispextern.h (struct bidi_it): Rename the disp_prop_p member
12 into disp_prop; all users changed.
13
14 * bidi.c (bidi_fetch_char): If compute_display_string_pos returns
15 DISP_PROP = 2, substitute the u+2029 PARAGRAPH SEPARATOR character
16 for the text covered by the display property.
17
12011-08-25 Chong Yidong <cyd@stupidchicken.com> 182011-08-25 Chong Yidong <cyd@stupidchicken.com>
2 19
3 * buffer.c (Fbury_buffer_internal): Rename from Funrecord_buffer. 20 * buffer.c (Fbury_buffer_internal): Rename from Funrecord_buffer.
diff --git a/src/bidi.c b/src/bidi.c
index 425a0be9578..79aaa03fb0b 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -540,7 +540,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
540 bidi_cache[idx].next_for_ws = bidi_it->next_for_ws; 540 bidi_cache[idx].next_for_ws = bidi_it->next_for_ws;
541 bidi_cache[idx].ignore_bn_limit = bidi_it->ignore_bn_limit; 541 bidi_cache[idx].ignore_bn_limit = bidi_it->ignore_bn_limit;
542 bidi_cache[idx].disp_pos = bidi_it->disp_pos; 542 bidi_cache[idx].disp_pos = bidi_it->disp_pos;
543 bidi_cache[idx].disp_prop_p = bidi_it->disp_prop_p; 543 bidi_cache[idx].disp_prop = bidi_it->disp_prop;
544 } 544 }
545 545
546 bidi_cache_last_idx = idx; 546 bidi_cache_last_idx = idx;
@@ -828,7 +828,7 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p,
828 bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; 828 bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT;
829 bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */ 829 bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */
830 bidi_it->disp_pos = -1; /* invalid/unknown */ 830 bidi_it->disp_pos = -1; /* invalid/unknown */
831 bidi_it->disp_prop_p = 0; 831 bidi_it->disp_prop = 0;
832 /* We can only shrink the cache if we are at the bottom level of its 832 /* We can only shrink the cache if we are at the bottom level of its
833 "stack". */ 833 "stack". */
834 if (bidi_cache_start == 0) 834 if (bidi_cache_start == 0)
@@ -908,19 +908,22 @@ bidi_char_at_pos (EMACS_INT bytepos, const unsigned char *s, int unibyte)
908 908
909/* Fetch and return the character at BYTEPOS/CHARPOS. If that 909/* Fetch and return the character at BYTEPOS/CHARPOS. If that
910 character is covered by a display string, treat the entire run of 910 character is covered by a display string, treat the entire run of
911 covered characters as a single character u+FFFC, and return their 911 covered characters as a single character, either u+2029 or u+FFFC,
912 combined length in CH_LEN and NCHARS. DISP_POS specifies the 912 and return their combined length in CH_LEN and NCHARS. DISP_POS
913 character position of the next display string, or -1 if not yet 913 specifies the character position of the next display string, or -1
914 computed. DISP_PROP_P non-zero means that there's really a display 914 if not yet computed. DISP_PROP non-zero means that there's really
915 string at DISP_POS, as opposed to when we searched till DISP_POS 915 a display string at DISP_POS, as opposed to when we searched till
916 without findingone. When the next character is at or beyond that 916 DISP_POS without finding one. If DISP_PROP is 2, it means the
917 position, the function updates DISP_POS with the position of the 917 display spec is of the form `(space ...)', which is replaced with
918 next display string. STRING->s is the C string to iterate, or NULL 918 u+2029 to handle it as a paragraph separator. When the next
919 if iterating over a buffer or a Lisp string; in the latter case, 919 character is at or beyond that position, the function updates
920 STRING->lstring is the Lisp string. */ 920 DISP_POS with the position of the next display string. STRING->s
921 is the C string to iterate, or NULL if iterating over a buffer or a
922 Lisp string; in the latter case, STRING->lstring is the Lisp
923 string. */
921static inline int 924static inline int
922bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, 925bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
923 int *disp_prop_p, struct bidi_string_data *string, 926 int *disp_prop, struct bidi_string_data *string,
924 int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars) 927 int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars)
925{ 928{
926 int ch; 929 int ch;
@@ -934,7 +937,7 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
934 { 937 {
935 SET_TEXT_POS (pos, charpos, bytepos); 938 SET_TEXT_POS (pos, charpos, bytepos);
936 *disp_pos = compute_display_string_pos (&pos, string, frame_window_p, 939 *disp_pos = compute_display_string_pos (&pos, string, frame_window_p,
937 disp_prop_p); 940 disp_prop);
938 } 941 }
939 942
940 /* Fetch the character at BYTEPOS. */ 943 /* Fetch the character at BYTEPOS. */
@@ -944,9 +947,9 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
944 *ch_len = 1; 947 *ch_len = 1;
945 *nchars = 1; 948 *nchars = 1;
946 *disp_pos = endpos; 949 *disp_pos = endpos;
947 *disp_prop_p = 0; 950 *disp_prop = 0;
948 } 951 }
949 else if (charpos >= *disp_pos && *disp_prop_p) 952 else if (charpos >= *disp_pos && *disp_prop)
950 { 953 {
951 EMACS_INT disp_end_pos; 954 EMACS_INT disp_end_pos;
952 955
@@ -954,9 +957,23 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
954 property. Hopefully, it will never be needed. */ 957 property. Hopefully, it will never be needed. */
955 if (charpos > *disp_pos) 958 if (charpos > *disp_pos)
956 abort (); 959 abort ();
957 /* Return the Unicode Object Replacement Character to represent 960 /* Text covered by `display' properties and overlays with
958 the entire run of characters covered by the display string. */ 961 display properties or display strings is handled as a single
959 ch = 0xFFFC; 962 character that represents the entire run of characters
963 covered by the display property. */
964 if (*disp_prop == 2)
965 {
966 /* `(space ...)' display specs are handled as paragraph
967 separators for the purposes of the reordering; see UAX#9
968 section 3 and clause HL1 in section 4.3 there. */
969 ch = 0x2029;
970 }
971 else
972 {
973 /* All other display specs are handled as the Unicode Object
974 Replacement Character. */
975 ch = 0xFFFC;
976 }
960 disp_end_pos = compute_display_string_end (*disp_pos, string); 977 disp_end_pos = compute_display_string_end (*disp_pos, string);
961 *nchars = disp_end_pos - *disp_pos; 978 *nchars = disp_end_pos - *disp_pos;
962 if (*nchars <= 0) 979 if (*nchars <= 0)
@@ -1014,11 +1031,11 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
1014 /* If we just entered a run of characters covered by a display 1031 /* If we just entered a run of characters covered by a display
1015 string, compute the position of the next display string. */ 1032 string, compute the position of the next display string. */
1016 if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos 1033 if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos
1017 && *disp_prop_p) 1034 && *disp_prop)
1018 { 1035 {
1019 SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len); 1036 SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len);
1020 *disp_pos = compute_display_string_pos (&pos, string, frame_window_p, 1037 *disp_pos = compute_display_string_pos (&pos, string, frame_window_p,
1021 disp_prop_p); 1038 disp_prop);
1022 } 1039 }
1023 1040
1024 return ch; 1041 return ch;
@@ -1126,7 +1143,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
1126 int ch; 1143 int ch;
1127 EMACS_INT ch_len, nchars; 1144 EMACS_INT ch_len, nchars;
1128 EMACS_INT pos, disp_pos = -1; 1145 EMACS_INT pos, disp_pos = -1;
1129 int disp_prop_p = 0; 1146 int disp_prop = 0;
1130 bidi_type_t type; 1147 bidi_type_t type;
1131 const unsigned char *s; 1148 const unsigned char *s;
1132 1149
@@ -1174,7 +1191,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
1174 bytepos = pstartbyte; 1191 bytepos = pstartbyte;
1175 if (!string_p) 1192 if (!string_p)
1176 pos = BYTE_TO_CHAR (bytepos); 1193 pos = BYTE_TO_CHAR (bytepos);
1177 ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop_p, 1194 ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop,
1178 &bidi_it->string, 1195 &bidi_it->string,
1179 bidi_it->frame_window_p, &ch_len, &nchars); 1196 bidi_it->frame_window_p, &ch_len, &nchars);
1180 type = bidi_get_type (ch, NEUTRAL_DIR); 1197 type = bidi_get_type (ch, NEUTRAL_DIR);
@@ -1199,7 +1216,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
1199 break; 1216 break;
1200 /* Fetch next character and advance to get past it. */ 1217 /* Fetch next character and advance to get past it. */
1201 ch = bidi_fetch_char (bytepos, pos, &disp_pos, 1218 ch = bidi_fetch_char (bytepos, pos, &disp_pos,
1202 &disp_prop_p, &bidi_it->string, 1219 &disp_prop, &bidi_it->string,
1203 bidi_it->frame_window_p, &ch_len, &nchars); 1220 bidi_it->frame_window_p, &ch_len, &nchars);
1204 pos += nchars; 1221 pos += nchars;
1205 bytepos += ch_len; 1222 bytepos += ch_len;
@@ -1336,7 +1353,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
1336 bidi_it->ch_len = 1; 1353 bidi_it->ch_len = 1;
1337 bidi_it->nchars = 1; 1354 bidi_it->nchars = 1;
1338 bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV); 1355 bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV);
1339 bidi_it->disp_prop_p = 0; 1356 bidi_it->disp_prop = 0;
1340 } 1357 }
1341 else 1358 else
1342 { 1359 {
@@ -1344,7 +1361,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
1344 display string, treat the entire run of covered characters as 1361 display string, treat the entire run of covered characters as
1345 a single character u+FFFC. */ 1362 a single character u+FFFC. */
1346 curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, 1363 curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos,
1347 &bidi_it->disp_pos, &bidi_it->disp_prop_p, 1364 &bidi_it->disp_pos, &bidi_it->disp_prop,
1348 &bidi_it->string, bidi_it->frame_window_p, 1365 &bidi_it->string, bidi_it->frame_window_p,
1349 &bidi_it->ch_len, &bidi_it->nchars); 1366 &bidi_it->ch_len, &bidi_it->nchars);
1350 } 1367 }
@@ -2079,7 +2096,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
2079 struct bidi_string_data bs = bidi_it->string; 2096 struct bidi_string_data bs = bidi_it->string;
2080 bidi_type_t chtype; 2097 bidi_type_t chtype;
2081 int fwp = bidi_it->frame_window_p; 2098 int fwp = bidi_it->frame_window_p;
2082 int dpp = bidi_it->disp_prop_p; 2099 int dpp = bidi_it->disp_prop;
2083 2100
2084 if (bidi_it->nchars <= 0) 2101 if (bidi_it->nchars <= 0)
2085 abort (); 2102 abort ();
diff --git a/src/dispextern.h b/src/dispextern.h
index 084a3f9e07f..f5d20250fa7 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1860,8 +1860,9 @@ struct bidi_it {
1860 bidi_dir_t sor; /* direction of start-of-run in effect */ 1860 bidi_dir_t sor; /* direction of start-of-run in effect */
1861 int scan_dir; /* direction of text scan, 1: forw, -1: back */ 1861 int scan_dir; /* direction of text scan, 1: forw, -1: back */
1862 EMACS_INT disp_pos; /* position of display string after ch */ 1862 EMACS_INT disp_pos; /* position of display string after ch */
1863 int disp_prop_p; /* if non-zero, there really is a 1863 int disp_prop; /* if non-zero, there really is a
1864 `display' property/string at disp_pos */ 1864 `display' property/string at disp_pos;
1865 if 2, the property is a `space' spec */
1865 int stack_idx; /* index of current data on the stack */ 1866 int stack_idx; /* index of current data on the stack */
1866 /* Note: Everything from here on is not copied/saved when the bidi 1867 /* Note: Everything from here on is not copied/saved when the bidi
1867 iterator state is saved, pushed, or popped. So only put here 1868 iterator state is saved, pushed, or popped. So only put here
diff --git a/src/xdisp.c b/src/xdisp.c
index 4ed08e72e19..5cbc7747f2f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3146,11 +3146,15 @@ next_overlay_change (EMACS_INT pos)
3146 text property whose value is a string. STRING is data about the 3146 text property whose value is a string. STRING is data about the
3147 string to iterate; if STRING->lstring is nil, we are iterating a 3147 string to iterate; if STRING->lstring is nil, we are iterating a
3148 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window 3148 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3149 on a GUI frame. */ 3149 on a GUI frame. DISP_PROP is set to zero if we searched
3150 MAX_DISP_SCAN characters forward without finding any display
3151 strings, non-zero otherwise. It is set to 2 if the display string
3152 uses any kind of `(space ...)' spec that will produce a stretch of
3153 white space in the text area. */
3150EMACS_INT 3154EMACS_INT
3151compute_display_string_pos (struct text_pos *position, 3155compute_display_string_pos (struct text_pos *position,
3152 struct bidi_string_data *string, 3156 struct bidi_string_data *string,
3153 int frame_window_p, int *disp_prop_p) 3157 int frame_window_p, int *disp_prop)
3154{ 3158{
3155 /* OBJECT = nil means current buffer. */ 3159 /* OBJECT = nil means current buffer. */
3156 Lisp_Object object = 3160 Lisp_Object object =
@@ -3163,8 +3167,9 @@ compute_display_string_pos (struct text_pos *position,
3163 EMACS_INT lim = 3167 EMACS_INT lim =
3164 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob; 3168 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3165 struct text_pos tpos; 3169 struct text_pos tpos;
3170 int rv = 0;
3166 3171
3167 *disp_prop_p = 1; 3172 *disp_prop = 1;
3168 3173
3169 if (charpos >= eob 3174 if (charpos >= eob
3170 /* We don't support display properties whose values are strings 3175 /* We don't support display properties whose values are strings
@@ -3173,7 +3178,7 @@ compute_display_string_pos (struct text_pos *position,
3173 /* C strings cannot have display properties. */ 3178 /* C strings cannot have display properties. */
3174 || (string->s && !STRINGP (object))) 3179 || (string->s && !STRINGP (object)))
3175 { 3180 {
3176 *disp_prop_p = 0; 3181 *disp_prop = 0;
3177 return eob; 3182 return eob;
3178 } 3183 }
3179 3184
@@ -3190,9 +3195,11 @@ compute_display_string_pos (struct text_pos *position,
3190 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay, 3195 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3191 object), 3196 object),
3192 spec)) 3197 spec))
3193 && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, 3198 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3194 frame_window_p)) 3199 frame_window_p)))
3195 { 3200 {
3201 if (rv == 2)
3202 *disp_prop = 2;
3196 return charpos; 3203 return charpos;
3197 } 3204 }
3198 3205
@@ -3204,7 +3211,7 @@ compute_display_string_pos (struct text_pos *position,
3204 CHARPOS (tpos) = XFASTINT (pos); 3211 CHARPOS (tpos) = XFASTINT (pos);
3205 if (CHARPOS (tpos) >= lim) 3212 if (CHARPOS (tpos) >= lim)
3206 { 3213 {
3207 *disp_prop_p = 0; 3214 *disp_prop = 0;
3208 break; 3215 break;
3209 } 3216 }
3210 if (STRINGP (object)) 3217 if (STRINGP (object))
@@ -3215,8 +3222,10 @@ compute_display_string_pos (struct text_pos *position,
3215 if (!STRINGP (object)) 3222 if (!STRINGP (object))
3216 bufpos = CHARPOS (tpos); 3223 bufpos = CHARPOS (tpos);
3217 } while (NILP (spec) 3224 } while (NILP (spec)
3218 || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, 3225 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3219 frame_window_p)); 3226 bufpos, frame_window_p)));
3227 if (rv == 2)
3228 *disp_prop = 2;
3220 3229
3221 return CHARPOS (tpos); 3230 return CHARPOS (tpos);
3222} 3231}
@@ -4078,7 +4087,9 @@ handle_display_prop (struct it *it)
4078/* Subroutine of handle_display_prop. Returns non-zero if the display 4087/* Subroutine of handle_display_prop. Returns non-zero if the display
4079 specification in SPEC is a replacing specification, i.e. it would 4088 specification in SPEC is a replacing specification, i.e. it would
4080 replace the text covered by `display' property with something else, 4089 replace the text covered by `display' property with something else,
4081 such as an image or a display string. 4090 such as an image or a display string. If SPEC includes any kind or
4091 `(space ...) specification, the value is 2; this is used by
4092 compute_display_string_pos, which see.
4082 4093
4083 See handle_single_display_spec for documentation of arguments. 4094 See handle_single_display_spec for documentation of arguments.
4084 frame_window_p is non-zero if the window being redisplayed is on a 4095 frame_window_p is non-zero if the window being redisplayed is on a
@@ -4095,6 +4106,7 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4095 EMACS_INT bufpos, int frame_window_p) 4106 EMACS_INT bufpos, int frame_window_p)
4096{ 4107{
4097 int replacing_p = 0; 4108 int replacing_p = 0;
4109 int rv;
4098 4110
4099 if (CONSP (spec) 4111 if (CONSP (spec)
4100 /* Simple specerties. */ 4112 /* Simple specerties. */
@@ -4113,11 +4125,11 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4113 { 4125 {
4114 for (; CONSP (spec); spec = XCDR (spec)) 4126 for (; CONSP (spec); spec = XCDR (spec))
4115 { 4127 {
4116 if (handle_single_display_spec (it, XCAR (spec), object, overlay, 4128 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4117 position, bufpos, replacing_p, 4129 overlay, position, bufpos,
4118 frame_window_p)) 4130 replacing_p, frame_window_p)))
4119 { 4131 {
4120 replacing_p = 1; 4132 replacing_p = rv;
4121 /* If some text in a string is replaced, `position' no 4133 /* If some text in a string is replaced, `position' no
4122 longer points to the position of `object'. */ 4134 longer points to the position of `object'. */
4123 if (!it || STRINGP (object)) 4135 if (!it || STRINGP (object))
@@ -4129,11 +4141,11 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4129 { 4141 {
4130 int i; 4142 int i;
4131 for (i = 0; i < ASIZE (spec); ++i) 4143 for (i = 0; i < ASIZE (spec); ++i)
4132 if (handle_single_display_spec (it, AREF (spec, i), object, overlay, 4144 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4133 position, bufpos, replacing_p, 4145 overlay, position, bufpos,
4134 frame_window_p)) 4146 replacing_p, frame_window_p)))
4135 { 4147 {
4136 replacing_p = 1; 4148 replacing_p = rv;
4137 /* If some text in a string is replaced, `position' no 4149 /* If some text in a string is replaced, `position' no
4138 longer points to the position of `object'. */ 4150 longer points to the position of `object'. */
4139 if (!it || STRINGP (object)) 4151 if (!it || STRINGP (object))
@@ -4142,9 +4154,10 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4142 } 4154 }
4143 else 4155 else
4144 { 4156 {
4145 if (handle_single_display_spec (it, spec, object, overlay, 4157 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4146 position, bufpos, 0, frame_window_p)) 4158 position, bufpos, 0,
4147 replacing_p = 1; 4159 frame_window_p)))
4160 replacing_p = rv;
4148 } 4161 }
4149 4162
4150 return replacing_p; 4163 return replacing_p;
@@ -4520,8 +4533,17 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4520 4533
4521 if (valid_p && !display_replaced_p) 4534 if (valid_p && !display_replaced_p)
4522 { 4535 {
4536 int retval = 1;
4537
4523 if (!it) 4538 if (!it)
4524 return 1; 4539 {
4540 /* Callers need to know whether the display spec is any kind
4541 of `(space ...)' spec that is about to affect text-area
4542 display. */
4543 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
4544 retval = 2;
4545 return retval;
4546 }
4525 4547
4526 /* Save current settings of IT so that we can restore them 4548 /* Save current settings of IT so that we can restore them
4527 when we are finished with the glyph property value. */ 4549 when we are finished with the glyph property value. */
@@ -4579,6 +4601,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4579 it->method = GET_FROM_STRETCH; 4601 it->method = GET_FROM_STRETCH;
4580 it->object = value; 4602 it->object = value;
4581 *position = it->position = start_pos; 4603 *position = it->position = start_pos;
4604 retval = 1 + (it->area == TEXT_AREA);
4582 } 4605 }
4583#ifdef HAVE_WINDOW_SYSTEM 4606#ifdef HAVE_WINDOW_SYSTEM
4584 else 4607 else
@@ -4596,7 +4619,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4596 } 4619 }
4597#endif /* HAVE_WINDOW_SYSTEM */ 4620#endif /* HAVE_WINDOW_SYSTEM */
4598 4621
4599 return 1; 4622 return retval;
4600 } 4623 }
4601 4624
4602 /* Invalid property or property not supported. Restore 4625 /* Invalid property or property not supported. Restore
@@ -5557,7 +5580,7 @@ forward_to_next_line_start (struct it *it, int *skipped_p,
5557 if (it->bidi_it.disp_pos < limit) 5580 if (it->bidi_it.disp_pos < limit)
5558 { 5581 {
5559 it->bidi_it.disp_pos = limit; 5582 it->bidi_it.disp_pos = limit;
5560 it->bidi_it.disp_prop_p = 0; 5583 it->bidi_it.disp_prop = 0;
5561 } 5584 }
5562 do { 5585 do {
5563 bprev = it->bidi_it; 5586 bprev = it->bidi_it;