diff options
| author | Eli Zaretskii | 2011-06-25 14:44:30 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-06-25 14:44:30 +0300 |
| commit | 0c22566f00ee467af8d41ef7dc9f18c3b66630c5 (patch) | |
| tree | 7db72a0297d9f21e0582d94286c21cad2c64dfa9 | |
| parent | 58b9f433ad4a4ea20e0c51997ca8a9aaab79a213 (diff) | |
| download | emacs-0c22566f00ee467af8d41ef7dc9f18c3b66630c5.tar.gz emacs-0c22566f00ee467af8d41ef7dc9f18c3b66630c5.zip | |
Set up the bidi iterator for iterating display strings and overlay strings.
Not tested yet, just compiled.
src/xdisp.c (handle_single_display_spec, next_overlay_string)
(get_overlay_strings_1, push_display_prop): Set up the bidi
iterator for displaying display or overlay strings.
(forward_to_next_line_start): Don't use the shortcut if
bidi-iterating.
(back_to_previous_visible_line_start): If handle_display_prop
pushed the iterator stack, restore the internal state of the bidi
iterator by calling bidi_pop_it same number of times.
(reseat_at_next_visible_line_start): If ON_NEWLINE_P is non-zero,
and we are bidi-iterating, don't decrement the iterator position;
instead, set the first_elt flag in the bidi iterator, to produce
the same effect.
(reseat_1): Remove redundant setting of string_from_display_prop_p.
(push_display_prop): xassert that we are iterating a buffer.
(push_it, pop_it): Save and restore the state of the
bidi iterator. Save and restore the bidi_p flag.
(pop_it): Iterate out of display property for string iteration as
well.
(iterate_out_of_display_property): Support iteration over strings.
(handle_single_display_spec): Set up it->bidi_it for iteration
over a display string, and call bidi_init_it.
src/bidi.c (bidi_cache_start_stack, bidi_push_it): Use IT_STACK_SIZE.
src/dispextern.h (struct iterator_stack_entry): New member bidi_p.
(struct it): Member bidi_p is now a bit field 1 bit wide.
| -rw-r--r-- | src/ChangeLog | 32 | ||||
| -rw-r--r-- | src/bidi.c | 11 | ||||
| -rw-r--r-- | src/dispextern.h | 7 | ||||
| -rw-r--r-- | src/xdisp.c | 202 |
4 files changed, 214 insertions, 38 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 40576554636..083aaaaa4bd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,35 @@ | |||
| 1 | 2011-06-25 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (handle_single_display_spec, next_overlay_string) | ||
| 4 | (get_overlay_strings_1, push_display_prop): Set up the bidi | ||
| 5 | iterator for displaying display or overlay strings. | ||
| 6 | (forward_to_next_line_start): Don't use the shortcut if | ||
| 7 | bidi-iterating. | ||
| 8 | (back_to_previous_visible_line_start): If handle_display_prop | ||
| 9 | pushed the iterator stack, restore the internal state of the bidi | ||
| 10 | iterator by calling bidi_pop_it same number of times. | ||
| 11 | (reseat_at_next_visible_line_start): If ON_NEWLINE_P is non-zero, | ||
| 12 | and we are bidi-iterating, don't decrement the iterator position; | ||
| 13 | instead, set the first_elt flag in the bidi iterator, to produce | ||
| 14 | the same effect. | ||
| 15 | (reseat_1): Remove redundant setting of string_from_display_prop_p. | ||
| 16 | (push_display_prop): xassert that we are iterating a buffer. | ||
| 17 | |||
| 18 | * bidi.c (bidi_cache_start_stack, bidi_push_it): Use IT_STACK_SIZE. | ||
| 19 | |||
| 20 | 2011-06-24 Eli Zaretskii <eliz@gnu.org> | ||
| 21 | |||
| 22 | * xdisp.c (push_it, pop_it): Save and restore the state of the | ||
| 23 | bidi iterator. Save and restore the bidi_p flag. | ||
| 24 | (pop_it): Iterate out of display property for string iteration as | ||
| 25 | well. | ||
| 26 | (iterate_out_of_display_property): Support iteration over strings. | ||
| 27 | (handle_single_display_spec): Set up it->bidi_it for iteration | ||
| 28 | over a display string, and call bidi_init_it. | ||
| 29 | |||
| 30 | * dispextern.h (struct iterator_stack_entry): New member bidi_p. | ||
| 31 | (struct it): Member bidi_p is now a bit field 1 bit wide. | ||
| 32 | |||
| 1 | 2011-06-23 Eli Zaretskii <eliz@gnu.org> | 33 | 2011-06-23 Eli Zaretskii <eliz@gnu.org> |
| 2 | 34 | ||
| 3 | * dispextern.h (bidi_push_it, bidi_pop_it): Add prototypes. | 35 | * dispextern.h (bidi_push_it, bidi_pop_it): Add prototypes. |
diff --git a/src/bidi.c b/src/bidi.c index b03e93df817..b518dd45782 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -548,11 +548,10 @@ bidi_peek_at_next_level (struct bidi_it *bidi_it) | |||
| 548 | /*********************************************************************** | 548 | /*********************************************************************** |
| 549 | Pushing and popping the bidi iterator state | 549 | Pushing and popping the bidi iterator state |
| 550 | ***********************************************************************/ | 550 | ***********************************************************************/ |
| 551 | /* 10-slot stack for saving the start of the previous level of the | 551 | /* 5-slot stack for saving the start of the previous level of the |
| 552 | cache. xdisp.c maintains a 5-slot cache for its iterator state, | 552 | cache. xdisp.c maintains a 5-slot stack for its iterator state, |
| 553 | and we need just a little bit more. */ | 553 | and we need the same size of our stack. */ |
| 554 | #define CACHE_STACK_SIZE 10 | 554 | static int bidi_cache_start_stack[IT_STACK_SIZE]; |
| 555 | static int bidi_cache_start_stack[CACHE_STACK_SIZE]; | ||
| 556 | static int bidi_cache_sp; | 555 | static int bidi_cache_sp; |
| 557 | 556 | ||
| 558 | /* Push the bidi iterator state in preparation for reordering a | 557 | /* Push the bidi iterator state in preparation for reordering a |
| @@ -569,7 +568,7 @@ bidi_push_it (struct bidi_it *bidi_it) | |||
| 569 | memcpy (&bidi_cache[bidi_cache_idx++], bidi_it, sizeof (struct bidi_it)); | 568 | memcpy (&bidi_cache[bidi_cache_idx++], bidi_it, sizeof (struct bidi_it)); |
| 570 | 569 | ||
| 571 | /* Push the current cache start onto the stack. */ | 570 | /* Push the current cache start onto the stack. */ |
| 572 | if (bidi_cache_sp >= CACHE_STACK_SIZE) | 571 | if (bidi_cache_sp >= IT_STACK_SIZE) |
| 573 | abort (); | 572 | abort (); |
| 574 | bidi_cache_start_stack[bidi_cache_sp++] = bidi_cache_start; | 573 | bidi_cache_start_stack[bidi_cache_sp++] = bidi_cache_start; |
| 575 | 574 | ||
diff --git a/src/dispextern.h b/src/dispextern.h index acd7862e5dc..d5479c7a64e 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2157,7 +2157,9 @@ struct it | |||
| 2157 | Lisp_Object *dpvec, *dpend; | 2157 | Lisp_Object *dpvec, *dpend; |
| 2158 | 2158 | ||
| 2159 | /* Length in bytes of the char that filled dpvec. A value of zero | 2159 | /* Length in bytes of the char that filled dpvec. A value of zero |
| 2160 | means that no such character is involved. */ | 2160 | means that no such character is involved. A negative value means |
| 2161 | the rest of the line from the current iterator position onwards | ||
| 2162 | is hidden by selective display or ellipsis. */ | ||
| 2161 | int dpvec_char_len; | 2163 | int dpvec_char_len; |
| 2162 | 2164 | ||
| 2163 | /* Face id to use for all characters in display vector. -1 if unused. */ | 2165 | /* Face id to use for all characters in display vector. -1 if unused. */ |
| @@ -2253,6 +2255,7 @@ struct it | |||
| 2253 | unsigned string_from_display_prop_p : 1; | 2255 | unsigned string_from_display_prop_p : 1; |
| 2254 | unsigned display_ellipsis_p : 1; | 2256 | unsigned display_ellipsis_p : 1; |
| 2255 | unsigned avoid_cursor_p : 1; | 2257 | unsigned avoid_cursor_p : 1; |
| 2258 | unsigned bidi_p:1; | ||
| 2256 | enum line_wrap_method line_wrap; | 2259 | enum line_wrap_method line_wrap; |
| 2257 | 2260 | ||
| 2258 | /* properties from display property that are reset by another display property. */ | 2261 | /* properties from display property that are reset by another display property. */ |
| @@ -2473,7 +2476,7 @@ struct it | |||
| 2473 | 2476 | ||
| 2474 | /* Non-zero means we need to reorder bidirectional text for display | 2477 | /* Non-zero means we need to reorder bidirectional text for display |
| 2475 | in the visual order. */ | 2478 | in the visual order. */ |
| 2476 | int bidi_p; | 2479 | unsigned bidi_p : 1; |
| 2477 | 2480 | ||
| 2478 | /* For iterating over bidirectional text. */ | 2481 | /* For iterating over bidirectional text. */ |
| 2479 | struct bidi_it bidi_it; | 2482 | struct bidi_it bidi_it; |
diff --git a/src/xdisp.c b/src/xdisp.c index 74afa80ada7..dc9a62fc0b6 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -4482,12 +4482,43 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4482 | it->end_charpos = it->string_nchars = SCHARS (it->string); | 4482 | it->end_charpos = it->string_nchars = SCHARS (it->string); |
| 4483 | it->method = GET_FROM_STRING; | 4483 | it->method = GET_FROM_STRING; |
| 4484 | it->stop_charpos = 0; | 4484 | it->stop_charpos = 0; |
| 4485 | it->prev_stop = 0; | ||
| 4486 | it->base_level_stop = 0; | ||
| 4485 | it->string_from_display_prop_p = 1; | 4487 | it->string_from_display_prop_p = 1; |
| 4486 | /* Say that we haven't consumed the characters with | 4488 | /* Say that we haven't consumed the characters with |
| 4487 | `display' property yet. The call to pop_it in | 4489 | `display' property yet. The call to pop_it in |
| 4488 | set_iterator_to_next will clean this up. */ | 4490 | set_iterator_to_next will clean this up. */ |
| 4489 | if (BUFFERP (object)) | 4491 | if (BUFFERP (object)) |
| 4490 | *position = start_pos; | 4492 | *position = start_pos; |
| 4493 | |||
| 4494 | /* Force paragraph direction to be that of the parent | ||
| 4495 | object. */ | ||
| 4496 | it->paragraph_embedding = | ||
| 4497 | (it->bidi_p ? it->bidi_it.paragraph_dir : L2R); | ||
| 4498 | |||
| 4499 | /* Do we need to reorder this display string? */ | ||
| 4500 | if (it->multibyte_p) | ||
| 4501 | { | ||
| 4502 | if (BUFFERP (object)) | ||
| 4503 | it->bidi_p = | ||
| 4504 | !NILP (BVAR (XBUFFER (object), bidi_display_reordering)); | ||
| 4505 | else | ||
| 4506 | it->bidi_p = | ||
| 4507 | !NILP (BVAR (&buffer_defaults, bidi_display_reordering)); | ||
| 4508 | } | ||
| 4509 | else | ||
| 4510 | it->bidi_p = 0; | ||
| 4511 | |||
| 4512 | /* Set up the bidi iterator for this display string. */ | ||
| 4513 | if (it->bidi_p) | ||
| 4514 | { | ||
| 4515 | it->bidi_it.string.lstring = it->string; | ||
| 4516 | it->bidi_it.string.s = NULL; | ||
| 4517 | it->bidi_it.string.schars = it->end_charpos; | ||
| 4518 | it->bidi_it.string.bufpos = bufpos; | ||
| 4519 | it->bidi_it.string.from_disp_str = 1; | ||
| 4520 | bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it); | ||
| 4521 | } | ||
| 4491 | } | 4522 | } |
| 4492 | else if (CONSP (value) && EQ (XCAR (value), Qspace)) | 4523 | else if (CONSP (value) && EQ (XCAR (value), Qspace)) |
| 4493 | { | 4524 | { |
| @@ -4839,6 +4870,24 @@ next_overlay_string (struct it *it) | |||
| 4839 | it->stop_charpos = 0; | 4870 | it->stop_charpos = 0; |
| 4840 | if (it->cmp_it.stop_pos >= 0) | 4871 | if (it->cmp_it.stop_pos >= 0) |
| 4841 | it->cmp_it.stop_pos = 0; | 4872 | it->cmp_it.stop_pos = 0; |
| 4873 | it->prev_stop = 0; | ||
| 4874 | it->base_level_stop = 0; | ||
| 4875 | |||
| 4876 | /* Do we need to reorder this overlay string? */ | ||
| 4877 | it->bidi_p = | ||
| 4878 | it->multibyte_p | ||
| 4879 | && !NILP (BVAR (current_buffer, bidi_display_reordering)); | ||
| 4880 | |||
| 4881 | /* Set up the bidi iterator for this overlay string. */ | ||
| 4882 | if (it->bidi_p) | ||
| 4883 | { | ||
| 4884 | it->bidi_it.string.lstring = it->string; | ||
| 4885 | it->bidi_it.string.s = NULL; | ||
| 4886 | it->bidi_it.string.schars = SCHARS (it->string); | ||
| 4887 | it->bidi_it.string.bufpos = it->overlay_strings_charpos; | ||
| 4888 | it->bidi_it.string.from_disp_str = it->string_from_display_prop_p; | ||
| 4889 | bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it); | ||
| 4890 | } | ||
| 4842 | } | 4891 | } |
| 4843 | 4892 | ||
| 4844 | CHECK_IT (it); | 4893 | CHECK_IT (it); |
| @@ -5105,8 +5154,32 @@ get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p) | |||
| 5105 | it->stop_charpos = 0; | 5154 | it->stop_charpos = 0; |
| 5106 | xassert (STRINGP (it->string)); | 5155 | xassert (STRINGP (it->string)); |
| 5107 | it->end_charpos = SCHARS (it->string); | 5156 | it->end_charpos = SCHARS (it->string); |
| 5157 | it->prev_stop = 0; | ||
| 5158 | it->base_level_stop = 0; | ||
| 5108 | it->multibyte_p = STRING_MULTIBYTE (it->string); | 5159 | it->multibyte_p = STRING_MULTIBYTE (it->string); |
| 5109 | it->method = GET_FROM_STRING; | 5160 | it->method = GET_FROM_STRING; |
| 5161 | |||
| 5162 | /* Do we need to reorder this overlay string? */ | ||
| 5163 | it->bidi_p = | ||
| 5164 | it->multibyte_p | ||
| 5165 | && !NILP (BVAR (current_buffer, bidi_display_reordering)); | ||
| 5166 | |||
| 5167 | /* Force paragraph direction to be that of the parent | ||
| 5168 | buffer. */ | ||
| 5169 | it->paragraph_embedding = (it->bidi_p ? it->bidi_it.paragraph_dir : L2R); | ||
| 5170 | |||
| 5171 | /* Set up the bidi iterator for this overlay string. */ | ||
| 5172 | if (it->bidi_p) | ||
| 5173 | { | ||
| 5174 | EMACS_INT pos = (charpos > 0 ? charpos : IT_CHARPOS (*it)); | ||
| 5175 | |||
| 5176 | it->bidi_it.string.lstring = it->string; | ||
| 5177 | it->bidi_it.string.s = NULL; | ||
| 5178 | it->bidi_it.string.schars = SCHARS (it->string); | ||
| 5179 | it->bidi_it.string.bufpos = pos; | ||
| 5180 | it->bidi_it.string.from_disp_str = it->string_from_display_prop_p; | ||
| 5181 | bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it); | ||
| 5182 | } | ||
| 5110 | return 1; | 5183 | return 1; |
| 5111 | } | 5184 | } |
| 5112 | 5185 | ||
| @@ -5181,19 +5254,28 @@ push_it (struct it *it, struct text_pos *position) | |||
| 5181 | p->string_from_display_prop_p = it->string_from_display_prop_p; | 5254 | p->string_from_display_prop_p = it->string_from_display_prop_p; |
| 5182 | p->display_ellipsis_p = 0; | 5255 | p->display_ellipsis_p = 0; |
| 5183 | p->line_wrap = it->line_wrap; | 5256 | p->line_wrap = it->line_wrap; |
| 5257 | p->bidi_p = it->bidi_p; | ||
| 5184 | ++it->sp; | 5258 | ++it->sp; |
| 5259 | |||
| 5260 | /* Save the state of the bidi iterator as well. */ | ||
| 5261 | if (it->bidi_p) | ||
| 5262 | bidi_push_it (&it->bidi_it); | ||
| 5185 | } | 5263 | } |
| 5186 | 5264 | ||
| 5187 | static void | 5265 | static void |
| 5188 | iterate_out_of_display_property (struct it *it) | 5266 | iterate_out_of_display_property (struct it *it) |
| 5189 | { | 5267 | { |
| 5268 | int buffer_p = BUFFERP (it->object); | ||
| 5269 | EMACS_INT eob = (buffer_p ? ZV : it->end_charpos); | ||
| 5270 | EMACS_INT bob = (buffer_p ? BEGV : 0); | ||
| 5271 | |||
| 5190 | /* Maybe initialize paragraph direction. If we are at the beginning | 5272 | /* Maybe initialize paragraph direction. If we are at the beginning |
| 5191 | of a new paragraph, next_element_from_buffer may not have a | 5273 | of a new paragraph, next_element_from_buffer may not have a |
| 5192 | chance to do that. */ | 5274 | chance to do that. */ |
| 5193 | if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV) | 5275 | if (it->bidi_it.first_elt && it->bidi_it.charpos < eob) |
| 5194 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | 5276 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); |
| 5195 | /* prev_stop can be zero, so check against BEGV as well. */ | 5277 | /* prev_stop can be zero, so check against BEGV as well. */ |
| 5196 | while (it->bidi_it.charpos >= BEGV | 5278 | while (it->bidi_it.charpos >= bob |
| 5197 | && it->prev_stop <= it->bidi_it.charpos | 5279 | && it->prev_stop <= it->bidi_it.charpos |
| 5198 | && it->bidi_it.charpos < CHARPOS (it->position)) | 5280 | && it->bidi_it.charpos < CHARPOS (it->position)) |
| 5199 | bidi_move_to_visually_next (&it->bidi_it); | 5281 | bidi_move_to_visually_next (&it->bidi_it); |
| @@ -5207,7 +5289,10 @@ iterate_out_of_display_property (struct it *it) | |||
| 5207 | { | 5289 | { |
| 5208 | SET_TEXT_POS (it->position, | 5290 | SET_TEXT_POS (it->position, |
| 5209 | it->bidi_it.charpos, it->bidi_it.bytepos); | 5291 | it->bidi_it.charpos, it->bidi_it.bytepos); |
| 5210 | it->current.pos = it->position; | 5292 | if (buffer_p) |
| 5293 | it->current.pos = it->position; | ||
| 5294 | else | ||
| 5295 | it->current.string_pos = it->position; | ||
| 5211 | } | 5296 | } |
| 5212 | } | 5297 | } |
| 5213 | 5298 | ||
| @@ -5249,18 +5334,6 @@ pop_it (struct it *it) | |||
| 5249 | break; | 5334 | break; |
| 5250 | case GET_FROM_BUFFER: | 5335 | case GET_FROM_BUFFER: |
| 5251 | it->object = it->w->buffer; | 5336 | it->object = it->w->buffer; |
| 5252 | if (it->bidi_p) | ||
| 5253 | { | ||
| 5254 | /* Bidi-iterate until we get out of the portion of text, if | ||
| 5255 | any, covered by a `display' text property or an overlay | ||
| 5256 | with `display' property. (We cannot just jump there, | ||
| 5257 | because the internal coherency of the bidi iterator state | ||
| 5258 | can not be preserved across such jumps.) We also must | ||
| 5259 | determine the paragraph base direction if the overlay we | ||
| 5260 | just processed is at the beginning of a new | ||
| 5261 | paragraph. */ | ||
| 5262 | iterate_out_of_display_property (it); | ||
| 5263 | } | ||
| 5264 | break; | 5337 | break; |
| 5265 | case GET_FROM_STRING: | 5338 | case GET_FROM_STRING: |
| 5266 | it->object = it->string; | 5339 | it->object = it->string; |
| @@ -5286,6 +5359,20 @@ pop_it (struct it *it) | |||
| 5286 | it->voffset = p->voffset; | 5359 | it->voffset = p->voffset; |
| 5287 | it->string_from_display_prop_p = p->string_from_display_prop_p; | 5360 | it->string_from_display_prop_p = p->string_from_display_prop_p; |
| 5288 | it->line_wrap = p->line_wrap; | 5361 | it->line_wrap = p->line_wrap; |
| 5362 | it->bidi_p = p->bidi_p; | ||
| 5363 | if (it->bidi_p) | ||
| 5364 | { | ||
| 5365 | bidi_pop_it (&it->bidi_it); | ||
| 5366 | /* Bidi-iterate until we get out of the portion of text, if any, | ||
| 5367 | covered by a `display' text property or by an overlay with | ||
| 5368 | `display' property. (We cannot just jump there, because the | ||
| 5369 | internal coherency of the bidi iterator state can not be | ||
| 5370 | preserved across such jumps.) We also must determine the | ||
| 5371 | paragraph base direction if the overlay we just processed is | ||
| 5372 | at the beginning of a new paragraph. */ | ||
| 5373 | if (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING) | ||
| 5374 | iterate_out_of_display_property (it); | ||
| 5375 | } | ||
| 5289 | } | 5376 | } |
| 5290 | 5377 | ||
| 5291 | 5378 | ||
| @@ -5368,15 +5455,16 @@ forward_to_next_line_start (struct it *it, int *skipped_p) | |||
| 5368 | 5455 | ||
| 5369 | xassert (!STRINGP (it->string)); | 5456 | xassert (!STRINGP (it->string)); |
| 5370 | 5457 | ||
| 5371 | /* If there isn't any `display' property in sight, and no | 5458 | /* If we are not bidi-reordering, and there isn't any `display' |
| 5372 | overlays, we can just use the position of the newline in | 5459 | property in sight, and no overlays, we can just use the |
| 5373 | buffer text. */ | 5460 | position of the newline in buffer text. */ |
| 5374 | if (it->stop_charpos >= limit | 5461 | if (!it->bidi_p |
| 5375 | || ((pos = Fnext_single_property_change (make_number (start), | 5462 | && (it->stop_charpos >= limit |
| 5376 | Qdisplay, | 5463 | || ((pos = Fnext_single_property_change (make_number (start), |
| 5377 | Qnil, make_number (limit)), | 5464 | Qdisplay, Qnil, |
| 5378 | NILP (pos)) | 5465 | make_number (limit)), |
| 5379 | && next_overlay_change (start) == ZV)) | 5466 | NILP (pos)) |
| 5467 | && next_overlay_change (start) == ZV))) | ||
| 5380 | { | 5468 | { |
| 5381 | IT_CHARPOS (*it) = limit; | 5469 | IT_CHARPOS (*it) = limit; |
| 5382 | IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit); | 5470 | IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit); |
| @@ -5456,7 +5544,20 @@ back_to_previous_visible_line_start (struct it *it) | |||
| 5456 | && (OVERLAYP (overlay) | 5544 | && (OVERLAYP (overlay) |
| 5457 | ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) | 5545 | ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) |
| 5458 | : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) | 5546 | : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) |
| 5459 | goto replaced; | 5547 | { |
| 5548 | /* If the call to handle_display_prop above pushed the | ||
| 5549 | iterator state, that causes side effects for the bidi | ||
| 5550 | iterator by calling bidi_push_it. Undo those side | ||
| 5551 | effects. */ | ||
| 5552 | while (it2.sp > 0) | ||
| 5553 | { | ||
| 5554 | /* push_it calls bidi_push_it only if the bidi_p flag | ||
| 5555 | is set in the iterator being pushed. */ | ||
| 5556 | if (it2.stack[--it2.sp].bidi_p) | ||
| 5557 | bidi_pop_it (&it2.bidi_it); | ||
| 5558 | } | ||
| 5559 | goto replaced; | ||
| 5560 | } | ||
| 5460 | 5561 | ||
| 5461 | /* Newline is not replaced by anything -- so we are done. */ | 5562 | /* Newline is not replaced by anything -- so we are done. */ |
| 5462 | break; | 5563 | break; |
| @@ -5525,14 +5626,29 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p) | |||
| 5525 | { | 5626 | { |
| 5526 | if (IT_STRING_CHARPOS (*it) > 0) | 5627 | if (IT_STRING_CHARPOS (*it) > 0) |
| 5527 | { | 5628 | { |
| 5528 | --IT_STRING_CHARPOS (*it); | 5629 | if (!it->bidi_p) |
| 5529 | --IT_STRING_BYTEPOS (*it); | 5630 | { |
| 5631 | --IT_STRING_CHARPOS (*it); | ||
| 5632 | --IT_STRING_BYTEPOS (*it); | ||
| 5633 | } | ||
| 5634 | else | ||
| 5635 | /* Setting this flag will cause | ||
| 5636 | bidi_move_to_visually_next not to advance, but | ||
| 5637 | instead deliver the current character (newline), | ||
| 5638 | which is what the ON_NEWLINE_P flag wants. */ | ||
| 5639 | it->bidi_it.first_elt = 1; | ||
| 5530 | } | 5640 | } |
| 5531 | } | 5641 | } |
| 5532 | else if (IT_CHARPOS (*it) > BEGV) | 5642 | else if (IT_CHARPOS (*it) > BEGV) |
| 5533 | { | 5643 | { |
| 5534 | --IT_CHARPOS (*it); | 5644 | if (!it->bidi_p) |
| 5535 | --IT_BYTEPOS (*it); | 5645 | { |
| 5646 | --IT_CHARPOS (*it); | ||
| 5647 | --IT_BYTEPOS (*it); | ||
| 5648 | } | ||
| 5649 | /* With bidi iteration, the call to `reseat' will cause | ||
| 5650 | bidi_move_to_visually_next deliver the current character, | ||
| 5651 | the newline, instead of advancing. */ | ||
| 5536 | reseat (it, it->current.pos, 0); | 5652 | reseat (it, it->current.pos, 0); |
| 5537 | } | 5653 | } |
| 5538 | } | 5654 | } |
| @@ -5614,7 +5730,6 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p) | |||
| 5614 | IT_STRING_CHARPOS (*it) = -1; | 5730 | IT_STRING_CHARPOS (*it) = -1; |
| 5615 | IT_STRING_BYTEPOS (*it) = -1; | 5731 | IT_STRING_BYTEPOS (*it) = -1; |
| 5616 | it->string = Qnil; | 5732 | it->string = Qnil; |
| 5617 | it->string_from_display_prop_p = 0; | ||
| 5618 | it->method = GET_FROM_BUFFER; | 5733 | it->method = GET_FROM_BUFFER; |
| 5619 | it->object = it->w->buffer; | 5734 | it->object = it->w->buffer; |
| 5620 | it->area = TEXT_AREA; | 5735 | it->area = TEXT_AREA; |
| @@ -17644,6 +17759,8 @@ cursor_row_p (struct glyph_row *row) | |||
| 17644 | static int | 17759 | static int |
| 17645 | push_display_prop (struct it *it, Lisp_Object prop) | 17760 | push_display_prop (struct it *it, Lisp_Object prop) |
| 17646 | { | 17761 | { |
| 17762 | xassert (it->method == GET_FROM_BUFFER); | ||
| 17763 | |||
| 17647 | push_it (it, NULL); | 17764 | push_it (it, NULL); |
| 17648 | 17765 | ||
| 17649 | if (STRINGP (prop)) | 17766 | if (STRINGP (prop)) |
| @@ -17661,6 +17778,30 @@ push_display_prop (struct it *it, Lisp_Object prop) | |||
| 17661 | it->end_charpos = it->string_nchars = SCHARS (it->string); | 17778 | it->end_charpos = it->string_nchars = SCHARS (it->string); |
| 17662 | it->method = GET_FROM_STRING; | 17779 | it->method = GET_FROM_STRING; |
| 17663 | it->stop_charpos = 0; | 17780 | it->stop_charpos = 0; |
| 17781 | it->prev_stop = 0; | ||
| 17782 | it->base_level_stop = 0; | ||
| 17783 | it->string_from_display_prop_p = 1; | ||
| 17784 | |||
| 17785 | /* Force paragraph direction to be that of the parent | ||
| 17786 | buffer. */ | ||
| 17787 | it->paragraph_embedding = (it->bidi_p ? it->bidi_it.paragraph_dir : L2R); | ||
| 17788 | |||
| 17789 | /* Do we need to reorder this string? */ | ||
| 17790 | if (it->multibyte_p) | ||
| 17791 | it->bidi_p = !NILP (BVAR (current_buffer, bidi_display_reordering)); | ||
| 17792 | else | ||
| 17793 | it->bidi_p = 0; | ||
| 17794 | |||
| 17795 | /* Set up the bidi iterator for this display string. */ | ||
| 17796 | if (it->bidi_p) | ||
| 17797 | { | ||
| 17798 | it->bidi_it.string.lstring = it->string; | ||
| 17799 | it->bidi_it.string.s = NULL; | ||
| 17800 | it->bidi_it.string.schars = it->end_charpos; | ||
| 17801 | it->bidi_it.string.bufpos = IT_CHARPOS (*it); | ||
| 17802 | it->bidi_it.string.from_disp_str = 1; | ||
| 17803 | bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it); | ||
| 17804 | } | ||
| 17664 | } | 17805 | } |
| 17665 | else if (CONSP (prop) && EQ (XCAR (prop), Qspace)) | 17806 | else if (CONSP (prop) && EQ (XCAR (prop), Qspace)) |
| 17666 | { | 17807 | { |
| @@ -17707,6 +17848,7 @@ static void | |||
| 17707 | handle_line_prefix (struct it *it) | 17848 | handle_line_prefix (struct it *it) |
| 17708 | { | 17849 | { |
| 17709 | Lisp_Object prefix; | 17850 | Lisp_Object prefix; |
| 17851 | |||
| 17710 | if (it->continuation_lines_width > 0) | 17852 | if (it->continuation_lines_width > 0) |
| 17711 | { | 17853 | { |
| 17712 | prefix = get_it_property (it, Qwrap_prefix); | 17854 | prefix = get_it_property (it, Qwrap_prefix); |