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

custom fontWeight numeric values for Text on Android #25341

Closed
wants to merge 6 commits into from

Conversation

dulmandakh
Copy link
Contributor

@dulmandakh dulmandakh commented Jun 21, 2019

Summary

I found that on Android we only support 2 fontWeight options, either normal or bold, even developer can set any numeric value. But iOS supports all possible numeric values. This PR tries to add support for all possible numeric values on Android, even if it's supported only on Android P(28) and above.

This change might break texts where fontWeight use improperly, because this PR removes conversion of values above 500 to BOLD and below 500 to normal.

FYI, also moved mCustomTypefaceCache usage up because it was working after unnecessary mFontCache usage.

Changelog

[Android] [Changed] - add custom font weight support to Text component on Android, only on P(API 28) and above versions.

Test Plan

RNTester app's Text examples will show Rubik Regular, Rubik Light, Rubik Bold, Rubik Medium and Rubik Medium Italic texts in corresponding font family, style and weights.

@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Contributor A React Native contributor. labels Jun 21, 2019
@dulmandakh dulmandakh changed the title Custom font weight support custom fontWeight numeric values for Text on Android Jun 21, 2019
@dulmandakh dulmandakh changed the title support custom fontWeight numeric values for Text on Android custom fontWeight numeric values for Text on Android Jun 21, 2019
@react-native-bot react-native-bot added the Platform: Android Android applications. label Jun 21, 2019
|| (fontWeightNumeric != -1 && fontWeightNumeric < 500)) {
fontWeight = Typeface.NORMAL;
}
int fontWeight = fontWeightNumeric != -1 ? fontWeightNumeric : Typeface.NORMAL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you change -1 for UNSET constant?

Copy link
Contributor

@mdvacca mdvacca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @dulmandakh, thanks for working on this. The code looks good to me, can you just make that small change of the constant? and I will import it

CC @fkgozali as you were involved in changes in the way we manage fonts in android

@dulmandakh
Copy link
Contributor Author

@mdvacca thanks for your review and comment. I made requested changes, please feel free to review, maybe import the changes.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mdvacca is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@mdvacca
Copy link
Contributor

mdvacca commented Jun 22, 2019

Thanks @dulmandakh, I'm landing it.

@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @dulmandakh in 3915c0f.

When will my fix make it into a release? | Upcoming Releases

@react-native-bot react-native-bot added the Merged This PR has been merged. label Jun 22, 2019
kelset pushed a commit that referenced this pull request Jun 28, 2019
Summary:
I found that on Android we only support 2 fontWeight options, either **normal** or **bold**, even developer can set any numeric value. But iOS supports all possible numeric values. This PR tries to add support for all possible numeric values on Android, even if it's supported only on Android P(28) and above.

This change might break texts where fontWeight use improperly, because this PR removes conversion of values above 500 to BOLD and below 500 to normal.

FYI, also moved **mCustomTypefaceCache** usage up because it was working after unnecessary mFontCache usage.

## Changelog

[Android] [Changed] - add custom font weight support to Text component on Android, only on P(API 28) and above versions.
Pull Request resolved: #25341

Test Plan: RNTester app's Text examples will show Rubik Regular, Rubik Light, Rubik Bold, Rubik Medium and Rubik Medium Italic texts in corresponding font family, style and weights.

Differential Revision: D15956350

Pulled By: mdvacca

fbshipit-source-id: 61079d953c65fb34ab4497d44c22317912a5a616
@dulmandakh dulmandakh deleted the custom-font-weight branch October 15, 2019 05:14
@greg7gkb
Copy link

It seems like this change broke previous behavior that was relied upon (my team included): #25696
So I'm curious to understand why the decision to break existing behaviors that seem reasonable?

@dulmandakh
Copy link
Contributor Author

So sorry that the change broke your code, but intention is described in the summary.

@greg7gkb
Copy link

The description does not describe why it was decided that the previous behavior should be broken. New behaviors for P+ might have been appropriate but could have been applied in a backwards-compatible way.
I'm sure this broke behavior for a lot of apps.

@dulmandakh
Copy link
Contributor Author

