patch 9.0.0908: with 'smoothscroll' cursor may end up in wrong position

Problem:    With 'smoothscroll' cursor may end up in wrong position.
Solution:   Correct the computation of screen lines. (Yee Cheng Chin,
            closes #11502)
diff --git a/src/move.c b/src/move.c
index 66e8c18..4205445 100644
--- a/src/move.c
+++ b/src/move.c
@@ -2460,18 +2460,50 @@
     used = curwin->w_cline_height;
 #endif
 
-    // If the cursor is below botline, we will at least scroll by the height
-    // of the cursor line.  Correct for empty lines, which are really part of
-    // botline.
+    // If the cursor is on or below botline, we will at least scroll by the
+    // height of the cursor line, which is "used".  Correct for empty lines,
+    // which are really part of botline.
     if (cln >= curwin->w_botline)
     {
 	scrolled = used;
 	if (cln == curwin->w_botline)
 	    scrolled -= curwin->w_empty_rows;
 	min_scrolled = scrolled;
-	if (cln > curwin->w_botline && curwin->w_p_sms && curwin->w_p_wrap)
-	    for (linenr_T lnum = curwin->w_botline + 1; lnum <= cln; ++lnum)
-		min_scrolled += PLINES_NOFILL(lnum);
+	if (curwin->w_p_sms && curwin->w_p_wrap)
+	{
+	    // 'smoothscroll' and 'wrap' are set
+	    if (cln > curwin->w_botline)
+		// add screen lines below w_botline
+		for (linenr_T lnum = curwin->w_botline + 1; lnum <= cln; ++lnum)
+		    min_scrolled += PLINES_NOFILL(lnum);
+
+	    // Calculate how many screen lines the current top line of window
+	    // occupies. If it is occupying more than the entire window, we
+	    // need to scroll the additional clipped lines to scroll past the
+	    // top line before we can move on to the other lines.
+	    int top_plines =
+#ifdef FEAT_DIFF
+			    plines_win_nofill
+#else
+			    plines_win
+#endif
+					(curwin, curwin->w_topline, FALSE);
+	    int skip_lines = 0;
+	    int width1 = curwin->w_width - curwin_col_off();
+	    int width2 = width1 + curwin_col_off2();
+	    // similar formula is used in curs_columns()
+	    if (curwin->w_skipcol > width1)
+		skip_lines += (curwin->w_skipcol - width1) / width2 + 1;
+	    else if (curwin->w_skipcol > 0)
+		skip_lines = 1;
+
+	    top_plines -= skip_lines;
+	    if (top_plines > curwin->w_height)
+	    {
+		scrolled += (top_plines - curwin->w_height);
+		min_scrolled += (top_plines - curwin->w_height);
+	    }
+	}
     }
 
     /*