Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android does not allow for use of all font weights even when explicitly provided #27310

Closed
aforty opened this issue Nov 22, 2019 · 6 comments
Closed
Labels
Bug Platform: Android Android applications. Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@aforty
Copy link
Contributor

aforty commented Nov 22, 2019

React Native version: 61.4

Problem

I'm declaring a custom font with all weights (300, 400, 500, 600, 700, 800, 900). I then have a Text node with fontWeight: '700' but because of the logic in ReactBaseTextShadowNode.setFontWeight() it gets reset to Typeface.BOLD. So if I use '800' or '900' it works correctly but specifically '700' gets reset to bold.

Further adding to my confusion is the fact that this logic differs from other setFontWeight() methods where anything over 500 is reset to bold. Then all three methods claim to be duplicates of the code of one another.

My question:
What should the proper logic be. Why are fontWeights being reset to bold and why '700' specifically in the case of ReactBaseTextShadowNode? In my search for a solution I also came across #25341 which seems related.

Here are all the various setFontWeight methods found throughout the android codebase.

// TextAttributeProps.java


/**
 * /* This code is duplicated in ReactTextInputManager /* TODO: Factor into a common place they
 * can both use
 */
public void setFontWeight(@Nullable String fontWeightString) {
  int fontWeightNumeric =
      fontWeightString != null ? parseNumericFontWeight(fontWeightString) : -1;
  int fontWeight = UNSET;
  if (fontWeightNumeric >= 500 || "bold".equals(fontWeightString)) {
    fontWeight = Typeface.BOLD;
  } else if ("normal".equals(fontWeightString)
      || (fontWeightNumeric != -1 && fontWeightNumeric < 500)) {
    fontWeight = Typeface.NORMAL;
  }
  if (fontWeight != mFontWeight) {
    mFontWeight = fontWeight;
  }
}
// ReacTextInputManager.java


/**
 * /* This code was taken from the method setFontWeight of the class ReactTextShadowNode /* TODO:
 * Factor into a common place they can both use
 */
@ReactProp(name = ViewProps.FONT_WEIGHT)
public void setFontWeight(ReactEditText view, @Nullable String fontWeightString) {
  int fontWeightNumeric =
      fontWeightString != null ? parseNumericFontWeight(fontWeightString) : -1;
  int fontWeight = UNSET;
  if (fontWeightNumeric >= 500 || "bold".equals(fontWeightString)) {
    fontWeight = Typeface.BOLD;
  } else if ("normal".equals(fontWeightString)
      || (fontWeightNumeric != -1 && fontWeightNumeric < 500)) {
    fontWeight = Typeface.NORMAL;
  }
  Typeface currentTypeface = view.getTypeface();
  if (currentTypeface == null) {
    currentTypeface = Typeface.DEFAULT;
  }
  if (fontWeight != currentTypeface.getStyle()) {
    view.setTypeface(currentTypeface, fontWeight);
  }
}
// ReactBaseTextShadowNode.java


/**
 * /* This code is duplicated in ReactTextInputManager /* TODO: Factor into a common place they
 * can both use
 */
@ReactProp(name = ViewProps.FONT_WEIGHT)
public void setFontWeight(@Nullable String fontWeightString) {
  int fontWeightNumeric =
      fontWeightString != null ? parseNumericFontWeight(fontWeightString) : UNSET;
  int fontWeight = fontWeightNumeric != UNSET ? fontWeightNumeric : Typeface.NORMAL;

  if (fontWeight == 700 || "bold".equals(fontWeightString)) fontWeight = Typeface.BOLD;
  else if (fontWeight == 400 || "normal".equals(fontWeightString)) fontWeight = Typeface.NORMAL;

  if (fontWeight != mFontWeight) {
    mFontWeight = fontWeight;
    markUpdated();
  }
}

Steps To Reproduce

  1. Add a font and define all the font weights and styles in an xml for Android.
  2. Attach the font to the ReactFontManager's addCustomFont()
  3. Use a font below 800, the font will be appear to be reset and does not adhere to the requested value.

Describe what you expected to happen:
I expect to be able to use all font weights that are available on both iOS and Android. This is possible on iOS but not Android.

Link to a repository:
https://github.com/aforty/react-native-android-font-weight-bug

Notice how the fonts are defined in android/app/src/main/res/font and then registered in MainApplication.onCreate().

Screen Shot 2019-11-22 at 14 21 57

@aforty aforty added the Bug label Nov 22, 2019
@react-native-bot react-native-bot added the Platform: Android Android applications. label Nov 22, 2019
@mcousillas6
Copy link

I'm having the exact same issue, is there any workaround until this is resolved?

@waqas19921
Copy link

Also having same issue
Android only differentiate three font types while loading font files.
Need to provide workaround for different font weights like for bold if you add suffix _bold in file name it will load

{"", "_bold", "_italic", "_bold_italic"}

Check this line
https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java#L31

@waqas19921
Copy link

Check this #26193 (comment) for solution

@es-lynn
Copy link

es-lynn commented Jan 3, 2020

I wrote a npm package react-native-font-weight (alpha) to handle fontWeights on Android.

Original Thread

@stale
Copy link

stale bot commented Apr 2, 2020

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Apr 2, 2020
@stale
Copy link

stale bot commented Apr 9, 2020

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

@stale stale bot closed this as completed Apr 9, 2020
@facebook facebook locked as resolved and limited conversation to collaborators Apr 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Platform: Android Android applications. Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests

5 participants