Skip to content

Commit 3827ca6

Browse files
fabOnReactfacebook-github-bot
authored andcommitted
Fix font weight numeric values (#29117)
Summary: This issue fixes #25696 fixes #28854 fixes #26193 Since Android API 28 it is possible to specify fontWeight with numerical values ranging from 100 to 900 This pr uses the new Typeface.create() method available on Android API 28+ to set font weight value ranging from 100 to 900, while still keeping existing functionalities (custom fonts, bold/italic and other styles). https://developer.android.com/reference/android/graphics/Typeface#create(android.graphics.Typeface,%20int,%20boolean) ## Changelog [Android] [Fixed] - Fix font weight numeric values Pull Request resolved: #29117 Test Plan: Works in all scenarios. **<details><summary>CLICK TO OPEN TESTS RESULTS</summary>** <p> | **BEFORE** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/84420949-1daa0e80-ac1b-11ea-9a2e-eaac03dc4533.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/84490766-edf31900-aca3-11ea-90d8-7c52d2e2be59.png" width="300" height="" /> | | **AFTER** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/84490768-ee8baf80-aca3-11ea-8d3e-937d87b3c56a.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/84490769-ef244600-aca3-11ea-9dec-5eb70358834b.png" width="300" height="" /> | | **AFTER** | |:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/84490772-f0557300-aca3-11ea-851a-5befc900192c.png" width="300" height="" />| </p> </details> Reviewed By: lunaleaps Differential Revision: D28917328 Pulled By: yungsters fbshipit-source-id: 8b84e855b3a8b87960cb79b9237d452b26974c36
1 parent b4cde15 commit 3827ca6

File tree

3 files changed

+60
-36
lines changed

3 files changed

+60
-36
lines changed

ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.java

+40-21
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,25 @@
99

1010
import android.content.res.AssetManager;
1111
import android.graphics.Typeface;
12+
import android.os.Build;
1213
import android.text.TextUtils;
1314
import androidx.annotation.Nullable;
15+
import com.facebook.common.logging.FLog;
1416
import com.facebook.react.bridge.ReadableArray;
1517
import java.util.ArrayList;
1618
import java.util.List;
1719

1820
public class ReactTypefaceUtils {
21+
private static final String TAG = "ReactTypefaceUtils";
1922
public static final int UNSET = -1;
2023

2124
public static int parseFontWeight(@Nullable String fontWeightString) {
2225
int fontWeightNumeric =
2326
fontWeightString != null ? parseNumericFontWeight(fontWeightString) : UNSET;
2427
int fontWeight = fontWeightNumeric != UNSET ? fontWeightNumeric : Typeface.NORMAL;
2528

26-
if (fontWeight == 700 || "bold".equals(fontWeightString)) fontWeight = Typeface.BOLD;
27-
else if (fontWeight == 400 || "normal".equals(fontWeightString)) fontWeight = Typeface.NORMAL;
29+
if ("bold".equals(fontWeightString)) fontWeight = Typeface.BOLD;
30+
else if ("normal".equals(fontWeightString)) fontWeight = Typeface.NORMAL;
2831

2932
return fontWeight;
3033
}
@@ -81,34 +84,50 @@ public static Typeface applyStyles(
8184
AssetManager assetManager) {
8285
int oldStyle;
8386
if (typeface == null) {
84-
oldStyle = 0;
87+
oldStyle = Typeface.NORMAL;
8588
} else {
8689
oldStyle = typeface.getStyle();
8790
}
8891

89-
int want = 0;
90-
if ((weight == Typeface.BOLD)
91-
|| ((oldStyle & Typeface.BOLD) != 0 && weight == ReactTextShadowNode.UNSET)) {
92-
want |= Typeface.BOLD;
92+
int newStyle = oldStyle;
93+
boolean italic = false;
94+
if (weight == UNSET) weight = Typeface.NORMAL;
95+
if (style == Typeface.ITALIC) italic = true;
96+
boolean UNDER_SDK_28 = Build.VERSION.SDK_INT < Build.VERSION_CODES.P;
97+
boolean applyNumericValues = !(weight < (Typeface.BOLD_ITALIC + 1) || family != null);
98+
boolean numericBold = UNDER_SDK_28 && weight > 699 && applyNumericValues;
99+
boolean numericNormal = UNDER_SDK_28 && weight < 700 && applyNumericValues;
100+
if (weight == Typeface.BOLD) {
101+
newStyle = (newStyle == Typeface.ITALIC) ? Typeface.BOLD_ITALIC : Typeface.BOLD;
102+
typeface = Typeface.create(typeface, newStyle);
93103
}
94-
95-
if ((style == Typeface.ITALIC)
96-
|| ((oldStyle & Typeface.ITALIC) != 0 && style == ReactTextShadowNode.UNSET)) {
97-
want |= Typeface.ITALIC;
104+
if (weight == Typeface.NORMAL) {
105+
typeface = Typeface.create(typeface, Typeface.NORMAL);
106+
newStyle = Typeface.NORMAL;
107+
}
108+
if (style == Typeface.ITALIC) {
109+
newStyle = (newStyle == Typeface.BOLD) ? Typeface.BOLD_ITALIC : Typeface.ITALIC;
110+
typeface = Typeface.create(typeface, newStyle);
111+
}
112+
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1 && weight > Typeface.BOLD_ITALIC) {
113+
typeface = Typeface.create(typeface, weight, italic);
114+
}
115+
if (family != null && UNDER_SDK_28 && weight > Typeface.BOLD_ITALIC) {
116+
FLog.d(
117+
TAG,
118+
"Support for numeric font weight numeric values with custom fonts under Android API 28 Pie is not yet supported in ReactNative.");
98119
}
99-
100120
if (family != null) {
101-
typeface = ReactFontManager.getInstance().getTypeface(family, want, weight, assetManager);
102-
} else if (typeface != null) {
103-
// TODO(t9055065): Fix custom fonts getting applied to text children with different style
104-
typeface = Typeface.create(typeface, want);
121+
typeface = ReactFontManager.getInstance().getTypeface(family, newStyle, weight, assetManager);
105122
}
106-
107-
if (typeface != null) {
108-
return typeface;
109-
} else {
110-
return Typeface.defaultFromStyle(want);
123+
if (numericBold || numericNormal) {
124+
newStyle = numericBold ? Typeface.BOLD : Typeface.NORMAL;
125+
typeface = Typeface.create(typeface, newStyle);
126+
FLog.d(
127+
TAG,
128+
"Support for numeric font weight numeric values available only from Android API 28 Pie. Android device lower then API 28 will use normal or bold.");
111129
}
130+
return typeface;
112131
}
113132

114133
/**

packages/rn-tester/js/examples/Text/TextExample.android.js

+9
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,15 @@ class TextExample extends React.Component<{...}> {
388388
<RNTesterBlock title="Font Weight">
389389
<Text style={{fontWeight: 'bold'}}>Move fast and be bold</Text>
390390
<Text style={{fontWeight: 'normal'}}>Move fast and be normal</Text>
391+
<Text style={{fontWeight: '900'}}>FONT WEIGHT 900</Text>
392+
<Text style={{fontWeight: '800'}}>FONT WEIGHT 800</Text>
393+
<Text style={{fontWeight: '700'}}>FONT WEIGHT 700</Text>
394+
<Text style={{fontWeight: '600'}}>FONT WEIGHT 600</Text>
395+
<Text style={{fontWeight: '500'}}>FONT WEIGHT 500</Text>
396+
<Text style={{fontWeight: '400'}}>FONT WEIGHT 400</Text>
397+
<Text style={{fontWeight: '300'}}>FONT WEIGHT 300</Text>
398+
<Text style={{fontWeight: '200'}}>FONT WEIGHT 200</Text>
399+
<Text style={{fontWeight: '100'}}>FONT WEIGHT 100</Text>
391400
</RNTesterBlock>
392401
<RNTesterBlock title="Font Style">
393402
<Text style={{fontStyle: 'italic'}}>Move fast and be italic</Text>

packages/rn-tester/js/examples/Text/TextExample.ios.js

+11-15
Original file line numberDiff line numberDiff line change
@@ -603,21 +603,17 @@ exports.examples = [
603603
render: function(): React.Node {
604604
return (
605605
<View>
606-
<Text style={{fontSize: 20, fontWeight: '100'}}>
607-
Move fast and be ultralight
608-
</Text>
609-
<Text style={{fontSize: 20, fontWeight: '200'}}>
610-
Move fast and be light
611-
</Text>
612-
<Text style={{fontSize: 20, fontWeight: 'normal'}}>
613-
Move fast and be normal
614-
</Text>
615-
<Text style={{fontSize: 20, fontWeight: 'bold'}}>
616-
Move fast and be bold
617-
</Text>
618-
<Text style={{fontSize: 20, fontWeight: '900'}}>
619-
Move fast and be ultrabold
620-
</Text>
606+
<Text style={{fontWeight: 'bold'}}>Move fast and be bold</Text>
607+
<Text style={{fontWeight: 'normal'}}>Move fast and be normal</Text>
608+
<Text style={{fontWeight: '900'}}>FONT WEIGHT 900</Text>
609+
<Text style={{fontWeight: '800'}}>FONT WEIGHT 800</Text>
610+
<Text style={{fontWeight: '700'}}>FONT WEIGHT 700</Text>
611+
<Text style={{fontWeight: '600'}}>FONT WEIGHT 600</Text>
612+
<Text style={{fontWeight: '500'}}>FONT WEIGHT 500</Text>
613+
<Text style={{fontWeight: '400'}}>FONT WEIGHT 400</Text>
614+
<Text style={{fontWeight: '300'}}>FONT WEIGHT 300</Text>
615+
<Text style={{fontWeight: '200'}}>FONT WEIGHT 200</Text>
616+
<Text style={{fontWeight: '100'}}>FONT WEIGHT 100</Text>
621617
</View>
622618
);
623619
},

0 commit comments

Comments
 (0)