diff options
Diffstat (limited to 'src/bidi.c')
-rw-r--r-- | src/bidi.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/src/bidi.c b/src/bidi.c index 697ebb92856..ae5143b37e0 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -792,6 +792,7 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p, bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */ bidi_it->disp_pos = -1; /* invalid/unknown */ + bidi_it->disp_prop_p = 0; /* We can only shrink the cache if we are at the bottom level of its "stack". */ if (bidi_cache_start == 0) @@ -874,14 +875,16 @@ bidi_char_at_pos (EMACS_INT bytepos, const unsigned char *s, int unibyte) covered characters as a single character u+FFFC, and return their combined length in CH_LEN and NCHARS. DISP_POS specifies the character position of the next display string, or -1 if not yet - computed. When the next character is at or beyond that position, - the function updates DISP_POS with the position of the next display - string. STRING->s is the C string to iterate, or NULL if iterating - over a buffer or a Lisp string; in the latter case, STRING->lstring - is the Lisp string. */ + computed. DISP_PROP_P non-zero means that there's really a display + string at DISP_POS, as opposed to when we searched till DISP_POS + without findingone. When the next character is at or beyond that + position, the function updates DISP_POS with the position of the + next display string. STRING->s is the C string to iterate, or NULL + if iterating over a buffer or a Lisp string; in the latter case, + STRING->lstring is the Lisp string. */ static inline int bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, - struct bidi_string_data *string, + int *disp_prop_p, struct bidi_string_data *string, int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars) { int ch; @@ -894,7 +897,8 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, if (charpos < endpos && charpos > *disp_pos) { SET_TEXT_POS (pos, charpos, bytepos); - *disp_pos = compute_display_string_pos (&pos, string, frame_window_p); + *disp_pos = compute_display_string_pos (&pos, string, frame_window_p, + disp_prop_p); } /* Fetch the character at BYTEPOS. */ @@ -904,8 +908,9 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, *ch_len = 1; *nchars = 1; *disp_pos = endpos; + *disp_prop_p = 0; } - else if (charpos >= *disp_pos) + else if (charpos >= *disp_pos && *disp_prop_p) { EMACS_INT disp_end_pos; @@ -972,10 +977,12 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, /* If we just entered a run of characters covered by a display string, compute the position of the next display string. */ - if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos) + if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos + && *disp_prop_p) { SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len); - *disp_pos = compute_display_string_pos (&pos, string, frame_window_p); + *disp_pos = compute_display_string_pos (&pos, string, frame_window_p, + disp_prop_p); } return ch; @@ -1083,6 +1090,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) int ch; EMACS_INT ch_len, nchars; EMACS_INT pos, disp_pos = -1; + int disp_prop_p = 0; bidi_type_t type; const unsigned char *s; @@ -1130,7 +1138,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) bytepos = pstartbyte; if (!string_p) pos = BYTE_TO_CHAR (bytepos); - ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string, + ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop_p, + &bidi_it->string, bidi_it->frame_window_p, &ch_len, &nchars); type = bidi_get_type (ch, NEUTRAL_DIR); @@ -1157,7 +1166,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) && bidi_at_paragraph_end (pos, bytepos) >= -1) break; /* Fetch next character and advance to get past it. */ - ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string, + ch = bidi_fetch_char (bytepos, pos, &disp_pos, + &disp_prop_p, &bidi_it->string, bidi_it->frame_window_p, &ch_len, &nchars); pos += nchars; bytepos += ch_len; @@ -1290,6 +1300,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) bidi_it->ch_len = 1; bidi_it->nchars = 1; bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV); + bidi_it->disp_prop_p = 0; } else { @@ -1297,8 +1308,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) display string, treat the entire run of covered characters as a single character u+FFFC. */ curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, - &bidi_it->disp_pos, &bidi_it->string, - bidi_it->frame_window_p, + &bidi_it->disp_pos, &bidi_it->disp_prop_p, + &bidi_it->string, bidi_it->frame_window_p, &bidi_it->ch_len, &bidi_it->nchars); } bidi_it->ch = curchar; @@ -2032,12 +2043,13 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) struct bidi_string_data bs = bidi_it->string; bidi_type_t chtype; int fwp = bidi_it->frame_window_p; + int dpp = bidi_it->disp_prop_p; if (bidi_it->nchars <= 0) abort (); do { - ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &bs, fwp, - &clen, &nc); + ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &dpp, &bs, + fwp, &clen, &nc); if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */) chtype = NEUTRAL_B; else |