From 9443b3c70494e010991a11b3be68e4777559df04 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 1 Jan 2010 10:04:53 -0500 Subject: [PATCH] Retrospective commit from 2009-12-26. Redesign handle_stop_backwards. Fix character mirroring for non-ASCII characters. xdisp.c (handle_stop_backwards): Call compute_stop_pos in the loop, instead of calling handle_stop. Call handle_stop only once, after the loop. (next_element_from_buffer): Don't call handle_stop_backwards if at stop position. If base_level_stop is zero, set it to 1. term.c (append_glyph): Fill resolved_level and bidi_type slots of struct glyph for unidirectional display. xdisp.c (set_cursor_from_row): Handle zero-width characters. bidi.c (bidi_mirror_char): More efficient code (suggested by Ehud Karni ). Don't even try to mirror non-ASCII characters. --- src/.gdbinit | 5 ++++- src/ChangeLog.bidi | 17 +++++++++++++++++ src/bidi.c | 7 ++----- src/term.c | 7 +++++++ src/xdisp.c | 48 +++++++++++++++++++++++++++++++----------------- 5 files changed, 61 insertions(+), 23 deletions(-) diff --git a/src/.gdbinit b/src/.gdbinit index 61e3da6c68c..a500f2532f5 100644 --- a/src/.gdbinit +++ b/src/.gdbinit @@ -448,6 +448,9 @@ Pretty print window structure w. end define pbiditype + if ($arg0 == 0) + printf "UNDEF" + end if ($arg0 == 1) printf "L" end @@ -466,7 +469,7 @@ define pbiditype if ($arg0 == 6) printf "B" end - if ($arg0 < 1 || $arg0 > 6) + if ($arg0 < 0 || $arg0 > 6) printf "%d??", $arg0 end end diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index b9fb7457cfd..7e11c6ec024 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi @@ -1,3 +1,20 @@ +2009-12-26 Eli Zaretskii + + * xdisp.c (handle_stop_backwards): Call compute_stop_pos in the + loop, instead of calling handle_stop. Call handle_stop only once, + after the loop. + (next_element_from_buffer): Don't call handle_stop_backwards if at + stop position. If base_level_stop is zero, set it to 1. + + * term.c (append_glyph): Fill resolved_level and bidi_type slots + of struct glyph for unidirectional display. + + * xdisp.c (set_cursor_from_row): Handle zero-width characters. + + * bidi.c (bidi_mirror_char): More efficient code (suggested by + Ehud Karni ). Don't even try to mirror + non-ASCII characters. + 2009-12-19 Eli Zaretskii * buffer.c (Fbuffer_swap_text): Swap the values of diff --git a/src/bidi.c b/src/bidi.c index d18629279d6..5abb4ca9f43 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -509,16 +509,13 @@ int bidi_mirror_char (int c) { static const char mirrored_pairs[] = "()<>[]{}"; - const char *p = strchr (mirrored_pairs, c); + const char *p = c > 0 && c < 128 ? strchr (mirrored_pairs, c) : NULL; if (p) { size_t i = p - mirrored_pairs; - if ((i & 1) == 0) - return mirrored_pairs[i + 1]; - else - return mirrored_pairs[i - 1]; + return mirrored_pairs [(i ^ 1)]; } return c; } diff --git a/src/term.c b/src/term.c index 7c9e05f36b2..51bf7a4aeb7 100644 --- a/src/term.c +++ b/src/term.c @@ -1579,8 +1579,15 @@ append_glyph (it) if (it->bidi_p) { glyph->resolved_level = it->bidi_it.resolved_level; + if ((it->bidi_it.type & 7) != it->bidi_it.type) + abort (); glyph->bidi_type = it->bidi_it.type; } + else + { + glyph->resolved_level = 0; + glyph->bidi_type = UNKNOWN_BT; + } ++it->glyph_row->used[it->area]; ++glyph; diff --git a/src/xdisp.c b/src/xdisp.c index ddd18d502a0..b18b0e04be2 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -6549,8 +6549,8 @@ next_element_from_stretch (it) } /* 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. + stop position > current IT's position. Then handle the stop + position before that. This is called when we are reordering bidirectional text. The caller should save and restore IT and in particular the bidi_p @@ -6563,6 +6563,7 @@ handle_stop_backwards (it, charpos) { struct text_pos pos1; EMACS_INT where_we_are = IT_CHARPOS (*it); + EMACS_INT next_stop; /* Scan in strict logical order. */ it->bidi_p = 0; @@ -6571,12 +6572,18 @@ handle_stop_backwards (it, charpos) it->prev_stop = charpos; SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos)); reseat_1 (it, pos1, 0); - handle_stop (it); + compute_stop_pos (it); /* We must advance forward, right? */ if (it->stop_charpos <= it->prev_stop) abort (); + charpos = it->stop_charpos; } - while (it->stop_charpos <= where_we_are); + while (charpos <= where_we_are); + + next_stop = it->stop_charpos; + it->stop_charpos = it->prev_stop; + handle_stop (it); + it->stop_charpos = next_stop; } /* Load IT with the next display element from current_buffer. Value @@ -6668,26 +6675,31 @@ next_element_from_buffer (it) success_p = 0; } } - else if (it->bidi_p && !BIDI_AT_BASE_LEVEL (it->bidi_it)) + else if (!(!it->bidi_p + || BIDI_AT_BASE_LEVEL (it->bidi_it) + || IT_CHARPOS (*it) == it->stop_charpos)) { /* 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. */ + them all now, in buffer's logical order, until we find + and handle the last stop_charpos that precedes our + current position. */ 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; + it->bidi_p = 1; + it->current = save_it.current; + it->position = save_it.position; return GET_NEXT_DISPLAY_ELEMENT (it); } else { + /* If we are at base paragraph embedding level, take note of + the last stop position seen at this level. */ + if (BIDI_AT_BASE_LEVEL (it->bidi_it)) + it->base_level_stop = it->stop_charpos; 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); } } @@ -6696,15 +6708,15 @@ next_element_from_buffer (it) struct it save_it = *it; if (it->base_level_stop <= 0) - abort (); + it->base_level_stop = 1; 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; + it->bidi_p = 1; + it->current = save_it.current; + it->position = save_it.position; return GET_NEXT_DISPLAY_ELEMENT (it); } else @@ -12771,7 +12783,9 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) glyph--; } } - else if (match_with_avoid_cursor) + else if (match_with_avoid_cursor + /* zero-width characters produce no glyphs */ + || eabs (glyph_after - glyph_before) == 1) { cursor = glyph_after; x = -1; -- 2.11.4.GIT