aboutsummaryrefslogtreecommitdiffstats
path: root/src/bidi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bidi.c')
-rw-r--r--src/bidi.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/src/bidi.c b/src/bidi.c
index 6f3d749ef22..c6bea62f67b 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -1,6 +1,6 @@
1/* Low-level bidirectional buffer/string-scanning functions for GNU Emacs. 1/* Low-level bidirectional buffer/string-scanning functions for GNU Emacs.
2 Copyright (C) 2000-2001, 2004-2005, 2009-2012 2 Copyright (C) 2000-2001, 2004-2005, 2009-2013 Free Software
3 Free Software Foundation, Inc. 3 Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -910,7 +910,7 @@ bidi_char_at_pos (ptrdiff_t bytepos, const unsigned char *s, bool unibyte)
910 return STRING_CHAR (s); 910 return STRING_CHAR (s);
911} 911}
912 912
913/* Fetch and return the character at BYTEPOS/CHARPOS. If that 913/* Fetch and return the character at CHARPOS/BYTEPOS. If that
914 character is covered by a display string, treat the entire run of 914 character is covered by a display string, treat the entire run of
915 covered characters as a single character, either u+2029 or u+FFFC, 915 covered characters as a single character, either u+2029 or u+FFFC,
916 and return their combined length in CH_LEN and NCHARS. DISP_POS 916 and return their combined length in CH_LEN and NCHARS. DISP_POS
@@ -925,7 +925,7 @@ bidi_char_at_pos (ptrdiff_t bytepos, const unsigned char *s, bool unibyte)
925 string to iterate, or NULL if iterating over a buffer or a Lisp 925 string to iterate, or NULL if iterating over a buffer or a Lisp
926 string; in the latter case, STRING->lstring is the Lisp string. */ 926 string; in the latter case, STRING->lstring is the Lisp string. */
927static int 927static int
928bidi_fetch_char (ptrdiff_t bytepos, ptrdiff_t charpos, ptrdiff_t *disp_pos, 928bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
929 int *disp_prop, struct bidi_string_data *string, 929 int *disp_prop, struct bidi_string_data *string,
930 bool frame_window_p, ptrdiff_t *ch_len, ptrdiff_t *nchars) 930 bool frame_window_p, ptrdiff_t *ch_len, ptrdiff_t *nchars)
931{ 931{
@@ -1109,8 +1109,8 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
1109 display string? And what if a display string covering some 1109 display string? And what if a display string covering some
1110 of the text over which we scan back includes 1110 of the text over which we scan back includes
1111 paragraph_start_re? */ 1111 paragraph_start_re? */
1112 pos = find_next_newline_no_quit (pos - 1, -1); 1112 DEC_BOTH (pos, pos_byte);
1113 pos_byte = CHAR_TO_BYTE (pos); 1113 pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
1114 } 1114 }
1115 if (n >= MAX_PARAGRAPH_SEARCH) 1115 if (n >= MAX_PARAGRAPH_SEARCH)
1116 pos_byte = BEGV_BYTE; 1116 pos_byte = BEGV_BYTE;
@@ -1223,7 +1223,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
1223 bytepos = pstartbyte; 1223 bytepos = pstartbyte;
1224 if (!string_p) 1224 if (!string_p)
1225 pos = BYTE_TO_CHAR (bytepos); 1225 pos = BYTE_TO_CHAR (bytepos);
1226 ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop, 1226 ch = bidi_fetch_char (pos, bytepos, &disp_pos, &disp_prop,
1227 &bidi_it->string, 1227 &bidi_it->string,
1228 bidi_it->frame_window_p, &ch_len, &nchars); 1228 bidi_it->frame_window_p, &ch_len, &nchars);
1229 type = bidi_get_type (ch, NEUTRAL_DIR); 1229 type = bidi_get_type (ch, NEUTRAL_DIR);
@@ -1251,7 +1251,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
1251 && bidi_at_paragraph_end (pos, bytepos) >= -1) 1251 && bidi_at_paragraph_end (pos, bytepos) >= -1)
1252 break; 1252 break;
1253 /* Fetch next character and advance to get past it. */ 1253 /* Fetch next character and advance to get past it. */
1254 ch = bidi_fetch_char (bytepos, pos, &disp_pos, 1254 ch = bidi_fetch_char (pos, bytepos, &disp_pos,
1255 &disp_prop, &bidi_it->string, 1255 &disp_prop, &bidi_it->string,
1256 bidi_it->frame_window_p, &ch_len, &nchars); 1256 bidi_it->frame_window_p, &ch_len, &nchars);
1257 pos += nchars; 1257 pos += nchars;
@@ -1282,8 +1282,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
1282 /* FXIME: What if p is covered by a display 1282 /* FXIME: What if p is covered by a display
1283 string? See also a FIXME inside 1283 string? See also a FIXME inside
1284 bidi_find_paragraph_start. */ 1284 bidi_find_paragraph_start. */
1285 p--; 1285 DEC_BOTH (p, pbyte);
1286 pbyte = CHAR_TO_BYTE (p);
1287 prevpbyte = bidi_find_paragraph_start (p, pbyte); 1286 prevpbyte = bidi_find_paragraph_start (p, pbyte);
1288 } 1287 }
1289 pstartbyte = prevpbyte; 1288 pstartbyte = prevpbyte;
@@ -1356,15 +1355,19 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
1356 : bidi_it->string.s); 1355 : bidi_it->string.s);
1357 1356
1358 if (bidi_it->charpos < 0) 1357 if (bidi_it->charpos < 0)
1359 bidi_it->charpos = 0; 1358 bidi_it->charpos = bidi_it->bytepos = 0;
1360 bidi_it->bytepos = bidi_count_bytes (p, 0, 0, bidi_it->charpos, 1359 eassert (bidi_it->bytepos == bidi_count_bytes (p, 0, 0,
1361 bidi_it->string.unibyte); 1360 bidi_it->charpos,
1361 bidi_it->string.unibyte));
1362 } 1362 }
1363 else 1363 else
1364 { 1364 {
1365 if (bidi_it->charpos < BEGV) 1365 if (bidi_it->charpos < BEGV)
1366 bidi_it->charpos = BEGV; 1366 {
1367 bidi_it->bytepos = CHAR_TO_BYTE (bidi_it->charpos); 1367 bidi_it->charpos = BEGV;
1368 bidi_it->bytepos = BEGV_BYTE;
1369 }
1370 eassert (bidi_it->bytepos == CHAR_TO_BYTE (bidi_it->charpos));
1368 } 1371 }
1369 } 1372 }
1370 /* Don't move at end of buffer/string. */ 1373 /* Don't move at end of buffer/string. */
@@ -1397,7 +1400,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
1397 /* Fetch the character at BYTEPOS. If it is covered by a 1400 /* Fetch the character at BYTEPOS. If it is covered by a
1398 display string, treat the entire run of covered characters as 1401 display string, treat the entire run of covered characters as
1399 a single character u+FFFC. */ 1402 a single character u+FFFC. */
1400 curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, 1403 curchar = bidi_fetch_char (bidi_it->charpos, bidi_it->bytepos,
1401 &bidi_it->disp_pos, &bidi_it->disp_prop, 1404 &bidi_it->disp_pos, &bidi_it->disp_prop,
1402 &bidi_it->string, bidi_it->frame_window_p, 1405 &bidi_it->string, bidi_it->frame_window_p,
1403 &bidi_it->ch_len, &bidi_it->nchars); 1406 &bidi_it->ch_len, &bidi_it->nchars);
@@ -1973,6 +1976,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
1973 next_type = STRONG_R; 1976 next_type = STRONG_R;
1974 break; 1977 break;
1975 case WEAK_BN: 1978 case WEAK_BN:
1979 case NEUTRAL_ON: /* W6/Retaining */
1976 if (!bidi_explicit_dir_char (bidi_it->ch)) 1980 if (!bidi_explicit_dir_char (bidi_it->ch))
1977 emacs_abort (); /* can't happen: BNs are skipped */ 1981 emacs_abort (); /* can't happen: BNs are skipped */
1978 /* FALLTHROUGH */ 1982 /* FALLTHROUGH */
@@ -2189,7 +2193,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
2189 if (bidi_it->nchars <= 0) 2193 if (bidi_it->nchars <= 0)
2190 emacs_abort (); 2194 emacs_abort ();
2191 do { 2195 do {
2192 ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &dpp, &bs, 2196 ch = bidi_fetch_char (cpos += nc, bpos += clen, &disp_pos, &dpp, &bs,
2193 fwp, &clen, &nc); 2197 fwp, &clen, &nc);
2194 if (ch == '\n' || ch == BIDI_EOB) 2198 if (ch == '\n' || ch == BIDI_EOB)
2195 chtype = NEUTRAL_B; 2199 chtype = NEUTRAL_B;
@@ -2391,6 +2395,10 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
2391 next_level = bidi_peek_at_next_level (bidi_it); 2395 next_level = bidi_peek_at_next_level (bidi_it);
2392 while (next_level != expected_next_level) 2396 while (next_level != expected_next_level)
2393 { 2397 {
2398 /* If next_level is -1, it means we have an unresolved level
2399 in the cache, which at this point should not happen. If
2400 it does, we will infloop. */
2401 eassert (next_level >= 0);
2394 expected_next_level += incr; 2402 expected_next_level += incr;
2395 level_to_search += incr; 2403 level_to_search += incr;
2396 bidi_find_other_level_edge (bidi_it, level_to_search, !ascending); 2404 bidi_find_other_level_edge (bidi_it, level_to_search, !ascending);