mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
custom fontWeight numeric values for Text on Android (#25341)
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: https://github.com/facebook/react-native/pull/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
This commit is contained in:
committed by
Lorenzo Sciandra
parent
9792f2c9d7
commit
13f4fa0245
+1
-1
@@ -47,7 +47,7 @@ public class RNTesterApplication extends Application implements ReactApplication
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
ReactFontManager.getInstance().addCustomFont(this, "Srisakdi", R.font.srisakdi);
|
||||
ReactFontManager.getInstance().addCustomFont(this, "Rubik", R.font.rubik);
|
||||
super.onCreate();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<font app:fontStyle="normal" app:fontWeight="300" app:font="@font/rubik_light"/>
|
||||
<font app:fontStyle="normal" app:fontWeight="400" app:font="@font/rubik_regular"/>
|
||||
<font app:fontStyle="normal" app:fontWeight="500" app:font="@font/rubik_medium" />
|
||||
<font app:fontStyle="normal" app:fontWeight="700" app:font="@font/rubik_bold" />
|
||||
<font app:fontStyle="italic" app:fontWeight="500" app:font="@font/rubik_medium_italic" />
|
||||
</font-family>
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<font app:fontStyle="normal" app:fontWeight="400" app:font="@font/srisakdi_regular"/>
|
||||
<font app:fontStyle="normal" app:fontWeight="700" app:font="@font/srisakdi_bold" />
|
||||
</font-family>
|
||||
Binary file not shown.
Binary file not shown.
@@ -183,13 +183,41 @@ class TextExample extends React.Component<{}> {
|
||||
<Text style={{fontFamily: 'notoserif', fontStyle: 'italic'}}>
|
||||
NotoSerif Italic (Missing Font file)
|
||||
</Text>
|
||||
<Text style={{fontFamily: 'Srisakdi'}}>Srisakdi Regular</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: 'Srisakdi',
|
||||
fontWeight: 'bold',
|
||||
fontFamily: 'Rubik',
|
||||
fontWeight: 'normal',
|
||||
}}>
|
||||
Srisakdi Bold
|
||||
Rubik Regular
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: 'Rubik',
|
||||
fontWeight: '300',
|
||||
}}>
|
||||
Rubik Light
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: 'Rubik',
|
||||
fontWeight: '700',
|
||||
}}>
|
||||
Rubik Bold
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: 'Rubik',
|
||||
fontWeight: '500',
|
||||
}}>
|
||||
Rubik Medium
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: 'Rubik',
|
||||
fontStyle: 'italic',
|
||||
fontWeight: '500',
|
||||
}}>
|
||||
Rubik Medium Italic
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -205,15 +233,15 @@ class TextExample extends React.Component<{}> {
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="Font Weight">
|
||||
<Text style={{fontWeight: 'bold'}}>Move fast and be bold</Text>
|
||||
<Text style={{fontWeight: 'normal'}}>Move fast and be bold</Text>
|
||||
<Text style={{fontWeight: 'normal'}}>Move fast and be normal</Text>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="Font Style">
|
||||
<Text style={{fontStyle: 'italic'}}>Move fast and be bold</Text>
|
||||
<Text style={{fontStyle: 'normal'}}>Move fast and be bold</Text>
|
||||
<Text style={{fontStyle: 'italic'}}>Move fast and be italic</Text>
|
||||
<Text style={{fontStyle: 'normal'}}>Move fast and be normal</Text>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="Font Style and Weight">
|
||||
<Text style={{fontStyle: 'italic', fontWeight: 'bold'}}>
|
||||
Move fast and be bold
|
||||
Move fast and be both bold and italic
|
||||
</Text>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="Text Decoration">
|
||||
|
||||
@@ -104,7 +104,7 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan {
|
||||
}
|
||||
|
||||
if (family != null) {
|
||||
typeface = ReactFontManager.getInstance().getTypeface(family, want, assetManager);
|
||||
typeface = ReactFontManager.getInstance().getTypeface(family, want, weight, assetManager);
|
||||
} else if (typeface != null) {
|
||||
// TODO(t9055065): Fix custom fonts getting applied to text children with different style
|
||||
typeface = Typeface.create(typeface, want);
|
||||
|
||||
+7
-9
@@ -309,7 +309,7 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode {
|
||||
&& fontWeightString.charAt(0) <= '9'
|
||||
&& fontWeightString.charAt(0) >= '1'
|
||||
? 100 * (fontWeightString.charAt(0) - '0')
|
||||
: -1;
|
||||
: UNSET;
|
||||
}
|
||||
|
||||
protected TextAttributes mTextAttributes;
|
||||
@@ -487,14 +487,12 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode {
|
||||
@ReactProp(name = ViewProps.FONT_WEIGHT)
|
||||
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;
|
||||
}
|
||||
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();
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.util.Map;
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Build;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -54,23 +55,32 @@ public class ReactFontManager {
|
||||
return sReactFontManagerInstance;
|
||||
}
|
||||
|
||||
public @Nullable Typeface getTypeface(
|
||||
String fontFamilyName,
|
||||
int style,
|
||||
AssetManager assetManager) {
|
||||
return getTypeface(fontFamilyName, style, 0, assetManager);
|
||||
}
|
||||
|
||||
public @Nullable Typeface getTypeface(
|
||||
String fontFamilyName,
|
||||
int style,
|
||||
int weight,
|
||||
AssetManager assetManager) {
|
||||
if(mCustomTypefaceCache.containsKey(fontFamilyName)) {
|
||||
Typeface typeface = mCustomTypefaceCache.get(fontFamilyName);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && weight >= 100 && weight <= 1000) {
|
||||
return Typeface.create(typeface, weight, (style & Typeface.ITALIC) != 0);
|
||||
}
|
||||
return Typeface.create(typeface, style);
|
||||
}
|
||||
|
||||
FontFamily fontFamily = mFontCache.get(fontFamilyName);
|
||||
if (fontFamily == null) {
|
||||
fontFamily = new FontFamily();
|
||||
mFontCache.put(fontFamilyName, fontFamily);
|
||||
}
|
||||
|
||||
if(mCustomTypefaceCache.containsKey(fontFamilyName)) {
|
||||
return Typeface.create(
|
||||
mCustomTypefaceCache.get(fontFamilyName),
|
||||
style
|
||||
);
|
||||
}
|
||||
|
||||
Typeface typeface = fontFamily.getTypeface(style);
|
||||
if (typeface == null) {
|
||||
typeface = createTypeface(fontFamilyName, style, assetManager);
|
||||
|
||||
Reference in New Issue
Block a user