From 1ace72676cb6749c45c5dd6462457fc2cea2988c Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 18 Jun 2011 14:14:51 +0300 Subject: [PATCH] Refactor getting the first element into a separate function. src/xdisp.c (get_visually_first_element): New function, refactored from common parts of next_element_from_buffer, next_element_from_string, and next_element_from_c_string. --- src/ChangeLog | 3 + src/xdisp.c | 246 +++++++++++++++++++++----------------------------- 2 files changed, 108 insertions(+), 141 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 315ac040d41..ba829af4026 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -3,6 +3,9 @@ * xdisp.c (face_before_or_after_it_pos): Support bidi iteration. (next_element_from_c_string): Handle the case of the first string character that is not the first one in the visual order. + (get_visually_first_element): New function, refactored from common + parts of next_element_from_buffer, next_element_from_string, and + next_element_from_c_string. 2011-06-16 Eli Zaretskii diff --git a/src/xdisp.c b/src/xdisp.c index 998076b30bb..ea55cdcc3d2 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -6658,6 +6658,107 @@ next_element_from_display_vector (struct it *it) return 1; } +/* Get the first element of string/buffer in the visual order, after + being reseated to a new position in a string or a buffer. */ +static void +get_visually_first_element (struct it *it) +{ + int string_p = STRINGP (it->string) || it->s; + EMACS_INT eob = (string_p ? it->string_nchars : ZV); + EMACS_INT bob = (string_p ? 0 : BEGV); + + if (STRINGP (it->string)) + { + it->bidi_it.charpos = IT_STRING_CHARPOS (*it); + it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it); + } + else + { + it->bidi_it.charpos = IT_CHARPOS (*it); + it->bidi_it.bytepos = IT_BYTEPOS (*it); + } + + if (it->bidi_it.charpos == eob) + { + /* Nothing to do, but reset the FIRST_ELT flag, like + bidi_paragraph_init does, because we are not going to + call it. */ + it->bidi_it.first_elt = 0; + } + else if (it->bidi_it.charpos == bob + || (!string_p + /* FIXME: Should support all Unicode line separators. */ + && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' + || FETCH_CHAR (it->bidi_it.bytepos) == '\n'))) + { + /* If we are at the beginning of a line/string, we can produce + the next element right away. */ + bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); + bidi_move_to_visually_next (&it->bidi_it); + } + else + { + EMACS_INT orig_bytepos = it->bidi_it.bytepos; + + /* We need to prime the bidi iterator starting at the line's or + string's beginning, before we will be able to produce the + next element. */ + if (string_p) + it->bidi_it.charpos = it->bidi_it.bytepos = 0; + else + { + it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it), + -1); + it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos); + } + bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); + do + { + /* Now return to buffer/string position where we were asked + to get the next display element, and produce that. */ + bidi_move_to_visually_next (&it->bidi_it); + } + while (it->bidi_it.bytepos != orig_bytepos + && it->bidi_it.charpos < eob); + } + + /* Adjust IT's position information to where we ended up. */ + if (STRINGP (it->string)) + { + IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; + IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; + } + else + { + IT_CHARPOS (*it) = it->bidi_it.charpos; + IT_BYTEPOS (*it) = it->bidi_it.bytepos; + } + + if (STRINGP (it->string) || !it->s) + { + EMACS_INT stop, charpos, bytepos; + + if (STRINGP (it->string)) + { + xassert (!it->s); + stop = SCHARS (it->string); + if (stop > it->end_charpos) + stop = it->end_charpos; + charpos = IT_STRING_CHARPOS (*it); + bytepos = IT_STRING_BYTEPOS (*it); + } + else + { + stop = it->end_charpos; + charpos = IT_CHARPOS (*it); + bytepos = IT_BYTEPOS (*it); + } + if (it->bidi_it.scan_dir < 0) + stop = -1; + composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop, + it->string); + } +} /* Load IT with the next display element from Lisp string IT->string. IT->current.string_pos is the current position within the string. @@ -6680,56 +6781,8 @@ next_element_from_string (struct it *it) direction is not known. */ if (it->bidi_p && it->bidi_it.first_elt) { - it->bidi_it.charpos = CHARPOS (position); - it->bidi_it.bytepos = BYTEPOS (position); - if (it->bidi_it.charpos >= it->string_nchars) - { - /* Nothing to do, but reset the FIRST_ELT flag, like - bidi_paragraph_init does, because we are not going to - call it. */ - it->bidi_it.first_elt = 0; - } - else if (it->bidi_it.charpos <= 0) - { - /* If we are at the beginning of the string, we can produce - the next element right away. */ - bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); - bidi_move_to_visually_next (&it->bidi_it); - } - else - { - EMACS_INT orig_bytepos = BYTEPOS (position); - - /* We need to prime the bidi iterator starting at the string - beginning, before we will be able to produce the next - element. */ - it->bidi_it.charpos = it->bidi_it.bytepos = 0; - bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); - do - { - /* Now return to buffer position where we were asked to - get the next display element, and produce that. */ - bidi_move_to_visually_next (&it->bidi_it); - } - while (it->bidi_it.bytepos != orig_bytepos - && it->bidi_it.charpos < it->string_nchars); - } - - /* Adjust IT's position information to where we ended up. */ - IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; - IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; + get_visually_first_element (it); SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it)); - { - EMACS_INT stop = SCHARS (it->string); - - if (it->bidi_it.scan_dir < 0) - stop = -1; - else if (stop > it->end_charpos) - stop = it->end_charpos; - composition_compute_stop_pos (&it->cmp_it, IT_STRING_CHARPOS (*it), - IT_STRING_BYTEPOS (*it), stop, - it->string); - } } /* Time to check for invisible text? */ @@ -6894,46 +6947,7 @@ next_element_from_c_string (struct it *it) we were reseated to a new string, whose paragraph direction is not known. */ if (it->bidi_p && it->bidi_it.first_elt) - { - it->bidi_it.charpos = IT_CHARPOS (*it); - it->bidi_it.bytepos = IT_BYTEPOS (*it); - if (it->bidi_it.charpos >= it->string_nchars) - { - /* Nothing to do, but reset the FIRST_ELT flag, like - bidi_paragraph_init does, because we are not going to - call it. */ - it->bidi_it.first_elt = 0; - } - else if (it->bidi_it.charpos <= 0) - { - /* If we are at the beginning of the string, we can produce - the next element right away. */ - bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); - bidi_move_to_visually_next (&it->bidi_it); - } - else - { - EMACS_INT orig_bytepos = IT_BYTEPOS (*it); - - /* We need to prime the bidi iterator starting at the string - beginning, before we will be able to produce the next - element. */ - it->bidi_it.charpos = it->bidi_it.bytepos = 0; - bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); - do - { - /* Now return to buffer position where we were asked to - get the next display element, and produce that. */ - bidi_move_to_visually_next (&it->bidi_it); - } - while (it->bidi_it.bytepos != orig_bytepos - && it->bidi_it.charpos < it->string_nchars); - } - - /* Adjust IT's position information to where we ended up. */ - IT_CHARPOS (*it) = it->bidi_it.charpos; - IT_BYTEPOS (*it) = it->bidi_it.bytepos; - } + get_visually_first_element (it); /* IT's position can be greater than IT->string_nchars in case a field width or precision has been specified when the iterator was @@ -7069,6 +7083,7 @@ next_element_from_buffer (struct it *it) int success_p = 1; xassert (IT_CHARPOS (*it) >= BEGV); + xassert (NILP (it->string) && !it->s); xassert (!it->bidi_p || (it->bidi_it.string.lstring == Qnil && it->bidi_it.string.s == NULL)); @@ -7079,59 +7094,8 @@ next_element_from_buffer (struct it *it) a different paragraph. */ if (it->bidi_p && it->bidi_it.first_elt) { - it->bidi_it.charpos = IT_CHARPOS (*it); - it->bidi_it.bytepos = IT_BYTEPOS (*it); - if (it->bidi_it.bytepos == ZV_BYTE) - { - /* Nothing to do, but reset the FIRST_ELT flag, like - bidi_paragraph_init does, because we are not going to - call it. */ - it->bidi_it.first_elt = 0; - } - else if (it->bidi_it.bytepos == BEGV_BYTE - /* FIXME: Should support all Unicode line separators. */ - || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' - || FETCH_CHAR (it->bidi_it.bytepos) == '\n') - { - /* If we are at the beginning of a line, we can produce the - next element right away. */ - bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); - bidi_move_to_visually_next (&it->bidi_it); - } - else - { - EMACS_INT orig_bytepos = IT_BYTEPOS (*it); - - /* We need to prime the bidi iterator starting at the line's - beginning, before we will be able to produce the next - element. */ - IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1); - IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it)); - it->bidi_it.charpos = IT_CHARPOS (*it); - it->bidi_it.bytepos = IT_BYTEPOS (*it); - bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); - do - { - /* Now return to buffer position where we were asked to - get the next display element, and produce that. */ - bidi_move_to_visually_next (&it->bidi_it); - } - while (it->bidi_it.bytepos != orig_bytepos - && it->bidi_it.bytepos < ZV_BYTE); - } - - it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */ - /* Adjust IT's position information to where we ended up. */ - IT_CHARPOS (*it) = it->bidi_it.charpos; - IT_BYTEPOS (*it) = it->bidi_it.bytepos; + get_visually_first_element (it); SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it)); - { - EMACS_INT stop = it->end_charpos; - if (it->bidi_it.scan_dir < 0) - stop = -1; - composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), - IT_BYTEPOS (*it), stop, Qnil); - } } if (IT_CHARPOS (*it) >= it->stop_charpos) -- 2.39.5