|
9 | 9 |
|
10 | 10 | import android.content.res.AssetManager;
|
11 | 11 | import android.graphics.Typeface;
|
| 12 | +import android.os.Build; |
12 | 13 | import android.text.TextUtils;
|
13 | 14 | import androidx.annotation.Nullable;
|
| 15 | +import com.facebook.common.logging.FLog; |
14 | 16 | import com.facebook.react.bridge.ReadableArray;
|
15 | 17 | import java.util.ArrayList;
|
16 | 18 | import java.util.List;
|
17 | 19 |
|
18 | 20 | public class ReactTypefaceUtils {
|
| 21 | + private static final String TAG = "ReactTypefaceUtils"; |
19 | 22 | public static final int UNSET = -1;
|
20 | 23 |
|
21 | 24 | public static int parseFontWeight(@Nullable String fontWeightString) {
|
22 | 25 | int fontWeightNumeric =
|
23 | 26 | fontWeightString != null ? parseNumericFontWeight(fontWeightString) : UNSET;
|
24 | 27 | int fontWeight = fontWeightNumeric != UNSET ? fontWeightNumeric : Typeface.NORMAL;
|
25 | 28 |
|
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; |
28 | 31 |
|
29 | 32 | return fontWeight;
|
30 | 33 | }
|
@@ -81,34 +84,50 @@ public static Typeface applyStyles(
|
81 | 84 | AssetManager assetManager) {
|
82 | 85 | int oldStyle;
|
83 | 86 | if (typeface == null) {
|
84 |
| - oldStyle = 0; |
| 87 | + oldStyle = Typeface.NORMAL; |
85 | 88 | } else {
|
86 | 89 | oldStyle = typeface.getStyle();
|
87 | 90 | }
|
88 | 91 |
|
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); |
93 | 103 | }
|
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."); |
98 | 119 | }
|
99 |
| - |
100 | 120 | 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); |
105 | 122 | }
|
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."); |
111 | 129 | }
|
| 130 | + return typeface; |
112 | 131 | }
|
113 | 132 |
|
114 | 133 | /**
|
|
0 commit comments