diff options
| author | Eli Zaretskii | 2010-01-01 09:46:25 -0500 |
|---|---|---|
| committer | Eli Zaretskii | 2010-01-01 09:46:25 -0500 |
| commit | e69a937075490a19d1b767e166d10f0e838b4173 (patch) | |
| tree | bfadd69c44dbffc682070d25db53b88abc86cea6 /src | |
| parent | 17a024a87de4008cd6cf94dd3b780efc7ace9a01 (diff) | |
| download | emacs-e69a937075490a19d1b767e166d10f0e838b4173.tar.gz emacs-e69a937075490a19d1b767e166d10f0e838b4173.zip | |
Retrospective commit from 2009-12-12.
Begin working on faces support. First version of handle_stop_backwards.
Rearrange struct bidi_it for more efficient push/pop ops.
dispextern.h (struct it): New members prev_stop and
base_level_stop.
xdisp.c (handle_stop_backwards): New function.
(next_element_from_buffer): Handle the situation where we
overstepped stop_charpos due to non-linearity of the bidi
iteration. Likewise for when we back up beyond the previous
stop_charpos.
(reseat_1, pop_it, push_it): Set prev_stop and base_level_stop.
dispextern.h (BIDI_AT_BASE_LEVEL): New macro.
bidi.c (bidi_copy_it): Fix compiler warning due to cast of a
pointer to `int'. Don't preserve the first_elt member, as it is
no longer copied, because its position in the structure was
changed, see below.
dispextern.h (struct bidi_it): Move first_elt, new_paragraph,
separator_limit, and paragraph_dir to after bidi_stack. Add a
note that anything beyond the level stack is not preserved when
the bidi iterator state is copied/saved.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog.bidi | 24 | ||||
| -rw-r--r-- | src/bidi.c | 9 | ||||
| -rw-r--r-- | src/dispextern.h | 37 | ||||
| -rw-r--r-- | src/xdisp.c | 92 |
4 files changed, 133 insertions, 29 deletions
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index e3e1eddab75..ef911354df8 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi | |||
| @@ -1,3 +1,27 @@ | |||
| 1 | 2009-12-12 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * dispextern.h (struct it): New members prev_stop and | ||
| 4 | base_level_stop. | ||
| 5 | |||
| 6 | * xdisp.c (handle_stop_backwards): New function. | ||
| 7 | (next_element_from_buffer): Handle the situation where we | ||
| 8 | overstepped stop_charpos due to non-linearity of the bidi | ||
| 9 | iteration. Likewise for when we back up beyond the previous | ||
| 10 | stop_charpos. | ||
| 11 | (reseat_1, pop_it, push_it): Set prev_stop and base_level_stop. | ||
| 12 | |||
| 13 | * dispextern.h (BIDI_AT_BASE_LEVEL): New macro. | ||
| 14 | |||
| 15 | * bidi.c (bidi_copy_it): Fix compiler warning due to cast of a | ||
| 16 | pointer to `int'. Don't preserve the first_elt member, as it is | ||
| 17 | no longer copied, because its position in the structure was | ||
| 18 | changed, see below. | ||
| 19 | |||
| 20 | * dispextern.h (struct bidi_it): Move first_elt, new_paragraph, | ||
| 21 | separator_limit, and paragraph_dir to after bidi_stack. Add a | ||
| 22 | note that anything beyond the level stack is not preserved when | ||
| 23 | the bidi iterator state is copied/saved. | ||
| 24 | |||
| 1 | 2009-11-21 Eli Zaretskii <eliz@gnu.org> | 25 | 2009-11-21 Eli Zaretskii <eliz@gnu.org> |
| 2 | 26 | ||
| 3 | * xdisp.c (set_cursor_from_row): Fix cursor positioning on empty | 27 | * xdisp.c (set_cursor_from_row): Fix cursor positioning on empty |
diff --git a/src/bidi.c b/src/bidi.c index e8b7b2a8c56..102326b41e8 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -528,15 +528,10 @@ bidi_mirror_char (int c) | |||
| 528 | static inline void | 528 | static inline void |
| 529 | bidi_copy_it (struct bidi_it *to, struct bidi_it *from) | 529 | bidi_copy_it (struct bidi_it *to, struct bidi_it *from) |
| 530 | { | 530 | { |
| 531 | int save_first_elt = to->first_elt; | ||
| 532 | int i; | 531 | int i; |
| 533 | 532 | ||
| 534 | /* Copy everything except the level stack. */ | 533 | /* Copy everything except the level stack and beyond. */ |
| 535 | memcpy (to, from, ((int)&((struct bidi_it *)0)->level_stack[0])); | 534 | memcpy (to, from, ((size_t)&((struct bidi_it *)0)->level_stack[0])); |
| 536 | /* Don't copy FIRST_ELT flag. */ | ||
| 537 | to->first_elt = save_first_elt; | ||
| 538 | if (to->first_elt != 0 && to->first_elt != 1) | ||
| 539 | to->first_elt = 0; | ||
| 540 | 535 | ||
| 541 | /* Copy the active part of the level stack. */ | 536 | /* Copy the active part of the level stack. */ |
| 542 | to->level_stack[0] = from->level_stack[0]; /* level zero is always in use */ | 537 | to->level_stack[0] = from->level_stack[0]; /* level zero is always in use */ |
diff --git a/src/dispextern.h b/src/dispextern.h index 19e3f13fd87..58e6ff91338 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -370,7 +370,7 @@ struct glyph | |||
| 370 | /* Non-zero means don't display cursor here. */ | 370 | /* Non-zero means don't display cursor here. */ |
| 371 | unsigned avoid_cursor_p : 1; | 371 | unsigned avoid_cursor_p : 1; |
| 372 | 372 | ||
| 373 | /* Resolved bidirection level of the characters [0..63]. */ | 373 | /* Resolved bidirectional level of this character [0..63]. */ |
| 374 | unsigned resolved_level : 5; | 374 | unsigned resolved_level : 5; |
| 375 | 375 | ||
| 376 | /* Resolved bidirectional type of this character, see enum | 376 | /* Resolved bidirectional type of this character, see enum |
| @@ -750,8 +750,8 @@ struct glyph_row | |||
| 750 | overlay position information etc, where the display of this row | 750 | overlay position information etc, where the display of this row |
| 751 | started, and can thus be less the position of the first glyph | 751 | started, and can thus be less the position of the first glyph |
| 752 | (e.g. due to invisible text or horizontal scrolling). BIDI Note: | 752 | (e.g. due to invisible text or horizontal scrolling). BIDI Note: |
| 753 | This is the smallest character position in the row, i.e. not | 753 | This is the smallest character position in the row, but not |
| 754 | necessarily the character that is displayed the leftmost. */ | 754 | necessarily the character that is the leftmost on the display. */ |
| 755 | struct display_pos start; | 755 | struct display_pos start; |
| 756 | 756 | ||
| 757 | /* Text position at the end of this row. This is the position after | 757 | /* Text position at the end of this row. This is the position after |
| @@ -759,8 +759,8 @@ struct glyph_row | |||
| 759 | glyph position + 1, due to truncation, invisible text etc. In an | 759 | glyph position + 1, due to truncation, invisible text etc. In an |
| 760 | up-to-date display, this should always be equal to the start | 760 | up-to-date display, this should always be equal to the start |
| 761 | position of the next row. BIDI Note: this is the character whose | 761 | position of the next row. BIDI Note: this is the character whose |
| 762 | buffer position is the largest, not necessarily the one displayed | 762 | buffer position is the largest, but not necessarily the rightmost |
| 763 | the rightmost. */ | 763 | one on the display. */ |
| 764 | struct display_pos end; | 764 | struct display_pos end; |
| 765 | 765 | ||
| 766 | /* Non-zero means the overlay arrow bitmap is on this line. | 766 | /* Non-zero means the overlay arrow bitmap is on this line. |
| @@ -1726,7 +1726,7 @@ struct face_cache | |||
| 1726 | 1726 | ||
| 1727 | extern int face_change_count; | 1727 | extern int face_change_count; |
| 1728 | 1728 | ||
| 1729 | /* For BIDI */ | 1729 | /* For reordering of bidirectional text. */ |
| 1730 | #define BIDI_MAXLEVEL 64 | 1730 | #define BIDI_MAXLEVEL 64 |
| 1731 | 1731 | ||
| 1732 | /* Data type for describing the bidirectional character types. The | 1732 | /* Data type for describing the bidirectional character types. The |
| @@ -1777,7 +1777,6 @@ struct bidi_stack { | |||
| 1777 | 1777 | ||
| 1778 | /* Data type for iterating over bidi text. */ | 1778 | /* Data type for iterating over bidi text. */ |
| 1779 | struct bidi_it { | 1779 | struct bidi_it { |
| 1780 | int first_elt; /* if non-zero, examine current char first */ | ||
| 1781 | EMACS_INT bytepos; /* iterator's position in buffer */ | 1780 | EMACS_INT bytepos; /* iterator's position in buffer */ |
| 1782 | EMACS_INT charpos; | 1781 | EMACS_INT charpos; |
| 1783 | int ch; /* character itself */ | 1782 | int ch; /* character itself */ |
| @@ -1789,9 +1788,6 @@ struct bidi_it { | |||
| 1789 | int resolved_level; /* final resolved level of this character */ | 1788 | int resolved_level; /* final resolved level of this character */ |
| 1790 | int invalid_levels; /* how many PDFs to ignore */ | 1789 | int invalid_levels; /* how many PDFs to ignore */ |
| 1791 | int invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */ | 1790 | int invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */ |
| 1792 | int new_paragraph; /* if non-zero, we expect a new paragraph */ | ||
| 1793 | EMACS_INT separator_limit; /* where paragraph separator should end */ | ||
| 1794 | bidi_dir_t paragraph_dir; /* current paragraph direction */ | ||
| 1795 | int prev_was_pdf; /* if non-zero, previous char was PDF */ | 1791 | int prev_was_pdf; /* if non-zero, previous char was PDF */ |
| 1796 | struct bidi_saved_info prev; /* info about previous character */ | 1792 | struct bidi_saved_info prev; /* info about previous character */ |
| 1797 | struct bidi_saved_info last_strong; /* last-seen strong directional char */ | 1793 | struct bidi_saved_info last_strong; /* last-seen strong directional char */ |
| @@ -1803,10 +1799,20 @@ struct bidi_it { | |||
| 1803 | bidi_dir_t sor; /* direction of start-of-run in effect */ | 1799 | bidi_dir_t sor; /* direction of start-of-run in effect */ |
| 1804 | int scan_dir; /* direction of text scan */ | 1800 | int scan_dir; /* direction of text scan */ |
| 1805 | int stack_idx; /* index of current data on the stack */ | 1801 | int stack_idx; /* index of current data on the stack */ |
| 1802 | /* Note: Everything from here is not copied/saved when the bidi | ||
| 1803 | iterator state is saved, pushed, or popped. So only put here | ||
| 1804 | stuff that is not part of the bidi iterator's state! */ | ||
| 1806 | struct bidi_stack level_stack[BIDI_MAXLEVEL]; /* stack of embedding levels */ | 1805 | struct bidi_stack level_stack[BIDI_MAXLEVEL]; /* stack of embedding levels */ |
| 1806 | int first_elt; /* if non-zero, examine current char first */ | ||
| 1807 | bidi_dir_t paragraph_dir; /* current paragraph direction */ | ||
| 1808 | int new_paragraph; /* if non-zero, we expect a new paragraph */ | ||
| 1809 | EMACS_INT separator_limit; /* where paragraph separator should end */ | ||
| 1807 | }; | 1810 | }; |
| 1808 | 1811 | ||
| 1809 | 1812 | /* Value is non-zero when the bidi iterator is at base paragraph | |
| 1813 | embedding level. */ | ||
| 1814 | #define BIDI_AT_BASE_LEVEL(BIDI_IT) \ | ||
| 1815 | (BIDI_IT).resolved_level == (BIDI_IT).level_stack[0].level | ||
| 1810 | 1816 | ||
| 1811 | 1817 | ||
| 1812 | /*********************************************************************** | 1818 | /*********************************************************************** |
| @@ -2006,6 +2012,13 @@ struct it | |||
| 2006 | text, overlay strings, end of text etc., which see. */ | 2012 | text, overlay strings, end of text etc., which see. */ |
| 2007 | EMACS_INT stop_charpos; | 2013 | EMACS_INT stop_charpos; |
| 2008 | 2014 | ||
| 2015 | /* Previous stop position, i.e. the last one before the current | ||
| 2016 | buffer position. */ | ||
| 2017 | EMACS_INT prev_stop; | ||
| 2018 | |||
| 2019 | /* Last stop_pos at the current paragraph's embedding level. */ | ||
| 2020 | EMACS_INT base_level_stop; | ||
| 2021 | |||
| 2009 | /* Maximum string or buffer position + 1. ZV when iterating over | 2022 | /* Maximum string or buffer position + 1. ZV when iterating over |
| 2010 | current_buffer. */ | 2023 | current_buffer. */ |
| 2011 | EMACS_INT end_charpos; | 2024 | EMACS_INT end_charpos; |
| @@ -2112,6 +2125,8 @@ struct it | |||
| 2112 | int string_nchars; | 2125 | int string_nchars; |
| 2113 | EMACS_INT end_charpos; | 2126 | EMACS_INT end_charpos; |
| 2114 | EMACS_INT stop_charpos; | 2127 | EMACS_INT stop_charpos; |
| 2128 | EMACS_INT prev_stop; | ||
| 2129 | EMACS_INT base_level_stop; | ||
| 2115 | struct composition_it cmp_it; | 2130 | struct composition_it cmp_it; |
| 2116 | int face_id; | 2131 | int face_id; |
| 2117 | 2132 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index 2d5314c7f83..ddd18d502a0 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -2659,7 +2659,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id) | |||
| 2659 | /* Are multibyte characters enabled in current_buffer? */ | 2659 | /* Are multibyte characters enabled in current_buffer? */ |
| 2660 | it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters); | 2660 | it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters); |
| 2661 | 2661 | ||
| 2662 | /* Do we need to reorded bidirectional text? */ | 2662 | /* Do we need to reorder bidirectional text? */ |
| 2663 | it->bidi_p = !NILP (current_buffer->bidi_display_reordering); | 2663 | it->bidi_p = !NILP (current_buffer->bidi_display_reordering); |
| 2664 | 2664 | ||
| 2665 | /* Non-zero if we should highlight the region. */ | 2665 | /* Non-zero if we should highlight the region. */ |
| @@ -5143,6 +5143,8 @@ push_it (it) | |||
| 5143 | p = it->stack + it->sp; | 5143 | p = it->stack + it->sp; |
| 5144 | 5144 | ||
| 5145 | p->stop_charpos = it->stop_charpos; | 5145 | p->stop_charpos = it->stop_charpos; |
| 5146 | p->prev_stop = it->prev_stop; | ||
| 5147 | p->base_level_stop = it->base_level_stop; | ||
| 5146 | p->cmp_it = it->cmp_it; | 5148 | p->cmp_it = it->cmp_it; |
| 5147 | xassert (it->face_id >= 0); | 5149 | xassert (it->face_id >= 0); |
| 5148 | p->face_id = it->face_id; | 5150 | p->face_id = it->face_id; |
| @@ -5193,6 +5195,8 @@ pop_it (it) | |||
| 5193 | --it->sp; | 5195 | --it->sp; |
| 5194 | p = it->stack + it->sp; | 5196 | p = it->stack + it->sp; |
| 5195 | it->stop_charpos = p->stop_charpos; | 5197 | it->stop_charpos = p->stop_charpos; |
| 5198 | it->prev_stop = p->prev_stop; | ||
| 5199 | it->base_level_stop = p->base_level_stop; | ||
| 5196 | it->cmp_it = p->cmp_it; | 5200 | it->cmp_it = p->cmp_it; |
| 5197 | it->face_id = p->face_id; | 5201 | it->face_id = p->face_id; |
| 5198 | it->current = p->current; | 5202 | it->current = p->current; |
| @@ -5569,7 +5573,10 @@ reseat_1 (it, pos, set_stop_p) | |||
| 5569 | it->bidi_it.first_elt = 1; | 5573 | it->bidi_it.first_elt = 1; |
| 5570 | 5574 | ||
| 5571 | if (set_stop_p) | 5575 | if (set_stop_p) |
| 5572 | it->stop_charpos = CHARPOS (pos); | 5576 | { |
| 5577 | it->stop_charpos = CHARPOS (pos); | ||
| 5578 | it->base_level_stop = CHARPOS (pos); | ||
| 5579 | } | ||
| 5573 | } | 5580 | } |
| 5574 | 5581 | ||
| 5575 | 5582 | ||
| @@ -5673,7 +5680,7 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte) | |||
| 5673 | 5680 | ||
| 5674 | /*********************************************************************** | 5681 | /*********************************************************************** |
| 5675 | Iteration | 5682 | Iteration |
| 5676 | ***********************************************************************/ | 5683 | ***********************************************************************/ |
| 5677 | 5684 | ||
| 5678 | /* Map enum it_method value to corresponding next_element_from_* function. */ | 5685 | /* Map enum it_method value to corresponding next_element_from_* function. */ |
| 5679 | 5686 | ||
| @@ -5746,7 +5753,7 @@ get_next_display_element (it) | |||
| 5746 | Lisp_Object dv; | 5753 | Lisp_Object dv; |
| 5747 | struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); | 5754 | struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); |
| 5748 | enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } | 5755 | enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } |
| 5749 | nbsp_or_shy = char_is_other; | 5756 | nbsp_or_shy = char_is_other; |
| 5750 | int decoded = it->c; | 5757 | int decoded = it->c; |
| 5751 | 5758 | ||
| 5752 | if (it->dp | 5759 | if (it->dp |
| @@ -5964,12 +5971,12 @@ get_next_display_element (it) | |||
| 5964 | happen actually, but due to bugs it may | 5971 | happen actually, but due to bugs it may |
| 5965 | happen. Let's print the char as is, there's | 5972 | happen. Let's print the char as is, there's |
| 5966 | not much meaningful we can do with it. */ | 5973 | not much meaningful we can do with it. */ |
| 5967 | str[0] = it->c; | 5974 | str[0] = it->c; |
| 5968 | str[1] = it->c >> 8; | 5975 | str[1] = it->c >> 8; |
| 5969 | str[2] = it->c >> 16; | 5976 | str[2] = it->c >> 16; |
| 5970 | str[3] = it->c >> 24; | 5977 | str[3] = it->c >> 24; |
| 5971 | len = 4; | 5978 | len = 4; |
| 5972 | } | 5979 | } |
| 5973 | 5980 | ||
| 5974 | for (i = 0; i < len; i++) | 5981 | for (i = 0; i < len; i++) |
| 5975 | { | 5982 | { |
| @@ -6306,7 +6313,7 @@ next_element_from_display_vector (it) | |||
| 6306 | it->face_id = it->saved_face_id; | 6313 | it->face_id = it->saved_face_id; |
| 6307 | 6314 | ||
| 6308 | /* KFS: This code used to check ip->dpvec[0] instead of the current element. | 6315 | /* KFS: This code used to check ip->dpvec[0] instead of the current element. |
| 6309 | That seemed totally bogus - so I changed it... */ | 6316 | That seemed totally bogus - so I changed it... */ |
| 6310 | gc = it->dpvec[it->current.dpvec_index]; | 6317 | gc = it->dpvec[it->current.dpvec_index]; |
| 6311 | 6318 | ||
| 6312 | if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc)) | 6319 | if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc)) |
| @@ -6541,6 +6548,36 @@ next_element_from_stretch (it) | |||
| 6541 | return 1; | 6548 | return 1; |
| 6542 | } | 6549 | } |
| 6543 | 6550 | ||
| 6551 | /* Scan forward from CHARPOS in the current buffer, until we find a | ||
| 6552 | stop position > current IT's position, handling all the stop | ||
| 6553 | positions in between. | ||
| 6554 | |||
| 6555 | This is called when we are reordering bidirectional text. The | ||
| 6556 | caller should save and restore IT and in particular the bidi_p | ||
| 6557 | flag, because this function modifies them. */ | ||
| 6558 | |||
| 6559 | static void | ||
| 6560 | handle_stop_backwards (it, charpos) | ||
| 6561 | struct it *it; | ||
| 6562 | EMACS_INT charpos; | ||
| 6563 | { | ||
| 6564 | struct text_pos pos1; | ||
| 6565 | EMACS_INT where_we_are = IT_CHARPOS (*it); | ||
| 6566 | |||
| 6567 | /* Scan in strict logical order. */ | ||
| 6568 | it->bidi_p = 0; | ||
| 6569 | do | ||
| 6570 | { | ||
| 6571 | it->prev_stop = charpos; | ||
| 6572 | SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos)); | ||
| 6573 | reseat_1 (it, pos1, 0); | ||
| 6574 | handle_stop (it); | ||
| 6575 | /* We must advance forward, right? */ | ||
| 6576 | if (it->stop_charpos <= it->prev_stop) | ||
| 6577 | abort (); | ||
| 6578 | } | ||
| 6579 | while (it->stop_charpos <= where_we_are); | ||
| 6580 | } | ||
| 6544 | 6581 | ||
| 6545 | /* Load IT with the next display element from current_buffer. Value | 6582 | /* Load IT with the next display element from current_buffer. Value |
| 6546 | is zero if end of buffer reached. IT->stop_charpos is the next | 6583 | is zero if end of buffer reached. IT->stop_charpos is the next |
| @@ -6631,12 +6668,45 @@ next_element_from_buffer (it) | |||
| 6631 | success_p = 0; | 6668 | success_p = 0; |
| 6632 | } | 6669 | } |
| 6633 | } | 6670 | } |
| 6671 | else if (it->bidi_p && !BIDI_AT_BASE_LEVEL (it->bidi_it)) | ||
| 6672 | { | ||
| 6673 | /* With bidi non-linear iteration, we could find ourselves | ||
| 6674 | far beyond the last computed stop_charpos, with several | ||
| 6675 | other stop positions in between that we missed. Scan | ||
| 6676 | them all now, in buffer's logical order. */ | ||
| 6677 | struct it save_it = *it; | ||
| 6678 | |||
| 6679 | handle_stop_backwards (it, it->stop_charpos); | ||
| 6680 | save_it.stop_charpos = it->stop_charpos; | ||
| 6681 | save_it.prev_stop = it->prev_stop; | ||
| 6682 | *it = save_it; | ||
| 6683 | return GET_NEXT_DISPLAY_ELEMENT (it); | ||
| 6684 | } | ||
| 6634 | else | 6685 | else |
| 6635 | { | 6686 | { |
| 6636 | handle_stop (it); | 6687 | handle_stop (it); |
| 6688 | /* We are at base paragraph embedding level, so take note of | ||
| 6689 | the last stop_pos seen at this level. */ | ||
| 6690 | it->base_level_stop = it->stop_charpos; | ||
| 6637 | return GET_NEXT_DISPLAY_ELEMENT (it); | 6691 | return GET_NEXT_DISPLAY_ELEMENT (it); |
| 6638 | } | 6692 | } |
| 6639 | } | 6693 | } |
| 6694 | else if (it->bidi_p && IT_CHARPOS (*it) < it->prev_stop) | ||
| 6695 | { | ||
| 6696 | struct it save_it = *it; | ||
| 6697 | |||
| 6698 | if (it->base_level_stop <= 0) | ||
| 6699 | abort (); | ||
| 6700 | if (IT_CHARPOS (*it) < it->base_level_stop) | ||
| 6701 | abort (); | ||
| 6702 | if (BIDI_AT_BASE_LEVEL (it->bidi_it)) | ||
| 6703 | abort (); | ||
| 6704 | handle_stop_backwards (it, it->base_level_stop); | ||
| 6705 | save_it.stop_charpos = it->stop_charpos; | ||
| 6706 | save_it.prev_stop = it->prev_stop; | ||
| 6707 | *it = save_it; | ||
| 6708 | return GET_NEXT_DISPLAY_ELEMENT (it); | ||
| 6709 | } | ||
| 6640 | else | 6710 | else |
| 6641 | { | 6711 | { |
| 6642 | /* No face changes, overlays etc. in sight, so just return a | 6712 | /* No face changes, overlays etc. in sight, so just return a |