Mercurial > emacs
diff src/xdisp.c @ 107604:9e8415b885ee
Retrospective commit from 2009-12-12.
Begin working on faces support. First version of handle_stop_backwards.
Rearrange struct bidi_it for more efficient push/pop ops.
dispextern.h (struct it): New members prev_stop and
base_level_stop.
xdisp.c (handle_stop_backwards): New function.
(next_element_from_buffer): Handle the situation where we
overstepped stop_charpos due to non-linearity of the bidi
iteration. Likewise for when we back up beyond the previous
stop_charpos.
(reseat_1, pop_it, push_it): Set prev_stop and base_level_stop.
dispextern.h (BIDI_AT_BASE_LEVEL): New macro.
bidi.c (bidi_copy_it): Fix compiler warning due to cast of a
pointer to `int'. Don't preserve the first_elt member, as it is
no longer copied, because its position in the structure was
changed, see below.
dispextern.h (struct bidi_it): Move first_elt, new_paragraph,
separator_limit, and paragraph_dir to after bidi_stack. Add a
note that anything beyond the level stack is not preserved when
the bidi iterator state is copied/saved.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Fri, 01 Jan 2010 09:46:25 -0500 |
parents | 0e2486128193 |
children | 297c59e52ecf |
line wrap: on
line diff
--- a/src/xdisp.c Fri Jan 01 07:01:23 2010 -0500 +++ b/src/xdisp.c Fri Jan 01 09:46:25 2010 -0500 @@ -2659,7 +2659,7 @@ /* Are multibyte characters enabled in current_buffer? */ it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters); - /* Do we need to reorded bidirectional text? */ + /* Do we need to reorder bidirectional text? */ it->bidi_p = !NILP (current_buffer->bidi_display_reordering); /* Non-zero if we should highlight the region. */ @@ -5143,6 +5143,8 @@ p = it->stack + it->sp; p->stop_charpos = it->stop_charpos; + p->prev_stop = it->prev_stop; + p->base_level_stop = it->base_level_stop; p->cmp_it = it->cmp_it; xassert (it->face_id >= 0); p->face_id = it->face_id; @@ -5193,6 +5195,8 @@ --it->sp; p = it->stack + it->sp; it->stop_charpos = p->stop_charpos; + it->prev_stop = p->prev_stop; + it->base_level_stop = p->base_level_stop; it->cmp_it = p->cmp_it; it->face_id = p->face_id; it->current = p->current; @@ -5569,7 +5573,10 @@ it->bidi_it.first_elt = 1; if (set_stop_p) - it->stop_charpos = CHARPOS (pos); + { + it->stop_charpos = CHARPOS (pos); + it->base_level_stop = CHARPOS (pos); + } } @@ -5673,7 +5680,7 @@ /*********************************************************************** Iteration - ***********************************************************************/ +***********************************************************************/ /* Map enum it_method value to corresponding next_element_from_* function. */ @@ -5746,7 +5753,7 @@ Lisp_Object dv; struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } - nbsp_or_shy = char_is_other; + nbsp_or_shy = char_is_other; int decoded = it->c; if (it->dp @@ -5964,12 +5971,12 @@ happen actually, but due to bugs it may happen. Let's print the char as is, there's not much meaningful we can do with it. */ - str[0] = it->c; - str[1] = it->c >> 8; - str[2] = it->c >> 16; - str[3] = it->c >> 24; - len = 4; - } + str[0] = it->c; + str[1] = it->c >> 8; + str[2] = it->c >> 16; + str[3] = it->c >> 24; + len = 4; + } for (i = 0; i < len; i++) { @@ -6306,7 +6313,7 @@ it->face_id = it->saved_face_id; /* KFS: This code used to check ip->dpvec[0] instead of the current element. - That seemed totally bogus - so I changed it... */ + That seemed totally bogus - so I changed it... */ gc = it->dpvec[it->current.dpvec_index]; if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc)) @@ -6541,6 +6548,36 @@ return 1; } +/* Scan forward from CHARPOS in the current buffer, until we find a + stop position > current IT's position, handling all the stop + positions in between. + + This is called when we are reordering bidirectional text. The + caller should save and restore IT and in particular the bidi_p + flag, because this function modifies them. */ + +static void +handle_stop_backwards (it, charpos) + struct it *it; + EMACS_INT charpos; +{ + struct text_pos pos1; + EMACS_INT where_we_are = IT_CHARPOS (*it); + + /* Scan in strict logical order. */ + it->bidi_p = 0; + do + { + it->prev_stop = charpos; + SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos)); + reseat_1 (it, pos1, 0); + handle_stop (it); + /* We must advance forward, right? */ + if (it->stop_charpos <= it->prev_stop) + abort (); + } + while (it->stop_charpos <= where_we_are); +} /* Load IT with the next display element from current_buffer. Value is zero if end of buffer reached. IT->stop_charpos is the next @@ -6631,12 +6668,45 @@ success_p = 0; } } + else if (it->bidi_p && !BIDI_AT_BASE_LEVEL (it->bidi_it)) + { + /* With bidi non-linear iteration, we could find ourselves + far beyond the last computed stop_charpos, with several + other stop positions in between that we missed. Scan + them all now, in buffer's logical order. */ + struct it save_it = *it; + + handle_stop_backwards (it, it->stop_charpos); + save_it.stop_charpos = it->stop_charpos; + save_it.prev_stop = it->prev_stop; + *it = save_it; + return GET_NEXT_DISPLAY_ELEMENT (it); + } else { handle_stop (it); + /* We are at base paragraph embedding level, so take note of + the last stop_pos seen at this level. */ + it->base_level_stop = it->stop_charpos; return GET_NEXT_DISPLAY_ELEMENT (it); } } + else if (it->bidi_p && IT_CHARPOS (*it) < it->prev_stop) + { + struct it save_it = *it; + + if (it->base_level_stop <= 0) + abort (); + if (IT_CHARPOS (*it) < it->base_level_stop) + abort (); + if (BIDI_AT_BASE_LEVEL (it->bidi_it)) + abort (); + handle_stop_backwards (it, it->base_level_stop); + save_it.stop_charpos = it->stop_charpos; + save_it.prev_stop = it->prev_stop; + *it = save_it; + return GET_NEXT_DISPLAY_ELEMENT (it); + } else { /* No face changes, overlays etc. in sight, so just return a