diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/window.c | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/src/window.c b/src/window.c index 0c08a662380..24be93a3943 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -4506,7 +4506,7 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4506 | results for variable height lines. */ | 4506 | results for variable height lines. */ |
| 4507 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); | 4507 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); |
| 4508 | it.current_y = it.last_visible_y; | 4508 | it.current_y = it.last_visible_y; |
| 4509 | move_it_vertically (&it, - window_box_height (w) / 2); | 4509 | move_it_vertically_backward (&it, window_box_height (w) / 2); |
| 4510 | 4510 | ||
| 4511 | /* The function move_iterator_vertically may move over more than | 4511 | /* The function move_iterator_vertically may move over more than |
| 4512 | the specified y-distance. If it->w is small, e.g. a | 4512 | the specified y-distance. If it->w is small, e.g. a |
| @@ -4516,7 +4516,7 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4516 | if (it.current_y <= 0) | 4516 | if (it.current_y <= 0) |
| 4517 | { | 4517 | { |
| 4518 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); | 4518 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); |
| 4519 | move_it_vertically (&it, 0); | 4519 | move_it_vertically_backward (&it, 0); |
| 4520 | it.current_y = 0; | 4520 | it.current_y = 0; |
| 4521 | } | 4521 | } |
| 4522 | 4522 | ||
| @@ -5185,7 +5185,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5185 | 5185 | ||
| 5186 | SET_TEXT_POS (pt, PT, PT_BYTE); | 5186 | SET_TEXT_POS (pt, PT, PT_BYTE); |
| 5187 | start_display (&it, w, pt); | 5187 | start_display (&it, w, pt); |
| 5188 | move_it_vertically (&it, - window_box_height (w) / 2); | 5188 | move_it_vertically_backward (&it, window_box_height (w) / 2); |
| 5189 | charpos = IT_CHARPOS (it); | 5189 | charpos = IT_CHARPOS (it); |
| 5190 | bytepos = IT_BYTEPOS (it); | 5190 | bytepos = IT_BYTEPOS (it); |
| 5191 | } | 5191 | } |
| @@ -5193,29 +5193,62 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5193 | { | 5193 | { |
| 5194 | struct it it; | 5194 | struct it it; |
| 5195 | struct text_pos pt; | 5195 | struct text_pos pt; |
| 5196 | int y0, y1, h, nlines; | 5196 | int nlines = - XINT (arg); |
| 5197 | int extra_line_spacing; | ||
| 5198 | int h = window_box_height (w); | ||
| 5197 | 5199 | ||
| 5198 | SET_TEXT_POS (pt, PT, PT_BYTE); | 5200 | SET_TEXT_POS (pt, PT, PT_BYTE); |
| 5199 | start_display (&it, w, pt); | 5201 | start_display (&it, w, pt); |
| 5200 | y0 = it.current_y; | 5202 | |
| 5203 | /* Be sure we have the exact height of the full line containing PT. */ | ||
| 5204 | move_it_by_lines (&it, 0, 1); | ||
| 5201 | 5205 | ||
| 5202 | /* The amount of pixels we have to move back is the window | 5206 | /* The amount of pixels we have to move back is the window |
| 5203 | height minus what's displayed in the line containing PT, | 5207 | height minus what's displayed in the line containing PT, |
| 5204 | and the lines below. */ | 5208 | and the lines below. */ |
| 5205 | nlines = - XINT (arg) - 1; | 5209 | it.current_y = 0; |
| 5210 | it.vpos = 0; | ||
| 5206 | move_it_by_lines (&it, nlines, 1); | 5211 | move_it_by_lines (&it, nlines, 1); |
| 5207 | 5212 | ||
| 5208 | y1 = line_bottom_y (&it); | 5213 | if (it.vpos == nlines) |
| 5214 | h -= it.current_y; | ||
| 5215 | else | ||
| 5216 | { | ||
| 5217 | /* Last line has no newline */ | ||
| 5218 | h -= line_bottom_y (&it); | ||
| 5219 | it.vpos++; | ||
| 5220 | } | ||
| 5221 | |||
| 5222 | /* Don't reserve space for extra line spacing of last line. */ | ||
| 5223 | extra_line_spacing = it.max_extra_line_spacing; | ||
| 5209 | 5224 | ||
| 5210 | /* If we can't move down NLINES lines because we hit | 5225 | /* If we can't move down NLINES lines because we hit |
| 5211 | the end of the buffer, count in some empty lines. */ | 5226 | the end of the buffer, count in some empty lines. */ |
| 5212 | if (it.vpos < nlines) | 5227 | if (it.vpos < nlines) |
| 5213 | y1 += (nlines - it.vpos) * FRAME_LINE_HEIGHT (it.f); | 5228 | { |
| 5214 | 5229 | nlines -= it.vpos; | |
| 5215 | h = window_box_height (w) - (y1 - y0); | 5230 | extra_line_spacing = it.extra_line_spacing; |
| 5231 | h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing); | ||
| 5232 | } | ||
| 5233 | if (h <= 0) | ||
| 5234 | return Qnil; | ||
| 5216 | 5235 | ||
| 5236 | /* Now find the new top line (starting position) of the window. */ | ||
| 5217 | start_display (&it, w, pt); | 5237 | start_display (&it, w, pt); |
| 5218 | move_it_vertically (&it, - h); | 5238 | it.current_y = 0; |
| 5239 | move_it_vertically_backward (&it, h); | ||
| 5240 | |||
| 5241 | /* If extra line spacing is present, we may move too far | ||
| 5242 | back. This causes the last line to be only partially | ||
| 5243 | visible (which triggers redisplay to recenter that line | ||
| 5244 | in the middle), so move forward. | ||
| 5245 | But ignore extra line spacing on last line, as it is not | ||
| 5246 | considered to be part of the visible height of the line. | ||
| 5247 | */ | ||
| 5248 | h += extra_line_spacing; | ||
| 5249 | while (-it.current_y > h) | ||
| 5250 | move_it_by_lines (&it, 1, 1); | ||
| 5251 | |||
| 5219 | charpos = IT_CHARPOS (it); | 5252 | charpos = IT_CHARPOS (it); |
| 5220 | bytepos = IT_BYTEPOS (it); | 5253 | bytepos = IT_BYTEPOS (it); |
| 5221 | } | 5254 | } |