Skip to content

Commit 1f5f086

Browse files
committed
fix(android): measure inline text views in dp
1 parent 40c90ad commit 1f5f086

2 files changed

Lines changed: 71 additions & 5 deletions

File tree

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,15 @@ internal object TextLayoutManager {
264264
val reactTag =
265265
if (fragment.contains(FR_KEY_REACT_TAG)) fragment.getInt(FR_KEY_REACT_TAG) else View.NO_ID
266266
if (fragment.contains(FR_KEY_IS_ATTACHMENT) && fragment.getBoolean(FR_KEY_IS_ATTACHMENT)) {
267-
val width = PixelUtil.toPixelFromSP(fragment.getDouble(FR_KEY_WIDTH))
268-
val height = PixelUtil.toPixelFromSP(fragment.getDouble(FR_KEY_HEIGHT))
269267
ops.add(
270268
SetSpanOperation(
271269
sb.length - 1,
272270
sb.length,
273-
TextInlineViewPlaceholderSpan(reactTag, width.toInt(), height.toInt()),
271+
TextInlineViewPlaceholderSpan(
272+
reactTag,
273+
inlineViewSizeToPixels(fragment.getDouble(FR_KEY_WIDTH)),
274+
inlineViewSizeToPixels(fragment.getDouble(FR_KEY_HEIGHT)),
275+
),
274276
)
275277
)
276278
} else if (end >= start) {
@@ -484,8 +486,8 @@ internal object TextLayoutManager {
484486
spannable.setSpan(
485487
TextInlineViewPlaceholderSpan(
486488
fragment.reactTag,
487-
PixelUtil.toPixelFromSP(fragment.width).toInt(),
488-
PixelUtil.toPixelFromSP(fragment.height).toInt(),
489+
inlineViewSizeToPixels(fragment.width),
490+
inlineViewSizeToPixels(fragment.height),
489491
),
490492
start,
491493
end,
@@ -649,6 +651,9 @@ internal object TextLayoutManager {
649651
return spannable
650652
}
651653

654+
private fun inlineViewSizeToPixels(size: Double): Int =
655+
ceil(PixelUtil.toPixelFromDIP(size).toDouble()).toInt()
656+
652657
@OptIn(UnstableReactNativeAPI::class)
653658
fun getOrCreateSpannableForText(
654659
assets: AssetManager,
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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(invokeInlineViewSizeToPixels(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(invokeInlineViewSizeToPixels(132.1)).isEqualTo(133)
50+
}
51+
52+
private fun invokeInlineViewSizeToPixels(size: Double): Int {
53+
val method =
54+
TextLayoutManager::class
55+
.java
56+
.getDeclaredMethod("inlineViewSizeToPixels", java.lang.Double.TYPE)
57+
.apply { isAccessible = true }
58+
59+
return method.invoke(TextLayoutManager, size) as Int
60+
}
61+
}

0 commit comments

Comments
 (0)