diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java index b93e3386b7cca..330a9fce1b83b 100644 --- a/core/java/android/util/TypedValue.java +++ b/core/java/android/util/TypedValue.java @@ -385,10 +385,22 @@ public class TypedValue { * * @return The complex unit type. */ - public int getComplexUnit() - { - return COMPLEX_UNIT_MASK & (data>>TypedValue.COMPLEX_UNIT_SHIFT); - } + public int getComplexUnit() { + return getUnitFromComplexDimension(data); + } + + /** + * Return the complex unit type for the given complex dimension. For example, a dimen type + * with value 12sp will return {@link #COMPLEX_UNIT_SP}. Use with values created with {@link + * #createComplexDimension(int, int)} etc. + * + * @return The complex unit type. + * + * @hide + */ + public static int getUnitFromComplexDimension(int complexDimension) { + return COMPLEX_UNIT_MASK & (complexDimension >> TypedValue.COMPLEX_UNIT_SHIFT); + } /** * Converts an unpacked complex data value holding a dimension to its final floating point pixel diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 65a937bdc4bc7..3fbb50581b25e 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -868,6 +868,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @UnsupportedAppUsage private float mSpacingAdd = 0.0f; + /** + * Remembers what line height was set to originally, before we broke it down into raw pixels. + * + *
This is stored as a complex dimension with both value and unit packed into one field! + * {@see TypedValue} + */ + private int mLineHeightComplexDimen; + private int mBreakStrategy; private int mHyphenationFrequency; private int mJustificationMode; @@ -4641,6 +4649,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (size != mTextPaint.getTextSize()) { mTextPaint.setTextSize(size); + maybeRecalculateLineHeight(); if (shouldRequestLayout && mLayout != null) { // Do not auto-size right after setting the text size. mNeedsAutoSizeText = false; @@ -6226,6 +6235,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (lineHeight != fontHeight) { // Set lineSpacingExtra by the difference of lineSpacing with lineHeight setLineSpacing(lineHeight - fontHeight, 1f); + + mLineHeightComplexDimen = + TypedValue.createComplexDimension(lineHeight, TypedValue.COMPLEX_UNIT_PX); } } @@ -6258,6 +6270,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener || mTextSizeUnit != TypedValue.COMPLEX_UNIT_SP ) { setLineHeightPx(TypedValue.applyDimension(unit, lineHeight, metrics)); + + // Do this last so it overwrites what setLineHeightPx() sets it to. + mLineHeightComplexDimen = TypedValue.createComplexDimension(lineHeight, unit); return; } @@ -6276,6 +6291,23 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener ); var ratio = lineHeight / textSizeSp; setLineHeightPx(textSizePx * ratio); + + // Do this last so it overwrites what setLineHeightPx() sets it to. + mLineHeightComplexDimen = TypedValue.createComplexDimension(lineHeight, unit); + } + + private void maybeRecalculateLineHeight() { + if (mLineHeightComplexDimen == 0) { + return; + } + int unit = TypedValue.getUnitFromComplexDimension(mLineHeightComplexDimen); + if (unit != TypedValue.COMPLEX_UNIT_SP) { + // The lineHeight was never supplied in SP, so we didn't do any fancy recalculations + // in setLineHeight(). We don't need to recalculate. + return; + } + + setLineHeight(unit, TypedValue.complexToFloat(mLineHeightComplexDimen)); } /**