Loading api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -579,6 +579,7 @@ package android { field public static final int fadingEdge = 16842975; // 0x10100df field public static final int fadingEdgeLength = 16842976; // 0x10100e0 field public static final int fadingMode = 16843745; // 0x10103e1 field public static final int fallbackLineSpacing = 16844155; // 0x101057b field public static final int fastScrollAlwaysVisible = 16843573; // 0x1010335 field public static final int fastScrollEnabled = 16843302; // 0x1010226 field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a Loading Loading @@ -52310,6 +52311,7 @@ package android.widget { method public boolean isAllCaps(); method public boolean isCursorVisible(); method public boolean isElegantTextHeight(); method public boolean isFallbackLineSpacing(); method public boolean isInputMethodTarget(); method public boolean isSuggestionsEnabled(); method public boolean isTextSelectable(); Loading Loading @@ -52353,6 +52355,7 @@ package android.widget { method public void setError(java.lang.CharSequence); method public void setError(java.lang.CharSequence, android.graphics.drawable.Drawable); method public void setExtractedText(android.view.inputmethod.ExtractedText); method public void setFallbackLineSpacing(boolean); method public void setFilters(android.text.InputFilter[]); method public void setFontFeatureSettings(java.lang.String); method public boolean setFontVariationSettings(java.lang.String); core/java/android/widget/TextView.java +55 −2 Original line number Diff line number Diff line Loading @@ -296,6 +296,7 @@ import java.util.Locale; * @attr ref android.R.styleable#TextView_imeActionId * @attr ref android.R.styleable#TextView_editorExtras * @attr ref android.R.styleable#TextView_elegantTextHeight * @attr ref android.R.styleable#TextView_fallbackLineSpacing * @attr ref android.R.styleable#TextView_letterSpacing * @attr ref android.R.styleable#TextView_fontFeatureSettings * @attr ref android.R.styleable#TextView_breakStrategy Loading Loading @@ -655,7 +656,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // True if internationalized input should be used for numbers and date and time. private final boolean mUseInternationalizedInput; // True if fallback fonts that end up getting used should be allowed to affect line spacing. /* package */ final boolean mUseFallbackLineSpacing; /* package */ boolean mUseFallbackLineSpacing; @ViewDebug.ExportedProperty(category = "text") private int mGravity = Gravity.TOP | Gravity.START; Loading Loading @@ -3255,6 +3256,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener float mShadowDx = 0, mShadowDy = 0, mShadowRadius = 0; boolean mHasElegant = false; boolean mElegant = false; boolean mHasFallbackLineSpacing = false; boolean mFallbackLineSpacing = false; boolean mHasLetterSpacing = false; float mLetterSpacing = 0; String mFontFeatureSettings = null; Loading @@ -3279,6 +3282,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener + " mShadowRadius:" + mShadowRadius + "\n" + " mHasElegant:" + mHasElegant + "\n" + " mElegant:" + mElegant + "\n" + " mHasFallbackLineSpacing:" + mHasFallbackLineSpacing + "\n" + " mFallbackLineSpacing:" + mFallbackLineSpacing + "\n" + " mHasLetterSpacing:" + mHasLetterSpacing + "\n" + " mLetterSpacing:" + mLetterSpacing + "\n" + " mFontFeatureSettings:" + mFontFeatureSettings + "\n" Loading Loading @@ -3317,6 +3322,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener com.android.internal.R.styleable.TextAppearance_shadowRadius); sAppearanceValues.put(com.android.internal.R.styleable.TextView_elegantTextHeight, com.android.internal.R.styleable.TextAppearance_elegantTextHeight); sAppearanceValues.put(com.android.internal.R.styleable.TextView_fallbackLineSpacing, com.android.internal.R.styleable.TextAppearance_fallbackLineSpacing); sAppearanceValues.put(com.android.internal.R.styleable.TextView_letterSpacing, com.android.internal.R.styleable.TextAppearance_letterSpacing); sAppearanceValues.put(com.android.internal.R.styleable.TextView_fontFeatureSettings, Loading Loading @@ -3407,6 +3414,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener attributes.mHasElegant = true; attributes.mElegant = appearance.getBoolean(attr, attributes.mElegant); break; case com.android.internal.R.styleable.TextAppearance_fallbackLineSpacing: attributes.mHasFallbackLineSpacing = true; attributes.mFallbackLineSpacing = appearance.getBoolean(attr, attributes.mFallbackLineSpacing); break; case com.android.internal.R.styleable.TextAppearance_letterSpacing: attributes.mHasLetterSpacing = true; attributes.mLetterSpacing = Loading Loading @@ -3460,6 +3472,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener setElegantTextHeight(attributes.mElegant); } if (attributes.mHasFallbackLineSpacing) { setFallbackLineSpacing(attributes.mFallbackLineSpacing); } if (attributes.mHasLetterSpacing) { setLetterSpacing(attributes.mLetterSpacing); } Loading Loading @@ -3741,7 +3757,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @param elegant set the paint's elegant metrics flag. * * @see Paint#isElegantTextHeight(boolean) * @see Paint#isElegantTextHeight() * * @attr ref android.R.styleable#TextView_elegantTextHeight */ Loading @@ -3756,6 +3772,43 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } /** * Set whether to respect the ascent and descent of the fallback fonts that are used in * displaying the text (which is needed to avoid text from consecutive lines running into * each other). If set, fallback fonts that end up getting used can increase the ascent * and descent of the lines that they are used on. * <p/> * It is required to be true if text could be in languages like Burmese or Tibetan where text * is typically much taller or deeper than Latin text. * * @param enabled whether to expand linespacing based on fallback fonts, {@code true} by default * * @see StaticLayout.Builder#setUseLineSpacingFromFallbacks(boolean) * * @attr ref android.R.styleable#TextView_fallbackLineSpacing */ public void setFallbackLineSpacing(boolean enabled) { if (mUseFallbackLineSpacing != enabled) { mUseFallbackLineSpacing = enabled; if (mLayout != null) { nullLayouts(); requestLayout(); invalidate(); } } } /** * @return whether fallback line spacing is enabled, {@code true} by default * * @see #setFallbackLineSpacing(boolean) * * @attr ref android.R.styleable#TextView_fallbackLineSpacing */ public boolean isFallbackLineSpacing() { return mUseFallbackLineSpacing; } /** * Get the value of the TextView's elegant height metrics flag. This setting selects font * variants that have not been compacted to fit Latin-based vertical Loading core/res/res/values/attrs.xml +8 −0 Original line number Diff line number Diff line Loading @@ -4470,6 +4470,10 @@ <attr name="shadowRadius" format="float" /> <!-- Elegant text height, especially for less compacted complex script text. --> <attr name="elegantTextHeight" format="boolean" /> <!-- Whether to respect the ascent and descent of the fallback fonts that are used in displaying the text. When true, fallback fonts that end up getting used can increase the ascent and descent of the lines that they are used on. --> <attr name="fallbackLineSpacing" format="boolean"/> <!-- Text letter-spacing. --> <attr name="letterSpacing" format="float" /> <!-- Font feature settings. --> Loading Loading @@ -4803,6 +4807,10 @@ <attr name="textAllCaps" /> <!-- Elegant text height, especially for less compacted complex script text. --> <attr name="elegantTextHeight" /> <!-- Whether to respect the ascent and descent of the fallback fonts that are used in displaying the text. When true, fallback fonts that end up getting used can increase the ascent and descent of the lines that they are used on. --> <attr name="fallbackLineSpacing" format="boolean"/> <!-- Text letter-spacing. --> <attr name="letterSpacing" /> <!-- Font feature settings. --> Loading core/res/res/values/public.xml +1 −0 Original line number Diff line number Diff line Loading @@ -2860,6 +2860,7 @@ <public name="isVrOnly"/> <public name="widgetFeatures" /> <public name="appComponentFactory" /> <public name="fallbackLineSpacing" /> </public-group> <public-group type="style" first-id="0x010302e0"> Loading core/tests/coretests/src/android/widget/TextViewFallbackLineSpacingTest.java 0 → 100644 +138 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.widget; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.app.Activity; import android.support.test.filters.MediumTest; import android.support.test.rule.ActivityTestRule; import android.text.DynamicLayout; import android.text.FontFallbackSetup; import android.text.Layout; import android.text.StaticLayout; import android.util.TypedValue; import android.view.View; import android.widget.TextView.BufferType; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.Arrays; import java.util.Collection; /** * Parametrized test for TextView#setFallbackLineSpacing. */ @MediumTest @RunWith(Parameterized.class) public class TextViewFallbackLineSpacingTest { @Parameterized.Parameters(name = "{0}") public static Collection layouts() { return Arrays.asList(new Object[][] { // name, enabled, BufferType { "Enabled - StaticLayout", true, BufferType.NORMAL}, { "Disabled - StaticLayout", false, BufferType.NORMAL}, { "Enabled - DynamicLayout", true, BufferType.EDITABLE}, { "Disabled - DynamicLayout", false, BufferType.EDITABLE}, }); } @Rule public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>( TextViewActivity.class); private final boolean mEnabled; private final BufferType mBufferType; public TextViewFallbackLineSpacingTest(String testName, boolean enabled, BufferType bufferType) { mEnabled = enabled; mBufferType = bufferType; } @Test public void testFallbackLineSpacing() { // All glyphs in the fonts are 1em wide. final String[] testFontFiles = { // ascent == 1em, descent == 2em, only supports 'a' and space "ascent1em-descent2em.ttf", // ascent == 3em, descent == 4em, only supports 'b' "ascent3em-descent4em.ttf" }; final String xml = "<?xml version='1.0' encoding='UTF-8'?>" + "<familyset>" + " <family name='sans-serif'>" + " <font weight='400' style='normal'>ascent1em-descent2em.ttf</font>" + " </family>" + " <family>" + " <font weight='400' style='normal'>ascent3em-descent4em.ttf</font>" + " </family>" + "</familyset>"; try (FontFallbackSetup setup = new FontFallbackSetup("DynamicLayout", testFontFiles, xml)) { final Activity activity = mActivityRule.getActivity(); final TextView textView = new TextView(activity); textView.setTypeface(setup.getTypefaceFor("sans-serif")); textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 100); // This should result in three lines. textView.setText("aaaaa aabaa aaaaa", mBufferType); textView.setPadding(0, 0, 0, 0); textView.setIncludeFontPadding(false); textView.setFallbackLineSpacing(mEnabled); final int em = (int) Math.ceil(textView.getPaint().measureText("a")); final int width = 5 * em; final int height = 30 * em; // tall enough to not affect our other measurements textView.measure( View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)); textView.layout(0, 0, width, height); final Layout layout = textView.getLayout(); assertNotNull(layout); if (mBufferType == BufferType.NORMAL) { assertTrue(layout instanceof StaticLayout); } else { assertTrue(layout instanceof DynamicLayout); } assertEquals(3, layout.getLineCount()); assertEquals(-em, layout.getLineAscent(0)); assertEquals(2 * em, layout.getLineDescent(0)); if (mEnabled) { // The second line has a 'b', so it needs more ascent and descent. assertEquals(-3 * em, layout.getLineAscent(1)); assertEquals(4 * em, layout.getLineDescent(1)); } else { // old behavior assertEquals(-em, layout.getLineAscent(1)); assertEquals(2 * em, layout.getLineDescent(1)); } assertEquals(-em, layout.getLineAscent(2)); assertEquals(2 * em, layout.getLineDescent(2)); } } } Loading
api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -579,6 +579,7 @@ package android { field public static final int fadingEdge = 16842975; // 0x10100df field public static final int fadingEdgeLength = 16842976; // 0x10100e0 field public static final int fadingMode = 16843745; // 0x10103e1 field public static final int fallbackLineSpacing = 16844155; // 0x101057b field public static final int fastScrollAlwaysVisible = 16843573; // 0x1010335 field public static final int fastScrollEnabled = 16843302; // 0x1010226 field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a Loading Loading @@ -52310,6 +52311,7 @@ package android.widget { method public boolean isAllCaps(); method public boolean isCursorVisible(); method public boolean isElegantTextHeight(); method public boolean isFallbackLineSpacing(); method public boolean isInputMethodTarget(); method public boolean isSuggestionsEnabled(); method public boolean isTextSelectable(); Loading Loading @@ -52353,6 +52355,7 @@ package android.widget { method public void setError(java.lang.CharSequence); method public void setError(java.lang.CharSequence, android.graphics.drawable.Drawable); method public void setExtractedText(android.view.inputmethod.ExtractedText); method public void setFallbackLineSpacing(boolean); method public void setFilters(android.text.InputFilter[]); method public void setFontFeatureSettings(java.lang.String); method public boolean setFontVariationSettings(java.lang.String);
core/java/android/widget/TextView.java +55 −2 Original line number Diff line number Diff line Loading @@ -296,6 +296,7 @@ import java.util.Locale; * @attr ref android.R.styleable#TextView_imeActionId * @attr ref android.R.styleable#TextView_editorExtras * @attr ref android.R.styleable#TextView_elegantTextHeight * @attr ref android.R.styleable#TextView_fallbackLineSpacing * @attr ref android.R.styleable#TextView_letterSpacing * @attr ref android.R.styleable#TextView_fontFeatureSettings * @attr ref android.R.styleable#TextView_breakStrategy Loading Loading @@ -655,7 +656,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // True if internationalized input should be used for numbers and date and time. private final boolean mUseInternationalizedInput; // True if fallback fonts that end up getting used should be allowed to affect line spacing. /* package */ final boolean mUseFallbackLineSpacing; /* package */ boolean mUseFallbackLineSpacing; @ViewDebug.ExportedProperty(category = "text") private int mGravity = Gravity.TOP | Gravity.START; Loading Loading @@ -3255,6 +3256,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener float mShadowDx = 0, mShadowDy = 0, mShadowRadius = 0; boolean mHasElegant = false; boolean mElegant = false; boolean mHasFallbackLineSpacing = false; boolean mFallbackLineSpacing = false; boolean mHasLetterSpacing = false; float mLetterSpacing = 0; String mFontFeatureSettings = null; Loading @@ -3279,6 +3282,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener + " mShadowRadius:" + mShadowRadius + "\n" + " mHasElegant:" + mHasElegant + "\n" + " mElegant:" + mElegant + "\n" + " mHasFallbackLineSpacing:" + mHasFallbackLineSpacing + "\n" + " mFallbackLineSpacing:" + mFallbackLineSpacing + "\n" + " mHasLetterSpacing:" + mHasLetterSpacing + "\n" + " mLetterSpacing:" + mLetterSpacing + "\n" + " mFontFeatureSettings:" + mFontFeatureSettings + "\n" Loading Loading @@ -3317,6 +3322,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener com.android.internal.R.styleable.TextAppearance_shadowRadius); sAppearanceValues.put(com.android.internal.R.styleable.TextView_elegantTextHeight, com.android.internal.R.styleable.TextAppearance_elegantTextHeight); sAppearanceValues.put(com.android.internal.R.styleable.TextView_fallbackLineSpacing, com.android.internal.R.styleable.TextAppearance_fallbackLineSpacing); sAppearanceValues.put(com.android.internal.R.styleable.TextView_letterSpacing, com.android.internal.R.styleable.TextAppearance_letterSpacing); sAppearanceValues.put(com.android.internal.R.styleable.TextView_fontFeatureSettings, Loading Loading @@ -3407,6 +3414,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener attributes.mHasElegant = true; attributes.mElegant = appearance.getBoolean(attr, attributes.mElegant); break; case com.android.internal.R.styleable.TextAppearance_fallbackLineSpacing: attributes.mHasFallbackLineSpacing = true; attributes.mFallbackLineSpacing = appearance.getBoolean(attr, attributes.mFallbackLineSpacing); break; case com.android.internal.R.styleable.TextAppearance_letterSpacing: attributes.mHasLetterSpacing = true; attributes.mLetterSpacing = Loading Loading @@ -3460,6 +3472,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener setElegantTextHeight(attributes.mElegant); } if (attributes.mHasFallbackLineSpacing) { setFallbackLineSpacing(attributes.mFallbackLineSpacing); } if (attributes.mHasLetterSpacing) { setLetterSpacing(attributes.mLetterSpacing); } Loading Loading @@ -3741,7 +3757,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @param elegant set the paint's elegant metrics flag. * * @see Paint#isElegantTextHeight(boolean) * @see Paint#isElegantTextHeight() * * @attr ref android.R.styleable#TextView_elegantTextHeight */ Loading @@ -3756,6 +3772,43 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } /** * Set whether to respect the ascent and descent of the fallback fonts that are used in * displaying the text (which is needed to avoid text from consecutive lines running into * each other). If set, fallback fonts that end up getting used can increase the ascent * and descent of the lines that they are used on. * <p/> * It is required to be true if text could be in languages like Burmese or Tibetan where text * is typically much taller or deeper than Latin text. * * @param enabled whether to expand linespacing based on fallback fonts, {@code true} by default * * @see StaticLayout.Builder#setUseLineSpacingFromFallbacks(boolean) * * @attr ref android.R.styleable#TextView_fallbackLineSpacing */ public void setFallbackLineSpacing(boolean enabled) { if (mUseFallbackLineSpacing != enabled) { mUseFallbackLineSpacing = enabled; if (mLayout != null) { nullLayouts(); requestLayout(); invalidate(); } } } /** * @return whether fallback line spacing is enabled, {@code true} by default * * @see #setFallbackLineSpacing(boolean) * * @attr ref android.R.styleable#TextView_fallbackLineSpacing */ public boolean isFallbackLineSpacing() { return mUseFallbackLineSpacing; } /** * Get the value of the TextView's elegant height metrics flag. This setting selects font * variants that have not been compacted to fit Latin-based vertical Loading
core/res/res/values/attrs.xml +8 −0 Original line number Diff line number Diff line Loading @@ -4470,6 +4470,10 @@ <attr name="shadowRadius" format="float" /> <!-- Elegant text height, especially for less compacted complex script text. --> <attr name="elegantTextHeight" format="boolean" /> <!-- Whether to respect the ascent and descent of the fallback fonts that are used in displaying the text. When true, fallback fonts that end up getting used can increase the ascent and descent of the lines that they are used on. --> <attr name="fallbackLineSpacing" format="boolean"/> <!-- Text letter-spacing. --> <attr name="letterSpacing" format="float" /> <!-- Font feature settings. --> Loading Loading @@ -4803,6 +4807,10 @@ <attr name="textAllCaps" /> <!-- Elegant text height, especially for less compacted complex script text. --> <attr name="elegantTextHeight" /> <!-- Whether to respect the ascent and descent of the fallback fonts that are used in displaying the text. When true, fallback fonts that end up getting used can increase the ascent and descent of the lines that they are used on. --> <attr name="fallbackLineSpacing" format="boolean"/> <!-- Text letter-spacing. --> <attr name="letterSpacing" /> <!-- Font feature settings. --> Loading
core/res/res/values/public.xml +1 −0 Original line number Diff line number Diff line Loading @@ -2860,6 +2860,7 @@ <public name="isVrOnly"/> <public name="widgetFeatures" /> <public name="appComponentFactory" /> <public name="fallbackLineSpacing" /> </public-group> <public-group type="style" first-id="0x010302e0"> Loading
core/tests/coretests/src/android/widget/TextViewFallbackLineSpacingTest.java 0 → 100644 +138 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.widget; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.app.Activity; import android.support.test.filters.MediumTest; import android.support.test.rule.ActivityTestRule; import android.text.DynamicLayout; import android.text.FontFallbackSetup; import android.text.Layout; import android.text.StaticLayout; import android.util.TypedValue; import android.view.View; import android.widget.TextView.BufferType; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.Arrays; import java.util.Collection; /** * Parametrized test for TextView#setFallbackLineSpacing. */ @MediumTest @RunWith(Parameterized.class) public class TextViewFallbackLineSpacingTest { @Parameterized.Parameters(name = "{0}") public static Collection layouts() { return Arrays.asList(new Object[][] { // name, enabled, BufferType { "Enabled - StaticLayout", true, BufferType.NORMAL}, { "Disabled - StaticLayout", false, BufferType.NORMAL}, { "Enabled - DynamicLayout", true, BufferType.EDITABLE}, { "Disabled - DynamicLayout", false, BufferType.EDITABLE}, }); } @Rule public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>( TextViewActivity.class); private final boolean mEnabled; private final BufferType mBufferType; public TextViewFallbackLineSpacingTest(String testName, boolean enabled, BufferType bufferType) { mEnabled = enabled; mBufferType = bufferType; } @Test public void testFallbackLineSpacing() { // All glyphs in the fonts are 1em wide. final String[] testFontFiles = { // ascent == 1em, descent == 2em, only supports 'a' and space "ascent1em-descent2em.ttf", // ascent == 3em, descent == 4em, only supports 'b' "ascent3em-descent4em.ttf" }; final String xml = "<?xml version='1.0' encoding='UTF-8'?>" + "<familyset>" + " <family name='sans-serif'>" + " <font weight='400' style='normal'>ascent1em-descent2em.ttf</font>" + " </family>" + " <family>" + " <font weight='400' style='normal'>ascent3em-descent4em.ttf</font>" + " </family>" + "</familyset>"; try (FontFallbackSetup setup = new FontFallbackSetup("DynamicLayout", testFontFiles, xml)) { final Activity activity = mActivityRule.getActivity(); final TextView textView = new TextView(activity); textView.setTypeface(setup.getTypefaceFor("sans-serif")); textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 100); // This should result in three lines. textView.setText("aaaaa aabaa aaaaa", mBufferType); textView.setPadding(0, 0, 0, 0); textView.setIncludeFontPadding(false); textView.setFallbackLineSpacing(mEnabled); final int em = (int) Math.ceil(textView.getPaint().measureText("a")); final int width = 5 * em; final int height = 30 * em; // tall enough to not affect our other measurements textView.measure( View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)); textView.layout(0, 0, width, height); final Layout layout = textView.getLayout(); assertNotNull(layout); if (mBufferType == BufferType.NORMAL) { assertTrue(layout instanceof StaticLayout); } else { assertTrue(layout instanceof DynamicLayout); } assertEquals(3, layout.getLineCount()); assertEquals(-em, layout.getLineAscent(0)); assertEquals(2 * em, layout.getLineDescent(0)); if (mEnabled) { // The second line has a 'b', so it needs more ascent and descent. assertEquals(-3 * em, layout.getLineAscent(1)); assertEquals(4 * em, layout.getLineDescent(1)); } else { // old behavior assertEquals(-em, layout.getLineAscent(1)); assertEquals(2 * em, layout.getLineDescent(1)); } assertEquals(-em, layout.getLineAscent(2)); assertEquals(2 * em, layout.getLineDescent(2)); } } }