aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2012-01-09 17:23:36 +0800
committerChong Yidong2012-01-09 17:23:36 +0800
commitde92a50b9e157cac071355b9836717e62b9edff1 (patch)
tree0ec64958200cae394fb2e18de34bf244d69c708a /src
parentd58cba753997eba892a0f4c9a642c5cfc77099f6 (diff)
downloademacs-de92a50b9e157cac071355b9836717e62b9edff1.tar.gz
emacs-de92a50b9e157cac071355b9836717e62b9edff1.zip
Fix glitch in scrolling_window (backport from trunk).
* dispnew.c (scrolling_window): Truncate overlaps in copy destination of scroll runs so as to avoid assigning disabled bogus rows and unnecessary graphics copy operations.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog6
-rw-r--r--src/dispnew.c74
2 files changed, 72 insertions, 8 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 55cc8e8bf27..d0c89f2e44c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
12012-01-09 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2
3 * dispnew.c (scrolling_window): Truncate overlaps in copy
4 destination of scroll runs so as to avoid assigning disabled bogus
5 rows and unnecessary graphics copy operations.
6
12012-01-09 Eli Zaretskii <eliz@gnu.org> 72012-01-09 Eli Zaretskii <eliz@gnu.org>
2 8
3 * dispnew.c (scrolling_window): Fix incorrect indices in accessing 9 * dispnew.c (scrolling_window): Fix incorrect indices in accessing
diff --git a/src/dispnew.c b/src/dispnew.c
index c116c3f7c47..45ad9df7da9 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5208,18 +5208,69 @@ scrolling_window (w, header_line_p)
5208 { 5208 {
5209 rif->clear_window_mouse_face (w); 5209 rif->clear_window_mouse_face (w);
5210 rif->scroll_run_hook (w, r); 5210 rif->scroll_run_hook (w, r);
5211 }
5212
5213 /* Truncate runs that copy to where we copied to, and
5214 invalidate runs that copy from where we copied to. */
5215 for (j = nruns - 1; j > i; --j)
5216 {
5217 struct run *p = runs[j];
5218 int truncated_p = 0;
5211 5219
5212 /* Invalidate runs that copy from where we copied to. */ 5220 if (p->nrows > 0
5213 for (j = i + 1; j < nruns; ++j) 5221 && p->desired_y < r->desired_y + r->height
5222 && p->desired_y + p->height > r->desired_y)
5214 { 5223 {
5215 struct run *p = runs[j]; 5224 if (p->desired_y < r->desired_y)
5225 {
5226 p->nrows = r->desired_vpos - p->desired_vpos;
5227 p->height = r->desired_y - p->desired_y;
5228 truncated_p = 1;
5229 }
5230 else
5231 {
5232 int nrows_copied = (r->desired_vpos + r->nrows
5233 - p->desired_vpos);
5234
5235 if (p->nrows <= nrows_copied)
5236 p->nrows = 0;
5237 else
5238 {
5239 int height_copied = (r->desired_y + r->height
5240 - p->desired_y);
5241
5242 p->current_vpos += nrows_copied;
5243 p->desired_vpos += nrows_copied;
5244 p->nrows -= nrows_copied;
5245 p->current_y += height_copied;
5246 p->desired_y += height_copied;
5247 p->height -= height_copied;
5248 truncated_p = 1;
5249 }
5250 }
5251 }
5216 5252
5217 if ((p->current_y >= r->desired_y 5253 if (r->current_y != r->desired_y
5254 /* The condition below is equivalent to
5255 ((p->current_y >= r->desired_y
5218 && p->current_y < r->desired_y + r->height) 5256 && p->current_y < r->desired_y + r->height)
5219 || (p->current_y + p->height >= r->desired_y 5257 || (p->current_y + p->height > r->desired_y
5220 && (p->current_y + p->height 5258 && (p->current_y + p->height
5221 < r->desired_y + r->height))) 5259 <= r->desired_y + r->height)))
5222 p->nrows = 0; 5260 because we have 0 < p->height <= r->height. */
5261 && p->current_y < r->desired_y + r->height
5262 && p->current_y + p->height > r->desired_y)
5263 p->nrows = 0;
5264
5265 /* Reorder runs by copied pixel lines if truncated. */
5266 if (truncated_p && p->nrows > 0)
5267 {
5268 int k = nruns - 1;
5269
5270 while (runs[k]->nrows == 0 || runs[k]->height < p->height)
5271 k--;
5272 memmove (runs + j, runs + j + 1, (k - j) * sizeof (*runs));
5273 runs[k] = p;
5223 } 5274 }
5224 } 5275 }
5225 5276
@@ -5234,7 +5285,14 @@ scrolling_window (w, header_line_p)
5234 to_overlapped_p = to->overlapped_p; 5285 to_overlapped_p = to->overlapped_p;
5235 from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p; 5286 from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
5236 assign_row (to, from); 5287 assign_row (to, from);
5237 to->enabled_p = 1, from->enabled_p = 0; 5288 /* The above `assign_row' actually does swap, so if we had
5289 an overlap in the copy destination of two runs, then
5290 the second run would assign a previously disabled bogus
5291 row. But thanks to the truncation code in the
5292 preceding for-loop, we no longer have such an overlap,
5293 and thus the assigned row should always be enabled. */
5294 xassert (to->enabled_p);
5295 from->enabled_p = 0;
5238 to->overlapped_p = to_overlapped_p; 5296 to->overlapped_p = to_overlapped_p;
5239 } 5297 }
5240 } 5298 }