aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2010-05-18 18:22:15 +0300
committerEli Zaretskii2010-05-18 18:22:15 +0300
commitd36fe2375ad338a799038a5afee82d00e6b6b7ac (patch)
treec556ef3bd494e8c858a285b1f408137b1266dab1 /src
parent560bb7ae8eb9873e1a6be40ff7f26e08228e1d1a (diff)
downloademacs-d36fe2375ad338a799038a5afee82d00e6b6b7ac.tar.gz
emacs-d36fe2375ad338a799038a5afee82d00e6b6b7ac.zip
Initial reimplementation of calculating line edge positions in bidi lines.
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. (display_line): Record minimum and maximum buffer positions for glyphs in this row. Record the position of the newline that terminates the line. 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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog29
-rw-r--r--src/dispextern.h36
-rw-r--r--src/dispnew.c16
-rw-r--r--src/xdisp.c248
4 files changed, 200 insertions, 129 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index b0965f8e514..fe30d07692a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,30 @@
12010-05-18 Eli Zaretskii <eliz@gnu.org>
2
3 * dispextern.h (struct glyph_row): New members minpos and maxpos.
4 (MATRIX_ROW_START_CHARPOS, MATRIX_ROW_START_BYTEPOS)
5 (MATRIX_ROW_END_CHARPOS, MATRIX_ROW_END_BYTEPOS): Reference minpos
6 and maxpos members instead of start.pos and end.pos, respectively.
7
8 * xdisp.c (display_line): Compare IT_CHARPOS with the position in
9 row->start.pos, rather than with MATRIX_ROW_START_CHARPOS.
10 (cursor_row_p): Use row->end.pos rather than MATRIX_ROW_END_CHARPOS.
11 (try_window_reusing_current_matrix, try_window_id): Use
12 ROW->minpos rather than ROW->start.pos.
13 (init_from_display_pos, init_iterator): Use EMACS_INT for
14 character and byte positions.
15 (find_row_edges): Renamed from find_row_end. Accept additional
16 arguments for minimum and maximum buffer positions seen by
17 display_line for this row. Don't use iterator to find the
18 position following the maximum one; instead, increment the
19 position found by display_line directly.
20 (display_line): Record minimum and maximum buffer positions for
21 glyphs in this row. Record the position of the newline that
22 terminates the line.
23
24 * dispnew.c (increment_row_positions, check_matrix_invariants):
25 Increment and check row->start.pos and row->end.pos, in addition
26 to MATRIX_ROW_START_CHARPOS and MATRIX_ROW_END_CHARPOS.
27
12010-05-18 Juanma Barranquero <lekktu@gmail.com> 282010-05-18 Juanma Barranquero <lekktu@gmail.com>
2 29
3 * charset.c (load_charset_map_from_file): Don't call close after fclose. 30 * charset.c (load_charset_map_from_file): Don't call close after fclose.
@@ -91,6 +118,8 @@
91 * xdisp.c (Fcurrent_bidi_paragraph_direction): New function. 118 * xdisp.c (Fcurrent_bidi_paragraph_direction): New function.
92 (syms_of_xdisp): Defsubr it. 119 (syms_of_xdisp): Defsubr it.
93 120
121 * cmds.c (Fforward_char, Fbackward_char): Doc fix.
122
94 * Makefile.in: Fix MSDOS-related comments. 123 * Makefile.in: Fix MSDOS-related comments.
95 124
962010-05-15 Glenn Morris <rgm@gnu.org> 1252010-05-15 Glenn Morris <rgm@gnu.org>
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 6b3097c9a1a..9cd562e8e3d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2598,7 +2598,7 @@ void
2598init_iterator (it, w, charpos, bytepos, row, base_face_id) 2598init_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
@@ -14972,7 +14972,7 @@ try_window_reusing_current_matrix (w)
14972 /* The variable new_start now holds the new window start. The old 14972 /* The variable new_start now holds the new window start. The old
14973 start `start' can be determined from the current matrix. */ 14973 start `start' can be determined from the current matrix. */
14974 SET_TEXT_POS_FROM_MARKER (new_start, w->start); 14974 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14975 start = start_row->start.pos; 14975 start = start_row->minpos;
14976 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix); 14976 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14977 14977
14978 /* Clear the desired matrix for the display below. */ 14978 /* Clear the desired matrix for the display below. */
@@ -15011,7 +15011,7 @@ try_window_reusing_current_matrix (w)
15011 { 15011 {
15012 /* Advance to the next row as the "start". */ 15012 /* Advance to the next row as the "start". */
15013 start_row++; 15013 start_row++;
15014 start = start_row->start.pos; 15014 start = start_row->minpos;
15015 /* If there are no more rows to try, or just one, give up. */ 15015 /* If there are no more rows to try, or just one, give up. */
15016 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1 15016 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
15017 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row) 15017 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
@@ -15905,13 +15905,13 @@ try_window_id (w)
15905 as is, without changing glyph positions since no text has 15905 as is, without changing glyph positions since no text has
15906 been added/removed in front of the window end. */ 15906 been added/removed in front of the window end. */
15907 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix); 15907 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15908 if (TEXT_POS_EQUAL_P (start, r0->start.pos) 15908 if (TEXT_POS_EQUAL_P (start, r0->minpos)
15909 /* PT must not be in a partially visible line. */ 15909 /* PT must not be in a partially visible line. */
15910 && !(PT >= MATRIX_ROW_START_CHARPOS (row) 15910 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
15911 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w))) 15911 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15912 { 15912 {
15913 /* We have to compute the window end anew since text 15913 /* We have to compute the window end anew since text
15914 can have been added/removed after it. */ 15914 could have been added/removed after it. */
15915 w->window_end_pos 15915 w->window_end_pos
15916 = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); 15916 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15917 w->window_end_bytepos 15917 w->window_end_bytepos
@@ -15943,7 +15943,7 @@ try_window_id (w)
15943 start is not in changed text, otherwise positions would not be 15943 start is not in changed text, otherwise positions would not be
15944 comparable. */ 15944 comparable. */
15945 row = MATRIX_FIRST_TEXT_ROW (current_matrix); 15945 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15946 if (!TEXT_POS_EQUAL_P (start, row->start.pos)) 15946 if (!TEXT_POS_EQUAL_P (start, row->minpos))
15947 GIVE_UP (16); 15947 GIVE_UP (16);
15948 15948
15949 /* Give up if the window ends in strings. Overlay strings 15949 /* Give up if the window ends in strings. Overlay strings
@@ -17335,7 +17335,7 @@ cursor_row_p (w, row)
17335{ 17335{
17336 int cursor_row_p = 1; 17336 int cursor_row_p = 1;
17337 17337
17338 if (PT == MATRIX_ROW_END_CHARPOS (row)) 17338 if (PT == CHARPOS (row->end.pos))
17339 { 17339 {
17340 /* Suppose the row ends on a string. 17340 /* Suppose the row ends on a string.
17341 Unless the row is continued, that means it ends on a newline 17341 Unless the row is continued, that means it ends on a newline
@@ -17372,14 +17372,15 @@ cursor_row_p (w, row)
17372 { 17372 {
17373 /* If the row ends in middle of a real character, 17373 /* If the row ends in middle of a real character,
17374 and the line is continued, we want the cursor here. 17374 and the line is continued, we want the cursor here.
17375 That's because MATRIX_ROW_END_CHARPOS would equal 17375 That's because CHARPOS (ROW->end.pos) would equal
17376 PT if PT is before the character. */ 17376 PT if PT is before the character. */
17377 if (!row->ends_in_ellipsis_p) 17377 if (!row->ends_in_ellipsis_p)
17378 cursor_row_p = row->continued_p; 17378 cursor_row_p = row->continued_p;
17379 else 17379 else
17380 /* If the row ends in an ellipsis, then 17380 /* If the row ends in an ellipsis, then
17381 MATRIX_ROW_END_CHARPOS will equal point after the invisible text. 17381 CHARPOS (ROW->end.pos) will equal point after the
17382 We want that position to be displayed after the ellipsis. */ 17382 invisible text. We want that position to be displayed
17383 after the ellipsis. */
17383 cursor_row_p = 0; 17384 cursor_row_p = 0;
17384 } 17385 }
17385 /* If the row ends at ZV, display the cursor at the end of that 17386 /* If the row ends at ZV, display the cursor at the end of that
@@ -17515,122 +17516,87 @@ unproduce_glyphs (it, n)
17515 glyph[-n] = *glyph; 17516 glyph[-n] = *glyph;
17516} 17517}
17517 17518
17518/* Find the positions in a bidi-reordered ROW to serve as ROW->start 17519/* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
17519 and ROW->end. */ 17520 and ROW->maxpos. */
17520static struct display_pos 17521static void
17521find_row_end (it, row) 17522find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos)
17522 struct it *it; 17523 struct it *it;
17523 struct glyph_row *row; 17524 struct glyph_row *row;
17525 EMACS_INT min_pos, min_bpos, max_pos, max_bpos;
17524{ 17526{
17525 /* FIXME: Revisit this when glyph ``spilling'' in continuation 17527 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17526 lines' rows is implemented for bidi-reordered rows. */ 17528 lines' rows is implemented for bidi-reordered rows. */
17527 EMACS_INT min_pos = ZV + 1, max_pos = 0;
17528 struct glyph *g;
17529 struct it save_it;
17530 struct text_pos tpos;
17531 struct display_pos row_end = it->current;
17532 17529
17533 for (g = row->glyphs[TEXT_AREA]; 17530 /* ROW->minpos is the value of min_pos, the minimal buffer position
17534 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; 17531 we have in ROW. */
17535 g++) 17532 if (min_pos <= ZV)
17536 { 17533 {
17537 if (BUFFERP (g->object)) 17534 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
17535 if (max_pos == 0)
17538 { 17536 {
17539 if (g->charpos > 0 && g->charpos < min_pos) 17537 max_pos = min_pos;
17540 min_pos = g->charpos; 17538 max_bpos = min_bpos;
17541 if (g->charpos > max_pos)
17542 max_pos = g->charpos;
17543 } 17539 }
17544 } 17540 }
17545 /* Empty lines have a valid buffer position at their first 17541 else
17546 glyph, but that glyph's OBJECT is zero, as if it didn't come
17547 from a buffer. If we didn't find any valid buffer positions
17548 in this row, maybe we have such an empty line. */
17549 if (max_pos == 0 && row->used[TEXT_AREA])
17550 { 17542 {
17551 for (g = row->glyphs[TEXT_AREA]; 17543 /* We didn't find _any_ valid buffer positions in any of the
17552 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; 17544 glyphs, so we must trust the iterator's computed
17553 g++) 17545 positions. */
17554 { 17546 row->minpos = row->start.pos;
17555 if (INTEGERP (g->object)) 17547 max_pos = CHARPOS (it->current.pos);
17556 { 17548 max_bpos = BYTEPOS (it->current.pos);
17557 if (g->charpos > 0 && g->charpos < min_pos)
17558 min_pos = g->charpos;
17559 if (g->charpos > max_pos)
17560 max_pos = g->charpos;
17561 }
17562 }
17563 } 17549 }
17564 17550
17565 /* ROW->start is the value of min_pos, the minimal buffer position 17551 if (!max_pos)
17566 we have in ROW. */ 17552 abort ();
17567 if (min_pos <= ZV)
17568 {
17569 /* Avoid calling the costly CHAR_TO_BYTE if possible. */
17570 if (min_pos != row->start.pos.charpos)
17571 SET_TEXT_POS (row->start.pos, min_pos, CHAR_TO_BYTE (min_pos));
17572 if (max_pos == 0)
17573 max_pos = min_pos;
17574 }
17575 17553
17576 /* For ROW->end, we need the position that is _after_ max_pos, in 17554 /* Here are the various use-cases for ending the row, and the
17577 the logical order, unless we are at ZV. */ 17555 corresponding values for ROW->maxpos:
17556
17557 Empty line min_pos + 1
17558 Line ends in a newline from buffer eol_pos + 1
17559 Line is continued from buffer max_pos + 1
17560 Line ends in a newline from string max_pos
17561 Line is continued from string max_pos
17562 Line is entirely from a string min_pos
17563 Line that ends at ZV ZV
17564
17565 If you discover other use-cases, please add them here as
17566 appropriate. */
17578 if (row->ends_at_zv_p) 17567 if (row->ends_at_zv_p)
17568 row->maxpos = it->current.pos;
17569 else if (row->used[TEXT_AREA])
17579 { 17570 {
17580 if (!row->used[TEXT_AREA]) 17571 if (max_pos == min_pos)
17581 row->start.pos = row_end.pos;
17582 }
17583 else if (row->used[TEXT_AREA] && max_pos)
17584 {
17585 int at_eol_p;
17586
17587 SET_TEXT_POS (tpos, max_pos, CHAR_TO_BYTE (max_pos));
17588 save_it = *it;
17589 it->bidi_p = 0;
17590 reseat (it, tpos, 0);
17591 if (!get_next_display_element (it))
17592 abort (); /* this row cannot be at ZV, see above */
17593 at_eol_p = ITERATOR_AT_END_OF_LINE_P (it);
17594 set_iterator_to_next (it, 1);
17595 row_end = it->current;
17596 /* If the character at max_pos is not a newline and the
17597 characters at max_pos+1 is a newline, skip that newline as
17598 well. Note that this may skip some invisible text. */
17599 if (!at_eol_p
17600 && get_next_display_element (it)
17601 && ITERATOR_AT_END_OF_LINE_P (it))
17602 { 17572 {
17603 set_iterator_to_next (it, 1); 17573 if (it->method == GET_FROM_BUFFER)
17604 /* Record the position after the newline of a continued row. 17574 /* Empty line, which stands for a newline. */
17605 We will need that to set ROW->end of the last row 17575 SET_TEXT_POS (row->maxpos, min_pos + 1, min_bpos + 1);
17606 produced for a continued line. */
17607 if (row->continued_p)
17608 save_it.eol_pos = it->current.pos;
17609 else 17576 else
17610 { 17577 /* A line that is entirely from a string. */
17611 row_end = it->current; 17578 row->maxpos = row->minpos;
17612 save_it.eol_pos.charpos = save_it.eol_pos.bytepos = 0;
17613 }
17614 } 17579 }
17615 else if (!row->continued_p 17580 else if (CHARPOS (it->eol_pos) > 0)
17616 && MATRIX_ROW_CONTINUATION_LINE_P (row) 17581 SET_TEXT_POS (row->maxpos,
17617 && it->eol_pos.charpos > 0) 17582 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
17583 else if (row->continued_p)
17618 { 17584 {
17619 /* Last row of a continued line. Use the position recorded 17585 if (it->method == GET_FROM_BUFFER)
17620 in IT->eol_pos, to the effect that the newline belongs to 17586 {
17621 this row, not to the row which displays the character 17587 INC_BOTH (max_pos, max_bpos);
17622 with the largest buffer position before the newline. */ 17588 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17623 row_end.pos = it->eol_pos; 17589 }
17624 it->eol_pos.charpos = it->eol_pos.bytepos = 0; 17590 else
17591 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17625 } 17592 }
17626 *it = save_it; 17593 else if (row->ends_in_newline_from_string_p)
17627 /* The members of ROW->end that are not taken from buffer 17594 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17628 positions are copied from IT->current. */ 17595 else
17629 row_end.string_pos = it->current.string_pos; 17596 abort ();
17630 row_end.overlay_string_index = it->current.overlay_string_index;
17631 row_end.dpvec_index = it->current.dpvec_index;
17632 } 17597 }
17633 return row_end; 17598 else
17599 row->maxpos = it->current.pos;
17634} 17600}
17635 17601
17636/* Construct the glyph row IT->glyph_row in the desired matrix of 17602/* Construct the glyph row IT->glyph_row in the desired matrix of
@@ -17651,6 +17617,7 @@ display_line (it)
17651 int wrap_row_phys_ascent, wrap_row_phys_height; 17617 int wrap_row_phys_ascent, wrap_row_phys_height;
17652 int wrap_row_extra_line_spacing; 17618 int wrap_row_extra_line_spacing;
17653 int cvpos; 17619 int cvpos;
17620 EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos;
17654 17621
17655 /* We always start displaying at hpos zero even if hscrolled. */ 17622 /* We always start displaying at hpos zero even if hscrolled. */
17656 xassert (it->hpos == 0 && it->current_x == 0); 17623 xassert (it->hpos == 0 && it->current_x == 0);
@@ -17741,7 +17708,8 @@ display_line (it)
17741 row->ends_at_zv_p = 1; 17708 row->ends_at_zv_p = 1;
17742 /* A row that displays right-to-left text must always have 17709 /* A row that displays right-to-left text must always have
17743 its last face extended all the way to the end of line, 17710 its last face extended all the way to the end of line,
17744 even if this row ends in ZV. */ 17711 even if this row ends in ZV, because we still write to th
17712 screen left to right. */
17745 if (row->reversed_p) 17713 if (row->reversed_p)
17746 extend_face_to_end_of_line (it); 17714 extend_face_to_end_of_line (it);
17747 break; 17715 break;
@@ -17889,6 +17857,27 @@ display_line (it)
17889 } 17857 }
17890 } 17858 }
17891 } 17859 }
17860
17861 /* Record the maximum and minimum buffer
17862 positions seen so far in glyphs that will be
17863 displayed by this row. */
17864 if (it->bidi_p)
17865 {
17866 if (BUFFERP (glyph->object)
17867 || INTEGERP (glyph->object))
17868 {
17869 if (IT_CHARPOS (*it) < min_pos)
17870 {
17871 min_pos = IT_CHARPOS (*it);
17872 min_bpos = IT_BYTEPOS (*it);
17873 }
17874 if (IT_CHARPOS (*it) > max_pos)
17875 {
17876 max_pos = IT_CHARPOS (*it);
17877 max_bpos = IT_BYTEPOS (*it);
17878 }
17879 }
17880 }
17892 } 17881 }
17893 else if (CHAR_GLYPH_PADDING_P (*glyph) 17882 else if (CHAR_GLYPH_PADDING_P (*glyph)
17894 && !FRAME_WINDOW_P (it->f)) 17883 && !FRAME_WINDOW_P (it->f))
@@ -17994,6 +17983,27 @@ display_line (it)
17994 /* Increment number of glyphs actually displayed. */ 17983 /* Increment number of glyphs actually displayed. */
17995 ++it->hpos; 17984 ++it->hpos;
17996 17985
17986 /* Record the maximum and minimum buffer positions
17987 seen so far in glyphs that will be displayed by
17988 this row. */
17989 if (it->bidi_p)
17990 {
17991 if (BUFFERP (glyph->object)
17992 || INTEGERP (glyph->object))
17993 {
17994 if (IT_CHARPOS (*it) < min_pos)
17995 {
17996 min_pos = IT_CHARPOS (*it);
17997 min_bpos = IT_BYTEPOS (*it);
17998 }
17999 if (IT_CHARPOS (*it) > max_pos)
18000 {
18001 max_pos = IT_CHARPOS (*it);
18002 max_bpos = IT_BYTEPOS (*it);
18003 }
18004 }
18005 }
18006
17997 if (x < it->first_visible_x) 18007 if (x < it->first_visible_x)
17998 /* Glyph is partially visible, i.e. row starts at 18008 /* Glyph is partially visible, i.e. row starts at
17999 negative X position. */ 18009 negative X position. */
@@ -18045,6 +18055,10 @@ display_line (it)
18045 if (used_before == 0) 18055 if (used_before == 0)
18046 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position); 18056 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
18047 18057
18058 /* Record the position of the newline, for use in
18059 find_row_edges. */
18060 it->eol_pos = it->current.pos;
18061
18048 /* Consume the line end. This skips over invisible lines. */ 18062 /* Consume the line end. This skips over invisible lines. */
18049 set_iterator_to_next (it, 1); 18063 set_iterator_to_next (it, 1);
18050 it->continuation_lines_width = 0; 18064 it->continuation_lines_width = 0;
@@ -18124,7 +18138,7 @@ display_line (it)
18124 /* If line is not empty and hscrolled, maybe insert truncation glyphs 18138 /* If line is not empty and hscrolled, maybe insert truncation glyphs
18125 at the left window margin. */ 18139 at the left window margin. */
18126 if (it->first_visible_x 18140 if (it->first_visible_x
18127 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row)) 18141 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
18128 { 18142 {
18129 if (!FRAME_WINDOW_P (it->f)) 18143 if (!FRAME_WINDOW_P (it->f))
18130 insert_left_trunc_glyphs (it); 18144 insert_left_trunc_glyphs (it);
@@ -18178,12 +18192,19 @@ display_line (it)
18178 18192
18179 /* Remember the position at which this line ends. */ 18193 /* Remember the position at which this line ends. */
18180 row->end = it->current; 18194 row->end = it->current;
18181 /* ROW->start and ROW->end must be the smallest and the largest 18195 if (!it->bidi_p)
18182 buffer positions in ROW. But if ROW was bidi-reordered, these 18196 {
18183 two positions can be anywhere in the row, so we must rescan all 18197 row->minpos = row->start.pos;
18184 of the ROW's glyphs to find them. */ 18198 row->maxpos = row->end.pos;
18185 if (it->bidi_p) 18199 }
18186 row->end = find_row_end (it, row); 18200 else
18201 {
18202 /* ROW->minpos and ROW->maxpos must be the smallest and
18203 `1 + the largest' buffer positions in ROW. But if ROW was
18204 bidi-reordered, these two positions can be anywhere in the
18205 row, so we must determine them now. */
18206 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
18207 }
18187 18208
18188 /* Record whether this row ends inside an ellipsis. */ 18209 /* Record whether this row ends inside an ellipsis. */
18189 row->ends_in_ellipsis_p 18210 row->ends_in_ellipsis_p
@@ -18229,6 +18250,7 @@ display_line (it)
18229 row to be used. */ 18250 row to be used. */
18230 it->current_x = it->hpos = 0; 18251 it->current_x = it->hpos = 0;
18231 it->current_y += row->height; 18252 it->current_y += row->height;
18253 SET_TEXT_POS (it->eol_pos, 0, 0);
18232 ++it->vpos; 18254 ++it->vpos;
18233 ++it->glyph_row; 18255 ++it->glyph_row;
18234 /* The next row should by default use the same value of the 18256 /* The next row should by default use the same value of the