Skip to content

Commit 551d12a

Browse files
TorinAsakurameta-codesync[bot]
authored andcommitted
Fix Android inline Text views with small font scale
Summary: Fixes #50916. Closes torin-asakura/workspace#126. Android inline views inside `<Text>` receive their measured layout size from Fabric as layout units/DIP. TextLayoutManager was converting those attachment dimensions with `PixelUtil.toPixelFromSP(...)`, so a device font scale below 1.0 shrank the inline view placeholder width. In the #50916 RNTester reproducer, a measured `Row cutoff` attachment around 155px became about 132px at `font_scale=0.85`, clipping the rendered text to `Row`. This changes inline text attachment dimensions to use DIP conversion and rounds them up to the pixel grid in both spannable construction paths. ## Changelog: [ANDROID] [FIXED] - Keep inline views inside Text from shrinking with Android system font scale X-link: #57132 Reviewed By: christophpurrer Differential Revision: D108030457 Pulled By: cipolleschi fbshipit-source-id: af68489aed0ee9c39f3a440f07ca9286ff5ed30c
1 parent 2b995be commit 551d12a

2 files changed

Lines changed: 62 additions & 5 deletions

File tree

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,15 @@ internal object TextLayoutManager {
266266
val reactTag =
267267
if (fragment.contains(FR_KEY_REACT_TAG)) fragment.getInt(FR_KEY_REACT_TAG) else View.NO_ID
268268
if (fragment.contains(FR_KEY_IS_ATTACHMENT) && fragment.getBoolean(FR_KEY_IS_ATTACHMENT)) {
269-
val width = PixelUtil.toPixelFromSP(fragment.getDouble(FR_KEY_WIDTH))
270-
val height = PixelUtil.toPixelFromSP(fragment.getDouble(FR_KEY_HEIGHT))
271269
ops.add(
272270
SetSpanOperation(
273271
sb.length - 1,
274272
sb.length,
275-
TextInlineViewPlaceholderSpan(reactTag, width.toInt(), height.toInt()),
273+
TextInlineViewPlaceholderSpan(
274+
reactTag,
275+
inlineViewSizeToPixels(fragment.getDouble(FR_KEY_WIDTH)),
276+
inlineViewSizeToPixels(fragment.getDouble(FR_KEY_HEIGHT)),
277+
),
276278
),
277279
)
278280
} else if (end >= start) {
@@ -490,8 +492,8 @@ internal object TextLayoutManager {
490492
spannable.setSpan(
491493
TextInlineViewPlaceholderSpan(
492494
fragment.reactTag,
493-
PixelUtil.toPixelFromSP(fragment.width).toInt(),
494-
PixelUtil.toPixelFromSP(fragment.height).toInt(),
495+
inlineViewSizeToPixels(fragment.width),
496+
inlineViewSizeToPixels(fragment.height),
495497
),
496498
start,
497499
end,
@@ -658,6 +660,10 @@ internal object TextLayoutManager {
658660
return spannable
659661
}
660662

663+
@VisibleForTesting
664+
internal fun inlineViewSizeToPixels(size: Double): Int =
665+
ceil(PixelUtil.toPixelFromDIP(size).toDouble()).toInt()
666+
661667
@OptIn(UnstableReactNativeAPI::class)
662668
fun getOrCreateSpannableForText(
663669
assets: AssetManager,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
@file:Suppress("DEPRECATION")
9+
10+
package com.facebook.react.views.text
11+
12+
import android.util.DisplayMetrics
13+
import com.facebook.react.uimanager.DisplayMetricsHolder
14+
import org.assertj.core.api.Assertions.assertThat
15+
import org.junit.After
16+
import org.junit.Test
17+
import org.junit.runner.RunWith
18+
import org.robolectric.RobolectricTestRunner
19+
20+
@RunWith(RobolectricTestRunner::class)
21+
class TextLayoutManagerInlineViewSizeTest {
22+
23+
@After
24+
fun tearDown() {
25+
DisplayMetricsHolder.setScreenDisplayMetrics(null)
26+
}
27+
28+
@Test
29+
fun `inline view attachment width does not shrink with small font scale`() {
30+
DisplayMetricsHolder.setScreenDisplayMetrics(
31+
DisplayMetrics().apply {
32+
density = 1f
33+
scaledDensity = 0.85f
34+
},
35+
)
36+
37+
assertThat(TextLayoutManager.inlineViewSizeToPixels(155.0)).isEqualTo(155)
38+
}
39+
40+
@Test
41+
fun `inline view attachment width is rounded up to the pixel grid`() {
42+
DisplayMetricsHolder.setScreenDisplayMetrics(
43+
DisplayMetrics().apply {
44+
density = 1f
45+
scaledDensity = 1f
46+
},
47+
)
48+
49+
assertThat(TextLayoutManager.inlineViewSizeToPixels(132.1)).isEqualTo(133)
50+
}
51+
}

0 commit comments

Comments
 (0)