comparison src/window.c @ 58175:eeb5474ef89f

(window_scroll_pixel_based, Frecenter): Use move_it_vertically_backward directly. (Frecenter): Fix calculation of new start pos for negative arg. Before, the new start pos was sometimes chosen too far back, so the last line became only partially visible, and thus would be either only semi-visible or automatically scrolled to the middle of the window by redisplay.
author Kim F. Storm <storm@cua.dk>
date Fri, 12 Nov 2004 14:26:53 +0000
parents 49b5dabf0ccc
children 72149deebe89 3ec251523b3e
comparison
equal deleted inserted replaced
58174:1e3a9e2d4cad 58175:eeb5474ef89f
4504 /* Move backward half the height of the window. Performance note: 4504 /* Move backward half the height of the window. Performance note:
4505 vmotion used here is about 10% faster, but would give wrong 4505 vmotion used here is about 10% faster, but would give wrong
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
4513 mini-buffer window, we may end up in front of the window's 4513 mini-buffer window, we may end up in front of the window's
4514 display area. This is the case when Start displaying at the 4514 display area. This is the case when Start displaying at the
4515 start of the line containing PT in this case. */ 4515 start of the line containing PT in this case. */
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
4523 start = it.current.pos; 4523 start = it.current.pos;
4524 } 4524 }
5183 struct it it; 5183 struct it it;
5184 struct text_pos pt; 5184 struct text_pos pt;
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 }
5192 else if (XINT (arg) < 0) 5192 else if (XINT (arg) < 0)
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;
5216 5231 h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing);
5232 }
5233 if (h <= 0)
5234 return Qnil;
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 }
5222 else 5255 else
5223 { 5256 {