Fix EditText cursor when line spacing is set

Test: bit FrameworksCoreTests:android.widget.TextViewTest
Test: bit FrameworksCoreTests:android.widget.EditorCursorTest
Test: bit CtsWidgetTestCases:android.widget.cts.TextViewTest
Test: bit CtsWidgetTestCases:android.widget.cts.EditTextTest

Bug: 30870806
Change-Id: I54f014b06af328c3e9a9c4ddb5a3348a26e290c2
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 2dc3f60..2c84ba0 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1451,6 +1451,16 @@
     }
 
     /**
+     * Return the vertical position of the bottom of the specified line without the line spacing
+     * added.
+     *
+     * @hide
+     */
+    public final int getLineBottomWithoutSpacing(int line) {
+        return getLineTop(line + 1) - getLineExtra(line);
+    }
+
+    /**
      * Return the vertical position of the baseline of the specified line.
      */
     public final int getLineBaseline(int line) {
@@ -1593,13 +1603,12 @@
      * but can be multiple discontinuous lines in text with multiple
      * directionalities.
      */
-    public void getCursorPath(int point, Path dest,
-                              CharSequence editingBuffer) {
+    public void getCursorPath(final int point, final Path dest, final CharSequence editingBuffer) {
         dest.reset();
 
         int line = getLineForOffset(point);
         int top = getLineTop(line);
-        int bottom = getLineTop(line+1);
+        int bottom = getLineBottomWithoutSpacing(line);
 
         boolean clamped = shouldClampCursor(line);
         float h1 = getPrimaryHorizontal(point, clamped) - 0.5f;
@@ -1719,11 +1728,11 @@
             start = temp;
         }
 
-        int startline = getLineForOffset(start);
-        int endline = getLineForOffset(end);
+        final int startline = getLineForOffset(start);
+        final int endline = getLineForOffset(end);
 
         int top = getLineTop(startline);
-        int bottom = getLineBottom(endline);
+        int bottom = getLineBottomWithoutSpacing(endline);
 
         if (startline == endline) {
             addSelection(startline, start, end, top, bottom, dest);
@@ -1747,10 +1756,9 @@
             }
 
             top = getLineTop(endline);
-            bottom = getLineBottom(endline);
+            bottom = getLineBottomWithoutSpacing(endline);
 
-            addSelection(endline, getLineStart(endline), end,
-                         top, bottom, dest);
+            addSelection(endline, getLineStart(endline), end, top, bottom, dest);
 
             if (getParagraphDirection(endline) == DIR_RIGHT_TO_LEFT)
                 dest.addRect(width, top, getLineRight(endline), bottom, Path.Direction.CW);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 0d02444..f008570 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1917,7 +1917,7 @@
         final int offset = mTextView.getSelectionStart();
         final int line = layout.getLineForOffset(offset);
         final int top = layout.getLineTop(line);
-        final int bottom = layout.getLineTop(line + 1);
+        final int bottom = layout.getLineBottomWithoutSpacing(line);
 
         mCursorCount = layout.isLevelBoundary(offset) ? 2 : 1;
 
@@ -2985,7 +2985,8 @@
 
         @Override
         protected int getVerticalLocalPosition(int line) {
-            return mTextView.getLayout().getLineBottom(line);
+            final Layout layout = mTextView.getLayout();
+            return layout.getLineBottomWithoutSpacing(line);
         }
 
         @Override
@@ -3642,7 +3643,8 @@
 
         @Override
         protected int getVerticalLocalPosition(int line) {
-            return mTextView.getLayout().getLineBottom(line) - mContainerMarginTop;
+            final Layout layout = mTextView.getLayout();
+            return layout.getLineBottomWithoutSpacing(line) - mContainerMarginTop;
         }
 
         @Override
@@ -4032,7 +4034,7 @@
                         primaryHorizontal,
                         layout.getLineTop(line),
                         primaryHorizontal,
-                        layout.getLineTop(line + 1) + mHandleHeight);
+                        layout.getLineBottom(line) - layout.getLineBottom(line) + mHandleHeight);
             }
             // Take TextView's padding and scroll into account.
             int textHorizontalOffset = mTextView.viewportToContentHorizontalOffset();
@@ -4127,7 +4129,7 @@
                         + viewportToContentVerticalOffset;
                 final float insertionMarkerBaseline = layout.getLineBaseline(line)
                         + viewportToContentVerticalOffset;
-                final float insertionMarkerBottom = layout.getLineBottom(line)
+                final float insertionMarkerBottom = layout.getLineBottomWithoutSpacing(line)
                         + viewportToContentVerticalOffset;
                 final boolean isTopVisible = mTextView
                         .isPositionVisible(insertionMarkerX, insertionMarkerTop);
@@ -4395,7 +4397,7 @@
 
                 mPositionX = getCursorHorizontalPosition(layout, offset) - mHotspotX
                         - getHorizontalOffset() + getCursorOffset();
-                mPositionY = layout.getLineBottom(line);
+                mPositionY = layout.getLineBottomWithoutSpacing(line);
 
                 // Take TextView's padding and scroll into account.
                 mPositionX += mTextView.viewportToContentHorizontalOffset();