aboutsummaryrefslogtreecommitdiffstats
path: root/src/bidi.c
diff options
context:
space:
mode:
authorEli Zaretskii2011-08-25 13:45:33 +0300
committerEli Zaretskii2011-08-25 13:45:33 +0300
commit0c95fcf739dbfbae70f4e4700fdafedb4497e8df (patch)
treef27c148c083aa9a6d290053b26ac8e45bfdcb07a /src/bidi.c
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.
Diffstat (limited to 'src/bidi.c')
-rw-r--r--src/bidi.c71
1 files changed, 44 insertions, 27 deletions
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 ();