From: Eli Zaretskii Date: Sat, 13 Feb 2010 17:41:13 +0000 (-0500) Subject: Continue work on continuation lines. Some progress with cursor motion. X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~438^2~635^2~13 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=ae9784892b7c9005b792b026d466af105bcb655f;p=emacs.git 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. --- diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index 73fd6bf8da2..22a19c66300 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi @@ -1,3 +1,13 @@ +2010-02-13 Eli Zaretskii + + * 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 Start working on cursor movement in continuation lines. diff --git a/src/xdisp.c b/src/xdisp.c index 8f366134cea..e8a77af8935 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13008,6 +13008,32 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) } } + /* 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 @@ display_line (it) 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 @@ display_line (it) it->max_phys_descent = phys_descent; } - row_end = it->current; break; } else if (new_x > it->first_visible_x) @@ -17429,10 +17453,7 @@ display_line (it) /* 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 @@ display_line (it) 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 @@ display_line (it) 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 @@ display_line (it) 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 @@ display_line (it) 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 @@ display_line (it) 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))