Skip to content

Commit

Permalink
fix: Text cut off issues when adjusting text size and font weight in …
Browse files Browse the repository at this point in the history
…system settings
  • Loading branch information
lizhiqiang05 committed Sep 22, 2023
1 parent ea85b31 commit 1af2486
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ public void setAdjustFontSizeToFit(ReactTextView view, boolean adjustsFontSizeTo
view.setAdjustFontSizeToFit(adjustsFontSizeToFit);
}

@ReactProp(name = ViewProps.ALLOW_FONT_SCALING, defaultBoolean = true)
public void setAllowFontScaling(ReactTextView view, boolean allowFontScaling) {
view.setAllowFontScaling(allowFontScaling);
}

@ReactProp(name = ViewProps.MAX_FONT_SIZE_MULTIPLIER, defaultFloat = Float.NaN)
public void setMaxFontSizeMultiplier(ReactTextView view, float maxFontSizeMultiplier) {
view.setMaxFontSizeMultiplier(maxFontSizeMultiplier);
}

@ReactProp(name = ViewProps.FONT_SIZE)
public void setFontSize(ReactTextView view, float fontSize) {
view.setFontSize(fontSize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,19 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
private int mNumberOfLines;
private TextUtils.TruncateAt mEllipsizeLocation;
private boolean mAdjustsFontSizeToFit;
private float mFontSize = Float.NaN;
private float mLetterSpacing = Float.NaN;
private int mLinkifyMaskType;
private boolean mNotifyOnInlineViewLayout;
private boolean mTextIsSelectable;

private ReactViewBackgroundManager mReactBackgroundManager;
private Spannable mSpanned;

/**
* Used to collect some text size affecting attributes to fix some text cut-off issues when users
* adjust text size and font weight to the max value in system font settings.
*/
private TextAttributes mTextAttributes;

public ReactTextView(Context context) {
super(context);

Expand Down Expand Up @@ -98,6 +102,7 @@ private void initView() {
mEllipsizeLocation = TextUtils.TruncateAt.END;

mSpanned = null;
mTextAttributes = new TextAttributes();
}

/* package */ void recycleView() {
Expand Down Expand Up @@ -587,29 +592,6 @@ public void setAdjustFontSizeToFit(boolean adjustsFontSizeToFit) {
mAdjustsFontSizeToFit = adjustsFontSizeToFit;
}

public void setFontSize(float fontSize) {
mFontSize =
mAdjustsFontSizeToFit
? (float) Math.ceil(PixelUtil.toPixelFromSP(fontSize))
: (float) Math.ceil(PixelUtil.toPixelFromDIP(fontSize));

applyTextAttributes();
}

public void setLetterSpacing(float letterSpacing) {
if (Float.isNaN(letterSpacing)) {
return;
}

float letterSpacingPixels = PixelUtil.toPixelFromDIP(letterSpacing);

// `letterSpacingPixels` and `getEffectiveFontSize` are both in pixels,
// yielding an accurate em value.
mLetterSpacing = letterSpacingPixels / mFontSize;

applyTextAttributes();
}

public void setEllipsizeLocation(TextUtils.TruncateAt ellipsizeLocation) {
mEllipsizeLocation = ellipsizeLocation;
}
Expand All @@ -625,6 +607,8 @@ public void updateView() {
? null
: mEllipsizeLocation;
setEllipsize(ellipsizeLocation);

applyTextAttributes();
}

@Override
Expand Down Expand Up @@ -680,16 +664,37 @@ protected boolean dispatchHoverEvent(MotionEvent event) {
return super.dispatchHoverEvent(event);
}

private void applyTextAttributes() {
// Workaround for an issue where text can be cut off with an ellipsis when
// using certain font sizes and padding. Sets the provided text size and
// letter spacing to ensure consistent rendering and prevent cut-off.
if (!Float.isNaN(mFontSize)) {
setTextSize(TypedValue.COMPLEX_UNIT_PX, mFontSize);
public void setLetterSpacing(float letterSpacing) {
mTextAttributes.setLetterSpacing(letterSpacing);
}

public void setAllowFontScaling(boolean allowFontScaling) {
if (mTextAttributes.getAllowFontScaling() != allowFontScaling) {
mTextAttributes.setAllowFontScaling(allowFontScaling);
}
}

public void setFontSize(float fontSize) {
mTextAttributes.setFontSize(fontSize);
}

public void setMaxFontSizeMultiplier(float maxFontSizeMultiplier) {
if (maxFontSizeMultiplier != mTextAttributes.getMaxFontSizeMultiplier()) {
mTextAttributes.setMaxFontSizeMultiplier(maxFontSizeMultiplier);
}
}

private void applyTextAttributes() {
// In general, the `getEffective*` functions return `Float.NaN` if the
// property hasn't been set.

// `getEffectiveFontSize` always returns a value so don't need to check for anything like
// `Float.NaN`.
setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextAttributes.getEffectiveFontSize());

if (!Float.isNaN(mLetterSpacing)) {
super.setLetterSpacing(mLetterSpacing);
float effectiveLetterSpacing = mTextAttributes.getEffectiveLetterSpacing();
if (!Float.isNaN(effectiveLetterSpacing)) {
super.setLetterSpacing(effectiveLetterSpacing);
}
}
}

0 comments on commit 1af2486

Please sign in to comment.