Skip to content

Commit 12ffb0a

Browse files
fix(android): font weight compatible with version 2.x (#3948)
Co-authored-by: maxli <[email protected]>
1 parent d9478f4 commit 12ffb0a

File tree

6 files changed

+97
-79
lines changed

6 files changed

+97
-79
lines changed

docs/api/style/appearance.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@
174174
| ------ | -------- | --- |
175175
| number \| string | 否 | Android、iOS
176176

177-
> Android API 28 以下仅支持 `normal``400``bold``700`两种字重,其它字重效果需配合 `fontFamily` 实现。
177+
> Android API 28 以下仅支持 `normal``bold` 两种字重,其它字重效果需配合 `fontFamily` 实现,Android API 28 及以上可以支持设置`1` - `1000`的字重值
178178
179179
# letterSpacing
180180

driver/js/examples/hippy-react-demo/src/components/Text/index.jsx

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const styles = StyleSheet.create({
4141
fontSize: 14,
4242
lineHeight: 18,
4343
color: 'black',
44+
fontWeight: 'normal'
4445
},
4546
buttonBar: {
4647
flexDirection: 'row',
@@ -54,6 +55,7 @@ const styles = StyleSheet.create({
5455
borderStyle: 'solid',
5556
flexGrow: 1,
5657
flexShrink: 1,
58+
justifyContent: 'center',
5759
},
5860
buttonText: {
5961
lineHeight: 24,
@@ -72,6 +74,7 @@ export default class TextExpo extends React.Component {
7274
super(props);
7375
this.state = {
7476
fontSize: 16,
77+
fontWeight: '400',
7578
textShadowColor: 'grey',
7679
textShadowOffset: {
7780
x: 1,
@@ -83,12 +86,36 @@ export default class TextExpo extends React.Component {
8386
};
8487
this.incrementFontSize = this.incrementFontSize.bind(this);
8588
this.decrementFontSize = this.decrementFontSize.bind(this);
89+
this.incrementFontWeight = this.incrementFontWeight.bind(this);
90+
this.decrementFontWeight = this.decrementFontWeight.bind(this);
8691
this.incrementLine = this.incrementLine.bind(this);
8792
this.decrementLine = this.decrementLine.bind(this);
8893
this.changeMode = this.changeMode.bind(this);
8994
this.changeColor = this.changeColor.bind(this);
9095
}
96+
incrementFontWeight() {
97+
const { fontWeight } = this.state;
98+
if (fontWeight == '1000') {
99+
return;
100+
}
101+
var weightNumber = parseInt(fontWeight, 10);
102+
weightNumber += 100;
103+
this.setState({
104+
fontWeight: weightNumber.toString(),
105+
});
106+
}
91107

108+
decrementFontWeight() {
109+
const { fontWeight } = this.state;
110+
if (fontWeight === '100') {
111+
return;
112+
}
113+
var weightNumber = parseInt(fontWeight, 10);
114+
weightNumber -= 100;
115+
this.setState({
116+
fontWeight: weightNumber.toString(),
117+
});
118+
}
92119
incrementFontSize() {
93120
const { fontSize } = this.state;
94121
if (fontSize === 24) {
@@ -140,7 +167,7 @@ export default class TextExpo extends React.Component {
140167
}
141168

142169
render() {
143-
const { fontSize, textShadowColor, textShadowOffset, numberOfLines, ellipsizeMode, breakStrategy,
170+
const { fontSize, fontWeight, textShadowColor, textShadowOffset, numberOfLines, ellipsizeMode, breakStrategy,
144171
scrollColor } = this.state;
145172
const renderTitle = title => (
146173
<View style={styles.itemTitle}>
@@ -194,6 +221,18 @@ export default class TextExpo extends React.Component {
194221
<Text style={styles.buttonText}>缩小字体</Text>
195222
</View>
196223
</View>
224+
{renderTitle('fontWeight')}
225+
<View style={[styles.itemContent, { height: 125, color: 'blue', fontFamily: 'not-support-fontstyle' }]}>
226+
<Text style={[styles.normalText, { fontWeight }]}>
227+
{ `Text fontWeight is ${fontWeight}` }
228+
</Text>
229+
<View style={styles.button} onClick={this.incrementFontWeight}>
230+
<Text style={styles.buttonText}>加粗字体</Text>
231+
</View>
232+
<View style={styles.button} onClick={this.decrementFontWeight}>
233+
<Text style={styles.buttonText}>减细字体</Text>
234+
</View>
235+
</View>
197236
{renderTitle('fontStyle')}
198237
<View style={[styles.itemContent, { height: 100 }]}>
199238
<Text style={[styles.normalText, { fontStyle: 'normal' }]}>Text fontStyle is normal</Text>

renderer/native/android/src/main/java/com/tencent/mtt/hippy/views/textinput/HippyTextInput.java

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public class HippyTextInput extends AppCompatEditText implements HippyViewBase,
9090
private int mListenerFlag = 0;
9191
private ReactContentSizeWatcher mReactContentSizeWatcher = null;
9292
private boolean mItalic = false;
93-
private int mFontWeight = TypeFaceUtil.WEIGHT_NORMAL;
93+
private String mFontWeight = TypeFaceUtil.TEXT_FONT_STYLE_NORMAL;
9494
private float mLineSpacingMultiplier = 1.0f;
9595
private float mLineSpacingExtra = 0.0f;
9696
private int mLineHeight = 0;
@@ -763,23 +763,8 @@ public void setFontFamily(String family) {
763763
}
764764

765765
public void setFontWeight(String weight) {
766-
int fontWeight;
767-
if (TextUtils.isEmpty(weight) || TypeFaceUtil.TEXT_FONT_STYLE_NORMAL.equals(weight)) {
768-
// case normal
769-
fontWeight = TypeFaceUtil.WEIGHT_NORMAL;
770-
} else if (TypeFaceUtil.TEXT_FONT_STYLE_BOLD.equals(weight)) {
771-
// case bold
772-
fontWeight = TypeFaceUtil.WEIGHT_BOLE;
773-
} else {
774-
// case number
775-
try {
776-
fontWeight = Math.min(Math.max(1, Integer.parseInt(weight)), 1000);
777-
} catch (NumberFormatException ignored) {
778-
fontWeight = TypeFaceUtil.WEIGHT_NORMAL;
779-
}
780-
}
781-
if (fontWeight != mFontWeight) {
782-
mFontWeight = fontWeight;
766+
if (!mFontWeight.equals(weight)) {
767+
mFontWeight = weight;
783768
mShouldUpdateTypeface = true;
784769
}
785770
}

renderer/native/android/src/main/java/com/tencent/renderer/component/text/TextStyleSpan.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,25 @@
2222
public class TextStyleSpan extends MetricAffectingSpan {
2323

2424
private final boolean mItalic;
25-
private final int mWeight;
25+
private final String mFontWeight;
2626
private final String mFontFamily;
2727
private final FontAdapter mFontAdapter;
2828

29-
public TextStyleSpan(boolean italic, int fontWeight, String fontFamily,
29+
public TextStyleSpan(boolean italic, String fontWeight, String fontFamily,
3030
FontAdapter adapter) {
3131
mItalic = italic;
32-
mWeight = fontWeight;
32+
mFontWeight = fontWeight;
3333
mFontFamily = fontFamily;
3434
mFontAdapter = adapter;
3535
}
3636

3737
@Override
3838
public void updateDrawState(TextPaint textPaint) {
39-
TypeFaceUtil.apply(textPaint, mItalic, mWeight, mFontFamily, mFontAdapter);
39+
TypeFaceUtil.apply(textPaint, mItalic, mFontWeight, mFontFamily, mFontAdapter);
4040
}
4141

4242
@Override
4343
public void updateMeasureState(TextPaint textPaint) {
44-
TypeFaceUtil.apply(textPaint, mItalic, mWeight, mFontFamily, mFontAdapter);
44+
TypeFaceUtil.apply(textPaint, mItalic, mFontWeight, mFontFamily, mFontAdapter);
4545
}
4646
}

renderer/native/android/src/main/java/com/tencent/renderer/component/text/TypeFaceUtil.java

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818

1919
import android.graphics.Paint;
2020
import android.graphics.Typeface;
21-
import android.os.Build;
21+
import android.os.Build.VERSION;
22+
import android.os.Build.VERSION_CODES;
2223
import android.text.TextUtils;
2324

2425
import android.util.SparseArray;
25-
import androidx.annotation.ChecksSdkIntAtLeast;
2626
import androidx.annotation.Nullable;
2727

2828
import com.tencent.mtt.hippy.utils.ContextHolder;
@@ -43,26 +43,25 @@ public class TypeFaceUtil {
4343
private static final String[] FONT_EXTENSIONS = {".ttf", ".otf"};
4444
private static final String FONTS_PATH = "fonts/";
4545
private static final Map<String, SparseArray<Typeface>> sFontCache = new HashMap<>();
46-
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.P)
47-
private static final boolean SUPPORT_FONT_WEIGHT = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
4846

4947
/**
50-
* @deprecated use {@link #getTypeface(String, int, boolean, FontAdapter)} instead
48+
* @deprecated use {@link #getTypeface(String, String, boolean, FontAdapter)} instead
5149
*/
5250
@Deprecated
5351
public static Typeface getTypeface(String fontFamilyName, int style,
5452
@Nullable FontAdapter fontAdapter) {
5553
boolean italic = (style & Typeface.ITALIC) != 0;
56-
int weightNumber = (style & Typeface.BOLD) != 0 ? WEIGHT_BOLE : WEIGHT_NORMAL;
57-
return getTypeface(fontFamilyName, weightNumber, italic, fontAdapter);
54+
String weight = (style & Typeface.BOLD) != 0 ? TEXT_FONT_STYLE_BOLD : TEXT_FONT_STYLE_NORMAL;
55+
return getTypeface(fontFamilyName, weight, italic, fontAdapter);
5856
}
5957

60-
public static Typeface getTypeface(String fontFamilyName, int weight, boolean italic,
58+
public static Typeface getTypeface(String fontFamilyName, String weight, boolean italic,
6159
@Nullable FontAdapter fontAdapter) {
62-
final int style = toStyle(weight, italic);
60+
int weightNumber = getWeightNumber(weight);
61+
final int style = toStyle(weight, weightNumber, italic);
6362
Typeface typeface = (fontAdapter != null) ? fontAdapter.getCustomTypeface(fontFamilyName, style) : null;
6463
if (typeface == null) {
65-
final int key = SUPPORT_FONT_WEIGHT ? ((weight << 1) | (italic ? 1 : 0)) : style;
64+
final int key = (weightNumber > 0) ? ((weightNumber << 1) | (italic ? 1 : 0)) : style;
6665
SparseArray<Typeface> cache = sFontCache.get(fontFamilyName);
6766
if (cache == null) {
6867
cache = new SparseArray<>(4);
@@ -71,7 +70,7 @@ public static Typeface getTypeface(String fontFamilyName, int weight, boolean it
7170
typeface = cache.get(key);
7271
}
7372
if (typeface == null) {
74-
typeface = createTypeface(fontFamilyName, weight, italic, fontAdapter);
73+
typeface = createTypeface(fontFamilyName, weightNumber, style, italic, fontAdapter);
7574
if (typeface != null) {
7675
cache.put(key, typeface);
7776
}
@@ -80,9 +79,8 @@ public static Typeface getTypeface(String fontFamilyName, int weight, boolean it
8079
return typeface;
8180
}
8281

83-
private static Typeface createTypeface(String fontFamilyName, int weight, boolean italic,
82+
private static Typeface createTypeface(String fontFamilyName, int weightNumber, int style, boolean italic,
8483
@Nullable FontAdapter fontAdapter) {
85-
final int style = toStyle(weight, italic);
8684
final String extension = EXTENSIONS[style];
8785
final String[] familyNameList;
8886
if (fontFamilyName.indexOf(',') == -1) {
@@ -113,8 +111,8 @@ private static Typeface createTypeface(String fontFamilyName, int weight, boolea
113111
try {
114112
Typeface typeface = Typeface.createFromAsset(ContextHolder.getAppContext().getAssets(), fileName);
115113
if (typeface != null && !typeface.equals(Typeface.DEFAULT)) {
116-
if (SUPPORT_FONT_WEIGHT) {
117-
return Typeface.create(typeface, weight, italic);
114+
if (VERSION.SDK_INT >= VERSION_CODES.P && weightNumber > 0) {
115+
return Typeface.create(typeface, weightNumber, italic);
118116
}
119117
// "bold" has no effect on api level < P, prefer to use `Paint.setFakeBoldText(boolean)`
120118
return italic ? Typeface.create(typeface, Typeface.ITALIC) : typeface;
@@ -138,46 +136,57 @@ private static Typeface createTypeface(String fontFamilyName, int weight, boolea
138136
}
139137
}
140138
}
141-
142139
final Typeface systemDefault = Typeface.create(Typeface.DEFAULT, style);
143140
for (String splitName : familyNameList) {
144141
Typeface typeface = Typeface.create(splitName, style);
145142
if (typeface != null && !typeface.equals(systemDefault)) {
146-
return SUPPORT_FONT_WEIGHT ? Typeface.create(typeface, weight, italic) : typeface;
143+
if (VERSION.SDK_INT >= VERSION_CODES.P && weightNumber > 0) {
144+
return Typeface.create(typeface, weightNumber, italic);
145+
}
146+
return typeface;
147147
}
148148
}
149-
return SUPPORT_FONT_WEIGHT ? Typeface.create(systemDefault, weight, italic) : systemDefault;
149+
return (VERSION.SDK_INT >= VERSION_CODES.P && weightNumber > 0) ?
150+
Typeface.create(systemDefault, weightNumber, italic) : systemDefault;
150151
}
151152

152-
private static int toStyle(int weight, boolean italic) {
153-
return weight < WEIGHT_BOLE ?
154-
(italic ? Typeface.ITALIC : Typeface.NORMAL) :
155-
(italic ? Typeface.BOLD_ITALIC : Typeface.BOLD);
153+
private static int getWeightNumber(String weight) {
154+
int weightNumber = 0;
155+
try {
156+
weightNumber = Math.min(Math.max(1, Integer.parseInt(weight)), 1000);
157+
} catch (NumberFormatException ignored) {
158+
// Weight supports setting non numeric strings
159+
}
160+
return weightNumber;
156161
}
157162

158-
/**
159-
* @deprecated use {@link #apply(Paint, boolean, int, String, FontAdapter)} instead
160-
*/
161-
@Deprecated
162-
public static void apply(Paint paint, int style, int weight, String family,
163-
@Nullable FontAdapter fontAdapter) {
164-
boolean italic = style == Typeface.ITALIC;
165-
int weightNumber = weight == Typeface.BOLD ? WEIGHT_BOLE : WEIGHT_NORMAL;
166-
apply(paint, italic, weightNumber, family, fontAdapter);
163+
private static int toStyle(String weight, int weightNumber, boolean italic) {
164+
if (weight.equals(TEXT_FONT_STYLE_NORMAL)) {
165+
return italic ? Typeface.ITALIC : Typeface.NORMAL;
166+
} else if (weight.equals(TEXT_FONT_STYLE_BOLD)) {
167+
return italic ? Typeface.BOLD_ITALIC : Typeface.BOLD;
168+
} else {
169+
return weightNumber < WEIGHT_BOLE ?
170+
(italic ? Typeface.ITALIC : Typeface.NORMAL) :
171+
(italic ? Typeface.BOLD_ITALIC : Typeface.BOLD);
172+
}
167173
}
168174

169-
public static void apply(Paint paint, boolean italic, int weight, String familyName,
175+
public static void apply(Paint paint, boolean italic, String weight, String familyName,
170176
@Nullable FontAdapter fontAdapter) {
171177
Typeface typeface;
178+
int weightNumber = getWeightNumber(weight);
172179
if (TextUtils.isEmpty(familyName)) {
173180
final Typeface base = paint.getTypeface();
174-
typeface = SUPPORT_FONT_WEIGHT
175-
? Typeface.create(base, weight, italic)
176-
: Typeface.create(base, toStyle(weight, italic));
181+
if (VERSION.SDK_INT >= VERSION_CODES.P && weightNumber > 0) {
182+
typeface = Typeface.create(base, weightNumber, italic);
183+
} else {
184+
typeface = Typeface.create(base, toStyle(weight, weightNumber, italic));
185+
}
177186
} else {
178187
typeface = getTypeface(familyName, weight, italic, fontAdapter);
179188
}
180-
if (weight >= WEIGHT_BOLE && typeface != null && !typeface.isBold()) {
189+
if (weightNumber >= WEIGHT_BOLE && typeface != null && !typeface.isBold()) {
181190
paint.setFakeBoldText(true);
182191
}
183192
paint.setTypeface(typeface);

renderer/native/android/src/main/java/com/tencent/renderer/node/TextVirtualNode.java

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public class TextVirtualNode extends VirtualNode {
8888
protected int mColor = Color.BLACK;
8989
protected int mNumberOfLines;
9090
protected boolean mItalic = false;
91-
protected int mFontWeight = TypeFaceUtil.WEIGHT_NORMAL;
91+
protected String mFontWeight = TypeFaceUtil.TEXT_FONT_STYLE_NORMAL;
9292
protected int mFontSize = (int) Math.ceil(PixelUtil.dp2px(NodeProps.FONT_SIZE_SP));
9393
protected int mShadowColor = TEXT_SHADOW_COLOR_DEFAULT;
9494
protected float mShadowOffsetDx = 0.0f;
@@ -183,23 +183,8 @@ public void setFontFamily(String family) {
183183
@SuppressWarnings("unused")
184184
@HippyControllerProps(name = NodeProps.FONT_WEIGHT, defaultType = HippyControllerProps.STRING)
185185
public void setFontWeight(String weight) {
186-
int fontWeight;
187-
if (TextUtils.isEmpty(weight) || TypeFaceUtil.TEXT_FONT_STYLE_NORMAL.equals(weight)) {
188-
// case normal
189-
fontWeight = TypeFaceUtil.WEIGHT_NORMAL;
190-
} else if (TypeFaceUtil.TEXT_FONT_STYLE_BOLD.equals(weight)) {
191-
// case bold
192-
fontWeight = TypeFaceUtil.WEIGHT_BOLE;
193-
} else {
194-
// case number
195-
try {
196-
fontWeight = Math.min(Math.max(1, Integer.parseInt(weight)), 1000);
197-
} catch (NumberFormatException ignored) {
198-
fontWeight = TypeFaceUtil.WEIGHT_NORMAL;
199-
}
200-
}
201-
if (fontWeight != mFontWeight) {
202-
mFontWeight = fontWeight;
186+
if (!mFontWeight.equals(weight)) {
187+
mFontWeight = weight;
203188
markDirty();
204189
}
205190
}

0 commit comments

Comments
 (0)