+ if (centering_position < 0)
+ {
+ int margin =
+ scroll_margin > 0
+ ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
+ : 0;
+ EMACS_INT margin_pos = CHARPOS (startp);
+ int scrolling_up;
+ Lisp_Object aggressive;
+
+ /* If there is a scroll margin at the top of the window, find
+ its character position. */
+ if (margin
+ /* Cannot call start_display if startp is not in the
+ accessible region of the buffer. This can happen when we
+ have just switched to a different buffer and/or changed
+ its restriction. In that case, startp is initialized to
+ the character position 1 (BEG) because we did not yet
+ have chance to display the buffer even once. */
+ && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
+ {
+ struct it it1;
+
+ start_display (&it1, w, startp);
+ move_it_vertically (&it1, margin);
+ margin_pos = IT_CHARPOS (it1);
+ }
+ scrolling_up = PT > margin_pos;
+ aggressive =
+ scrolling_up
+ ? BVAR (current_buffer, scroll_up_aggressively)
+ : BVAR (current_buffer, scroll_down_aggressively);
+
+ if (!MINI_WINDOW_P (w)
+ && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
+ {
+ int pt_offset = 0;
+
+ /* Setting scroll-conservatively overrides
+ scroll-*-aggressively. */
+ if (!scroll_conservatively && NUMBERP (aggressive))
+ {
+ double float_amount = XFLOATINT (aggressive);
+
+ pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
+ if (pt_offset == 0 && float_amount > 0)
+ pt_offset = 1;
+ if (pt_offset)
+ margin -= 1;
+ }
+ /* Compute how much to move the window start backward from
+ point so that point will be displayed where the user
+ wants it. */
+ if (scrolling_up)
+ {
+ centering_position = it.last_visible_y;
+ if (pt_offset)
+ centering_position -= pt_offset;
+ centering_position -=
+ FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0));
+ /* Don't let point enter the scroll margin near top of
+ the window. */
+ if (centering_position < margin * FRAME_LINE_HEIGHT (f))
+ centering_position = margin * FRAME_LINE_HEIGHT (f);
+ }
+ else
+ centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
+ }
+ else
+ /* Set the window start half the height of the window backward
+ from point. */
+ centering_position = window_box_height (w) / 2;
+ }