diff options
| author | Eli Zaretskii | 2010-05-22 22:32:21 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2010-05-22 22:32:21 +0300 |
| commit | 1111783029f1d7f50c348d1836ec56c62fb344c2 (patch) | |
| tree | 82dfbad243f61c19044985c98639ada8815bc47a /src | |
| parent | 6e83d8007b844f1d0d68ad235015a154da8050c4 (diff) | |
| parent | a9f86045d9966fd1090951731050bd51e4cc6a8e (diff) | |
| download | emacs-1111783029f1d7f50c348d1836ec56c62fb344c2.tar.gz emacs-1111783029f1d7f50c348d1836ec56c62fb344c2.zip | |
Redesign bidi-aware edge positions of glyph rows, fix bug #6036.
dispextern.h (struct glyph_row): New members minpos and maxpos.
(MATRIX_ROW_START_CHARPOS, MATRIX_ROW_START_BYTEPOS)
(MATRIX_ROW_END_CHARPOS, MATRIX_ROW_END_BYTEPOS): Reference minpos
and maxpos members instead of start.pos and end.pos, respectively.
xdisp.c (display_line): Compare IT_CHARPOS with the position in
row->start.pos, rather than with MATRIX_ROW_START_CHARPOS.
(cursor_row_p): Use row->end.pos rather than MATRIX_ROW_END_CHARPOS.
(try_window_reusing_current_matrix, try_window_id): Use
ROW->minpos rather than ROW->start.pos.
(init_from_display_pos, init_iterator): Use EMACS_INT for
character and byte positions.
(find_row_edges): Renamed from find_row_end. Accept additional
arguments for minimum and maximum buffer positions seen by
display_line for this row. Don't use iterator to find the
position following the maximum one; instead, increment the
position found by display_line directly. Fix logic; eol_pos
should be tested before the rest. Handle the case of characters
delivered from display vector (bug#6036). Fix tests related to
it->method. Handle the truncated_on_right_p rows.
(RECORD_MAX_MIN_POS): New macro.
(display_line): Use it to record the minimum and maximum buffer
positions for glyphs in the row being assembled. Record the
position of the newline that terminates the line. If word wrap is
in effect, restore minimum and maximum positions seen up to the
wrap point, when iterator returns to it.
(try_window_reusing_current_matrix): Give up if in bidi-reordered
row and cursor not already at point. Restore original pre-bidi
code for unidirectional buffers.
dispnew.c (increment_row_positions, check_matrix_invariants):
Increment and check row->start.pos and row->end.pos, in addition
to MATRIX_ROW_START_CHARPOS and MATRIX_ROW_END_CHARPOS.
.gdbinit (prowlims): Display row->minpos and row->maxpos.
Display truncated_on_left_p and truncated_on_right_p flags.
Formatting fixes.
(pmtxrows): Display the ordinal number of each row. Don't display
rows beyond the last one.
bidi.c (bidi_cache_iterator_state): Don't zero out new_paragraph:
it is not copied by bidi_copy_it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/.gdbinit | 7 | ||||
| -rw-r--r-- | src/ChangeLog | 51 | ||||
| -rw-r--r-- | src/bidi.c | 1 | ||||
| -rw-r--r-- | src/dispextern.h | 36 | ||||
| -rw-r--r-- | src/dispnew.c | 16 | ||||
| -rw-r--r-- | src/xdisp.c | 307 |
6 files changed, 249 insertions, 169 deletions
diff --git a/src/.gdbinit b/src/.gdbinit index 5ecdaa4a572..1fd7e288736 100644 --- a/src/.gdbinit +++ b/src/.gdbinit | |||
| @@ -616,7 +616,7 @@ Pretty print all glyphs in it->glyph_row. | |||
| 616 | end | 616 | end |
| 617 | 617 | ||
| 618 | define prowlims | 618 | define prowlims |
| 619 | printf "start=%d,end=%d,reversed=%d,cont=%d,at_zv=%d\n", $arg0->start.pos.charpos, $arg0->end.pos.charpos, $arg0->reversed_p, $arg0->continued_p, $arg0->ends_at_zv_p | 619 | printf "edges=(%d,%d),r2l=%d,cont=%d,trunc=(%d,%d),at_zv=%d\n", $arg0->minpos.charpos, $arg0->maxpos.charpos, $arg0->reversed_p, $arg0->continued_p, $arg0->truncated_on_left_p, $arg0->truncated_on_right_p, $arg0->ends_at_zv_p |
| 620 | end | 620 | end |
| 621 | document prowlims | 621 | document prowlims |
| 622 | Print important attributes of a glyph_row structure. | 622 | Print important attributes of a glyph_row structure. |
| @@ -626,10 +626,13 @@ end | |||
| 626 | define pmtxrows | 626 | define pmtxrows |
| 627 | set $mtx = $arg0 | 627 | set $mtx = $arg0 |
| 628 | set $gl = $mtx->rows | 628 | set $gl = $mtx->rows |
| 629 | set $glend = $mtx->rows + $mtx->nrows | 629 | set $glend = $mtx->rows + $mtx->nrows - 1 |
| 630 | set $i = 0 | ||
| 630 | while ($gl < $glend) | 631 | while ($gl < $glend) |
| 632 | printf "%d: ", $i | ||
| 631 | prowlims $gl | 633 | prowlims $gl |
| 632 | set $gl = $gl + 1 | 634 | set $gl = $gl + 1 |
| 635 | set $i = $i + 1 | ||
| 633 | end | 636 | end |
| 634 | end | 637 | end |
| 635 | document pmtxrows | 638 | document pmtxrows |
diff --git a/src/ChangeLog b/src/ChangeLog index 540a85a6b1d..eb71ddf9377 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,50 @@ | |||
| 1 | 2010-05-19 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | Redesign and reimplement bidi-aware edge positions of glyph rows. | ||
| 4 | |||
| 5 | * dispextern.h (struct glyph_row): New members minpos and maxpos. | ||
| 6 | (MATRIX_ROW_START_CHARPOS, MATRIX_ROW_START_BYTEPOS) | ||
| 7 | (MATRIX_ROW_END_CHARPOS, MATRIX_ROW_END_BYTEPOS): Reference minpos | ||
| 8 | and maxpos members instead of start.pos and end.pos, respectively. | ||
| 9 | |||
| 10 | * xdisp.c (display_line): Compare IT_CHARPOS with the position in | ||
| 11 | row->start.pos, rather than with MATRIX_ROW_START_CHARPOS. | ||
| 12 | (cursor_row_p): Use row->end.pos rather than MATRIX_ROW_END_CHARPOS. | ||
| 13 | (try_window_reusing_current_matrix, try_window_id): Use | ||
| 14 | ROW->minpos rather than ROW->start.pos. | ||
| 15 | (init_from_display_pos, init_iterator): Use EMACS_INT for | ||
| 16 | character and byte positions. | ||
| 17 | (find_row_edges): Renamed from find_row_end. Accept additional | ||
| 18 | arguments for minimum and maximum buffer positions seen by | ||
| 19 | display_line for this row. Don't use iterator to find the | ||
| 20 | position following the maximum one; instead, increment the | ||
| 21 | position found by display_line directly. Fix logic; eol_pos | ||
| 22 | should be tested before the rest. Handle the case of characters | ||
| 23 | delivered from display vector (bug#6036). Fix tests related to | ||
| 24 | it->method. Handle the truncated_on_right_p rows. | ||
| 25 | (RECORD_MAX_MIN_POS): New macro. | ||
| 26 | (display_line): Use it to record the minimum and maximum buffer | ||
| 27 | positions for glyphs in the row being assembled. Record the | ||
| 28 | position of the newline that terminates the line. If word wrap is | ||
| 29 | in effect, restore minimum and maximum positions seen up to the | ||
| 30 | wrap point, when iterator returns to it. | ||
| 31 | (try_window_reusing_current_matrix): Give up if in bidi-reordered | ||
| 32 | row and cursor not already at point. Restore original pre-bidi | ||
| 33 | code for unidirectional buffers. | ||
| 34 | |||
| 35 | * dispnew.c (increment_row_positions, check_matrix_invariants): | ||
| 36 | Increment and check row->start.pos and row->end.pos, in addition | ||
| 37 | to MATRIX_ROW_START_CHARPOS and MATRIX_ROW_END_CHARPOS. | ||
| 38 | |||
| 39 | * .gdbinit (prowlims): Display row->minpos and row->maxpos. | ||
| 40 | Display truncated_on_left_p and truncated_on_right_p flags. | ||
| 41 | Formatting fixes. | ||
| 42 | (pmtxrows): Display the ordinal number of each row. Don't display | ||
| 43 | rows beyond the last one. | ||
| 44 | |||
| 45 | * bidi.c (bidi_cache_iterator_state): Don't zero out new_paragraph: | ||
| 46 | it is not copied by bidi_copy_it. | ||
| 47 | |||
| 1 | 2010-05-22 Eli Zaretskii <eliz@gnu.org> | 48 | 2010-05-22 Eli Zaretskii <eliz@gnu.org> |
| 2 | 49 | ||
| 3 | * w32.c (sys_write): Break writes into chunks smaller than 32MB. | 50 | * w32.c (sys_write): Break writes into chunks smaller than 32MB. |
| @@ -51,8 +98,6 @@ | |||
| 51 | Move static/dynamic dependency stuff to deps.mk/autodeps.mk. | 98 | Move static/dynamic dependency stuff to deps.mk/autodeps.mk. |
| 52 | * deps.mk, autodeps.mk: New files, extracted from Makefile.in. | 99 | * deps.mk, autodeps.mk: New files, extracted from Makefile.in. |
| 53 | 100 | ||
| 54 | 2010-05-19 Eli Zaretskii <eliz@gnu.org> | ||
| 55 | |||
| 56 | * bidi.c (bidi_cache_shrink, bidi_cache_iterator_state): Fix | 101 | * bidi.c (bidi_cache_shrink, bidi_cache_iterator_state): Fix |
| 57 | reallocation of the cache. (Bug#6210) | 102 | reallocation of the cache. (Bug#6210) |
| 58 | 103 | ||
| @@ -175,6 +220,8 @@ | |||
| 175 | * xdisp.c (Fcurrent_bidi_paragraph_direction): New function. | 220 | * xdisp.c (Fcurrent_bidi_paragraph_direction): New function. |
| 176 | (syms_of_xdisp): Defsubr it. | 221 | (syms_of_xdisp): Defsubr it. |
| 177 | 222 | ||
| 223 | * cmds.c (Fforward_char, Fbackward_char): Doc fix. | ||
| 224 | |||
| 178 | * Makefile.in: Fix MSDOS-related comments. | 225 | * Makefile.in: Fix MSDOS-related comments. |
| 179 | 226 | ||
| 180 | 2010-05-15 Glenn Morris <rgm@gnu.org> | 227 | 2010-05-15 Glenn Morris <rgm@gnu.org> |
diff --git a/src/bidi.c b/src/bidi.c index 6bcbf6f6aea..bdeccfee97c 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -707,7 +707,6 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | |||
| 707 | bidi_copy_it (&bidi_cache[idx], bidi_it); | 707 | bidi_copy_it (&bidi_cache[idx], bidi_it); |
| 708 | if (!resolved) | 708 | if (!resolved) |
| 709 | bidi_cache[idx].resolved_level = -1; | 709 | bidi_cache[idx].resolved_level = -1; |
| 710 | bidi_cache[idx].new_paragraph = 0; | ||
| 711 | } | 710 | } |
| 712 | else | 711 | else |
| 713 | { | 712 | { |
diff --git a/src/dispextern.h b/src/dispextern.h index 8e8da36daea..ce8527b92de 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -748,21 +748,29 @@ struct glyph_row | |||
| 748 | 748 | ||
| 749 | /* First position in this row. This is the text position, including | 749 | /* First position in this row. This is the text position, including |
| 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 than the position of the first |
| 752 | (e.g. due to invisible text or horizontal scrolling). BIDI Note: | 752 | glyph (e.g. due to invisible text or horizontal scrolling). |
| 753 | This is the smallest character position in the row, but not | 753 | BIDI Note: In R2L rows, that have its reversed_p flag set, this |
| 754 | necessarily the character that is the leftmost on the display. */ | 754 | position is at or beyond the right edge of the row. */ |
| 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 |
| 758 | the last glyph on this row. It can be greater than the last | 758 | the last glyph on this row. It can be greater than the last |
| 759 | glyph position + 1, due to truncation, invisible text etc. In an | 759 | glyph position + 1, due to a newline that ends the line, |
| 760 | up-to-date display, this should always be equal to the start | 760 | truncation, invisible text etc. In an up-to-date display, this |
| 761 | position of the next row. BIDI Note: this is the character whose | 761 | should always be equal to the start position of the next row. |
| 762 | buffer position is the largest, but not necessarily the rightmost | 762 | BIDI Note: In R2L rows, this position is at or beyond the left |
| 763 | one on the display. */ | 763 | edge of the row. */ |
| 764 | struct display_pos end; | 764 | struct display_pos end; |
| 765 | 765 | ||
| 766 | /* The smallest and the largest buffer positions that contributed to | ||
| 767 | glyphs in this row. Note that due to bidi reordering, these are | ||
| 768 | in general different from the text positions stored in `start' | ||
| 769 | and `end' members above, and also different from the buffer | ||
| 770 | positions recorded in the glyphs displayed the leftmost and | ||
| 771 | rightmost on the screen. */ | ||
| 772 | struct text_pos minpos, maxpos; | ||
| 773 | |||
| 766 | /* Non-zero means the overlay arrow bitmap is on this line. | 774 | /* Non-zero means the overlay arrow bitmap is on this line. |
| 767 | -1 means use default overlay arrow bitmap, else | 775 | -1 means use default overlay arrow bitmap, else |
| 768 | it specifies actual fringe bitmap number. */ | 776 | it specifies actual fringe bitmap number. */ |
| @@ -947,16 +955,16 @@ struct glyph_row *matrix_row P_ ((struct glyph_matrix *, int)); | |||
| 947 | displayed by ROW, which is not necessarily the smallest horizontal | 955 | displayed by ROW, which is not necessarily the smallest horizontal |
| 948 | position. */ | 956 | position. */ |
| 949 | 957 | ||
| 950 | #define MATRIX_ROW_START_CHARPOS(ROW) ((ROW)->start.pos.charpos) | 958 | #define MATRIX_ROW_START_CHARPOS(ROW) ((ROW)->minpos.charpos) |
| 951 | #define MATRIX_ROW_START_BYTEPOS(ROW) ((ROW)->start.pos.bytepos) | 959 | #define MATRIX_ROW_START_BYTEPOS(ROW) ((ROW)->minpos.bytepos) |
| 952 | 960 | ||
| 953 | /* Return the character/ byte position at which ROW ends. BIDI Note: | 961 | /* Return the character/ byte position at which ROW ends. BIDI Note: |
| 954 | this is the largest character/byte position among characters in | 962 | this is the largest character/byte position among characters in |
| 955 | ROW, i.e. the last logical-order character displayed by ROW, which | 963 | ROW, i.e. the last logical-order character displayed by ROW, which |
| 956 | is not necessarily the largest horizontal position. */ | 964 | is not necessarily the largest horizontal position. */ |
| 957 | 965 | ||
| 958 | #define MATRIX_ROW_END_CHARPOS(ROW) ((ROW)->end.pos.charpos) | 966 | #define MATRIX_ROW_END_CHARPOS(ROW) ((ROW)->maxpos.charpos) |
| 959 | #define MATRIX_ROW_END_BYTEPOS(ROW) ((ROW)->end.pos.bytepos) | 967 | #define MATRIX_ROW_END_BYTEPOS(ROW) ((ROW)->maxpos.bytepos) |
| 960 | 968 | ||
| 961 | /* Return the vertical position of ROW in MATRIX. */ | 969 | /* Return the vertical position of ROW in MATRIX. */ |
| 962 | 970 | ||
| @@ -1789,7 +1797,7 @@ struct bidi_it { | |||
| 1789 | EMACS_INT next_en_pos; /* position of next EN char for ET */ | 1797 | EMACS_INT next_en_pos; /* position of next EN char for ET */ |
| 1790 | EMACS_INT ignore_bn_limit; /* position until which to ignore BNs */ | 1798 | EMACS_INT ignore_bn_limit; /* position until which to ignore BNs */ |
| 1791 | bidi_dir_t sor; /* direction of start-of-run in effect */ | 1799 | bidi_dir_t sor; /* direction of start-of-run in effect */ |
| 1792 | int scan_dir; /* direction of text scan */ | 1800 | int scan_dir; /* direction of text scan, 1: forw, -1: back */ |
| 1793 | int stack_idx; /* index of current data on the stack */ | 1801 | int stack_idx; /* index of current data on the stack */ |
| 1794 | /* Note: Everything from here on is not copied/saved when the bidi | 1802 | /* Note: Everything from here on is not copied/saved when the bidi |
| 1795 | iterator state is saved, pushed, or popped. So only put here | 1803 | iterator state is saved, pushed, or popped. So only put here |
diff --git a/src/dispnew.c b/src/dispnew.c index 7ab2bf35811..476b58ae7e3 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -1188,6 +1188,10 @@ increment_row_positions (row, delta, delta_bytes) | |||
| 1188 | MATRIX_ROW_START_BYTEPOS (row) += delta_bytes; | 1188 | MATRIX_ROW_START_BYTEPOS (row) += delta_bytes; |
| 1189 | MATRIX_ROW_END_CHARPOS (row) += delta; | 1189 | MATRIX_ROW_END_CHARPOS (row) += delta; |
| 1190 | MATRIX_ROW_END_BYTEPOS (row) += delta_bytes; | 1190 | MATRIX_ROW_END_BYTEPOS (row) += delta_bytes; |
| 1191 | CHARPOS (row->start.pos) += delta; | ||
| 1192 | BYTEPOS (row->start.pos) += delta_bytes; | ||
| 1193 | CHARPOS (row->end.pos) += delta; | ||
| 1194 | BYTEPOS (row->end.pos) += delta_bytes; | ||
| 1191 | 1195 | ||
| 1192 | if (!row->enabled_p) | 1196 | if (!row->enabled_p) |
| 1193 | return; | 1197 | return; |
| @@ -1748,13 +1752,19 @@ check_matrix_invariants (w) | |||
| 1748 | /* Check that character and byte positions are in sync. */ | 1752 | /* Check that character and byte positions are in sync. */ |
| 1749 | xassert (MATRIX_ROW_START_BYTEPOS (row) | 1753 | xassert (MATRIX_ROW_START_BYTEPOS (row) |
| 1750 | == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row))); | 1754 | == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row))); |
| 1755 | xassert (BYTEPOS (row->start.pos) | ||
| 1756 | == CHAR_TO_BYTE (CHARPOS (row->start.pos))); | ||
| 1751 | 1757 | ||
| 1752 | /* CHAR_TO_BYTE aborts when invoked for a position > Z. We can | 1758 | /* CHAR_TO_BYTE aborts when invoked for a position > Z. We can |
| 1753 | have such a position temporarily in case of a minibuffer | 1759 | have such a position temporarily in case of a minibuffer |
| 1754 | displaying something like `[Sole completion]' at its end. */ | 1760 | displaying something like `[Sole completion]' at its end. */ |
| 1755 | if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer)) | 1761 | if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer)) |
| 1756 | xassert (MATRIX_ROW_END_BYTEPOS (row) | 1762 | { |
| 1757 | == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row))); | 1763 | xassert (MATRIX_ROW_END_BYTEPOS (row) |
| 1764 | == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row))); | ||
| 1765 | xassert (BYTEPOS (row->end.pos) | ||
| 1766 | == CHAR_TO_BYTE (CHARPOS (row->end.pos))); | ||
| 1767 | } | ||
| 1758 | 1768 | ||
| 1759 | /* Check that end position of `row' is equal to start position | 1769 | /* Check that end position of `row' is equal to start position |
| 1760 | of next row. */ | 1770 | of next row. */ |
| @@ -1764,6 +1774,8 @@ check_matrix_invariants (w) | |||
| 1764 | == MATRIX_ROW_START_CHARPOS (next)); | 1774 | == MATRIX_ROW_START_CHARPOS (next)); |
| 1765 | xassert (MATRIX_ROW_END_BYTEPOS (row) | 1775 | xassert (MATRIX_ROW_END_BYTEPOS (row) |
| 1766 | == MATRIX_ROW_START_BYTEPOS (next)); | 1776 | == MATRIX_ROW_START_BYTEPOS (next)); |
| 1777 | xassert (CHARPOS (row->end.pos) == CHARPOS (next->start.pos)); | ||
| 1778 | xassert (BYTEPOS (row->end.pos) == BYTEPOS (next->start.pos)); | ||
| 1767 | } | 1779 | } |
| 1768 | row = next; | 1780 | row = next; |
| 1769 | } | 1781 | } |
diff --git a/src/xdisp.c b/src/xdisp.c index 2ff12730b8a..56e09f54842 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -2598,7 +2598,7 @@ void | |||
| 2598 | init_iterator (it, w, charpos, bytepos, row, base_face_id) | 2598 | init_iterator (it, w, charpos, bytepos, row, base_face_id) |
| 2599 | struct it *it; | 2599 | struct it *it; |
| 2600 | struct window *w; | 2600 | struct window *w; |
| 2601 | int charpos, bytepos; | 2601 | EMACS_INT charpos, bytepos; |
| 2602 | struct glyph_row *row; | 2602 | struct glyph_row *row; |
| 2603 | enum face_id base_face_id; | 2603 | enum face_id base_face_id; |
| 2604 | { | 2604 | { |
| @@ -3012,7 +3012,7 @@ init_from_display_pos (it, w, pos) | |||
| 3012 | struct window *w; | 3012 | struct window *w; |
| 3013 | struct display_pos *pos; | 3013 | struct display_pos *pos; |
| 3014 | { | 3014 | { |
| 3015 | int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos); | 3015 | EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos); |
| 3016 | int i, overlay_strings_with_newlines = 0; | 3016 | int i, overlay_strings_with_newlines = 0; |
| 3017 | 3017 | ||
| 3018 | /* If POS specifies a position in a display vector, this might | 3018 | /* If POS specifies a position in a display vector, this might |
| @@ -14975,7 +14975,7 @@ try_window_reusing_current_matrix (w) | |||
| 14975 | /* The variable new_start now holds the new window start. The old | 14975 | /* The variable new_start now holds the new window start. The old |
| 14976 | start `start' can be determined from the current matrix. */ | 14976 | start `start' can be determined from the current matrix. */ |
| 14977 | SET_TEXT_POS_FROM_MARKER (new_start, w->start); | 14977 | SET_TEXT_POS_FROM_MARKER (new_start, w->start); |
| 14978 | start = start_row->start.pos; | 14978 | start = start_row->minpos; |
| 14979 | start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix); | 14979 | start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix); |
| 14980 | 14980 | ||
| 14981 | /* Clear the desired matrix for the display below. */ | 14981 | /* Clear the desired matrix for the display below. */ |
| @@ -15014,7 +15014,7 @@ try_window_reusing_current_matrix (w) | |||
| 15014 | { | 15014 | { |
| 15015 | /* Advance to the next row as the "start". */ | 15015 | /* Advance to the next row as the "start". */ |
| 15016 | start_row++; | 15016 | start_row++; |
| 15017 | start = start_row->start.pos; | 15017 | start = start_row->minpos; |
| 15018 | /* If there are no more rows to try, or just one, give up. */ | 15018 | /* If there are no more rows to try, or just one, give up. */ |
| 15019 | if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1 | 15019 | if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1 |
| 15020 | || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row) | 15020 | || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row) |
| @@ -15296,39 +15296,26 @@ try_window_reusing_current_matrix (w) | |||
| 15296 | { | 15296 | { |
| 15297 | struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos; | 15297 | struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos; |
| 15298 | struct glyph *end = glyph + row->used[TEXT_AREA]; | 15298 | struct glyph *end = glyph + row->used[TEXT_AREA]; |
| 15299 | struct glyph *orig_glyph = glyph; | ||
| 15300 | struct cursor_pos orig_cursor = w->cursor; | ||
| 15301 | 15299 | ||
| 15302 | for (; glyph < end | 15300 | /* Can't use this optimization with bidi-reordered glyph |
| 15303 | && (!BUFFERP (glyph->object) | 15301 | rows, unless cursor is already at point. */ |
| 15304 | || glyph->charpos != PT); | 15302 | if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)) |
| 15305 | glyph++) | ||
| 15306 | { | 15303 | { |
| 15307 | w->cursor.hpos++; | 15304 | if (!(w->cursor.hpos >= 0 |
| 15308 | w->cursor.x += glyph->pixel_width; | 15305 | && w->cursor.hpos < row->used[TEXT_AREA] |
| 15309 | } | 15306 | && BUFFERP (glyph->object) |
| 15310 | /* With bidi reordering, charpos changes non-linearly | 15307 | && glyph->charpos == PT)) |
| 15311 | with hpos, so the right glyph could be to the | 15308 | return 0; |
| 15312 | left. */ | ||
| 15313 | if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering) | ||
| 15314 | && (!BUFFERP (glyph->object) || glyph->charpos != PT)) | ||
| 15315 | { | ||
| 15316 | struct glyph *start_glyph = row->glyphs[TEXT_AREA]; | ||
| 15317 | |||
| 15318 | glyph = orig_glyph - 1; | ||
| 15319 | orig_cursor.hpos--; | ||
| 15320 | orig_cursor.x -= glyph->pixel_width; | ||
| 15321 | for (; glyph >= start_glyph | ||
| 15322 | && (!BUFFERP (glyph->object) | ||
| 15323 | || glyph->charpos != PT); | ||
| 15324 | glyph--) | ||
| 15325 | { | ||
| 15326 | w->cursor.hpos--; | ||
| 15327 | w->cursor.x -= glyph->pixel_width; | ||
| 15328 | } | ||
| 15329 | if (BUFFERP (glyph->object) && glyph->charpos == PT) | ||
| 15330 | w->cursor = orig_cursor; | ||
| 15331 | } | 15309 | } |
| 15310 | else | ||
| 15311 | for (; glyph < end | ||
| 15312 | && (!BUFFERP (glyph->object) | ||
| 15313 | || glyph->charpos < PT); | ||
| 15314 | glyph++) | ||
| 15315 | { | ||
| 15316 | w->cursor.hpos++; | ||
| 15317 | w->cursor.x += glyph->pixel_width; | ||
| 15318 | } | ||
| 15332 | } | 15319 | } |
| 15333 | } | 15320 | } |
| 15334 | 15321 | ||
| @@ -15908,13 +15895,13 @@ try_window_id (w) | |||
| 15908 | as is, without changing glyph positions since no text has | 15895 | as is, without changing glyph positions since no text has |
| 15909 | been added/removed in front of the window end. */ | 15896 | been added/removed in front of the window end. */ |
| 15910 | r0 = MATRIX_FIRST_TEXT_ROW (current_matrix); | 15897 | r0 = MATRIX_FIRST_TEXT_ROW (current_matrix); |
| 15911 | if (TEXT_POS_EQUAL_P (start, r0->start.pos) | 15898 | if (TEXT_POS_EQUAL_P (start, r0->minpos) |
| 15912 | /* PT must not be in a partially visible line. */ | 15899 | /* PT must not be in a partially visible line. */ |
| 15913 | && !(PT >= MATRIX_ROW_START_CHARPOS (row) | 15900 | && !(PT >= MATRIX_ROW_START_CHARPOS (row) |
| 15914 | && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w))) | 15901 | && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w))) |
| 15915 | { | 15902 | { |
| 15916 | /* We have to compute the window end anew since text | 15903 | /* We have to compute the window end anew since text |
| 15917 | can have been added/removed after it. */ | 15904 | could have been added/removed after it. */ |
| 15918 | w->window_end_pos | 15905 | w->window_end_pos |
| 15919 | = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); | 15906 | = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); |
| 15920 | w->window_end_bytepos | 15907 | w->window_end_bytepos |
| @@ -15946,7 +15933,7 @@ try_window_id (w) | |||
| 15946 | start is not in changed text, otherwise positions would not be | 15933 | start is not in changed text, otherwise positions would not be |
| 15947 | comparable. */ | 15934 | comparable. */ |
| 15948 | row = MATRIX_FIRST_TEXT_ROW (current_matrix); | 15935 | row = MATRIX_FIRST_TEXT_ROW (current_matrix); |
| 15949 | if (!TEXT_POS_EQUAL_P (start, row->start.pos)) | 15936 | if (!TEXT_POS_EQUAL_P (start, row->minpos)) |
| 15950 | GIVE_UP (16); | 15937 | GIVE_UP (16); |
| 15951 | 15938 | ||
| 15952 | /* Give up if the window ends in strings. Overlay strings | 15939 | /* Give up if the window ends in strings. Overlay strings |
| @@ -17338,7 +17325,7 @@ cursor_row_p (w, row) | |||
| 17338 | { | 17325 | { |
| 17339 | int cursor_row_p = 1; | 17326 | int cursor_row_p = 1; |
| 17340 | 17327 | ||
| 17341 | if (PT == MATRIX_ROW_END_CHARPOS (row)) | 17328 | if (PT == CHARPOS (row->end.pos)) |
| 17342 | { | 17329 | { |
| 17343 | /* Suppose the row ends on a string. | 17330 | /* Suppose the row ends on a string. |
| 17344 | Unless the row is continued, that means it ends on a newline | 17331 | Unless the row is continued, that means it ends on a newline |
| @@ -17375,14 +17362,15 @@ cursor_row_p (w, row) | |||
| 17375 | { | 17362 | { |
| 17376 | /* If the row ends in middle of a real character, | 17363 | /* If the row ends in middle of a real character, |
| 17377 | and the line is continued, we want the cursor here. | 17364 | and the line is continued, we want the cursor here. |
| 17378 | That's because MATRIX_ROW_END_CHARPOS would equal | 17365 | That's because CHARPOS (ROW->end.pos) would equal |
| 17379 | PT if PT is before the character. */ | 17366 | PT if PT is before the character. */ |
| 17380 | if (!row->ends_in_ellipsis_p) | 17367 | if (!row->ends_in_ellipsis_p) |
| 17381 | cursor_row_p = row->continued_p; | 17368 | cursor_row_p = row->continued_p; |
| 17382 | else | 17369 | else |
| 17383 | /* If the row ends in an ellipsis, then | 17370 | /* If the row ends in an ellipsis, then |
| 17384 | MATRIX_ROW_END_CHARPOS will equal point after the invisible text. | 17371 | CHARPOS (ROW->end.pos) will equal point after the |
| 17385 | We want that position to be displayed after the ellipsis. */ | 17372 | invisible text. We want that position to be displayed |
| 17373 | after the ellipsis. */ | ||
| 17386 | cursor_row_p = 0; | 17374 | cursor_row_p = 0; |
| 17387 | } | 17375 | } |
| 17388 | /* If the row ends at ZV, display the cursor at the end of that | 17376 | /* If the row ends at ZV, display the cursor at the end of that |
| @@ -17518,122 +17506,87 @@ unproduce_glyphs (it, n) | |||
| 17518 | glyph[-n] = *glyph; | 17506 | glyph[-n] = *glyph; |
| 17519 | } | 17507 | } |
| 17520 | 17508 | ||
| 17521 | /* Find the positions in a bidi-reordered ROW to serve as ROW->start | 17509 | /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos |
| 17522 | and ROW->end. */ | 17510 | and ROW->maxpos. */ |
| 17523 | static struct display_pos | 17511 | static void |
| 17524 | find_row_end (it, row) | 17512 | find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos) |
| 17525 | struct it *it; | 17513 | struct it *it; |
| 17526 | struct glyph_row *row; | 17514 | struct glyph_row *row; |
| 17515 | EMACS_INT min_pos, min_bpos, max_pos, max_bpos; | ||
| 17527 | { | 17516 | { |
| 17528 | /* FIXME: Revisit this when glyph ``spilling'' in continuation | 17517 | /* FIXME: Revisit this when glyph ``spilling'' in continuation |
| 17529 | lines' rows is implemented for bidi-reordered rows. */ | 17518 | lines' rows is implemented for bidi-reordered rows. */ |
| 17530 | EMACS_INT min_pos = ZV + 1, max_pos = 0; | ||
| 17531 | struct glyph *g; | ||
| 17532 | struct it save_it; | ||
| 17533 | struct text_pos tpos; | ||
| 17534 | struct display_pos row_end = it->current; | ||
| 17535 | 17519 | ||
| 17536 | for (g = row->glyphs[TEXT_AREA]; | 17520 | /* ROW->minpos is the value of min_pos, the minimal buffer position |
| 17537 | g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; | ||
| 17538 | g++) | ||
| 17539 | { | ||
| 17540 | if (BUFFERP (g->object)) | ||
| 17541 | { | ||
| 17542 | if (g->charpos > 0 && g->charpos < min_pos) | ||
| 17543 | min_pos = g->charpos; | ||
| 17544 | if (g->charpos > max_pos) | ||
| 17545 | max_pos = g->charpos; | ||
| 17546 | } | ||
| 17547 | } | ||
| 17548 | /* Empty lines have a valid buffer position at their first | ||
| 17549 | glyph, but that glyph's OBJECT is zero, as if it didn't come | ||
| 17550 | from a buffer. If we didn't find any valid buffer positions | ||
| 17551 | in this row, maybe we have such an empty line. */ | ||
| 17552 | if (max_pos == 0 && row->used[TEXT_AREA]) | ||
| 17553 | { | ||
| 17554 | for (g = row->glyphs[TEXT_AREA]; | ||
| 17555 | g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; | ||
| 17556 | g++) | ||
| 17557 | { | ||
| 17558 | if (INTEGERP (g->object)) | ||
| 17559 | { | ||
| 17560 | if (g->charpos > 0 && g->charpos < min_pos) | ||
| 17561 | min_pos = g->charpos; | ||
| 17562 | if (g->charpos > max_pos) | ||
| 17563 | max_pos = g->charpos; | ||
| 17564 | } | ||
| 17565 | } | ||
| 17566 | } | ||
| 17567 | |||
| 17568 | /* ROW->start is the value of min_pos, the minimal buffer position | ||
| 17569 | we have in ROW. */ | 17521 | we have in ROW. */ |
| 17570 | if (min_pos <= ZV) | 17522 | if (min_pos <= ZV) |
| 17523 | SET_TEXT_POS (row->minpos, min_pos, min_bpos); | ||
| 17524 | else | ||
| 17571 | { | 17525 | { |
| 17572 | /* Avoid calling the costly CHAR_TO_BYTE if possible. */ | 17526 | /* We didn't find _any_ valid buffer positions in any of the |
| 17573 | if (min_pos != row->start.pos.charpos) | 17527 | glyphs, so we must trust the iterator's computed |
| 17574 | SET_TEXT_POS (row->start.pos, min_pos, CHAR_TO_BYTE (min_pos)); | 17528 | positions. */ |
| 17575 | if (max_pos == 0) | 17529 | row->minpos = row->start.pos; |
| 17576 | max_pos = min_pos; | 17530 | max_pos = CHARPOS (it->current.pos); |
| 17531 | max_bpos = BYTEPOS (it->current.pos); | ||
| 17577 | } | 17532 | } |
| 17578 | 17533 | ||
| 17579 | /* For ROW->end, we need the position that is _after_ max_pos, in | 17534 | if (!max_pos) |
| 17580 | the logical order, unless we are at ZV. */ | 17535 | abort (); |
| 17581 | if (row->ends_at_zv_p) | ||
| 17582 | { | ||
| 17583 | if (!row->used[TEXT_AREA]) | ||
| 17584 | row->start.pos = row_end.pos; | ||
| 17585 | } | ||
| 17586 | else if (row->used[TEXT_AREA] && max_pos) | ||
| 17587 | { | ||
| 17588 | int at_eol_p; | ||
| 17589 | 17536 | ||
| 17590 | SET_TEXT_POS (tpos, max_pos, CHAR_TO_BYTE (max_pos)); | 17537 | /* Here are the various use-cases for ending the row, and the |
| 17591 | save_it = *it; | 17538 | corresponding values for ROW->maxpos: |
| 17592 | it->bidi_p = 0; | 17539 | |
| 17593 | reseat (it, tpos, 0); | 17540 | Line ends in a newline from buffer eol_pos + 1 |
| 17594 | if (!get_next_display_element (it)) | 17541 | Line is continued from buffer max_pos + 1 |
| 17595 | abort (); /* this row cannot be at ZV, see above */ | 17542 | Line is truncated on right it->current.pos |
| 17596 | at_eol_p = ITERATOR_AT_END_OF_LINE_P (it); | 17543 | Line ends in a newline from string max_pos |
| 17597 | set_iterator_to_next (it, 1); | 17544 | Line is continued from string max_pos |
| 17598 | row_end = it->current; | 17545 | Line is continued from display vector max_pos |
| 17599 | /* If the character at max_pos is not a newline and the | 17546 | Line is entirely from a string min_pos == max_pos |
| 17600 | characters at max_pos+1 is a newline, skip that newline as | 17547 | Line is entirely from a display vector min_pos == max_pos |
| 17601 | well. Note that this may skip some invisible text. */ | 17548 | Line that ends at ZV ZV |
| 17602 | if (!at_eol_p | 17549 | |
| 17603 | && get_next_display_element (it) | 17550 | If you discover other use-cases, please add them here as |
| 17604 | && ITERATOR_AT_END_OF_LINE_P (it)) | 17551 | appropriate. */ |
| 17605 | { | 17552 | if (row->ends_at_zv_p) |
| 17606 | set_iterator_to_next (it, 1); | 17553 | row->maxpos = it->current.pos; |
| 17607 | /* Record the position after the newline of a continued row. | 17554 | else if (row->used[TEXT_AREA]) |
| 17608 | We will need that to set ROW->end of the last row | 17555 | { |
| 17609 | produced for a continued line. */ | 17556 | if (row->ends_in_newline_from_string_p) |
| 17610 | if (row->continued_p) | 17557 | SET_TEXT_POS (row->maxpos, max_pos, max_bpos); |
| 17611 | save_it.eol_pos = it->current.pos; | 17558 | else if (CHARPOS (it->eol_pos) > 0) |
| 17559 | SET_TEXT_POS (row->maxpos, | ||
| 17560 | CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1); | ||
| 17561 | else if (row->continued_p) | ||
| 17562 | { | ||
| 17563 | /* If max_pos is different from IT's current position, it | ||
| 17564 | means IT->method does not belong to the display element | ||
| 17565 | at max_pos. However, it also means that the display | ||
| 17566 | element at max_pos was displayed in its entirety on this | ||
| 17567 | line, which is equivalent to saying that the next line | ||
| 17568 | starts at the next buffer position. */ | ||
| 17569 | if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER) | ||
| 17570 | SET_TEXT_POS (row->maxpos, max_pos, max_bpos); | ||
| 17612 | else | 17571 | else |
| 17613 | { | 17572 | { |
| 17614 | row_end = it->current; | 17573 | INC_BOTH (max_pos, max_bpos); |
| 17615 | save_it.eol_pos.charpos = save_it.eol_pos.bytepos = 0; | 17574 | SET_TEXT_POS (row->maxpos, max_pos, max_bpos); |
| 17616 | } | 17575 | } |
| 17617 | } | 17576 | } |
| 17618 | else if (!row->continued_p | 17577 | else if (row->truncated_on_right_p) |
| 17619 | && MATRIX_ROW_CONTINUATION_LINE_P (row) | 17578 | /* display_line already called reseat_at_next_visible_line_start, |
| 17620 | && it->eol_pos.charpos > 0) | 17579 | which puts the iterator at the beginning of the next line, in |
| 17621 | { | 17580 | the logical order. */ |
| 17622 | /* Last row of a continued line. Use the position recorded | 17581 | row->maxpos = it->current.pos; |
| 17623 | in IT->eol_pos, to the effect that the newline belongs to | 17582 | else if (max_pos == min_pos && it->method != GET_FROM_BUFFER) |
| 17624 | this row, not to the row which displays the character | 17583 | /* A line that is entirely from a string/image/stretch... */ |
| 17625 | with the largest buffer position before the newline. */ | 17584 | row->maxpos = row->minpos; |
| 17626 | row_end.pos = it->eol_pos; | 17585 | else |
| 17627 | it->eol_pos.charpos = it->eol_pos.bytepos = 0; | 17586 | abort (); |
| 17628 | } | ||
| 17629 | *it = save_it; | ||
| 17630 | /* The members of ROW->end that are not taken from buffer | ||
| 17631 | positions are copied from IT->current. */ | ||
| 17632 | row_end.string_pos = it->current.string_pos; | ||
| 17633 | row_end.overlay_string_index = it->current.overlay_string_index; | ||
| 17634 | row_end.dpvec_index = it->current.dpvec_index; | ||
| 17635 | } | 17587 | } |
| 17636 | return row_end; | 17588 | else |
| 17589 | row->maxpos = it->current.pos; | ||
| 17637 | } | 17590 | } |
| 17638 | 17591 | ||
| 17639 | /* Construct the glyph row IT->glyph_row in the desired matrix of | 17592 | /* Construct the glyph row IT->glyph_row in the desired matrix of |
| @@ -17653,7 +17606,10 @@ display_line (it) | |||
| 17653 | int wrap_row_used = -1, wrap_row_ascent, wrap_row_height; | 17606 | int wrap_row_used = -1, wrap_row_ascent, wrap_row_height; |
| 17654 | int wrap_row_phys_ascent, wrap_row_phys_height; | 17607 | int wrap_row_phys_ascent, wrap_row_phys_height; |
| 17655 | int wrap_row_extra_line_spacing; | 17608 | int wrap_row_extra_line_spacing; |
| 17609 | EMACS_INT wrap_row_min_pos, wrap_row_min_bpos; | ||
| 17610 | EMACS_INT wrap_row_max_pos, wrap_row_max_bpos; | ||
| 17656 | int cvpos; | 17611 | int cvpos; |
| 17612 | EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos; | ||
| 17657 | 17613 | ||
| 17658 | /* We always start displaying at hpos zero even if hscrolled. */ | 17614 | /* We always start displaying at hpos zero even if hscrolled. */ |
| 17659 | xassert (it->hpos == 0 && it->current_x == 0); | 17615 | xassert (it->hpos == 0 && it->current_x == 0); |
| @@ -17710,6 +17666,23 @@ display_line (it) | |||
| 17710 | row->phys_height = it->max_phys_ascent + it->max_phys_descent; | 17666 | row->phys_height = it->max_phys_ascent + it->max_phys_descent; |
| 17711 | row->extra_line_spacing = it->max_extra_line_spacing; | 17667 | row->extra_line_spacing = it->max_extra_line_spacing; |
| 17712 | 17668 | ||
| 17669 | /* Utility macro to record max and min buffer positions seen until now. */ | ||
| 17670 | #define RECORD_MAX_MIN_POS(IT) \ | ||
| 17671 | do \ | ||
| 17672 | { \ | ||
| 17673 | if (IT_CHARPOS (*(IT)) < min_pos) \ | ||
| 17674 | { \ | ||
| 17675 | min_pos = IT_CHARPOS (*(IT)); \ | ||
| 17676 | min_bpos = IT_BYTEPOS (*(IT)); \ | ||
| 17677 | } \ | ||
| 17678 | if (IT_CHARPOS (*(IT)) > max_pos) \ | ||
| 17679 | { \ | ||
| 17680 | max_pos = IT_CHARPOS (*(IT)); \ | ||
| 17681 | max_bpos = IT_BYTEPOS (*(IT)); \ | ||
| 17682 | } \ | ||
| 17683 | } \ | ||
| 17684 | while (0) | ||
| 17685 | |||
| 17713 | /* Loop generating characters. The loop is left with IT on the next | 17686 | /* Loop generating characters. The loop is left with IT on the next |
| 17714 | character to display. */ | 17687 | character to display. */ |
| 17715 | while (1) | 17688 | while (1) |
| @@ -17744,7 +17717,8 @@ display_line (it) | |||
| 17744 | row->ends_at_zv_p = 1; | 17717 | row->ends_at_zv_p = 1; |
| 17745 | /* A row that displays right-to-left text must always have | 17718 | /* A row that displays right-to-left text must always have |
| 17746 | its last face extended all the way to the end of line, | 17719 | its last face extended all the way to the end of line, |
| 17747 | even if this row ends in ZV. */ | 17720 | even if this row ends in ZV, because we still write to th |
| 17721 | screen left to right. */ | ||
| 17748 | if (row->reversed_p) | 17722 | if (row->reversed_p) |
| 17749 | extend_face_to_end_of_line (it); | 17723 | extend_face_to_end_of_line (it); |
| 17750 | break; | 17724 | break; |
| @@ -17778,6 +17752,10 @@ display_line (it) | |||
| 17778 | wrap_row_phys_ascent = row->phys_ascent; | 17752 | wrap_row_phys_ascent = row->phys_ascent; |
| 17779 | wrap_row_phys_height = row->phys_height; | 17753 | wrap_row_phys_height = row->phys_height; |
| 17780 | wrap_row_extra_line_spacing = row->extra_line_spacing; | 17754 | wrap_row_extra_line_spacing = row->extra_line_spacing; |
| 17755 | wrap_row_min_pos = min_pos; | ||
| 17756 | wrap_row_min_bpos = min_bpos; | ||
| 17757 | wrap_row_max_pos = max_pos; | ||
| 17758 | wrap_row_max_bpos = max_bpos; | ||
| 17781 | may_wrap = 0; | 17759 | may_wrap = 0; |
| 17782 | } | 17760 | } |
| 17783 | } | 17761 | } |
| @@ -17828,6 +17806,10 @@ display_line (it) | |||
| 17828 | it->max_extra_line_spacing); | 17806 | it->max_extra_line_spacing); |
| 17829 | if (it->current_x - it->pixel_width < it->first_visible_x) | 17807 | if (it->current_x - it->pixel_width < it->first_visible_x) |
| 17830 | row->x = x - it->first_visible_x; | 17808 | row->x = x - it->first_visible_x; |
| 17809 | /* Record the maximum and minimum buffer positions seen so | ||
| 17810 | far in glyphs that will be displayed by this row. */ | ||
| 17811 | if (it->bidi_p) | ||
| 17812 | RECORD_MAX_MIN_POS (it); | ||
| 17831 | } | 17813 | } |
| 17832 | else | 17814 | else |
| 17833 | { | 17815 | { |
| @@ -17861,6 +17843,11 @@ display_line (it) | |||
| 17861 | it->current_x = new_x; | 17843 | it->current_x = new_x; |
| 17862 | it->continuation_lines_width += new_x; | 17844 | it->continuation_lines_width += new_x; |
| 17863 | ++it->hpos; | 17845 | ++it->hpos; |
| 17846 | /* Record the maximum and minimum buffer | ||
| 17847 | positions seen so far in glyphs that will be | ||
| 17848 | displayed by this row. */ | ||
| 17849 | if (it->bidi_p) | ||
| 17850 | RECORD_MAX_MIN_POS (it); | ||
| 17864 | if (i == nglyphs - 1) | 17851 | if (i == nglyphs - 1) |
| 17865 | { | 17852 | { |
| 17866 | /* If line-wrap is on, check if a previous | 17853 | /* If line-wrap is on, check if a previous |
| @@ -17935,6 +17922,10 @@ display_line (it) | |||
| 17935 | row->phys_ascent = wrap_row_phys_ascent; | 17922 | row->phys_ascent = wrap_row_phys_ascent; |
| 17936 | row->phys_height = wrap_row_phys_height; | 17923 | row->phys_height = wrap_row_phys_height; |
| 17937 | row->extra_line_spacing = wrap_row_extra_line_spacing; | 17924 | row->extra_line_spacing = wrap_row_extra_line_spacing; |
| 17925 | min_pos = wrap_row_min_pos; | ||
| 17926 | min_bpos = wrap_row_min_bpos; | ||
| 17927 | max_pos = wrap_row_max_pos; | ||
| 17928 | max_bpos = wrap_row_max_bpos; | ||
| 17938 | row->continued_p = 1; | 17929 | row->continued_p = 1; |
| 17939 | row->ends_at_zv_p = 0; | 17930 | row->ends_at_zv_p = 0; |
| 17940 | row->exact_window_width_line_p = 0; | 17931 | row->exact_window_width_line_p = 0; |
| @@ -17997,6 +17988,12 @@ display_line (it) | |||
| 17997 | /* Increment number of glyphs actually displayed. */ | 17988 | /* Increment number of glyphs actually displayed. */ |
| 17998 | ++it->hpos; | 17989 | ++it->hpos; |
| 17999 | 17990 | ||
| 17991 | /* Record the maximum and minimum buffer positions | ||
| 17992 | seen so far in glyphs that will be displayed by | ||
| 17993 | this row. */ | ||
| 17994 | if (it->bidi_p) | ||
| 17995 | RECORD_MAX_MIN_POS (it); | ||
| 17996 | |||
| 18000 | if (x < it->first_visible_x) | 17997 | if (x < it->first_visible_x) |
| 18001 | /* Glyph is partially visible, i.e. row starts at | 17998 | /* Glyph is partially visible, i.e. row starts at |
| 18002 | negative X position. */ | 17999 | negative X position. */ |
| @@ -18048,6 +18045,10 @@ display_line (it) | |||
| 18048 | if (used_before == 0) | 18045 | if (used_before == 0) |
| 18049 | row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position); | 18046 | row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position); |
| 18050 | 18047 | ||
| 18048 | /* Record the position of the newline, for use in | ||
| 18049 | find_row_edges. */ | ||
| 18050 | it->eol_pos = it->current.pos; | ||
| 18051 | |||
| 18051 | /* Consume the line end. This skips over invisible lines. */ | 18052 | /* Consume the line end. This skips over invisible lines. */ |
| 18052 | set_iterator_to_next (it, 1); | 18053 | set_iterator_to_next (it, 1); |
| 18053 | it->continuation_lines_width = 0; | 18054 | it->continuation_lines_width = 0; |
| @@ -18127,7 +18128,7 @@ display_line (it) | |||
| 18127 | /* If line is not empty and hscrolled, maybe insert truncation glyphs | 18128 | /* If line is not empty and hscrolled, maybe insert truncation glyphs |
| 18128 | at the left window margin. */ | 18129 | at the left window margin. */ |
| 18129 | if (it->first_visible_x | 18130 | if (it->first_visible_x |
| 18130 | && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row)) | 18131 | && IT_CHARPOS (*it) != CHARPOS (row->start.pos)) |
| 18131 | { | 18132 | { |
| 18132 | if (!FRAME_WINDOW_P (it->f)) | 18133 | if (!FRAME_WINDOW_P (it->f)) |
| 18133 | insert_left_trunc_glyphs (it); | 18134 | insert_left_trunc_glyphs (it); |
| @@ -18181,12 +18182,19 @@ display_line (it) | |||
| 18181 | 18182 | ||
| 18182 | /* Remember the position at which this line ends. */ | 18183 | /* Remember the position at which this line ends. */ |
| 18183 | row->end = it->current; | 18184 | row->end = it->current; |
| 18184 | /* ROW->start and ROW->end must be the smallest and the largest | 18185 | if (!it->bidi_p) |
| 18185 | buffer positions in ROW. But if ROW was bidi-reordered, these | 18186 | { |
| 18186 | two positions can be anywhere in the row, so we must rescan all | 18187 | row->minpos = row->start.pos; |
| 18187 | of the ROW's glyphs to find them. */ | 18188 | row->maxpos = row->end.pos; |
| 18188 | if (it->bidi_p) | 18189 | } |
| 18189 | row->end = find_row_end (it, row); | 18190 | else |
| 18191 | { | ||
| 18192 | /* ROW->minpos and ROW->maxpos must be the smallest and | ||
| 18193 | `1 + the largest' buffer positions in ROW. But if ROW was | ||
| 18194 | bidi-reordered, these two positions can be anywhere in the | ||
| 18195 | row, so we must determine them now. */ | ||
| 18196 | find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos); | ||
| 18197 | } | ||
| 18190 | 18198 | ||
| 18191 | /* Record whether this row ends inside an ellipsis. */ | 18199 | /* Record whether this row ends inside an ellipsis. */ |
| 18192 | row->ends_in_ellipsis_p | 18200 | row->ends_in_ellipsis_p |
| @@ -18232,6 +18240,7 @@ display_line (it) | |||
| 18232 | row to be used. */ | 18240 | row to be used. */ |
| 18233 | it->current_x = it->hpos = 0; | 18241 | it->current_x = it->hpos = 0; |
| 18234 | it->current_y += row->height; | 18242 | it->current_y += row->height; |
| 18243 | SET_TEXT_POS (it->eol_pos, 0, 0); | ||
| 18235 | ++it->vpos; | 18244 | ++it->vpos; |
| 18236 | ++it->glyph_row; | 18245 | ++it->glyph_row; |
| 18237 | /* The next row should by default use the same value of the | 18246 | /* The next row should by default use the same value of the |
| @@ -18242,6 +18251,8 @@ display_line (it) | |||
| 18242 | it->glyph_row->reversed_p = row->reversed_p; | 18251 | it->glyph_row->reversed_p = row->reversed_p; |
| 18243 | it->start = row->end; | 18252 | it->start = row->end; |
| 18244 | return row->displays_text_p; | 18253 | return row->displays_text_p; |
| 18254 | |||
| 18255 | #undef RECORD_MAX_MIN_POS | ||
| 18245 | } | 18256 | } |
| 18246 | 18257 | ||
| 18247 | DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction, | 18258 | DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction, |