diff options
| author | Eli Zaretskii | 2009-12-31 16:09:28 -0500 |
|---|---|---|
| committer | Eli Zaretskii | 2009-12-31 16:09:28 -0500 |
| commit | 90fcfd71cf705476cf64f7314a57eea8ac9bc8db (patch) | |
| tree | 7d1d9fc759b527be6fad0a343559bc356db51b44 | |
| parent | a88bbf05709b0ac38669479a80465f7334fa62b2 (diff) | |
| download | emacs-90fcfd71cf705476cf64f7314a57eea8ac9bc8db.tar.gz emacs-90fcfd71cf705476cf64f7314a57eea8ac9bc8db.zip | |
Retrospective commit from 2009-08-12.
An (unsuccessful) attempt to solve the issue with row->start and row->end.
xdisp.c (set_iterator_to_next, reseat, reseat_1)
(reseat_at_next_visible_line_start): Accept additional argument
force_logical_p; all callers changed. If force_logical_p is
non-zero, force iteration in buffer's logical order even in bidi
buffers.
dispnew.c (direct_output_for_insert): Call set_iterator_to_next
with additional argument zero.
dispextern.h (set_iterator_to_next): Now accepts an additional
argument.
| -rw-r--r-- | src/ChangeLog.bidi | 26 | ||||
| -rw-r--r-- | src/dispextern.h | 4 | ||||
| -rw-r--r-- | src/dispnew.c | 8 | ||||
| -rw-r--r-- | src/xdisp.c | 140 |
4 files changed, 120 insertions, 58 deletions
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index c36ab231fa8..515f74b39ea 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi | |||
| @@ -1,3 +1,29 @@ | |||
| 1 | 2009-09-12 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * dispnew.c (direct_output_for_insert): Give up if we are | ||
| 4 | reordering bidirectional text. | ||
| 5 | |||
| 6 | * dispextern.h (IT_STACK_SIZE): Enlarge to 5. | ||
| 7 | |||
| 8 | * xdisp.c (display_line): Set row->end and it->start for the next | ||
| 9 | row to the next character in logical order. If we are reordering | ||
| 10 | bidi text, push and pop the iterator before and after momentarily | ||
| 11 | iterating in logical order. | ||
| 12 | |||
| 13 | 2009-09-11 Eli Zaretskii <eliz@gnu.org> | ||
| 14 | |||
| 15 | * xdisp.c (set_iterator_to_next, reseat, reseat_1) | ||
| 16 | (reseat_at_next_visible_line_start): Accept additional argument | ||
| 17 | force_logical_p; all callers changed. If force_logical_p is | ||
| 18 | non-zero, force iteration in buffer's logical order even in bidi | ||
| 19 | buffers. | ||
| 20 | |||
| 21 | * dispnew.c (direct_output_for_insert): Call set_iterator_to_next | ||
| 22 | with additional argument zero. | ||
| 23 | |||
| 24 | * dispextern.h (set_iterator_to_next): Now accepts an additional | ||
| 25 | argument. | ||
| 26 | |||
| 1 | 2009-08-29 Eli Zaretskii <eliz@gnu.org> | 27 | 2009-08-29 Eli Zaretskii <eliz@gnu.org> |
| 2 | 28 | ||
| 3 | * xdisp.c (set_cursor_from_row): Don't assume glyph->charpos | 29 | * xdisp.c (set_cursor_from_row): Don't assume glyph->charpos |
diff --git a/src/dispextern.h b/src/dispextern.h index 3cc1c83c7e3..36533a3f4c5 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1927,7 +1927,7 @@ enum it_method { | |||
| 1927 | NUM_IT_METHODS | 1927 | NUM_IT_METHODS |
| 1928 | }; | 1928 | }; |
| 1929 | 1929 | ||
| 1930 | #define IT_STACK_SIZE 4 | 1930 | #define IT_STACK_SIZE 5 |
| 1931 | 1931 | ||
| 1932 | /* Iterator for composition (both for static and automatic). */ | 1932 | /* Iterator for composition (both for static and automatic). */ |
| 1933 | struct composition_it | 1933 | struct composition_it |
| @@ -2825,7 +2825,7 @@ void init_iterator P_ ((struct it *, struct window *, int, | |||
| 2825 | void init_iterator_to_row_start P_ ((struct it *, struct window *, | 2825 | void init_iterator_to_row_start P_ ((struct it *, struct window *, |
| 2826 | struct glyph_row *)); | 2826 | struct glyph_row *)); |
| 2827 | int get_next_display_element P_ ((struct it *)); | 2827 | int get_next_display_element P_ ((struct it *)); |
| 2828 | void set_iterator_to_next P_ ((struct it *, int)); | 2828 | void set_iterator_to_next P_ ((struct it *, int, int)); |
| 2829 | void start_display P_ ((struct it *, struct window *, struct text_pos)); | 2829 | void start_display P_ ((struct it *, struct window *, struct text_pos)); |
| 2830 | void move_it_to P_ ((struct it *, int, int, int, int, int)); | 2830 | void move_it_to P_ ((struct it *, int, int, int, int, int)); |
| 2831 | void move_it_vertically P_ ((struct it *, int)); | 2831 | void move_it_vertically P_ ((struct it *, int)); |
diff --git a/src/dispnew.c b/src/dispnew.c index d8cab59dbe9..d74462d31b8 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -1760,6 +1760,8 @@ check_matrix_invariants (w) | |||
| 1760 | 1760 | ||
| 1761 | /* Check that end position of `row' is equal to start position | 1761 | /* Check that end position of `row' is equal to start position |
| 1762 | of next row. */ | 1762 | of next row. */ |
| 1763 | /* WARNING: This assumption is blatantly incorrect when we are | ||
| 1764 | reordering bdirectional text for display!! */ | ||
| 1763 | if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next)) | 1765 | if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next)) |
| 1764 | { | 1766 | { |
| 1765 | xassert (MATRIX_ROW_END_CHARPOS (row) | 1767 | xassert (MATRIX_ROW_END_CHARPOS (row) |
| @@ -3500,6 +3502,8 @@ direct_output_for_insert (g) | |||
| 3500 | || !display_completed | 3502 | || !display_completed |
| 3501 | /* Give up if buffer appears in two places. */ | 3503 | /* Give up if buffer appears in two places. */ |
| 3502 | || buffer_shared > 1 | 3504 | || buffer_shared > 1 |
| 3505 | /* Give up if we need to reorder bidirectional text. */ | ||
| 3506 | || !NILP (current_buffer->bidi_display_reordering) | ||
| 3503 | /* Give up if currently displaying a message instead of the | 3507 | /* Give up if currently displaying a message instead of the |
| 3504 | minibuffer contents. */ | 3508 | minibuffer contents. */ |
| 3505 | || (EQ (selected_window, minibuf_window) | 3509 | || (EQ (selected_window, minibuf_window) |
| @@ -3608,7 +3612,7 @@ direct_output_for_insert (g) | |||
| 3608 | 3612 | ||
| 3609 | delta += 1; | 3613 | delta += 1; |
| 3610 | delta_bytes += it.len; | 3614 | delta_bytes += it.len; |
| 3611 | set_iterator_to_next (&it, 1); | 3615 | set_iterator_to_next (&it, 1, 0); |
| 3612 | } | 3616 | } |
| 3613 | 3617 | ||
| 3614 | /* Give up if we hit the right edge of the window. We would have | 3618 | /* Give up if we hit the right edge of the window. We would have |
| @@ -3626,7 +3630,7 @@ direct_output_for_insert (g) | |||
| 3626 | { | 3630 | { |
| 3627 | if (it2.c == '\t') | 3631 | if (it2.c == '\t') |
| 3628 | return 0; | 3632 | return 0; |
| 3629 | set_iterator_to_next (&it2, 1); | 3633 | set_iterator_to_next (&it2, 1, 0); |
| 3630 | } | 3634 | } |
| 3631 | 3635 | ||
| 3632 | /* Number of new glyphs produced. */ | 3636 | /* Number of new glyphs produced. */ |
diff --git a/src/xdisp.c b/src/xdisp.c index 54ac640da64..947a743ae70 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -963,11 +963,11 @@ static void run_redisplay_end_trigger_hook P_ ((struct it *)); | |||
| 963 | static int get_overlay_strings P_ ((struct it *, int)); | 963 | static int get_overlay_strings P_ ((struct it *, int)); |
| 964 | static int get_overlay_strings_1 P_ ((struct it *, int, int)); | 964 | static int get_overlay_strings_1 P_ ((struct it *, int, int)); |
| 965 | static void next_overlay_string P_ ((struct it *)); | 965 | static void next_overlay_string P_ ((struct it *)); |
| 966 | static void reseat P_ ((struct it *, struct text_pos, int)); | 966 | static void reseat P_ ((struct it *, struct text_pos, int, int)); |
| 967 | static void reseat_1 P_ ((struct it *, struct text_pos, int)); | 967 | static void reseat_1 P_ ((struct it *, struct text_pos, int, int)); |
| 968 | static void back_to_previous_visible_line_start P_ ((struct it *)); | 968 | static void back_to_previous_visible_line_start P_ ((struct it *)); |
| 969 | void reseat_at_previous_visible_line_start P_ ((struct it *)); | 969 | void reseat_at_previous_visible_line_start P_ ((struct it *)); |
| 970 | static void reseat_at_next_visible_line_start P_ ((struct it *, int)); | 970 | static void reseat_at_next_visible_line_start P_ ((struct it *, int, int)); |
| 971 | static int next_element_from_ellipsis P_ ((struct it *)); | 971 | static int next_element_from_ellipsis P_ ((struct it *)); |
| 972 | static int next_element_from_display_vector P_ ((struct it *)); | 972 | static int next_element_from_display_vector P_ ((struct it *)); |
| 973 | static int next_element_from_string P_ ((struct it *)); | 973 | static int next_element_from_string P_ ((struct it *)); |
| @@ -2823,7 +2823,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id) | |||
| 2823 | it->start = it->current; | 2823 | it->start = it->current; |
| 2824 | 2824 | ||
| 2825 | /* Compute faces etc. */ | 2825 | /* Compute faces etc. */ |
| 2826 | reseat (it, it->current.pos, 1); | 2826 | reseat (it, it->current.pos, 1, 0); |
| 2827 | } | 2827 | } |
| 2828 | 2828 | ||
| 2829 | CHECK_IT (it); | 2829 | CHECK_IT (it); |
| @@ -2883,7 +2883,7 @@ start_display (it, w, pos) | |||
| 2883 | if (it->current.dpvec_index >= 0 | 2883 | if (it->current.dpvec_index >= 0 |
| 2884 | || it->current.overlay_string_index >= 0) | 2884 | || it->current.overlay_string_index >= 0) |
| 2885 | { | 2885 | { |
| 2886 | set_iterator_to_next (it, 1); | 2886 | set_iterator_to_next (it, 1, 0); |
| 2887 | move_it_in_display_line_to (it, -1, -1, 0); | 2887 | move_it_in_display_line_to (it, -1, -1, 0); |
| 2888 | } | 2888 | } |
| 2889 | 2889 | ||
| @@ -5242,7 +5242,7 @@ forward_to_next_line_start (it, skipped_p) | |||
| 5242 | && it->c == '\n' | 5242 | && it->c == '\n' |
| 5243 | && CHARPOS (it->position) == IT_CHARPOS (*it)) | 5243 | && CHARPOS (it->position) == IT_CHARPOS (*it)) |
| 5244 | { | 5244 | { |
| 5245 | set_iterator_to_next (it, 0); | 5245 | set_iterator_to_next (it, 0, 0); |
| 5246 | it->c = 0; | 5246 | it->c = 0; |
| 5247 | return 1; | 5247 | return 1; |
| 5248 | } | 5248 | } |
| @@ -5263,7 +5263,7 @@ forward_to_next_line_start (it, skipped_p) | |||
| 5263 | if (!get_next_display_element (it)) | 5263 | if (!get_next_display_element (it)) |
| 5264 | return 0; | 5264 | return 0; |
| 5265 | newline_found_p = it->what == IT_CHARACTER && it->c == '\n'; | 5265 | newline_found_p = it->what == IT_CHARACTER && it->c == '\n'; |
| 5266 | set_iterator_to_next (it, 0); | 5266 | set_iterator_to_next (it, 0, 0); |
| 5267 | } | 5267 | } |
| 5268 | 5268 | ||
| 5269 | /* If we didn't find a newline near enough, see if we can use a | 5269 | /* If we didn't find a newline near enough, see if we can use a |
| @@ -5296,7 +5296,7 @@ forward_to_next_line_start (it, skipped_p) | |||
| 5296 | && !newline_found_p) | 5296 | && !newline_found_p) |
| 5297 | { | 5297 | { |
| 5298 | newline_found_p = ITERATOR_AT_END_OF_LINE_P (it); | 5298 | newline_found_p = ITERATOR_AT_END_OF_LINE_P (it); |
| 5299 | set_iterator_to_next (it, 0); | 5299 | set_iterator_to_next (it, 0, 0); |
| 5300 | } | 5300 | } |
| 5301 | } | 5301 | } |
| 5302 | } | 5302 | } |
| @@ -5397,22 +5397,24 @@ reseat_at_previous_visible_line_start (it) | |||
| 5397 | struct it *it; | 5397 | struct it *it; |
| 5398 | { | 5398 | { |
| 5399 | back_to_previous_visible_line_start (it); | 5399 | back_to_previous_visible_line_start (it); |
| 5400 | reseat (it, it->current.pos, 1); | 5400 | reseat (it, it->current.pos, 1, 0); |
| 5401 | CHECK_IT (it); | 5401 | CHECK_IT (it); |
| 5402 | } | 5402 | } |
| 5403 | 5403 | ||
| 5404 | 5404 | ||
| 5405 | /* Reseat iterator IT on the next visible line start in the current | 5405 | /* Reseat iterator IT on the next visible line start in the current |
| 5406 | buffer. ON_NEWLINE_P non-zero means position IT on the newline | 5406 | buffer. ON_NEWLINE_P non-zero means position IT on the newline |
| 5407 | preceding the line start. Skip over invisible text that is so | 5407 | preceding the line start. FORCE_LOGICAL_P non-zero means force |
| 5408 | because of selective display. Compute faces, overlays etc at the | 5408 | iteration in logical order even if we are reordering bidirectional |
| 5409 | new position. Note that this function does not skip over text that | 5409 | text. Skip over invisible text that is so because of selective |
| 5410 | is invisible because of text properties. */ | 5410 | display. Compute faces, overlays etc at the new position. Note |
| 5411 | that this function does not skip over text that is invisible | ||
| 5412 | because of text properties. */ | ||
| 5411 | 5413 | ||
| 5412 | static void | 5414 | static void |
| 5413 | reseat_at_next_visible_line_start (it, on_newline_p) | 5415 | reseat_at_next_visible_line_start (it, on_newline_p, force_logical_p) |
| 5414 | struct it *it; | 5416 | struct it *it; |
| 5415 | int on_newline_p; | 5417 | int on_newline_p, force_logical_p; |
| 5416 | { | 5418 | { |
| 5417 | int newline_found_p, skipped_p = 0; | 5419 | int newline_found_p, skipped_p = 0; |
| 5418 | 5420 | ||
| @@ -5443,13 +5445,16 @@ reseat_at_next_visible_line_start (it, on_newline_p) | |||
| 5443 | } | 5445 | } |
| 5444 | else if (IT_CHARPOS (*it) > BEGV) | 5446 | else if (IT_CHARPOS (*it) > BEGV) |
| 5445 | { | 5447 | { |
| 5448 | if (on_newline_p | ||
| 5449 | && !(force_logical_p || !it->bidi_p)) | ||
| 5450 | abort (); | ||
| 5446 | --IT_CHARPOS (*it); | 5451 | --IT_CHARPOS (*it); |
| 5447 | --IT_BYTEPOS (*it); | 5452 | --IT_BYTEPOS (*it); |
| 5448 | reseat (it, it->current.pos, 0); | 5453 | reseat (it, it->current.pos, 0, 1); |
| 5449 | } | 5454 | } |
| 5450 | } | 5455 | } |
| 5451 | else if (skipped_p) | 5456 | else if (skipped_p) |
| 5452 | reseat (it, it->current.pos, 0); | 5457 | reseat (it, it->current.pos, 0, force_logical_p); |
| 5453 | 5458 | ||
| 5454 | CHECK_IT (it); | 5459 | CHECK_IT (it); |
| 5455 | } | 5460 | } |
| @@ -5463,17 +5468,19 @@ reseat_at_next_visible_line_start (it, on_newline_p) | |||
| 5463 | /* Change IT's current position to POS in current_buffer. If FORCE_P | 5468 | /* Change IT's current position to POS in current_buffer. If FORCE_P |
| 5464 | is non-zero, always check for text properties at the new position. | 5469 | is non-zero, always check for text properties at the new position. |
| 5465 | Otherwise, text properties are only looked up if POS >= | 5470 | Otherwise, text properties are only looked up if POS >= |
| 5466 | IT->check_charpos of a property. */ | 5471 | IT->check_charpos of a property. If FORCE_LOGICAL_P is non-zero, |
| 5472 | force iteration in logical order even when reordering bidirectional | ||
| 5473 | text. */ | ||
| 5467 | 5474 | ||
| 5468 | static void | 5475 | static void |
| 5469 | reseat (it, pos, force_p) | 5476 | reseat (it, pos, force_p, force_logical_p) |
| 5470 | struct it *it; | 5477 | struct it *it; |
| 5471 | struct text_pos pos; | 5478 | struct text_pos pos; |
| 5472 | int force_p; | 5479 | int force_p, force_logical_p; |
| 5473 | { | 5480 | { |
| 5474 | int original_pos = IT_CHARPOS (*it); | 5481 | int original_pos = IT_CHARPOS (*it); |
| 5475 | 5482 | ||
| 5476 | reseat_1 (it, pos, 0); | 5483 | reseat_1 (it, pos, 0, force_logical_p); |
| 5477 | 5484 | ||
| 5478 | /* Determine where to check text properties. Avoid doing it | 5485 | /* Determine where to check text properties. Avoid doing it |
| 5479 | where possible because text property lookup is very expensive. */ | 5486 | where possible because text property lookup is very expensive. */ |
| @@ -5487,13 +5494,15 @@ reseat (it, pos, force_p) | |||
| 5487 | 5494 | ||
| 5488 | 5495 | ||
| 5489 | /* Change IT's buffer position to POS. SET_STOP_P non-zero means set | 5496 | /* Change IT's buffer position to POS. SET_STOP_P non-zero means set |
| 5490 | IT->stop_pos to POS, also. */ | 5497 | IT->stop_pos to POS, also. FORCE_LOGICAL_P non-zero means force |
| 5498 | iteration in logical order even when reordering bidirectional | ||
| 5499 | text. */ | ||
| 5491 | 5500 | ||
| 5492 | static void | 5501 | static void |
| 5493 | reseat_1 (it, pos, set_stop_p) | 5502 | reseat_1 (it, pos, set_stop_p, force_logical_p) |
| 5494 | struct it *it; | 5503 | struct it *it; |
| 5495 | struct text_pos pos; | 5504 | struct text_pos pos; |
| 5496 | int set_stop_p; | 5505 | int set_stop_p, force_logical_p; |
| 5497 | { | 5506 | { |
| 5498 | /* Don't call this function when scanning a C string. */ | 5507 | /* Don't call this function when scanning a C string. */ |
| 5499 | xassert (it->s == NULL); | 5508 | xassert (it->s == NULL); |
| @@ -5518,7 +5527,7 @@ reseat_1 (it, pos, set_stop_p) | |||
| 5518 | it->string_from_display_prop_p = 0; | 5527 | it->string_from_display_prop_p = 0; |
| 5519 | it->face_before_selective_p = 0; | 5528 | it->face_before_selective_p = 0; |
| 5520 | 5529 | ||
| 5521 | if (it->bidi_p) | 5530 | if (it->bidi_p && !force_logical_p) |
| 5522 | { | 5531 | { |
| 5523 | /* FIXME: L2R below is just for easyness of testing, as we | 5532 | /* FIXME: L2R below is just for easyness of testing, as we |
| 5524 | currently support only left-to-right paragraphs. The value | 5533 | currently support only left-to-right paragraphs. The value |
| @@ -5729,7 +5738,7 @@ get_next_display_element (it) | |||
| 5729 | } | 5738 | } |
| 5730 | else | 5739 | else |
| 5731 | { | 5740 | { |
| 5732 | set_iterator_to_next (it, 0); | 5741 | set_iterator_to_next (it, 0, 0); |
| 5733 | } | 5742 | } |
| 5734 | goto get_next; | 5743 | goto get_next; |
| 5735 | } | 5744 | } |
| @@ -6051,6 +6060,9 @@ get_next_display_element (it) | |||
| 6051 | RESEAT_P non-zero means if called on a newline in buffer text, | 6060 | RESEAT_P non-zero means if called on a newline in buffer text, |
| 6052 | skip to the next visible line start. | 6061 | skip to the next visible line start. |
| 6053 | 6062 | ||
| 6063 | FORCE_LOGICAL_P non-zero means force iteration in logical order | ||
| 6064 | even when reordering bidirectional text. | ||
| 6065 | |||
| 6054 | Functions get_next_display_element and set_iterator_to_next are | 6066 | Functions get_next_display_element and set_iterator_to_next are |
| 6055 | separate because I find this arrangement easier to handle than a | 6067 | separate because I find this arrangement easier to handle than a |
| 6056 | get_next_display_element function that also increments IT's | 6068 | get_next_display_element function that also increments IT's |
| @@ -6062,9 +6074,9 @@ get_next_display_element (it) | |||
| 6062 | decrement position function which would not be easy to write. */ | 6074 | decrement position function which would not be easy to write. */ |
| 6063 | 6075 | ||
| 6064 | void | 6076 | void |
| 6065 | set_iterator_to_next (it, reseat_p) | 6077 | set_iterator_to_next (it, reseat_p, force_logical_p) |
| 6066 | struct it *it; | 6078 | struct it *it; |
| 6067 | int reseat_p; | 6079 | int reseat_p, force_logical_p; |
| 6068 | { | 6080 | { |
| 6069 | /* Reset flags indicating start and end of a sequence of characters | 6081 | /* Reset flags indicating start and end of a sequence of characters |
| 6070 | with box. Reset them at the start of this function because | 6082 | with box. Reset them at the start of this function because |
| @@ -6078,7 +6090,7 @@ set_iterator_to_next (it, reseat_p) | |||
| 6078 | current_buffer. Advance in the buffer, and maybe skip over | 6090 | current_buffer. Advance in the buffer, and maybe skip over |
| 6079 | invisible lines that are so because of selective display. */ | 6091 | invisible lines that are so because of selective display. */ |
| 6080 | if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p) | 6092 | if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p) |
| 6081 | reseat_at_next_visible_line_start (it, 0); | 6093 | reseat_at_next_visible_line_start (it, 0, force_logical_p); |
| 6082 | else if (it->cmp_it.id >= 0) | 6094 | else if (it->cmp_it.id >= 0) |
| 6083 | { | 6095 | { |
| 6084 | IT_CHARPOS (*it) += it->cmp_it.nchars; | 6096 | IT_CHARPOS (*it) += it->cmp_it.nchars; |
| @@ -6097,7 +6109,7 @@ set_iterator_to_next (it, reseat_p) | |||
| 6097 | { | 6109 | { |
| 6098 | xassert (it->len != 0); | 6110 | xassert (it->len != 0); |
| 6099 | 6111 | ||
| 6100 | if (! it->bidi_p) | 6112 | if (!(it->bidi_p && !force_logical_p)) |
| 6101 | { | 6113 | { |
| 6102 | IT_BYTEPOS (*it) += it->len; | 6114 | IT_BYTEPOS (*it) += it->len; |
| 6103 | IT_CHARPOS (*it) += 1; | 6115 | IT_CHARPOS (*it) += 1; |
| @@ -6148,14 +6160,14 @@ set_iterator_to_next (it, reseat_p) | |||
| 6148 | 6160 | ||
| 6149 | /* Skip over characters which were displayed via IT->dpvec. */ | 6161 | /* Skip over characters which were displayed via IT->dpvec. */ |
| 6150 | if (it->dpvec_char_len < 0) | 6162 | if (it->dpvec_char_len < 0) |
| 6151 | reseat_at_next_visible_line_start (it, 1); | 6163 | reseat_at_next_visible_line_start (it, 1, 1); |
| 6152 | else if (it->dpvec_char_len > 0) | 6164 | else if (it->dpvec_char_len > 0) |
| 6153 | { | 6165 | { |
| 6154 | if (it->method == GET_FROM_STRING | 6166 | if (it->method == GET_FROM_STRING |
| 6155 | && it->n_overlay_strings > 0) | 6167 | && it->n_overlay_strings > 0) |
| 6156 | it->ignore_overlay_strings_at_pos_p = 1; | 6168 | it->ignore_overlay_strings_at_pos_p = 1; |
| 6157 | it->len = it->dpvec_char_len; | 6169 | it->len = it->dpvec_char_len; |
| 6158 | set_iterator_to_next (it, reseat_p); | 6170 | set_iterator_to_next (it, reseat_p, 0); |
| 6159 | } | 6171 | } |
| 6160 | 6172 | ||
| 6161 | /* Maybe recheck faces after display vector */ | 6173 | /* Maybe recheck faces after display vector */ |
| @@ -6461,7 +6473,7 @@ next_element_from_ellipsis (it) | |||
| 6461 | it->saved_face_id = it->face_id; | 6473 | it->saved_face_id = it->face_id; |
| 6462 | it->method = GET_FROM_BUFFER; | 6474 | it->method = GET_FROM_BUFFER; |
| 6463 | it->object = it->w->buffer; | 6475 | it->object = it->w->buffer; |
| 6464 | reseat_at_next_visible_line_start (it, 1); | 6476 | reseat_at_next_visible_line_start (it, 1, 1); |
| 6465 | it->face_before_selective_p = 1; | 6477 | it->face_before_selective_p = 1; |
| 6466 | } | 6478 | } |
| 6467 | 6479 | ||
| @@ -6849,7 +6861,7 @@ move_it_in_display_line_to (struct it *it, | |||
| 6849 | 6861 | ||
| 6850 | if (it->area != TEXT_AREA) | 6862 | if (it->area != TEXT_AREA) |
| 6851 | { | 6863 | { |
| 6852 | set_iterator_to_next (it, 1); | 6864 | set_iterator_to_next (it, 1, 0); |
| 6853 | continue; | 6865 | continue; |
| 6854 | } | 6866 | } |
| 6855 | 6867 | ||
| @@ -6957,7 +6969,7 @@ move_it_in_display_line_to (struct it *it, | |||
| 6957 | } | 6969 | } |
| 6958 | } | 6970 | } |
| 6959 | 6971 | ||
| 6960 | set_iterator_to_next (it, 1); | 6972 | set_iterator_to_next (it, 1, 0); |
| 6961 | /* On graphical terminals, newlines may | 6973 | /* On graphical terminals, newlines may |
| 6962 | "overflow" into the fringe if | 6974 | "overflow" into the fringe if |
| 6963 | overflow-newline-into-fringe is non-nil. | 6975 | overflow-newline-into-fringe is non-nil. |
| @@ -7053,7 +7065,7 @@ move_it_in_display_line_to (struct it *it, | |||
| 7053 | 7065 | ||
| 7054 | /* The current display element has been consumed. Advance | 7066 | /* The current display element has been consumed. Advance |
| 7055 | to the next. */ | 7067 | to the next. */ |
| 7056 | set_iterator_to_next (it, 1); | 7068 | set_iterator_to_next (it, 1, 0); |
| 7057 | 7069 | ||
| 7058 | /* Stop if lines are truncated and IT's current x-position is | 7070 | /* Stop if lines are truncated and IT's current x-position is |
| 7059 | past the right edge of the window now. */ | 7071 | past the right edge of the window now. */ |
| @@ -7298,13 +7310,13 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op) | |||
| 7298 | goto out; | 7310 | goto out; |
| 7299 | 7311 | ||
| 7300 | case MOVE_NEWLINE_OR_CR: | 7312 | case MOVE_NEWLINE_OR_CR: |
| 7301 | set_iterator_to_next (it, 1); | 7313 | set_iterator_to_next (it, 1, 0); |
| 7302 | it->continuation_lines_width = 0; | 7314 | it->continuation_lines_width = 0; |
| 7303 | break; | 7315 | break; |
| 7304 | 7316 | ||
| 7305 | case MOVE_LINE_TRUNCATED: | 7317 | case MOVE_LINE_TRUNCATED: |
| 7306 | it->continuation_lines_width = 0; | 7318 | it->continuation_lines_width = 0; |
| 7307 | reseat_at_next_visible_line_start (it, 0); | 7319 | reseat_at_next_visible_line_start (it, 0, 0); |
| 7308 | if ((op & MOVE_TO_POS) != 0 | 7320 | if ((op & MOVE_TO_POS) != 0 |
| 7309 | && IT_CHARPOS (*it) > to_charpos) | 7321 | && IT_CHARPOS (*it) > to_charpos) |
| 7310 | { | 7322 | { |
| @@ -7330,7 +7342,7 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op) | |||
| 7330 | { | 7342 | { |
| 7331 | line_start_x = it->current_x + it->pixel_width | 7343 | line_start_x = it->current_x + it->pixel_width |
| 7332 | - it->last_visible_x; | 7344 | - it->last_visible_x; |
| 7333 | set_iterator_to_next (it, 0); | 7345 | set_iterator_to_next (it, 0, 0); |
| 7334 | } | 7346 | } |
| 7335 | } | 7347 | } |
| 7336 | else | 7348 | else |
| @@ -7416,7 +7428,7 @@ move_it_vertically_backward (it, dy) | |||
| 7416 | reseat to skip forward over invisible text, set up the iterator | 7428 | reseat to skip forward over invisible text, set up the iterator |
| 7417 | to deliver from overlay strings at the new position etc. So, | 7429 | to deliver from overlay strings at the new position etc. So, |
| 7418 | use reseat_1 here. */ | 7430 | use reseat_1 here. */ |
| 7419 | reseat_1 (it, it->current.pos, 1); | 7431 | reseat_1 (it, it->current.pos, 1, 0); |
| 7420 | 7432 | ||
| 7421 | /* We are now surely at a line start. */ | 7433 | /* We are now surely at a line start. */ |
| 7422 | it->current_x = it->hpos = 0; | 7434 | it->current_x = it->hpos = 0; |
| @@ -7546,7 +7558,7 @@ move_it_past_eol (it) | |||
| 7546 | 7558 | ||
| 7547 | rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS); | 7559 | rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS); |
| 7548 | if (rc == MOVE_NEWLINE_OR_CR) | 7560 | if (rc == MOVE_NEWLINE_OR_CR) |
| 7549 | set_iterator_to_next (it, 0); | 7561 | set_iterator_to_next (it, 0, 0); |
| 7550 | } | 7562 | } |
| 7551 | 7563 | ||
| 7552 | 7564 | ||
| @@ -7575,7 +7587,7 @@ move_it_by_lines (it, dvpos, need_y_p) | |||
| 7575 | 7587 | ||
| 7576 | pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w); | 7588 | pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w); |
| 7577 | SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos); | 7589 | SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos); |
| 7578 | reseat (it, textpos, 1); | 7590 | reseat (it, textpos, 1, 0); |
| 7579 | it->vpos += pos.vpos; | 7591 | it->vpos += pos.vpos; |
| 7580 | it->current_y += pos.vpos; | 7592 | it->current_y += pos.vpos; |
| 7581 | } | 7593 | } |
| @@ -7611,7 +7623,7 @@ move_it_by_lines (it, dvpos, need_y_p) | |||
| 7611 | start_charpos = IT_CHARPOS (*it); | 7623 | start_charpos = IT_CHARPOS (*it); |
| 7612 | for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i) | 7624 | for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i) |
| 7613 | back_to_previous_visible_line_start (it); | 7625 | back_to_previous_visible_line_start (it); |
| 7614 | reseat (it, it->current.pos, 1); | 7626 | reseat (it, it->current.pos, 1, 0); |
| 7615 | 7627 | ||
| 7616 | /* Move further back if we end up in a string or an image. */ | 7628 | /* Move further back if we end up in a string or an image. */ |
| 7617 | while (!IT_POS_VALID_AFTER_MOVE_P (it)) | 7629 | while (!IT_POS_VALID_AFTER_MOVE_P (it)) |
| @@ -7625,7 +7637,7 @@ move_it_by_lines (it, dvpos, need_y_p) | |||
| 7625 | /* If start of line is still in string or image, | 7637 | /* If start of line is still in string or image, |
| 7626 | move further back. */ | 7638 | move further back. */ |
| 7627 | back_to_previous_visible_line_start (it); | 7639 | back_to_previous_visible_line_start (it); |
| 7628 | reseat (it, it->current.pos, 1); | 7640 | reseat (it, it->current.pos, 1, 0); |
| 7629 | dvpos--; | 7641 | dvpos--; |
| 7630 | } | 7642 | } |
| 7631 | 7643 | ||
| @@ -10226,7 +10238,7 @@ display_tool_bar_line (it, height) | |||
| 10226 | if (ITERATOR_AT_END_OF_LINE_P (it)) | 10238 | if (ITERATOR_AT_END_OF_LINE_P (it)) |
| 10227 | break; | 10239 | break; |
| 10228 | 10240 | ||
| 10229 | set_iterator_to_next (it, 1); | 10241 | set_iterator_to_next (it, 1, 0); |
| 10230 | } | 10242 | } |
| 10231 | 10243 | ||
| 10232 | out:; | 10244 | out:; |
| @@ -16548,6 +16560,7 @@ display_line (it) | |||
| 16548 | int wrap_row_used = -1, wrap_row_ascent, wrap_row_height; | 16560 | int wrap_row_used = -1, wrap_row_ascent, wrap_row_height; |
| 16549 | int wrap_row_phys_ascent, wrap_row_phys_height; | 16561 | int wrap_row_phys_ascent, wrap_row_phys_height; |
| 16550 | int wrap_row_extra_line_spacing; | 16562 | int wrap_row_extra_line_spacing; |
| 16563 | struct display_pos row_end; | ||
| 16551 | 16564 | ||
| 16552 | /* We always start displaying at hpos zero even if hscrolled. */ | 16565 | /* We always start displaying at hpos zero even if hscrolled. */ |
| 16553 | xassert (it->hpos == 0 && it->current_x == 0); | 16566 | xassert (it->hpos == 0 && it->current_x == 0); |
| @@ -16636,6 +16649,7 @@ display_line (it) | |||
| 16636 | 16649 | ||
| 16637 | it->continuation_lines_width = 0; | 16650 | it->continuation_lines_width = 0; |
| 16638 | row->ends_at_zv_p = 1; | 16651 | row->ends_at_zv_p = 1; |
| 16652 | row_end = it->current; | ||
| 16639 | break; | 16653 | break; |
| 16640 | } | 16654 | } |
| 16641 | 16655 | ||
| @@ -16685,7 +16699,7 @@ display_line (it) | |||
| 16685 | it->max_phys_ascent + it->max_phys_descent); | 16699 | it->max_phys_ascent + it->max_phys_descent); |
| 16686 | row->extra_line_spacing = max (row->extra_line_spacing, | 16700 | row->extra_line_spacing = max (row->extra_line_spacing, |
| 16687 | it->max_extra_line_spacing); | 16701 | it->max_extra_line_spacing); |
| 16688 | set_iterator_to_next (it, 1); | 16702 | set_iterator_to_next (it, 1, 0); |
| 16689 | continue; | 16703 | continue; |
| 16690 | } | 16704 | } |
| 16691 | 16705 | ||
| @@ -16764,7 +16778,7 @@ display_line (it) | |||
| 16764 | || IT_DISPLAYING_WHITESPACE (it))) | 16778 | || IT_DISPLAYING_WHITESPACE (it))) |
| 16765 | goto back_to_wrap; | 16779 | goto back_to_wrap; |
| 16766 | 16780 | ||
| 16767 | set_iterator_to_next (it, 1); | 16781 | set_iterator_to_next (it, 1, 0); |
| 16768 | if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) | 16782 | if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) |
| 16769 | { | 16783 | { |
| 16770 | if (!get_next_display_element (it)) | 16784 | if (!get_next_display_element (it)) |
| @@ -16870,6 +16884,7 @@ display_line (it) | |||
| 16870 | it->max_phys_descent = phys_descent; | 16884 | it->max_phys_descent = phys_descent; |
| 16871 | } | 16885 | } |
| 16872 | 16886 | ||
| 16887 | row_end = it->current; | ||
| 16873 | break; | 16888 | break; |
| 16874 | } | 16889 | } |
| 16875 | else if (new_x > it->first_visible_x) | 16890 | else if (new_x > it->first_visible_x) |
| @@ -16903,7 +16918,10 @@ display_line (it) | |||
| 16903 | 16918 | ||
| 16904 | /* End of this display line if row is continued. */ | 16919 | /* End of this display line if row is continued. */ |
| 16905 | if (row->continued_p || row->ends_at_zv_p) | 16920 | if (row->continued_p || row->ends_at_zv_p) |
| 16906 | break; | 16921 | { |
| 16922 | row_end = it->current; | ||
| 16923 | break; | ||
| 16924 | } | ||
| 16907 | } | 16925 | } |
| 16908 | 16926 | ||
| 16909 | at_end_of_line: | 16927 | at_end_of_line: |
| @@ -16929,14 +16947,26 @@ display_line (it) | |||
| 16929 | row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position); | 16947 | row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position); |
| 16930 | 16948 | ||
| 16931 | /* Consume the line end. This skips over invisible lines. */ | 16949 | /* Consume the line end. This skips over invisible lines. */ |
| 16932 | set_iterator_to_next (it, 1); | 16950 | if (it->bidi_p) |
| 16951 | { | ||
| 16952 | /* When we are reordering bidi text, we still need the | ||
| 16953 | next character in logical order, to set row->end | ||
| 16954 | correctly below. */ | ||
| 16955 | push_it (it); | ||
| 16956 | set_iterator_to_next (it, 1, 1); | ||
| 16957 | row_end = it->current; | ||
| 16958 | pop_it (it); | ||
| 16959 | } | ||
| 16960 | set_iterator_to_next (it, 1, 0); | ||
| 16933 | it->continuation_lines_width = 0; | 16961 | it->continuation_lines_width = 0; |
| 16962 | if (!it->bidi_p) | ||
| 16963 | row_end = it->current; | ||
| 16934 | break; | 16964 | break; |
| 16935 | } | 16965 | } |
| 16936 | 16966 | ||
| 16937 | /* Proceed with next display element. Note that this skips | 16967 | /* Proceed with next display element. Note that this skips |
| 16938 | over lines invisible because of selective display. */ | 16968 | over lines invisible because of selective display. */ |
| 16939 | set_iterator_to_next (it, 1); | 16969 | set_iterator_to_next (it, 1, 0); |
| 16940 | 16970 | ||
| 16941 | /* If we truncate lines, we are done when the last displayed | 16971 | /* If we truncate lines, we are done when the last displayed |
| 16942 | glyphs reach past the right margin of the window. */ | 16972 | glyphs reach past the right margin of the window. */ |
| @@ -16968,6 +16998,7 @@ display_line (it) | |||
| 16968 | it->continuation_lines_width = 0; | 16998 | it->continuation_lines_width = 0; |
| 16969 | row->ends_at_zv_p = 1; | 16999 | row->ends_at_zv_p = 1; |
| 16970 | row->exact_window_width_line_p = 1; | 17000 | row->exact_window_width_line_p = 1; |
| 17001 | row_end = it->current; | ||
| 16971 | break; | 17002 | break; |
| 16972 | } | 17003 | } |
| 16973 | if (ITERATOR_AT_END_OF_LINE_P (it)) | 17004 | if (ITERATOR_AT_END_OF_LINE_P (it)) |
| @@ -16979,10 +17010,11 @@ display_line (it) | |||
| 16979 | 17010 | ||
| 16980 | row->truncated_on_right_p = 1; | 17011 | row->truncated_on_right_p = 1; |
| 16981 | it->continuation_lines_width = 0; | 17012 | it->continuation_lines_width = 0; |
| 16982 | reseat_at_next_visible_line_start (it, 0); | 17013 | reseat_at_next_visible_line_start (it, 0, 0); |
| 16983 | row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n'; | 17014 | row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n'; |
| 16984 | it->hpos = hpos_before; | 17015 | it->hpos = hpos_before; |
| 16985 | it->current_x = x_before; | 17016 | it->current_x = x_before; |
| 17017 | row_end = it->current; | ||
| 16986 | break; | 17018 | break; |
| 16987 | } | 17019 | } |
| 16988 | } | 17020 | } |
| @@ -17043,7 +17075,7 @@ display_line (it) | |||
| 17043 | compute_line_metrics (it); | 17075 | compute_line_metrics (it); |
| 17044 | 17076 | ||
| 17045 | /* Remember the position at which this line ends. */ | 17077 | /* Remember the position at which this line ends. */ |
| 17046 | row->end = it->current; | 17078 | row->end = row_end; |
| 17047 | 17079 | ||
| 17048 | /* Record whether this row ends inside an ellipsis. */ | 17080 | /* Record whether this row ends inside an ellipsis. */ |
| 17049 | row->ends_in_ellipsis_p | 17081 | row->ends_in_ellipsis_p |
| @@ -17080,7 +17112,7 @@ display_line (it) | |||
| 17080 | it->current_y += row->height; | 17112 | it->current_y += row->height; |
| 17081 | ++it->vpos; | 17113 | ++it->vpos; |
| 17082 | ++it->glyph_row; | 17114 | ++it->glyph_row; |
| 17083 | it->start = it->current; | 17115 | it->start = row_end; |
| 17084 | return row->displays_text_p; | 17116 | return row->displays_text_p; |
| 17085 | } | 17117 | } |
| 17086 | 17118 | ||
| @@ -19024,7 +19056,7 @@ display_string (string, lisp_string, face_string, face_string_pos, | |||
| 19024 | break; | 19056 | break; |
| 19025 | } | 19057 | } |
| 19026 | 19058 | ||
| 19027 | set_iterator_to_next (it, 1); | 19059 | set_iterator_to_next (it, 1, 0); |
| 19028 | 19060 | ||
| 19029 | /* Stop if truncating at the right edge. */ | 19061 | /* Stop if truncating at the right edge. */ |
| 19030 | if (it->line_wrap == TRUNCATE | 19062 | if (it->line_wrap == TRUNCATE |