Fix EditText line spacing
DynamicLayout did not include the line spacing for the newly added
lines. This CL updates StaticLayout with a parameter to force addition
of line spacing to the last line, and updates DynamicLayout to use this
parameter. With this change the last line will have the line spacing
applied, and it will provide a consistent UX.
Test: Manual/Visual test
Test: bit -t FrameworksCoreTests:android.text.StaticLayoutTest
Test: bit -t FrameworksCoreTests:android.text.StaticLayoutTextMeasuringTest
Test: bit -t FrameworksCoreTests:android.text.StaticLayoutLineBreakingTest
Test: bit -t FrameworksCoreTests:android.text.DynamicLayoutTest
Test: bit -t FrameworksCoreTests:android.text.DynamicLayoutBlocksTest
Test: bit -t CtsTextTestCases:android.text.cts.StaticLayoutTest
Test: bit -t CtsTextTestCases:android.text.cts.DynamicLayoutTest
Bug: 25194907
Change-Id: I52497fbd108538729758e842072f3ce87c6bbfdd
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index dc5553e..4eb74a7 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -334,6 +334,17 @@
return this;
}
+ /**
+ * Sets whether the line spacing should be applied for the last line. Default value is
+ * {@code false}.
+ *
+ * @hide
+ */
+ /* package */ Builder setAddLastLineLineSpacing(boolean value) {
+ mAddLastLineLineSpacing = value;
+ return this;
+ }
+
private long[] getHyphenators(LocaleList locales) {
final int length = locales.size();
final long[] result = new long[length];
@@ -430,6 +441,7 @@
int[] mLeftIndents;
int[] mRightIndents;
int mJustificationMode;
+ boolean mAddLastLineLineSpacing;
Paint.FontMetricsInt mFontMetricsInt = new Paint.FontMetricsInt();
@@ -599,6 +611,7 @@
float spacingadd = b.mSpacingAdd;
float ellipsizedWidth = b.mEllipsizedWidth;
TextUtils.TruncateAt ellipsize = b.mEllipsize;
+ final boolean addLastLineSpacing = b.mAddLastLineLineSpacing;
LineBreaks lineBreaks = new LineBreaks(); // TODO: move to builder to avoid allocation costs
// store span end locations
int[] spanEndCache = new int[4];
@@ -849,8 +862,8 @@
fmAscent, fmDescent, fmTop, fmBottom,
v, spacingmult, spacingadd, chooseHt, chooseHtv, fm, flags[breakIndex],
needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad,
- chs, widths, paraStart, ellipsize, ellipsizedWidth,
- lineWidths[breakIndex], paint, moreChars);
+ addLastLineSpacing, chs, widths, paraStart, ellipsize,
+ ellipsizedWidth, lineWidths[breakIndex], paint, moreChars);
if (endPos < spanEnd) {
// preserve metrics for current span
@@ -890,7 +903,7 @@
spacingmult, spacingadd, null,
null, fm, 0,
needMultiply, measured.mLevels, measured.mDir, measured.mEasy, bufEnd,
- includepad, trackpad, null,
+ includepad, trackpad, addLastLineSpacing, null,
null, bufStart, ellipsize,
ellipsizedWidth, 0, paint, false);
}
@@ -903,7 +916,7 @@
Paint.FontMetricsInt fm, int flags,
boolean needMultiply, byte[] chdirs, int dir,
boolean easy, int bufEnd, boolean includePad,
- boolean trackPad, char[] chs,
+ boolean trackPad, boolean addLastLineLineSpacing, char[] chs,
float[] widths, int widthStart, TextUtils.TruncateAt ellipsize,
float ellipsisWidth, float textWidth,
TextPaint paint, boolean moreChars) {
@@ -992,7 +1005,7 @@
}
}
- if (needMultiply && !lastLine) {
+ if (needMultiply && (addLastLineLineSpacing || !lastLine)) {
double ex = (below - above) * (spacingmult - 1) + spacingadd;
if (ex >= 0) {
extra = (int)(ex + EXTRA_ROUNDING);