Mercurial > emacs
changeset 107634:199cad45d7ba
Continue work on continuation lines. Some progress with cursor motion.
xdisp.c (set_cursor_from_row): Don't overwrite cursor position
if it is not a better candidate than what we already have.
(display_line): Keep calling set_cursor_from_row for
bidi-reordered rows even if we already have a possible candidate
for cursor position. Undo the row_end setting throughout the
code, and instead do it after all the row's glyphs have been
produced, by looping over the glyphs.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Sat, 13 Feb 2010 12:41:13 -0500 |
parents | 7e1441b44e84 |
children | a5eeeb631d8a |
files | src/ChangeLog.bidi src/xdisp.c |
diffstat | 2 files changed, 81 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog.bidi Sat Feb 13 08:18:46 2010 -0500 +++ b/src/ChangeLog.bidi Sat Feb 13 12:41:13 2010 -0500 @@ -1,3 +1,13 @@ +2010-02-13 Eli Zaretskii <eliz@gnu.org> + + * xdisp.c (set_cursor_from_row): Don't overwrite cursor position + if it is not a better candidate than what we already have. + (display_line): Keep calling set_cursor_from_row for + bidi-reordered rows even if we already have a possible candidate + for cursor position. Undo the row_end setting throughout the + code, and instead do it after all the row's glyphs have been + produced, by looping over the glyphs. + 2010-02-06 Eli Zaretskii <eliz@gnu.org> Start working on cursor movement in continuation lines.
--- a/src/xdisp.c Sat Feb 13 08:18:46 2010 -0500 +++ b/src/xdisp.c Sat Feb 13 12:41:13 2010 -0500 @@ -13008,6 +13008,32 @@ } } + /* ROW could be part of a continued line, which might have other + rows whose start and end charpos occlude point. Only set + w->cursor if we found a better approximation to the cursor + position than we have from previously examined rows. */ + if (w->cursor.vpos >= 0) + { + struct glyph *g1 = + MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos; + + /* Keep the candidate whose buffer position is the closest to + point. */ + if (BUFFERP (g1->object) + && (g1->charpos == pt_old /* an exact match always wins */ + || (BUFFERP (glyph->object) + && eabs (g1->charpos - pt_old) + < eabs (glyph->charpos - pt_old)))) + return 0; + /* Keep the candidate that comes from a row spanning less buffer + positions. This may win when one or both candidate positions + are on glyphs that came from display strings, for which we + cannot compare buffer positions. */ + if (MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) + - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) + < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row)) + return 0; + } w->cursor.hpos = glyph - row->glyphs[TEXT_AREA]; w->cursor.x = x; w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos; @@ -17160,7 +17186,6 @@ even if this row ends in ZV. */ if (row->reversed_p) extend_face_to_end_of_line (it); - row_end = it->current; break; } @@ -17395,7 +17420,6 @@ it->max_phys_descent = phys_descent; } - row_end = it->current; break; } else if (new_x > it->first_visible_x) @@ -17429,10 +17453,7 @@ /* End of this display line if row is continued. */ if (row->continued_p || row->ends_at_zv_p) - { - row_end = it->current; - break; - } + break; } at_end_of_line: @@ -17458,22 +17479,8 @@ row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position); /* Consume the line end. This skips over invisible lines. */ - if (it->bidi_p) - { - /* When we are reordering bidi text, we still need the - next character in logical order, to set row->end - correctly below. */ - push_it (it); - it->bidi_p = 0; - set_iterator_to_next (it, 1); - row_end = it->current; - pop_it (it); - it->bidi_p = 1; - } set_iterator_to_next (it, 1); it->continuation_lines_width = 0; - if (!it->bidi_p) - row_end = it->current; break; } @@ -17511,7 +17518,6 @@ it->continuation_lines_width = 0; row->ends_at_zv_p = 1; row->exact_window_width_line_p = 1; - row_end = it->current; break; } if (ITERATOR_AT_END_OF_LINE_P (it)) @@ -17527,7 +17533,6 @@ row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n'; it->hpos = hpos_before; it->current_x = x_before; - row_end = it->current; break; } } @@ -17588,7 +17593,44 @@ compute_line_metrics (it); /* Remember the position at which this line ends. */ - row->end = row_end; + if (!it->bidi_p) + row->end = row_end = it->current; + else + { + EMACS_INT min_pos = ZV, max_pos = BEGV; + struct glyph *g; + struct it save_it; + struct text_pos tpos; + + /* ROW->start and ROW->end must be the smallest and largest + buffer positions in ROW. But if ROW was bidi-reordered, + these two positions can be anywhere in the row, so we must + rescan all of the ROW's glyphs to find them. */ + for (g = row->glyphs[TEXT_AREA]; + g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; + g++) + { + if (BUFFERP (g->object)) + { + if (g->charpos < min_pos) + min_pos = g->charpos; + if (g->charpos > max_pos) + max_pos = g->charpos; + } + } + row->start.pos.charpos = min_pos; + row->start.pos.bytepos = CHAR_TO_BYTE (min_pos); + /* For ROW->end, we need the display element that is _after_ + max_pos, in the logical order. Note that this may be after + skipping some invisible text. */ + save_it = *it; + it->bidi_p = 0; + SET_TEXT_POS (tpos, max_pos, CHAR_TO_BYTE (max_pos)); + reseat_1 (it, tpos, 0); + set_iterator_to_next (it, 1); + row->end = row_end = it->current; + *it = save_it; + } /* Record whether this row ends inside an ellipsis. */ row->ends_in_ellipsis_p @@ -17607,7 +17649,12 @@ it->right_user_fringe_face_id = 0; /* Maybe set the cursor. */ - if (it->w->cursor.vpos < 0 + if ((it->w->cursor.vpos < 0 + /* In bidi-reordered rows, keep checking for proper cursor + position even if one has been found already, because buffer + positions in such rows change non-linearly with ROW->VPOS, + when a line is continued. */ + || it->bidi_p) && PT >= MATRIX_ROW_START_CHARPOS (row) && PT <= MATRIX_ROW_END_CHARPOS (row) && cursor_row_p (it->w, row))