It's my bad that I didn't expected that developers would depend on this behavior. Please feel free to create a PR and add backwards-compatibility, I would be happy to review and test it.

@aforty
Copy link
Contributor

aforty commented Nov 22, 2019

I found this PR as I was investigating an issue.

My issue:
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?

// 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();
  }
}

@ou2s
Copy link

ou2s commented Nov 27, 2019

So sad that the old behavior is broken now, because the impact is quite big on our app...
I understand the motivation behind this PR but why remove the code that removes conversion of values above 500 to BOLD and below 500 to normal?
Why not leave it for backward compatibility?

vonovak added a commit to react-navigation/react-navigation that referenced this pull request Mar 3, 2020
the previously used fort weight of 500 would effectively be converted to `fontWeight: bold` because of facebook/react-native#25341

this fixes the title appearance to look as customary
vonovak added a commit to react-navigation/react-navigation that referenced this pull request Mar 3, 2020
the previously used fort weight of 500 would effectively be converted to `fontWeight: bold` because of facebook/react-native#25341

this fixes the title appearance to look as customary

Update HeaderTitle.tsx
vonovak added a commit to react-navigation/react-navigation that referenced this pull request Mar 6, 2020
the previously used fort weight of 500 would effectively be converted to `fontWeight: bold` because of facebook/react-native#25341

this fixes the title appearance to look as customary

Update HeaderTitle.tsx
M-i-k-e-l pushed a commit to M-i-k-e-l/react-native that referenced this pull request Mar 10, 2020
Summary:
I found that on Android we only support 2 fontWeight options, either **normal** or **bold**, even developer can set any numeric value. But iOS supports all possible numeric values. This PR tries to add support for all possible numeric values on Android, even if it's supported only on Android P(28) and above.

This change might break texts where fontWeight use improperly, because this PR removes conversion of values above 500 to BOLD and below 500 to normal.

FYI, also moved **mCustomTypefaceCache** usage up because it was working after unnecessary mFontCache usage.

## Changelog

[Android] [Changed] - add custom font weight support to Text component on Android, only on P(API 28) and above versions.
Pull Request resolved: facebook#25341

Test Plan: RNTester app's Text examples will show Rubik Regular, Rubik Light, Rubik Bold, Rubik Medium and Rubik Medium Italic texts in corresponding font family, style and weights.

Differential Revision: D15956350

Pulled By: mdvacca

fbshipit-source-id: 61079d953c65fb34ab4497d44c22317912a5a616
satya164 pushed a commit to react-navigation/react-navigation that referenced this pull request Mar 16, 2020
the previously used fort weight of 500 would effectively be converted to `fontWeight: bold` because of facebook/react-native#25341

this fixes the title appearance to look as customary
xvonabur added a commit to xvonabur/react-native that referenced this pull request Mar 25, 2020
joshuapinter pushed a commit to cntral/react-navigation that referenced this pull request Sep 29, 2021
the previously used fort weight of 500 would effectively be converted to `fontWeight: bold` because of facebook/react-native#25341

this fixes the title appearance to look as customary
YAfullStack pushed a commit to YAfullStack/React-navigation that referenced this pull request Dec 4, 2021
the previously used fort weight of 500 would effectively be converted to `fontWeight: bold` because of facebook/react-native#25341

this fixes the title appearance to look as customary
redhawkIT pushed a commit to redhawkIT/react-navigation that referenced this pull request Dec 23, 2021
the previously used fort weight of 500 would effectively be converted to `fontWeight: bold` because of facebook/react-native#25341

this fixes the title appearance to look as customary
darkhorse-coder pushed a commit to darkhorse-coder/react-navigation that referenced this pull request Apr 7, 2022
the previously used fort weight of 500 would effectively be converted to `fontWeight: bold` because of facebook/react-native#25341

this fixes the title appearance to look as customary
nenad0212 pushed a commit to nenad0212/temp1 that referenced this pull request Sep 6, 2022
the previously used fort weight of 500 would effectively be converted to `fontWeight: bold` because of facebook/react-native#25341

this fixes the title appearance to look as customary
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Contributor A React Native contributor. Merged This PR has been merged. Platform: Android Android applications.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants