Skip to content

Commit 63c34a8

Browse files
committed
fix: account for Android font weight adjustment in text measurement
1 parent 29ab78a commit 63c34a8

8 files changed

Lines changed: 309 additions & 10 deletions

File tree

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
import com.facebook.react.views.text.PreparedLayout;
9494
import com.facebook.react.views.text.ReactTextViewManager;
9595
import com.facebook.react.views.text.ReactTextViewManagerCallback;
96+
import com.facebook.react.views.text.ReactTypefaceUtils;
9697
import com.facebook.react.views.text.TextEffectRegistry;
9798
import com.facebook.react.views.text.TextLayoutManager;
9899
import java.util.ArrayList;
@@ -553,6 +554,7 @@ private NativeArray measureLines(
553554
return (NativeArray)
554555
TextLayoutManager.measureLines(
555556
mReactApplicationContext.getAssets(),
557+
ReactTypefaceUtils.getFontWeightAdjustment(mReactApplicationContext),
556558
attributedString,
557559
paragraphAttributes,
558560
PixelUtil.toPixelFromDIP(width),
@@ -639,6 +641,7 @@ public long measureText(
639641

640642
return TextLayoutManager.measureText(
641643
mReactApplicationContext.getAssets(),
644+
ReactTypefaceUtils.getFontWeightAdjustment(mReactApplicationContext),
642645
attributedString,
643646
paragraphAttributes,
644647
getYogaSize(minWidth, maxWidth),
@@ -666,6 +669,7 @@ public PreparedLayout prepareTextLayout(
666669

667670
return TextLayoutManager.createPreparedLayout(
668671
mReactApplicationContext.getAssets(),
672+
ReactTypefaceUtils.getFontWeightAdjustment(mReactApplicationContext),
669673
attributedString,
670674
paragraphAttributes,
671675
getYogaSize(minWidth, maxWidth),

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ public constructor(
158158
val spanned: Spannable =
159159
TextLayoutManager.getOrCreateSpannableForText(
160160
view.context.assets,
161+
ReactTypefaceUtils.getFontWeightAdjustment(view.context),
161162
attributedString,
162163
reactTextViewManagerCallback,
163164
TextEffectRegistry.current,

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,22 @@
77

88
package com.facebook.react.views.text
99

10+
import android.content.Context
11+
import android.content.res.Configuration
1012
import android.content.res.AssetManager
1113
import android.graphics.Typeface
14+
import android.os.Build
1215
import com.facebook.react.bridge.ReadableArray
1316
import com.facebook.react.common.ReactConstants
1417
import com.facebook.react.common.assets.ReactFontManager
18+
import kotlin.math.max
19+
import kotlin.math.min
1520

1621
public object ReactTypefaceUtils {
1722

23+
private const val FONT_WEIGHT_MIN = 1
24+
private const val FONT_WEIGHT_MAX = 1000
25+
1826
@JvmStatic
1927
public fun parseFontWeight(fontWeightString: String?): Int =
2028
when (fontWeightString) {
@@ -110,4 +118,33 @@ public object ReactTypefaceUtils {
110118
ReactFontManager.getInstance().getTypeface(fontFamilyName, typefaceStyle, assetManager)
111119
}
112120
}
121+
122+
@JvmStatic
123+
public fun getFontWeightAdjustment(context: Context): Int =
124+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
125+
context.resources.configuration.fontWeightAdjustment
126+
} else {
127+
0
128+
}
129+
130+
@JvmStatic
131+
public fun applyFontWeightAdjustment(
132+
typeface: Typeface?,
133+
fontWeightAdjustment: Int,
134+
): Typeface? {
135+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || fontWeightAdjustment == 0) {
136+
return typeface
137+
}
138+
139+
if (fontWeightAdjustment == Configuration.FONT_WEIGHT_ADJUSTMENT_UNDEFINED) {
140+
return typeface
141+
}
142+
143+
val baseTypeface = typeface ?: Typeface.DEFAULT
144+
val adjustedWeight =
145+
min(max(baseTypeface.weight + fontWeightAdjustment, FONT_WEIGHT_MIN), FONT_WEIGHT_MAX)
146+
val italic = baseTypeface.style and Typeface.ITALIC != 0
147+
148+
return Typeface.create(baseTypeface, adjustedWeight, italic)
149+
}
113150
}

0 commit comments

Comments
 (0)