diff options
Diffstat (limited to 'src/window.c')
| -rw-r--r-- | src/window.c | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/src/window.c b/src/window.c index d9ac2eb62bd..be5e9167d67 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -206,7 +206,7 @@ static int window_initialized; | |||
| 206 | Lisp_Object Qwindow_configuration_change_hook; | 206 | Lisp_Object Qwindow_configuration_change_hook; |
| 207 | Lisp_Object Vwindow_configuration_change_hook; | 207 | Lisp_Object Vwindow_configuration_change_hook; |
| 208 | 208 | ||
| 209 | /* Nonzero means scroll commands try to put point | 209 | /* Non-nil means scroll commands try to put point |
| 210 | at the same screen height as previously. */ | 210 | at the same screen height as previously. */ |
| 211 | 211 | ||
| 212 | Lisp_Object Vscroll_preserve_screen_position; | 212 | Lisp_Object Vscroll_preserve_screen_position; |
| @@ -4508,7 +4508,7 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4508 | results for variable height lines. */ | 4508 | results for variable height lines. */ |
| 4509 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); | 4509 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); |
| 4510 | it.current_y = it.last_visible_y; | 4510 | it.current_y = it.last_visible_y; |
| 4511 | move_it_vertically (&it, - window_box_height (w) / 2); | 4511 | move_it_vertically_backward (&it, window_box_height (w) / 2); |
| 4512 | 4512 | ||
| 4513 | /* The function move_iterator_vertically may move over more than | 4513 | /* The function move_iterator_vertically may move over more than |
| 4514 | the specified y-distance. If it->w is small, e.g. a | 4514 | the specified y-distance. If it->w is small, e.g. a |
| @@ -4518,14 +4518,14 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4518 | if (it.current_y <= 0) | 4518 | if (it.current_y <= 0) |
| 4519 | { | 4519 | { |
| 4520 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); | 4520 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); |
| 4521 | move_it_vertically (&it, 0); | 4521 | move_it_vertically_backward (&it, 0); |
| 4522 | it.current_y = 0; | 4522 | it.current_y = 0; |
| 4523 | } | 4523 | } |
| 4524 | 4524 | ||
| 4525 | start = it.current.pos; | 4525 | start = it.current.pos; |
| 4526 | } | 4526 | } |
| 4527 | 4527 | ||
| 4528 | /* If scroll_preserve_screen_position is non-zero, we try to set | 4528 | /* If scroll_preserve_screen_position is non-nil, we try to set |
| 4529 | point in the same window line as it is now, so get that line. */ | 4529 | point in the same window line as it is now, so get that line. */ |
| 4530 | if (!NILP (Vscroll_preserve_screen_position)) | 4530 | if (!NILP (Vscroll_preserve_screen_position)) |
| 4531 | { | 4531 | { |
| @@ -5187,7 +5187,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5187 | 5187 | ||
| 5188 | SET_TEXT_POS (pt, PT, PT_BYTE); | 5188 | SET_TEXT_POS (pt, PT, PT_BYTE); |
| 5189 | start_display (&it, w, pt); | 5189 | start_display (&it, w, pt); |
| 5190 | move_it_vertically (&it, - window_box_height (w) / 2); | 5190 | move_it_vertically_backward (&it, window_box_height (w) / 2); |
| 5191 | charpos = IT_CHARPOS (it); | 5191 | charpos = IT_CHARPOS (it); |
| 5192 | bytepos = IT_BYTEPOS (it); | 5192 | bytepos = IT_BYTEPOS (it); |
| 5193 | } | 5193 | } |
| @@ -5195,29 +5195,62 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5195 | { | 5195 | { |
| 5196 | struct it it; | 5196 | struct it it; |
| 5197 | struct text_pos pt; | 5197 | struct text_pos pt; |
| 5198 | int y0, y1, h, nlines; | 5198 | int nlines = - XINT (arg); |
| 5199 | int extra_line_spacing; | ||
| 5200 | int h = window_box_height (w); | ||
| 5199 | 5201 | ||
| 5200 | SET_TEXT_POS (pt, PT, PT_BYTE); | 5202 | SET_TEXT_POS (pt, PT, PT_BYTE); |
| 5201 | start_display (&it, w, pt); | 5203 | start_display (&it, w, pt); |
| 5202 | y0 = it.current_y; | 5204 | |
| 5205 | /* Be sure we have the exact height of the full line containing PT. */ | ||
| 5206 | move_it_by_lines (&it, 0, 1); | ||
| 5203 | 5207 | ||
| 5204 | /* The amount of pixels we have to move back is the window | 5208 | /* The amount of pixels we have to move back is the window |
| 5205 | height minus what's displayed in the line containing PT, | 5209 | height minus what's displayed in the line containing PT, |
| 5206 | and the lines below. */ | 5210 | and the lines below. */ |
| 5207 | nlines = - XINT (arg) - 1; | 5211 | it.current_y = 0; |
| 5212 | it.vpos = 0; | ||
| 5208 | move_it_by_lines (&it, nlines, 1); | 5213 | move_it_by_lines (&it, nlines, 1); |
| 5209 | 5214 | ||
| 5210 | y1 = line_bottom_y (&it); | 5215 | if (it.vpos == nlines) |
| 5216 | h -= it.current_y; | ||
| 5217 | else | ||
| 5218 | { | ||
| 5219 | /* Last line has no newline */ | ||
| 5220 | h -= line_bottom_y (&it); | ||
| 5221 | it.vpos++; | ||
| 5222 | } | ||
| 5223 | |||
| 5224 | /* Don't reserve space for extra line spacing of last line. */ | ||
| 5225 | extra_line_spacing = it.max_extra_line_spacing; | ||
| 5211 | 5226 | ||
| 5212 | /* If we can't move down NLINES lines because we hit | 5227 | /* If we can't move down NLINES lines because we hit |
| 5213 | the end of the buffer, count in some empty lines. */ | 5228 | the end of the buffer, count in some empty lines. */ |
| 5214 | if (it.vpos < nlines) | 5229 | if (it.vpos < nlines) |
| 5215 | y1 += (nlines - it.vpos) * FRAME_LINE_HEIGHT (it.f); | 5230 | { |
| 5216 | 5231 | nlines -= it.vpos; | |
| 5217 | h = window_box_height (w) - (y1 - y0); | 5232 | extra_line_spacing = it.extra_line_spacing; |
| 5233 | h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing); | ||
| 5234 | } | ||
| 5235 | if (h <= 0) | ||
| 5236 | return Qnil; | ||
| 5218 | 5237 | ||
| 5238 | /* Now find the new top line (starting position) of the window. */ | ||
| 5219 | start_display (&it, w, pt); | 5239 | start_display (&it, w, pt); |
| 5220 | move_it_vertically (&it, - h); | 5240 | it.current_y = 0; |
| 5241 | move_it_vertically_backward (&it, h); | ||
| 5242 | |||
| 5243 | /* If extra line spacing is present, we may move too far | ||
| 5244 | back. This causes the last line to be only partially | ||
| 5245 | visible (which triggers redisplay to recenter that line | ||
| 5246 | in the middle), so move forward. | ||
| 5247 | But ignore extra line spacing on last line, as it is not | ||
| 5248 | considered to be part of the visible height of the line. | ||
| 5249 | */ | ||
| 5250 | h += extra_line_spacing; | ||
| 5251 | while (-it.current_y > h) | ||
| 5252 | move_it_by_lines (&it, 1, 1); | ||
| 5253 | |||
| 5221 | charpos = IT_CHARPOS (it); | 5254 | charpos = IT_CHARPOS (it); |
| 5222 | bytepos = IT_BYTEPOS (it); | 5255 | bytepos = IT_BYTEPOS (it); |
| 5223 | } | 5256 | } |