Commit 408f5064 authored by Gerd Moellmann's avatar Gerd Moellmann

(redraw_overlapping_rows): Use flag overlapping_p.

(direct_output_for_insert): Ditto.
(direct_output_for_insert): Don't use this method if
row is overlapped by others.
(update_text_area): Write full line if current line is overlapped.
(redraw_overlapped_rows): New.
(update_window): Call it.
(redraw_overlapping_rows): New.
(update_window): Call it.
(scrolling_window): Make sure overlapped_p flag in current rows is
unchanged.
(row_equal_p): Take rows overlapped_p flag into account.
(adjust_glyphs): Block input while adjusting matrices.
(direct_output_for_insert): Don't use this
optimization for rows that overlap others.
(update_window_line): Return non-zero if display has changed.
(update_text_area): Ditto.
(update_window): Record if display has been changed.
(blank_row): Compute glyph row's physical height.
(row_equal_p): Take physical row heights into account.
(direct_output_for_insert): Ditto.
(update_text_area): Ditto.
parent 2febf6e0
...@@ -109,6 +109,8 @@ struct dim ...@@ -109,6 +109,8 @@ struct dim
/* Function prototypes. */ /* Function prototypes. */
static void redraw_overlapping_rows P_ ((struct window *, int));
static void redraw_overlapped_rows P_ ((struct window *, int));
static int count_blanks P_ ((struct glyph *, int)); static int count_blanks P_ ((struct glyph *, int));
static int count_match P_ ((struct glyph *, struct glyph *, static int count_match P_ ((struct glyph *, struct glyph *,
struct glyph *, struct glyph *)); struct glyph *, struct glyph *));
...@@ -146,9 +148,9 @@ void scroll_glyph_matrix_range P_ ((struct glyph_matrix *, int, int, ...@@ -146,9 +148,9 @@ void scroll_glyph_matrix_range P_ ((struct glyph_matrix *, int, int,
static void clear_window_matrices P_ ((struct window *, int)); static void clear_window_matrices P_ ((struct window *, int));
static void fill_up_glyph_row_area_with_spaces P_ ((struct glyph_row *, int)); static void fill_up_glyph_row_area_with_spaces P_ ((struct glyph_row *, int));
static int scrolling_window P_ ((struct window *, int)); static int scrolling_window P_ ((struct window *, int));
static void update_window_line P_ ((struct window *, int)); static int update_window_line P_ ((struct window *, int));
static void update_marginal_area P_ ((struct window *, int, int)); static void update_marginal_area P_ ((struct window *, int, int));
static void update_text_area P_ ((struct window *, int)); static int update_text_area P_ ((struct window *, int));
static void make_current P_ ((struct glyph_matrix *, struct glyph_matrix *, static void make_current P_ ((struct glyph_matrix *, struct glyph_matrix *,
int)); int));
static void mirror_make_current P_ ((struct window *, int)); static void mirror_make_current P_ ((struct window *, int));
...@@ -999,8 +1001,8 @@ blank_row (w, row, y) ...@@ -999,8 +1001,8 @@ blank_row (w, row, y)
clear_glyph_row (row); clear_glyph_row (row);
row->y = y; row->y = y;
row->ascent = 0; row->ascent = row->phys_ascent = 0;
row->height = CANON_Y_UNIT (XFRAME (WINDOW_FRAME (w))); row->height = row->phys_height = CANON_Y_UNIT (XFRAME (w->frame));
if (row->y < min_y) if (row->y < min_y)
row->visible_height = row->height - (min_y - row->y); row->visible_height = row->height - (min_y - row->y);
...@@ -1361,12 +1363,15 @@ row_equal_p (w, a, b) ...@@ -1361,12 +1363,15 @@ row_equal_p (w, a, b)
|| a->overlay_arrow_p != b->overlay_arrow_p || a->overlay_arrow_p != b->overlay_arrow_p
|| a->continued_p != b->continued_p || a->continued_p != b->continued_p
|| a->indicate_empty_line_p != b->indicate_empty_line_p || a->indicate_empty_line_p != b->indicate_empty_line_p
|| a->overlapped_p != b->overlapped_p
|| (MATRIX_ROW_CONTINUATION_LINE_P (a) || (MATRIX_ROW_CONTINUATION_LINE_P (a)
!= MATRIX_ROW_CONTINUATION_LINE_P (b)) != MATRIX_ROW_CONTINUATION_LINE_P (b))
/* Different partially visible characters on left margin. */ /* Different partially visible characters on left margin. */
|| a->x != b->x || a->x != b->x
/* Different height. */ /* Different height. */
|| a->ascent != b->ascent || a->ascent != b->ascent
|| a->phys_ascent != b->phys_ascent
|| a->phys_height != b->phys_height
|| a->visible_height != b->visible_height) || a->visible_height != b->visible_height)
return 0; return 0;
} }
...@@ -1863,6 +1868,10 @@ void ...@@ -1863,6 +1868,10 @@ void
adjust_glyphs (f) adjust_glyphs (f)
struct frame *f; struct frame *f;
{ {
/* Block input so that expose events and other events that access
glyph matrices are not processed while we are changing them. */
BLOCK_INPUT;
if (f) if (f)
adjust_frame_glyphs (f); adjust_frame_glyphs (f);
else else
...@@ -1872,6 +1881,8 @@ adjust_glyphs (f) ...@@ -1872,6 +1881,8 @@ adjust_glyphs (f)
FOR_EACH_FRAME (tail, lisp_frame) FOR_EACH_FRAME (tail, lisp_frame)
adjust_frame_glyphs (XFRAME (lisp_frame)); adjust_frame_glyphs (XFRAME (lisp_frame));
} }
UNBLOCK_INPUT;
} }
...@@ -3025,9 +3036,15 @@ direct_output_for_insert (g) ...@@ -3025,9 +3036,15 @@ direct_output_for_insert (g)
|| g == '\r' || g == '\r'
/* Give up if unable to display the cursor in the window. */ /* Give up if unable to display the cursor in the window. */
|| w->cursor.vpos < 0 || w->cursor.vpos < 0
/* Can't do it in a continued line because continuation lines || (glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos),
will change. */ /* Can't do it in a continued line because continuation
|| MATRIX_ROW (w->current_matrix, w->cursor.vpos)->continued_p lines would change. */
(glyph_row->continued_p
/* Can't use this method if the line overlaps others or is
overlapped by others because these other lines would
have to be redisplayed. */
|| glyph_row->overlapping_p
|| glyph_row->overlapped_p))
/* Can't do it for partial width windows on terminal frames /* Can't do it for partial width windows on terminal frames
because we can't clear to eol in such a window. */ because we can't clear to eol in such a window. */
|| (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w))) || (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w)))
...@@ -3088,6 +3105,8 @@ direct_output_for_insert (g) ...@@ -3088,6 +3105,8 @@ direct_output_for_insert (g)
the original row, or if it is not a character glyph. */ the original row, or if it is not a character glyph. */
if (glyph_row->ascent != it.ascent if (glyph_row->ascent != it.ascent
|| glyph_row->height != it.ascent + it.descent || glyph_row->height != it.ascent + it.descent
|| glyph_row->phys_ascent != it.phys_ascent
|| glyph_row->phys_height != it.phys_ascent + it.phys_descent
|| it.what != IT_CHARACTER) || it.what != IT_CHARACTER)
return 0; return 0;
...@@ -3450,6 +3469,104 @@ update_single_window (w, force_p) ...@@ -3450,6 +3469,104 @@ update_single_window (w, force_p)
} }
/* Redraw lines from the current matrix of window W that are
overlapped by other rows. YB is bottom-most y-position in W. */
static void
redraw_overlapped_rows (w, yb)
struct window *w;
int yb;
{
int i, bottom_y;
struct glyph_row *row;
/* If rows overlapping others have been changed, the rows being
overlapped have to be redrawn. This won't draw lines that have
already been drawn in update_window_line because overlapped_p in
desired rows is 0, so after row assignment overlapped_p in
current rows is 0. */
for (i = 0; i < w->current_matrix->nrows; ++i)
{
row = w->current_matrix->rows + i;
if (!row->enabled_p)
break;
else if (row->mode_line_p)
continue;
if (row->overlapped_p)
{
enum glyph_row_area area;
for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
{
updated_row = row;
updated_area = area;
rif->cursor_to (i, 0, row->y, area == TEXT_AREA ? row->x : 0);
if (row->used[area])
rif->write_glyphs (row->glyphs[area], row->used[area]);
rif->clear_end_of_line (-1);
}
row->overlapped_p = 0;
}
bottom_y = MATRIX_ROW_BOTTOM_Y (row);
if (bottom_y >= yb)
break;
}
}
/* Redraw lines from the current matrix of window W that overlap
others. YB is bottom-most y-position in W. */
static void
redraw_overlapping_rows (w, yb)
struct window *w;
int yb;
{
int i, bottom_y;
struct glyph_row *row;
for (i = 0; i < w->current_matrix->nrows; ++i)
{
row = w->current_matrix->rows + i;
if (!row->enabled_p)
break;
else if (row->mode_line_p)
continue;
bottom_y = MATRIX_ROW_BOTTOM_Y (row);
if (row->overlapping_p && i > 0 && bottom_y < yb)
{
if (row->used[LEFT_MARGIN_AREA])
rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
if (row->used[TEXT_AREA])
rif->fix_overlapping_area (w, row, TEXT_AREA);
if (row->used[RIGHT_MARGIN_AREA])
rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
/* Record in neighbor rows that ROW overwrites part of their
display. */
if (row->phys_ascent > row->ascent && i > 0)
MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
if ((row->phys_height - row->phys_ascent
> row->height - row->ascent)
&& bottom_y < yb)
MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
}
if (bottom_y >= yb)
break;
}
}
/* Update display of window W. FORCE_P non-zero means that we should /* Update display of window W. FORCE_P non-zero means that we should
not stop when detecting pending input. */ not stop when detecting pending input. */
...@@ -3482,7 +3599,7 @@ update_window (w, force_p) ...@@ -3482,7 +3599,7 @@ update_window (w, force_p)
struct glyph_row *row, *end; struct glyph_row *row, *end;
struct glyph_row *mode_line_row; struct glyph_row *mode_line_row;
struct glyph_row *top_line_row = NULL; struct glyph_row *top_line_row = NULL;
int yb; int yb, changed_p = 0;
rif->update_window_begin_hook (w); rif->update_window_begin_hook (w);
yb = window_text_bottom_y (w); yb = window_text_bottom_y (w);
...@@ -3501,6 +3618,7 @@ update_window (w, force_p) ...@@ -3501,6 +3618,7 @@ update_window (w, force_p)
mode_line_row->y = yb; mode_line_row->y = yb;
update_window_line (w, MATRIX_ROW_VPOS (mode_line_row, update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
desired_matrix)); desired_matrix));
changed_p = 1;
} }
/* Find first enabled row. Optimizations in redisplay_internal /* Find first enabled row. Optimizations in redisplay_internal
...@@ -3521,6 +3639,7 @@ update_window (w, force_p) ...@@ -3521,6 +3639,7 @@ update_window (w, force_p)
} }
else if (rc > 0) else if (rc > 0)
force_p = 1; force_p = 1;
changed_p = 1;
} }
/* Update the top mode line after scrolling because a new top /* Update the top mode line after scrolling because a new top
...@@ -3530,6 +3649,7 @@ update_window (w, force_p) ...@@ -3530,6 +3649,7 @@ update_window (w, force_p)
{ {
top_line_row->y = 0; top_line_row->y = 0;
update_window_line (w, 0); update_window_line (w, 0);
changed_p = 1;
} }
/* Update the rest of the lines. */ /* Update the rest of the lines. */
...@@ -3550,7 +3670,7 @@ update_window (w, force_p) ...@@ -3550,7 +3670,7 @@ update_window (w, force_p)
if (!force_p && vpos % preempt_count == 0) if (!force_p && vpos % preempt_count == 0)
detect_input_pending (); detect_input_pending ();
update_window_line (w, vpos); changed_p |= update_window_line (w, vpos);
/* Mark all rows below the last visible one in the current /* Mark all rows below the last visible one in the current
matrix as invalid. This is necessary because of matrix as invalid. This is necessary because of
...@@ -3571,6 +3691,16 @@ update_window (w, force_p) ...@@ -3571,6 +3691,16 @@ update_window (w, force_p)
set_cursor: set_cursor:
/* Fix the appearance of overlapping(overlapped rows. */
if (rif->fix_overlapping_area
&& !w->pseudo_window_p
&& changed_p
&& !paused_p)
{
redraw_overlapped_rows (w, yb);
redraw_overlapping_rows (w, yb);
}
if (!paused_p && !w->pseudo_window_p) if (!paused_p && !w->pseudo_window_p)
{ {
/* Make cursor visible at cursor position of W. */ /* Make cursor visible at cursor position of W. */
...@@ -3588,14 +3718,16 @@ update_window (w, force_p) ...@@ -3588,14 +3718,16 @@ update_window (w, force_p)
/* Remember the redisplay method used to display the matrix. */ /* Remember the redisplay method used to display the matrix. */
strcpy (w->current_matrix->method, w->desired_matrix->method); strcpy (w->current_matrix->method, w->desired_matrix->method);
#endif #endif
/* End of update of window W. */ /* End of update of window W. */
rif->update_window_end_hook (w, 1); rif->update_window_end_hook (w, 1);
} }
else else
paused_p = 1; paused_p = 1;
clear_glyph_matrix (desired_matrix); clear_glyph_matrix (desired_matrix);
return paused_p; return paused_p;
} }
...@@ -3624,15 +3756,17 @@ update_marginal_area (w, area, vpos) ...@@ -3624,15 +3756,17 @@ update_marginal_area (w, area, vpos)
} }
/* Update the display of the text area of row VPOS in window W. */ /* Update the display of the text area of row VPOS in window W.
Value is non-zero if display has changed. */
static void static int
update_text_area (w, vpos) update_text_area (w, vpos)
struct window *w; struct window *w;
int vpos; int vpos;
{ {
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
int changed_p = 0;
/* Let functions in xterm.c know what area subsequent X positions /* Let functions in xterm.c know what area subsequent X positions
will be relative to. */ will be relative to. */
...@@ -3643,7 +3777,10 @@ update_text_area (w, vpos) ...@@ -3643,7 +3777,10 @@ update_text_area (w, vpos)
if (!current_row->enabled_p if (!current_row->enabled_p
|| desired_row->y != current_row->y || desired_row->y != current_row->y
|| desired_row->ascent != current_row->ascent || desired_row->ascent != current_row->ascent
|| desired_row->phys_ascent != current_row->phys_ascent
|| desired_row->phys_height != current_row->phys_height
|| desired_row->visible_height != current_row->visible_height || desired_row->visible_height != current_row->visible_height
|| current_row->overlapped_p
|| current_row->x != desired_row->x) || current_row->x != desired_row->x)
{ {
rif->cursor_to (vpos, 0, desired_row->y, desired_row->x); rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
...@@ -3654,6 +3791,7 @@ update_text_area (w, vpos) ...@@ -3654,6 +3791,7 @@ update_text_area (w, vpos)
/* Clear to end of window. */ /* Clear to end of window. */
rif->clear_end_of_line (-1); rif->clear_end_of_line (-1);
changed_p = 1;
} }
else else
{ {
...@@ -3736,6 +3874,7 @@ update_text_area (w, vpos) ...@@ -3736,6 +3874,7 @@ update_text_area (w, vpos)
rif->cursor_to (vpos, start_hpos, desired_row->y, start_x); rif->cursor_to (vpos, start_hpos, desired_row->y, start_x);
rif->write_glyphs (start, i - start_hpos); rif->write_glyphs (start, i - start_hpos);
changed_p = 1;
} }
} }
...@@ -3744,6 +3883,7 @@ update_text_area (w, vpos) ...@@ -3744,6 +3883,7 @@ update_text_area (w, vpos)
{ {
rif->cursor_to (vpos, i, desired_row->y, x); rif->cursor_to (vpos, i, desired_row->y, x);
rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i); rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i);
changed_p = 1;
} }
/* Maybe clear to end of line. */ /* Maybe clear to end of line. */
...@@ -3762,6 +3902,7 @@ update_text_area (w, vpos) ...@@ -3762,6 +3902,7 @@ update_text_area (w, vpos)
rif->cursor_to (vpos, i, desired_row->y, rif->cursor_to (vpos, i, desired_row->y,
desired_row->x + desired_row->pixel_width); desired_row->x + desired_row->pixel_width);
rif->clear_end_of_line (-1); rif->clear_end_of_line (-1);
changed_p = 1;
} }
else if (desired_row->pixel_width < current_row->pixel_width) else if (desired_row->pixel_width < current_row->pixel_width)
{ {
...@@ -3787,20 +3928,25 @@ update_text_area (w, vpos) ...@@ -3787,20 +3928,25 @@ update_text_area (w, vpos)
else else
x = current_row->x + current_row->pixel_width; x = current_row->x + current_row->pixel_width;
rif->clear_end_of_line (x); rif->clear_end_of_line (x);
changed_p = 1;
} }
} }
return changed_p;
} }
/* Update row VPOS in window W. */ /* Update row VPOS in window W. Value is non-zero if display has been
changed. */
static void static int
update_window_line (w, vpos) update_window_line (w, vpos)
struct window *w; struct window *w;
int vpos; int vpos;
{ {
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
int changed_p = 0;
xassert (desired_row->enabled_p); xassert (desired_row->enabled_p);
...@@ -3811,15 +3957,21 @@ update_window_line (w, vpos) ...@@ -3811,15 +3957,21 @@ update_window_line (w, vpos)
/* Update display of the left margin area, if there is one. */ /* Update display of the left margin area, if there is one. */
if (!desired_row->full_width_p if (!desired_row->full_width_p
&& !NILP (w->left_margin_width)) && !NILP (w->left_margin_width))
update_marginal_area (w, LEFT_MARGIN_AREA, vpos); {
update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
changed_p = 1;
}
/* Update the display of the text area. */ /* Update the display of the text area. */
update_text_area (w, vpos); changed_p |= update_text_area (w, vpos);
/* Update display of the right margin area, if there is one. */ /* Update display of the right margin area, if there is one. */
if (!desired_row->full_width_p if (!desired_row->full_width_p
&& !NILP (w->right_margin_width)) && !NILP (w->right_margin_width))
update_marginal_area (w, RIGHT_MARGIN_AREA, vpos); {
changed_p = 1;
update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
}
/* Draw truncation marks etc. */ /* Draw truncation marks etc. */
if (!current_row->enabled_p if (!current_row->enabled_p
...@@ -3839,6 +3991,7 @@ update_window_line (w, vpos) ...@@ -3839,6 +3991,7 @@ update_window_line (w, vpos)
/* Update current_row from desired_row. */ /* Update current_row from desired_row. */
make_current (w->desired_matrix, w->current_matrix, vpos); make_current (w->desired_matrix, w->current_matrix, vpos);
updated_row = NULL; updated_row = NULL;
return changed_p;
} }
...@@ -4207,10 +4360,14 @@ scrolling_window (w, top_line_p) ...@@ -4207,10 +4360,14 @@ scrolling_window (w, top_line_p)
for (j = 0; j < r->nrows; ++j) for (j = 0; j < r->nrows; ++j)
{ {
struct glyph_row *from, *to; struct glyph_row *from, *to;
int to_overlapped_p;
to = MATRIX_ROW (current_matrix, r->desired_vpos + j); to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
to_overlapped_p = to->overlapped_p;
from = MATRIX_ROW (desired_matrix, r->desired_vpos + j); from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
assign_row (to, from); assign_row (to, from);
to->enabled_p = 1, from->enabled_p = 0; to->enabled_p = 1, from->enabled_p = 0;
to->overlapped_p = to_overlapped_p;
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment