diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.kt index 154062b966d5..6253b10db5d0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTypefaceUtils.kt @@ -179,6 +179,10 @@ public object ReactTypefaceUtils { } try { + // Paint skips unchanged settings even after setTypeface, so clear them first. + if (paint.fontVariationSettings != null) { + paint.setFontVariationSettings(null) + } paint.setFontVariationSettings(fontVariationSettings) } catch (exception: IllegalArgumentException) { // Paint instances are reused, so explicitly clear axes from a previous layout. diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt index e27330c87149..6b51c8067f99 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt @@ -689,6 +689,10 @@ public open class ReactEditText public constructor(context: Context) : AppCompat val newTypeface = applyStyles(typeface, fontStyle, fontWeight, fontFamily, context.assets) typeface = newTypeface if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // TextView skips unchanged settings even after a typeface change, so clear them first. + if (fontVariationSettings != null) { + super.setFontVariationSettings(null) + } super.setFontVariationSettings(parsedFontVariationSettings) } diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerFontWeightAdjustmentTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerFontWeightAdjustmentTest.kt index 9b7454b1e0b0..b2df8cfd4c0e 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerFontWeightAdjustmentTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerFontWeightAdjustmentTest.kt @@ -24,6 +24,7 @@ import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.inOrder import org.mockito.kotlin.mock +import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.robolectric.RobolectricTestRunner @@ -127,6 +128,55 @@ class TextLayoutManagerFontWeightAdjustmentTest { verify(paint).setFontVariationSettings(null) } + @Test + fun `reused paint re-applies unchanged font variation settings to a new typeface`() { + val paint = mock() + whenever(paint.fontVariationSettings).thenReturn("'wght' 600") + + ReactTypefaceUtils.applyFontVariationSettings(paint, "'wght' 600") + + inOrder(paint) { + verify(paint).setFontVariationSettings(null) + verify(paint).setFontVariationSettings("'wght' 600") + } + } + + @Test + fun `fresh paint applies font variation settings without clearing first`() { + val paint = mock() + whenever(paint.fontVariationSettings).thenReturn(null) + + ReactTypefaceUtils.applyFontVariationSettings(paint, "'wght' 600") + + verify(paint).setFontVariationSettings("'wght' 600") + verify(paint, never()).setFontVariationSettings(null) + } + + @Test + fun `scratch text paint re-applies font variation settings on repeated measurement`() { + val paint = mock() + whenever(paint.fontVariationSettings).thenReturn("'wght' 600") + val textAttributes = + TextAttributeProps.fromReadableMap( + ReactStylesDiffMap( + JavaOnlyMap.of("fontWeight", "600", "fontVariationSettings", "'wght' 600"), + ), + ) + + TextLayoutManager.updateTextPaint( + paint, + textAttributes, + RuntimeEnvironment.getApplication().assets, + 0, + ) + + inOrder(paint) { + verify(paint).setTypeface(any()) + verify(paint).setFontVariationSettings(null) + verify(paint).setFontVariationSettings("'wght' 600") + } + } + private companion object { const val FONT_WEIGHT_ADJUSTMENT_BOLD_TEXT = 300 }