diff options
| author | Eli Zaretskii | 2015-09-21 12:35:26 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-09-21 12:35:26 +0300 |
| commit | e2f0dd2f49d8638d20615bfa38e95a71202dd543 (patch) | |
| tree | 1cc5aef3f8c01348621904b5062c963702b40e0a /src | |
| parent | 18028318d8908d547d82e8e3159994c14bb47dce (diff) | |
| download | emacs-e2f0dd2f49d8638d20615bfa38e95a71202dd543.tar.gz emacs-e2f0dd2f49d8638d20615bfa38e95a71202dd543.zip | |
Avoid infinite recursion while displaying box face
* src/xdisp.c (face_before_or_after_it_pos): Fix calculation of
the previous string/buffer character position under bidi
iteration. (Bug#21428)
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 3eff61f3716..34b5ca3cced 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -4014,21 +4014,23 @@ face_before_or_after_it_pos (struct it *it, bool before_p) | |||
| 4014 | /* With bidi iteration, the character before the current | 4014 | /* With bidi iteration, the character before the current |
| 4015 | in the visual order cannot be found by simple | 4015 | in the visual order cannot be found by simple |
| 4016 | iteration, because "reverse" reordering is not | 4016 | iteration, because "reverse" reordering is not |
| 4017 | supported. Instead, we need to use the move_it_* | 4017 | supported. Instead, we need to start from the string |
| 4018 | family of functions. */ | 4018 | beginning and go all the way to the current string |
| 4019 | position, remembering the previous position. */ | ||
| 4019 | /* Ignore face changes before the first visible | 4020 | /* Ignore face changes before the first visible |
| 4020 | character on this display line. */ | 4021 | character on this display line. */ |
| 4021 | if (it->current_x <= it->first_visible_x) | 4022 | if (it->current_x <= it->first_visible_x) |
| 4022 | return it->face_id; | 4023 | return it->face_id; |
| 4023 | SAVE_IT (it_copy, *it, it_copy_data); | 4024 | SAVE_IT (it_copy, *it, it_copy_data); |
| 4024 | /* Implementation note: Since move_it_in_display_line | 4025 | IT_STRING_CHARPOS (it_copy) = 0; |
| 4025 | works in the iterator geometry, and thinks the first | 4026 | bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it); |
| 4026 | character is always the leftmost, even in R2L lines, | 4027 | while (IT_STRING_CHARPOS (it_copy) != IT_STRING_CHARPOS (*it)) |
| 4027 | we don't need to distinguish between the R2L and L2R | 4028 | { |
| 4028 | cases here. */ | 4029 | charpos = IT_STRING_CHARPOS (it_copy); |
| 4029 | move_it_in_display_line (&it_copy, SCHARS (it_copy.string), | 4030 | if (charpos >= SCHARS (it->string)) |
| 4030 | it_copy.current_x - 1, MOVE_TO_X); | 4031 | break; |
| 4031 | charpos = IT_STRING_CHARPOS (it_copy); | 4032 | bidi_move_to_visually_next (&it_copy.bidi_it); |
| 4033 | } | ||
| 4032 | RESTORE_IT (it, it, it_copy_data); | 4034 | RESTORE_IT (it, it, it_copy_data); |
| 4033 | } | 4035 | } |
| 4034 | else | 4036 | else |
| @@ -4108,11 +4110,15 @@ face_before_or_after_it_pos (struct it *it, bool before_p) | |||
| 4108 | { | 4110 | { |
| 4109 | if (before_p) | 4111 | if (before_p) |
| 4110 | { | 4112 | { |
| 4113 | int current_x; | ||
| 4114 | |||
| 4111 | /* With bidi iteration, the character before the current | 4115 | /* With bidi iteration, the character before the current |
| 4112 | in the visual order cannot be found by simple | 4116 | in the visual order cannot be found by simple |
| 4113 | iteration, because "reverse" reordering is not | 4117 | iteration, because "reverse" reordering is not |
| 4114 | supported. Instead, we need to use the move_it_* | 4118 | supported. Instead, we need to use the move_it_* |
| 4115 | family of functions. */ | 4119 | family of functions, and move to the previous |
| 4120 | character starting from the beginning of the visual | ||
| 4121 | line. */ | ||
| 4116 | /* Ignore face changes before the first visible | 4122 | /* Ignore face changes before the first visible |
| 4117 | character on this display line. */ | 4123 | character on this display line. */ |
| 4118 | if (it->current_x <= it->first_visible_x) | 4124 | if (it->current_x <= it->first_visible_x) |
| @@ -4123,8 +4129,9 @@ face_before_or_after_it_pos (struct it *it, bool before_p) | |||
| 4123 | character is always the leftmost, even in R2L lines, | 4129 | character is always the leftmost, even in R2L lines, |
| 4124 | we don't need to distinguish between the R2L and L2R | 4130 | we don't need to distinguish between the R2L and L2R |
| 4125 | cases here. */ | 4131 | cases here. */ |
| 4126 | move_it_in_display_line (&it_copy, ZV, | 4132 | current_x = it_copy.current_x; |
| 4127 | it_copy.current_x - 1, MOVE_TO_X); | 4133 | move_it_vertically_backward (&it_copy, 0); |
| 4134 | move_it_in_display_line (&it_copy, ZV, current_x - 1, MOVE_TO_X); | ||
| 4128 | pos = it_copy.current.pos; | 4135 | pos = it_copy.current.pos; |
| 4129 | RESTORE_IT (it, it, it_copy_data); | 4136 | RESTORE_IT (it, it, it_copy_data); |
| 4130 | } | 4137 | } |