From 63c34a822a58ec728d623faae23f26b8aa12cc3f Mon Sep 17 00:00:00 2001 From: Andrew Ghostuhin Date: Tue, 9 Jun 2026 02:34:15 +0300 Subject: [PATCH] fix: account for Android font weight adjustment in text measurement --- .../react/fabric/FabricUIManager.java | 4 + .../react/views/text/ReactTextViewManager.kt | 1 + .../react/views/text/ReactTypefaceUtils.kt | 37 +++++ .../react/views/text/TextLayoutManager.kt | 147 +++++++++++++++++- .../text/internal/span/CustomStyleSpan.kt | 26 +++- .../react/views/textinput/ReactEditText.kt | 10 +- .../views/textinput/ReactTextInputManager.kt | 2 + ...xtLayoutManagerFontWeightAdjustmentTest.kt | 92 +++++++++++ 8 files changed, 309 insertions(+), 10 deletions(-) create mode 100644 packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerFontWeightAdjustmentTest.kt diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index ee64131ab18..6bc5d8f60f6 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -93,6 +93,7 @@ import com.facebook.react.views.text.PreparedLayout; import com.facebook.react.views.text.ReactTextViewManager; import com.facebook.react.views.text.ReactTextViewManagerCallback; +import com.facebook.react.views.text.ReactTypefaceUtils; import com.facebook.react.views.text.TextEffectRegistry; import com.facebook.react.views.text.TextLayoutManager; import java.util.ArrayList; @@ -553,6 +554,7 @@ private NativeArray measureLines( return (NativeArray) TextLayoutManager.measureLines( mReactApplicationContext.getAssets(), + ReactTypefaceUtils.getFontWeightAdjustment(mReactApplicationContext), attributedString, paragraphAttributes, PixelUtil.toPixelFromDIP(width), @@ -639,6 +641,7 @@ public long measureText( return TextLayoutManager.measureText( mReactApplicationContext.getAssets(), + ReactTypefaceUtils.getFontWeightAdjustment(mReactApplicationContext), attributedString, paragraphAttributes, getYogaSize(minWidth, maxWidth), @@ -666,6 +669,7 @@ public PreparedLayout prepareTextLayout( return TextLayoutManager.createPreparedLayout( mReactApplicationContext.getAssets(), + ReactTypefaceUtils.getFontWeightAdjustment(mReactApplicationContext), attributedString, paragraphAttributes, getYogaSize(minWidth, maxWidth), diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.kt index bc420d79c67..2d06fcdab42 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.kt @@ -158,6 +158,7 @@ public constructor( val spanned: Spannable = TextLayoutManager.getOrCreateSpannableForText( view.context.assets, + ReactTypefaceUtils.getFontWeightAdjustment(view.context), attributedString, reactTextViewManagerCallback, TextEffectRegistry.current, 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 e33daa691f3..fbdcd298611 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 @@ -7,14 +7,22 @@ package com.facebook.react.views.text +import android.content.Context +import android.content.res.Configuration import android.content.res.AssetManager import android.graphics.Typeface +import android.os.Build import com.facebook.react.bridge.ReadableArray import com.facebook.react.common.ReactConstants import com.facebook.react.common.assets.ReactFontManager +import kotlin.math.max +import kotlin.math.min public object ReactTypefaceUtils { + private const val FONT_WEIGHT_MIN = 1 + private const val FONT_WEIGHT_MAX = 1000 + @JvmStatic public fun parseFontWeight(fontWeightString: String?): Int = when (fontWeightString) { @@ -110,4 +118,33 @@ public object ReactTypefaceUtils { ReactFontManager.getInstance().getTypeface(fontFamilyName, typefaceStyle, assetManager) } } + + @JvmStatic + public fun getFontWeightAdjustment(context: Context): Int = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + context.resources.configuration.fontWeightAdjustment + } else { + 0 + } + + @JvmStatic + public fun applyFontWeightAdjustment( + typeface: Typeface?, + fontWeightAdjustment: Int, + ): Typeface? { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || fontWeightAdjustment == 0) { + return typeface + } + + if (fontWeightAdjustment == Configuration.FONT_WEIGHT_ADJUSTMENT_UNDEFINED) { + return typeface + } + + val baseTypeface = typeface ?: Typeface.DEFAULT + val adjustedWeight = + min(max(baseTypeface.weight + fontWeightAdjustment, FONT_WEIGHT_MIN), FONT_WEIGHT_MAX) + val italic = baseTypeface.style and Typeface.ITALIC != 0 + + return Typeface.create(baseTypeface, adjustedWeight, italic) + } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt index 4a900ffcf71..e40f00e9f6e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt @@ -238,6 +238,7 @@ internal object TextLayoutManager { @OptIn(UnstableReactNativeAPI::class) private fun buildSpannableFromFragments( assets: AssetManager, + fontWeightAdjustment: Int, fragments: MapBuffer, sb: SpannableStringBuilder, ops: MutableList, @@ -323,6 +324,7 @@ internal object TextLayoutManager { textAttributes.fontFeatureSettings, textAttributes.fontFamily, assets, + fontWeightAdjustment, ), ) ) @@ -426,6 +428,7 @@ internal object TextLayoutManager { @OptIn(UnstableReactNativeAPI::class) private fun buildSpannableFromFragmentsOptimized( assets: AssetManager, + fontWeightAdjustment: Int, fragments: MapBuffer, outputReactTags: IntArray?, textEffectRegistry: TextEffectRegistry?, @@ -552,6 +555,7 @@ internal object TextLayoutManager { fragment.props.fontFeatureSettings, fragment.props.fontFamily, assets, + fontWeightAdjustment, ), start, end, @@ -657,9 +661,40 @@ internal object TextLayoutManager { ): Spannable = getOrCreateSpannableForText(assets, attributedString, reactTextViewManagerCallback, null) + @OptIn(UnstableReactNativeAPI::class) + fun getOrCreateSpannableForText( + assets: AssetManager, + fontWeightAdjustment: Int, + attributedString: MapBuffer, + reactTextViewManagerCallback: ReactTextViewManagerCallback?, + ): Spannable = + getOrCreateSpannableForText( + assets, + fontWeightAdjustment, + attributedString, + reactTextViewManagerCallback, + null, + ) + + @OptIn(UnstableReactNativeAPI::class) + internal fun getOrCreateSpannableForText( + assets: AssetManager, + attributedString: MapBuffer, + reactTextViewManagerCallback: ReactTextViewManagerCallback?, + textEffectRegistry: TextEffectRegistry?, + ): Spannable = + getOrCreateSpannableForText( + assets, + 0, + attributedString, + reactTextViewManagerCallback, + textEffectRegistry, + ) + @OptIn(UnstableReactNativeAPI::class) internal fun getOrCreateSpannableForText( assets: AssetManager, + fontWeightAdjustment: Int, attributedString: MapBuffer, reactTextViewManagerCallback: ReactTextViewManagerCallback?, textEffectRegistry: TextEffectRegistry?, @@ -672,6 +707,7 @@ internal object TextLayoutManager { text = createSpannableFromAttributedString( assets, + fontWeightAdjustment, attributedString.getMapBuffer(AS_KEY_FRAGMENTS), reactTextViewManagerCallback, null, @@ -685,6 +721,7 @@ internal object TextLayoutManager { @OptIn(UnstableReactNativeAPI::class) private fun createSpannableFromAttributedString( assets: AssetManager, + fontWeightAdjustment: Int, fragments: MapBuffer, reactTextViewManagerCallback: ReactTextViewManagerCallback?, outputReactTags: IntArray?, @@ -694,6 +731,7 @@ internal object TextLayoutManager { val spannable = buildSpannableFromFragmentsOptimized( assets, + fontWeightAdjustment, fragments, outputReactTags, textEffectRegistry, @@ -709,7 +747,15 @@ internal object TextLayoutManager { // a new spannable will be wiped out val ops: MutableList = ArrayList() - buildSpannableFromFragments(assets, fragments, sb, ops, outputReactTags, textEffectRegistry) + buildSpannableFromFragments( + assets, + fontWeightAdjustment, + fragments, + sb, + ops, + outputReactTags, + textEffectRegistry, + ) // TODO T31905686: add support for inline Images // While setting the Spans on the final text, we also check whether any of them are images. @@ -829,6 +875,7 @@ internal object TextLayoutManager { paint: TextPaint, baseTextAttributes: TextAttributeProps, assets: AssetManager, + fontWeightAdjustment: Int, ) { if (baseTextAttributes.fontSize != ReactConstants.UNSET) { paint.textSize = baseTextAttributes.fontSize.toFloat() @@ -847,7 +894,7 @@ internal object TextLayoutManager { baseTextAttributes.fontFamily, assets, ) - paint.setTypeface(typeface) + paint.setTypeface(ReactTypefaceUtils.applyFontWeightAdjustment(typeface, fontWeightAdjustment)) if ( baseTextAttributes.fontStyle != ReactConstants.UNSET && @@ -858,6 +905,8 @@ internal object TextLayoutManager { paint.isFakeBoldText = missingStyle and Typeface.BOLD != 0 paint.textSkewX = if ((missingStyle and Typeface.ITALIC) != 0) -0.25f else 0f } + } else { + paint.setTypeface(ReactTypefaceUtils.applyFontWeightAdjustment(null, fontWeightAdjustment)) } } @@ -868,28 +917,31 @@ internal object TextLayoutManager { private fun scratchPaintWithAttributes( baseTextAttributes: TextAttributeProps, assets: AssetManager, + fontWeightAdjustment: Int, ): TextPaint { val paint = checkNotNull(textPaintInstance.get()) paint.setTypeface(null) paint.textSize = 12f paint.isFakeBoldText = false paint.textSkewX = 0f - updateTextPaint(paint, baseTextAttributes, assets) + updateTextPaint(paint, baseTextAttributes, assets, fontWeightAdjustment) return paint } private fun newPaintWithAttributes( baseTextAttributes: TextAttributeProps, assets: AssetManager, + fontWeightAdjustment: Int, ): TextPaint { val paint = TextPaint(TextPaint.ANTI_ALIAS_FLAG) - updateTextPaint(paint, baseTextAttributes, assets) + updateTextPaint(paint, baseTextAttributes, assets, fontWeightAdjustment) return paint } @OptIn(UnstableReactNativeAPI::class) private fun createLayoutForMeasurement( assets: AssetManager, + fontWeightAdjustment: Int, attributedString: MapBuffer, paragraphAttributes: MapBuffer, width: Float, @@ -902,6 +954,7 @@ internal object TextLayoutManager { val text = getOrCreateSpannableForText( assets, + fontWeightAdjustment, attributedString, reactTextViewManagerCallback, textEffectRegistry, @@ -913,7 +966,7 @@ internal object TextLayoutManager { } else { val baseTextAttributes = TextAttributeProps.fromMapBuffer(attributedString.getMapBuffer(AS_KEY_BASE_ATTRIBUTES)) - paint = scratchPaintWithAttributes(baseTextAttributes, assets) + paint = scratchPaintWithAttributes(baseTextAttributes, assets, fontWeightAdjustment) } return createLayout( @@ -1028,12 +1081,40 @@ internal object TextLayoutManager { heightYogaMeasureMode: YogaMeasureMode, reactTextViewManagerCallback: ReactTextViewManagerCallback?, textEffectRegistry: TextEffectRegistry? = null, + ): PreparedLayout = + createPreparedLayout( + assets, + 0, + attributedString, + paragraphAttributes, + width, + widthYogaMeasureMode, + height, + heightYogaMeasureMode, + reactTextViewManagerCallback, + textEffectRegistry, + ) + + @JvmStatic + @OptIn(UnstableReactNativeAPI::class) + fun createPreparedLayout( + assets: AssetManager, + fontWeightAdjustment: Int, + attributedString: ReadableMapBuffer, + paragraphAttributes: ReadableMapBuffer, + width: Float, + widthYogaMeasureMode: YogaMeasureMode, + height: Float, + heightYogaMeasureMode: YogaMeasureMode, + reactTextViewManagerCallback: ReactTextViewManagerCallback?, + textEffectRegistry: TextEffectRegistry? = null, ): PreparedLayout { val fragments = attributedString.getMapBuffer(AS_KEY_FRAGMENTS) val reactTags = IntArray(fragments.count) val text = createSpannableFromAttributedString( assets, + fontWeightAdjustment, fragments, reactTextViewManagerCallback, reactTags, @@ -1044,7 +1125,7 @@ internal object TextLayoutManager { val result = createLayout( text, - newPaintWithAttributes(baseTextAttributes, assets), + newPaintWithAttributes(baseTextAttributes, assets, fontWeightAdjustment), attributedString, paragraphAttributes, width, @@ -1195,11 +1276,41 @@ internal object TextLayoutManager { reactTextViewManagerCallback: ReactTextViewManagerCallback?, attachmentsPositions: FloatArray?, textEffectRegistry: TextEffectRegistry? = null, + ): Long = + measureText( + assets, + 0, + attributedString, + paragraphAttributes, + width, + widthYogaMeasureMode, + height, + heightYogaMeasureMode, + reactTextViewManagerCallback, + attachmentsPositions, + textEffectRegistry, + ) + + @JvmStatic + @OptIn(UnstableReactNativeAPI::class) + fun measureText( + assets: AssetManager, + fontWeightAdjustment: Int, + attributedString: MapBuffer, + paragraphAttributes: MapBuffer, + width: Float, + widthYogaMeasureMode: YogaMeasureMode, + height: Float, + heightYogaMeasureMode: YogaMeasureMode, + reactTextViewManagerCallback: ReactTextViewManagerCallback?, + attachmentsPositions: FloatArray?, + textEffectRegistry: TextEffectRegistry? = null, ): Long { // TODO(5578671): Handle text direction (see View#getTextDirectionHeuristic) val layout = createLayoutForMeasurement( assets, + fontWeightAdjustment, attributedString, paragraphAttributes, width, @@ -1465,10 +1576,34 @@ internal object TextLayoutManager { height: Float, reactTextViewManagerCallback: ReactTextViewManagerCallback?, textEffectRegistry: TextEffectRegistry? = null, + ): WritableArray = + measureLines( + assetManager, + 0, + attributedString, + paragraphAttributes, + width, + height, + reactTextViewManagerCallback, + textEffectRegistry, + ) + + @JvmStatic + @OptIn(UnstableReactNativeAPI::class) + fun measureLines( + assetManager: AssetManager, + fontWeightAdjustment: Int, + attributedString: MapBuffer, + paragraphAttributes: MapBuffer, + width: Float, + height: Float, + reactTextViewManagerCallback: ReactTextViewManagerCallback?, + textEffectRegistry: TextEffectRegistry? = null, ): WritableArray { val layout = createLayoutForMeasurement( assetManager, + fontWeightAdjustment, attributedString, paragraphAttributes, width, diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/CustomStyleSpan.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/CustomStyleSpan.kt index dec85221456..29eb30f1447 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/CustomStyleSpan.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/CustomStyleSpan.kt @@ -33,13 +33,30 @@ internal class CustomStyleSpan( val fontFeatureSettings: String?, val fontFamily: String?, private val assetManager: AssetManager, + private val fontWeightAdjustment: Int = 0, ) : MetricAffectingSpan(), ReactSpan { override fun updateDrawState(ds: TextPaint) { - apply(ds, privateStyle, privateWeight, fontFeatureSettings, fontFamily, assetManager) + apply( + ds, + privateStyle, + privateWeight, + fontFeatureSettings, + fontFamily, + assetManager, + fontWeightAdjustment, + ) } override fun updateMeasureState(paint: TextPaint) { - apply(paint, privateStyle, privateWeight, fontFeatureSettings, fontFamily, assetManager) + apply( + paint, + privateStyle, + privateWeight, + fontFeatureSettings, + fontFamily, + assetManager, + fontWeightAdjustment, + ) } val style: Int @@ -66,12 +83,15 @@ internal class CustomStyleSpan( fontFeatureSettingsParam: String?, family: String?, assetManager: AssetManager, + fontWeightAdjustment: Int, ) { val typeface = ReactTypefaceUtils.applyStyles(paint.typeface, style, weight, family, assetManager) + val adjustedTypeface = + ReactTypefaceUtils.applyFontWeightAdjustment(typeface, fontWeightAdjustment) paint.apply { fontFeatureSettings = fontFeatureSettingsParam - setTypeface(typeface) + setTypeface(adjustedTypeface) isSubpixelText = true isLinearText = true } 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 aae65314509..9e37b9aab24 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 @@ -71,6 +71,7 @@ import com.facebook.react.uimanager.style.LogicalEdge import com.facebook.react.uimanager.style.Overflow import com.facebook.react.views.text.ReactTextUpdate import com.facebook.react.views.text.ReactTypefaceUtils.applyStyles +import com.facebook.react.views.text.ReactTypefaceUtils.getFontWeightAdjustment import com.facebook.react.views.text.ReactTypefaceUtils.parseFontStyle import com.facebook.react.views.text.ReactTypefaceUtils.parseFontWeight import com.facebook.react.views.text.TextAttributes @@ -849,7 +850,14 @@ public open class ReactEditText public constructor(context: Context) : AppCompat fontFeatureSettings != null ) { workingText.setSpan( - CustomStyleSpan(fontStyle, fontWeight, fontFeatureSettings, fontFamily, context.assets), + CustomStyleSpan( + fontStyle, + fontWeight, + fontFeatureSettings, + fontFamily, + context.assets, + getFontWeightAdjustment(context), + ), 0, workingText.length, spanFlags, diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.kt index 9e40dbe5e69..02d20c2af7f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.kt @@ -69,6 +69,7 @@ import com.facebook.react.views.text.DefaultStyleValuesUtil.getDefaultTextColorH import com.facebook.react.views.text.ReactTextUpdate import com.facebook.react.views.text.ReactTextUpdate.Companion.buildReactTextUpdateFromState import com.facebook.react.views.text.ReactTextViewManagerCallback +import com.facebook.react.views.text.ReactTypefaceUtils.getFontWeightAdjustment import com.facebook.react.views.text.ReactTypefaceUtils.parseFontVariant import com.facebook.react.views.text.TextAttributeProps import com.facebook.react.views.text.TextLayoutManager @@ -1016,6 +1017,7 @@ public open class ReactTextInputManager public constructor() : val spanned = TextLayoutManager.getOrCreateSpannableForText( view.context.assets, + getFontWeightAdjustment(view.context), attributedString, reactTextViewManagerCallback, ) 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 new file mode 100644 index 00000000000..9155055d9e7 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerFontWeightAdjustmentTest.kt @@ -0,0 +1,92 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.views.text + +import android.content.res.AssetManager +import android.text.TextPaint +import com.facebook.react.bridge.JavaOnlyMap +import com.facebook.react.uimanager.DisplayMetricsHolder +import com.facebook.react.uimanager.ReactStylesDiffMap +import org.assertj.core.api.Assertions.assertThat +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RuntimeEnvironment +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [34]) +class TextLayoutManagerFontWeightAdjustmentTest { + + @Before + fun setUp() { + DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(RuntimeEnvironment.getApplication()) + } + + @After + fun tearDown() { + DisplayMetricsHolder.setScreenDisplayMetrics(null) + } + + @Test + fun `plain text paint applies Android font weight adjustment`() { + val paint = TextPaint(TextPaint.ANTI_ALIAS_FLAG) + val textAttributes = TextAttributeProps.fromReadableMap(ReactStylesDiffMap(JavaOnlyMap())) + + invokeUpdateTextPaint( + paint, + textAttributes, + RuntimeEnvironment.getApplication().assets, + FONT_WEIGHT_ADJUSTMENT_BOLD_TEXT, + ) + + assertThat(paint.typeface).isNotNull + } + + @Test + fun `plain text paint keeps default typeface unset without font weight adjustment`() { + val paint = TextPaint(TextPaint.ANTI_ALIAS_FLAG) + val textAttributes = TextAttributeProps.fromReadableMap(ReactStylesDiffMap(JavaOnlyMap())) + + invokeUpdateTextPaint( + paint, + textAttributes, + RuntimeEnvironment.getApplication().assets, + 0, + ) + + assertThat(paint.typeface).isNull() + } + + private fun invokeUpdateTextPaint( + paint: TextPaint, + textAttributes: TextAttributeProps, + assets: AssetManager, + fontWeightAdjustment: Int, + ) { + val method = + TextLayoutManager::class + .java + .getDeclaredMethod( + "updateTextPaint", + TextPaint::class.java, + TextAttributeProps::class.java, + AssetManager::class.java, + java.lang.Integer.TYPE, + ) + .apply { isAccessible = true } + + method.invoke(TextLayoutManager, paint, textAttributes, assets, fontWeightAdjustment) + } + + private companion object { + const val FONT_WEIGHT_ADJUSTMENT_BOLD_TEXT = 300 + } +}