summaryrefslogtreecommitdiff
path: root/src/bidi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bidi.c')
-rw-r--r--src/bidi.c44
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