fix(non linear font scaling): recalculate proportional line height if they setTextSize() after setting line height

This will only recalculate if both were set in SP, since that's the only
time the proportion calculation happens anyway.

Bug: 273326061
Test: atest cts/tests/tests/widget/src/android/widget/cts/TextViewFontScalingTest.kt

Change-Id: I41ad12cdef6f1b93b60deca039c9ab72bb59e39f
This commit is contained in:
Tyler Freeman
2023-04-13 19:27:34 +00:00
parent a4d59758d4
commit fa043bb5d9
2 changed files with 48 additions and 4 deletions

View File

@@ -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

View File

@@ -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.
*
* <p>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));
}
/**