Fix off-by-one error in computeEllipsis

In the Truncate.MIDDLE case, when the line is less than half the layout
width, the computeEllipsis logic could go past the left edge of the
string. This patch fixes the off-by-one and avoids the resulting index
out of bounds crash, and also changes the behavior so that when
ellipsizing at the middle, the string to the end of the paragraph is
taken into account.

Bug: 18508627
Change-Id: I24be09c23a5aa158791a9717419307613b8a22e8
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 02297e3..74b7b69 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -416,7 +416,11 @@
                             currentTextWidth = widths[here - paraStart];
                         }
 
-                        v = out(source, here, endPos,
+                        int ellipseEnd = endPos;
+                        if (mMaximumVisibleLineCount == 1 && ellipsize == TextUtils.TruncateAt.MIDDLE) {
+                            ellipseEnd = paraEnd;
+                        }
+                        v = out(source, here, ellipseEnd,
                                 above, below, top, bottom,
                                 v, spacingmult, spacingadd, chooseHt,chooseHtv, fm, hasTabOrEmoji,
                                 needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad,
@@ -704,7 +708,7 @@
                 int left = 0, right = len;
 
                 float ravail = (avail - ellipsisWidth) / 2;
-                for (right = len; right >= 0; right--) {
+                for (right = len; right > 0; right--) {
                     float w = widths[right - 1 + lineStart - widthStart];
 
                     if (w + rsum > ravail) {