diff options
| author | YAMAMOTO Mitsuharu | 2012-01-09 17:23:36 +0800 |
|---|---|---|
| committer | Chong Yidong | 2012-01-09 17:23:36 +0800 |
| commit | de92a50b9e157cac071355b9836717e62b9edff1 (patch) | |
| tree | 0ec64958200cae394fb2e18de34bf244d69c708a /src | |
| parent | d58cba753997eba892a0f4c9a642c5cfc77099f6 (diff) | |
| download | emacs-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/ChangeLog | 6 | ||||
| -rw-r--r-- | src/dispnew.c | 74 |
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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-01-09 Eli Zaretskii <eliz@gnu.org> | 7 | 2012-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 | } |