aboutsummaryrefslogtreecommitdiffstats
path: root/src/dispnew.c
diff options
context:
space:
mode:
authorPaul Eggert <[email protected]>2011-12-10 16:56:50 -0800
committerPaul Eggert <[email protected]>2011-12-10 16:56:50 -0800
commit8f50130c565eaf0ad7c49e4ad044c3291ecdfa71 (patch)
treec8129448cbbf387fe82667ccac02983592c688f1 /src/dispnew.c
parent85a83e2e2585a1906dec5168ed96ad521b5849ed (diff)
parent7b9d523a07395ecea505be88f45c33d73aea7038 (diff)
Merge from trunk.
Diffstat (limited to 'src/dispnew.c')
-rw-r--r--src/dispnew.c84
1 files changed, 71 insertions, 13 deletions
diff --git a/src/dispnew.c b/src/dispnew.c
index 88f7541407..e53e3fdf80 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -431,7 +431,7 @@ margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin
#if XASSERTS
/* Return non-zero if ROW's hash value is correct, zero if not. */
-static int
+int
verify_row_hash (struct glyph_row *row)
{
return row->hash == row_hash (row);
@@ -608,7 +608,6 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
row->glyphs[LAST_AREA]
= row->glyphs[LEFT_MARGIN_AREA] + dim.width;
}
- xassert (!row->enabled_p || verify_row_hash (row));
++row;
}
}
@@ -3575,12 +3574,11 @@ update_window (struct window *w, int force_p)
rif->update_window_begin_hook (w);
yb = window_text_bottom_y (w);
-
- /* If window has a header line, update it before everything else.
- Adjust y-positions of other rows by the header line height. */
row = desired_matrix->rows;
end = row + desired_matrix->nrows - 1;
+ /* Take note of the header line, if there is one. We will
+ update it below, after updating all of the window's lines. */
if (row->mode_line_p)
{
header_line_row = row;
@@ -3625,6 +3623,8 @@ update_window (struct window *w, int force_p)
/* Update the rest of the lines. */
for (; row < end && (force_p || !input_pending); ++row)
+ /* scrolling_window resets the enabled_p flag of the rows it
+ reuses from current_matrix. */
if (row->enabled_p)
{
int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
@@ -4550,18 +4550,69 @@ scrolling_window (struct window *w, int header_line_p)
{
rif->clear_window_mouse_face (w);
rif->scroll_run_hook (w, r);
+ }
- /* Invalidate runs that copy from where we copied to. */
- for (j = i + 1; j < nruns; ++j)
+ /* Truncate runs that copy to where we copied to, and
+ invalidate runs that copy from where we copied to. */
+ for (j = nruns - 1; j > i; --j)
+ {
+ struct run *p = runs[j];
+ int truncated_p = 0;
+
+ if (p->nrows > 0
+ && p->desired_y < r->desired_y + r->height
+ && p->desired_y + p->height > r->desired_y)
{
- struct run *p = runs[j];
+ if (p->desired_y < r->desired_y)
+ {
+ p->nrows = r->desired_vpos - p->desired_vpos;
+ p->height = r->desired_y - p->desired_y;
+ truncated_p = 1;
+ }
+ else
+ {
+ int nrows_copied = (r->desired_vpos + r->nrows
+ - p->desired_vpos);
+
+ if (p->nrows <= nrows_copied)
+ p->nrows = 0;
+ else
+ {
+ int height_copied = (r->desired_y + r->height
+ - p->desired_y);
+
+ p->current_vpos += nrows_copied;
+ p->desired_vpos += nrows_copied;
+ p->nrows -= nrows_copied;
+ p->current_y += height_copied;
+ p->desired_y += height_copied;
+ p->height -= height_copied;
+ truncated_p = 1;
+ }
+ }
+ }
- if ((p->current_y >= r->desired_y
+ if (r->current_y != r->desired_y
+ /* The condition below is equivalent to
+ ((p->current_y >= r->desired_y
&& p->current_y < r->desired_y + r->height)
- || (p->current_y + p->height >= r->desired_y
+ || (p->current_y + p->height > r->desired_y
&& (p->current_y + p->height
- < r->desired_y + r->height)))
- p->nrows = 0;
+ <= r->desired_y + r->height)))
+ because we have 0 < p->height <= r->height. */
+ && p->current_y < r->desired_y + r->height
+ && p->current_y + p->height > r->desired_y)
+ p->nrows = 0;
+
+ /* Reorder runs by copied pixel lines if truncated. */
+ if (truncated_p && p->nrows > 0)
+ {
+ int k = nruns - 1;
+
+ while (runs[k]->nrows == 0 || runs[k]->height < p->height)
+ k--;
+ memmove (runs + j, runs + j + 1, (k - j) * sizeof (*runs));
+ runs[k] = p;
}
}
@@ -4576,7 +4627,14 @@ scrolling_window (struct window *w, int header_line_p)
to_overlapped_p = to->overlapped_p;
from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
assign_row (to, from);
- to->enabled_p = 1, from->enabled_p = 0;
+ /* The above `assign_row' actually does swap, so if we had
+ an overlap in the copy destination of two runs, then
+ the second run would assign a previously disabled bogus
+ row. But thanks to the truncation code in the
+ preceding for-loop, we no longer have such an overlap,
+ and thus the assigned row should always be enabled. */
+ xassert (to->enabled_p);
+ from->enabled_p = 0;
to->overlapped_p = to_overlapped_p;
}
}