diff options
| author | Eli Zaretskii | 2011-06-18 14:14:51 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-06-18 14:14:51 +0300 |
| commit | 1ace72676cb6749c45c5dd6462457fc2cea2988c (patch) | |
| tree | b5108765156806efaccf8e5a523951361f480250 /src | |
| parent | 4d3a8bb4de2958ba1f5b004da0307b89df4068eb (diff) | |
| download | emacs-1ace72676cb6749c45c5dd6462457fc2cea2988c.tar.gz emacs-1ace72676cb6749c45c5dd6462457fc2cea2988c.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 3 | ||||
| -rw-r--r-- | 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 @@ | |||
| 3 | * xdisp.c (face_before_or_after_it_pos): Support bidi iteration. | 3 | * xdisp.c (face_before_or_after_it_pos): Support bidi iteration. |
| 4 | (next_element_from_c_string): Handle the case of the first string | 4 | (next_element_from_c_string): Handle the case of the first string |
| 5 | character that is not the first one in the visual order. | 5 | character that is not the first one in the visual order. |
| 6 | (get_visually_first_element): New function, refactored from common | ||
| 7 | parts of next_element_from_buffer, next_element_from_string, and | ||
| 8 | next_element_from_c_string. | ||
| 6 | 9 | ||
| 7 | 2011-06-16 Eli Zaretskii <eliz@gnu.org> | 10 | 2011-06-16 Eli Zaretskii <eliz@gnu.org> |
| 8 | 11 | ||
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) | |||
| 6658 | return 1; | 6658 | return 1; |
| 6659 | } | 6659 | } |
| 6660 | 6660 | ||
| 6661 | /* Get the first element of string/buffer in the visual order, after | ||
| 6662 | being reseated to a new position in a string or a buffer. */ | ||
| 6663 | static void | ||
| 6664 | get_visually_first_element (struct it *it) | ||
| 6665 | { | ||
| 6666 | int string_p = STRINGP (it->string) || it->s; | ||
| 6667 | EMACS_INT eob = (string_p ? it->string_nchars : ZV); | ||
| 6668 | EMACS_INT bob = (string_p ? 0 : BEGV); | ||
| 6669 | |||
| 6670 | if (STRINGP (it->string)) | ||
| 6671 | { | ||
| 6672 | it->bidi_it.charpos = IT_STRING_CHARPOS (*it); | ||
| 6673 | it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it); | ||
| 6674 | } | ||
| 6675 | else | ||
| 6676 | { | ||
| 6677 | it->bidi_it.charpos = IT_CHARPOS (*it); | ||
| 6678 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | ||
| 6679 | } | ||
| 6680 | |||
| 6681 | if (it->bidi_it.charpos == eob) | ||
| 6682 | { | ||
| 6683 | /* Nothing to do, but reset the FIRST_ELT flag, like | ||
| 6684 | bidi_paragraph_init does, because we are not going to | ||
| 6685 | call it. */ | ||
| 6686 | it->bidi_it.first_elt = 0; | ||
| 6687 | } | ||
| 6688 | else if (it->bidi_it.charpos == bob | ||
| 6689 | || (!string_p | ||
| 6690 | /* FIXME: Should support all Unicode line separators. */ | ||
| 6691 | && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' | ||
| 6692 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n'))) | ||
| 6693 | { | ||
| 6694 | /* If we are at the beginning of a line/string, we can produce | ||
| 6695 | the next element right away. */ | ||
| 6696 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6697 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6698 | } | ||
| 6699 | else | ||
| 6700 | { | ||
| 6701 | EMACS_INT orig_bytepos = it->bidi_it.bytepos; | ||
| 6702 | |||
| 6703 | /* We need to prime the bidi iterator starting at the line's or | ||
| 6704 | string's beginning, before we will be able to produce the | ||
| 6705 | next element. */ | ||
| 6706 | if (string_p) | ||
| 6707 | it->bidi_it.charpos = it->bidi_it.bytepos = 0; | ||
| 6708 | else | ||
| 6709 | { | ||
| 6710 | it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it), | ||
| 6711 | -1); | ||
| 6712 | it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos); | ||
| 6713 | } | ||
| 6714 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6715 | do | ||
| 6716 | { | ||
| 6717 | /* Now return to buffer/string position where we were asked | ||
| 6718 | to get the next display element, and produce that. */ | ||
| 6719 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6720 | } | ||
| 6721 | while (it->bidi_it.bytepos != orig_bytepos | ||
| 6722 | && it->bidi_it.charpos < eob); | ||
| 6723 | } | ||
| 6724 | |||
| 6725 | /* Adjust IT's position information to where we ended up. */ | ||
| 6726 | if (STRINGP (it->string)) | ||
| 6727 | { | ||
| 6728 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6729 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6730 | } | ||
| 6731 | else | ||
| 6732 | { | ||
| 6733 | IT_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6734 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6735 | } | ||
| 6736 | |||
| 6737 | if (STRINGP (it->string) || !it->s) | ||
| 6738 | { | ||
| 6739 | EMACS_INT stop, charpos, bytepos; | ||
| 6740 | |||
| 6741 | if (STRINGP (it->string)) | ||
| 6742 | { | ||
| 6743 | xassert (!it->s); | ||
| 6744 | stop = SCHARS (it->string); | ||
| 6745 | if (stop > it->end_charpos) | ||
| 6746 | stop = it->end_charpos; | ||
| 6747 | charpos = IT_STRING_CHARPOS (*it); | ||
| 6748 | bytepos = IT_STRING_BYTEPOS (*it); | ||
| 6749 | } | ||
| 6750 | else | ||
| 6751 | { | ||
| 6752 | stop = it->end_charpos; | ||
| 6753 | charpos = IT_CHARPOS (*it); | ||
| 6754 | bytepos = IT_BYTEPOS (*it); | ||
| 6755 | } | ||
| 6756 | if (it->bidi_it.scan_dir < 0) | ||
| 6757 | stop = -1; | ||
| 6758 | composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop, | ||
| 6759 | it->string); | ||
| 6760 | } | ||
| 6761 | } | ||
| 6661 | 6762 | ||
| 6662 | /* Load IT with the next display element from Lisp string IT->string. | 6763 | /* Load IT with the next display element from Lisp string IT->string. |
| 6663 | IT->current.string_pos is the current position within the string. | 6764 | IT->current.string_pos is the current position within the string. |
| @@ -6680,56 +6781,8 @@ next_element_from_string (struct it *it) | |||
| 6680 | direction is not known. */ | 6781 | direction is not known. */ |
| 6681 | if (it->bidi_p && it->bidi_it.first_elt) | 6782 | if (it->bidi_p && it->bidi_it.first_elt) |
| 6682 | { | 6783 | { |
| 6683 | it->bidi_it.charpos = CHARPOS (position); | 6784 | get_visually_first_element (it); |
| 6684 | it->bidi_it.bytepos = BYTEPOS (position); | ||
| 6685 | if (it->bidi_it.charpos >= it->string_nchars) | ||
| 6686 | { | ||
| 6687 | /* Nothing to do, but reset the FIRST_ELT flag, like | ||
| 6688 | bidi_paragraph_init does, because we are not going to | ||
| 6689 | call it. */ | ||
| 6690 | it->bidi_it.first_elt = 0; | ||
| 6691 | } | ||
| 6692 | else if (it->bidi_it.charpos <= 0) | ||
| 6693 | { | ||
| 6694 | /* If we are at the beginning of the string, we can produce | ||
| 6695 | the next element right away. */ | ||
| 6696 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6697 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6698 | } | ||
| 6699 | else | ||
| 6700 | { | ||
| 6701 | EMACS_INT orig_bytepos = BYTEPOS (position); | ||
| 6702 | |||
| 6703 | /* We need to prime the bidi iterator starting at the string | ||
| 6704 | beginning, before we will be able to produce the next | ||
| 6705 | element. */ | ||
| 6706 | it->bidi_it.charpos = it->bidi_it.bytepos = 0; | ||
| 6707 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6708 | do | ||
| 6709 | { | ||
| 6710 | /* Now return to buffer position where we were asked to | ||
| 6711 | get the next display element, and produce that. */ | ||
| 6712 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6713 | } | ||
| 6714 | while (it->bidi_it.bytepos != orig_bytepos | ||
| 6715 | && it->bidi_it.charpos < it->string_nchars); | ||
| 6716 | } | ||
| 6717 | |||
| 6718 | /* Adjust IT's position information to where we ended up. */ | ||
| 6719 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6720 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6721 | SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it)); | 6785 | SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it)); |
| 6722 | { | ||
| 6723 | EMACS_INT stop = SCHARS (it->string); | ||
| 6724 | |||
| 6725 | if (it->bidi_it.scan_dir < 0) | ||
| 6726 | stop = -1; | ||
| 6727 | else if (stop > it->end_charpos) | ||
| 6728 | stop = it->end_charpos; | ||
| 6729 | composition_compute_stop_pos (&it->cmp_it, IT_STRING_CHARPOS (*it), | ||
| 6730 | IT_STRING_BYTEPOS (*it), stop, | ||
| 6731 | it->string); | ||
| 6732 | } | ||
| 6733 | } | 6786 | } |
| 6734 | 6787 | ||
| 6735 | /* Time to check for invisible text? */ | 6788 | /* Time to check for invisible text? */ |
| @@ -6894,46 +6947,7 @@ next_element_from_c_string (struct it *it) | |||
| 6894 | we were reseated to a new string, whose paragraph direction is | 6947 | we were reseated to a new string, whose paragraph direction is |
| 6895 | not known. */ | 6948 | not known. */ |
| 6896 | if (it->bidi_p && it->bidi_it.first_elt) | 6949 | if (it->bidi_p && it->bidi_it.first_elt) |
| 6897 | { | 6950 | get_visually_first_element (it); |
| 6898 | it->bidi_it.charpos = IT_CHARPOS (*it); | ||
| 6899 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | ||
| 6900 | if (it->bidi_it.charpos >= it->string_nchars) | ||
| 6901 | { | ||
| 6902 | /* Nothing to do, but reset the FIRST_ELT flag, like | ||
| 6903 | bidi_paragraph_init does, because we are not going to | ||
| 6904 | call it. */ | ||
| 6905 | it->bidi_it.first_elt = 0; | ||
| 6906 | } | ||
| 6907 | else if (it->bidi_it.charpos <= 0) | ||
| 6908 | { | ||
| 6909 | /* If we are at the beginning of the string, we can produce | ||
| 6910 | the next element right away. */ | ||
| 6911 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6912 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6913 | } | ||
| 6914 | else | ||
| 6915 | { | ||
| 6916 | EMACS_INT orig_bytepos = IT_BYTEPOS (*it); | ||
| 6917 | |||
| 6918 | /* We need to prime the bidi iterator starting at the string | ||
| 6919 | beginning, before we will be able to produce the next | ||
| 6920 | element. */ | ||
| 6921 | it->bidi_it.charpos = it->bidi_it.bytepos = 0; | ||
| 6922 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6923 | do | ||
| 6924 | { | ||
| 6925 | /* Now return to buffer position where we were asked to | ||
| 6926 | get the next display element, and produce that. */ | ||
| 6927 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6928 | } | ||
| 6929 | while (it->bidi_it.bytepos != orig_bytepos | ||
| 6930 | && it->bidi_it.charpos < it->string_nchars); | ||
| 6931 | } | ||
| 6932 | |||
| 6933 | /* Adjust IT's position information to where we ended up. */ | ||
| 6934 | IT_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6935 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6936 | } | ||
| 6937 | 6951 | ||
| 6938 | /* IT's position can be greater than IT->string_nchars in case a | 6952 | /* IT's position can be greater than IT->string_nchars in case a |
| 6939 | field width or precision has been specified when the iterator was | 6953 | field width or precision has been specified when the iterator was |
| @@ -7069,6 +7083,7 @@ next_element_from_buffer (struct it *it) | |||
| 7069 | int success_p = 1; | 7083 | int success_p = 1; |
| 7070 | 7084 | ||
| 7071 | xassert (IT_CHARPOS (*it) >= BEGV); | 7085 | xassert (IT_CHARPOS (*it) >= BEGV); |
| 7086 | xassert (NILP (it->string) && !it->s); | ||
| 7072 | xassert (!it->bidi_p | 7087 | xassert (!it->bidi_p |
| 7073 | || (it->bidi_it.string.lstring == Qnil | 7088 | || (it->bidi_it.string.lstring == Qnil |
| 7074 | && it->bidi_it.string.s == NULL)); | 7089 | && it->bidi_it.string.s == NULL)); |
| @@ -7079,59 +7094,8 @@ next_element_from_buffer (struct it *it) | |||
| 7079 | a different paragraph. */ | 7094 | a different paragraph. */ |
| 7080 | if (it->bidi_p && it->bidi_it.first_elt) | 7095 | if (it->bidi_p && it->bidi_it.first_elt) |
| 7081 | { | 7096 | { |
| 7082 | it->bidi_it.charpos = IT_CHARPOS (*it); | 7097 | get_visually_first_element (it); |
| 7083 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | ||
| 7084 | if (it->bidi_it.bytepos == ZV_BYTE) | ||
| 7085 | { | ||
| 7086 | /* Nothing to do, but reset the FIRST_ELT flag, like | ||
| 7087 | bidi_paragraph_init does, because we are not going to | ||
| 7088 | call it. */ | ||
| 7089 | it->bidi_it.first_elt = 0; | ||
| 7090 | } | ||
| 7091 | else if (it->bidi_it.bytepos == BEGV_BYTE | ||
| 7092 | /* FIXME: Should support all Unicode line separators. */ | ||
| 7093 | || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' | ||
| 7094 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n') | ||
| 7095 | { | ||
| 7096 | /* If we are at the beginning of a line, we can produce the | ||
| 7097 | next element right away. */ | ||
| 7098 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 7099 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 7100 | } | ||
| 7101 | else | ||
| 7102 | { | ||
| 7103 | EMACS_INT orig_bytepos = IT_BYTEPOS (*it); | ||
| 7104 | |||
| 7105 | /* We need to prime the bidi iterator starting at the line's | ||
| 7106 | beginning, before we will be able to produce the next | ||
| 7107 | element. */ | ||
| 7108 | IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1); | ||
| 7109 | IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it)); | ||
| 7110 | it->bidi_it.charpos = IT_CHARPOS (*it); | ||
| 7111 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | ||
| 7112 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 7113 | do | ||
| 7114 | { | ||
| 7115 | /* Now return to buffer position where we were asked to | ||
| 7116 | get the next display element, and produce that. */ | ||
| 7117 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 7118 | } | ||
| 7119 | while (it->bidi_it.bytepos != orig_bytepos | ||
| 7120 | && it->bidi_it.bytepos < ZV_BYTE); | ||
| 7121 | } | ||
| 7122 | |||
| 7123 | it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */ | ||
| 7124 | /* Adjust IT's position information to where we ended up. */ | ||
| 7125 | IT_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 7126 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 7127 | SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it)); | 7098 | SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it)); |
| 7128 | { | ||
| 7129 | EMACS_INT stop = it->end_charpos; | ||
| 7130 | if (it->bidi_it.scan_dir < 0) | ||
| 7131 | stop = -1; | ||
| 7132 | composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | ||
| 7133 | IT_BYTEPOS (*it), stop, Qnil); | ||
| 7134 | } | ||
| 7135 | } | 7099 | } |
| 7136 | 7100 | ||
| 7137 | if (IT_CHARPOS (*it) >= it->stop_charpos) | 7101 | if (IT_CHARPOS (*it) >= it->stop_charpos) |