Skip to content

Commit fc7ca37

Browse files
Dark Knightfacebook-github-bot
authored andcommitted
Revert D122079801
Summary: Reverts #58719 Changelog: [Internal] Reviewed By: Abbondanzo Differential Revision: D122273888
1 parent eaa9d7f commit fc7ca37

1 file changed

Lines changed: 70 additions & 5 deletions

File tree

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

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package com.facebook.react.views.text
99

1010
import android.content.res.AssetManager
1111
import android.graphics.Color
12+
import android.graphics.RectF
1213
import android.graphics.Typeface
1314
import android.os.Build
1415
import android.text.BoringLayout
@@ -41,6 +42,7 @@ import com.facebook.react.uimanager.PixelUtil
4142
import com.facebook.react.uimanager.PixelUtil.dpToPx
4243
import com.facebook.react.uimanager.PixelUtil.pxToDp
4344
import com.facebook.react.uimanager.ReactAccessibilityDelegate
45+
import com.facebook.react.util.AndroidVersion.VERSION_CODE_VANILLA_ICE_CREAM
4446
import com.facebook.react.views.text.internal.span.CustomLetterSpacingSpan
4547
import com.facebook.react.views.text.internal.span.CustomLineHeightSpan
4648
import com.facebook.react.views.text.internal.span.CustomStyleSpan
@@ -114,6 +116,69 @@ internal object TextLayoutManager {
114116

115117
private val tagToSpannableCache = ConcurrentHashMap<Int, Spannable>()
116118

119+
// These wrappers mirror Android 15 APIs but use reflection because some internal targets still
120+
// compile against Android 14. They return null when the API is unavailable or cannot be invoked.
121+
private val setUseBoundsForWidthMethod: java.lang.reflect.Method? by lazy {
122+
try {
123+
StaticLayout.Builder::class
124+
.java
125+
.getMethod("setUseBoundsForWidth", Boolean::class.javaPrimitiveType)
126+
} catch (_: ReflectiveOperationException) {
127+
null
128+
}
129+
}
130+
131+
private fun setUseBoundsForWidth(
132+
builder: StaticLayout.Builder,
133+
useBoundsForWidth: Boolean,
134+
): StaticLayout.Builder? =
135+
try {
136+
setUseBoundsForWidthMethod?.invoke(builder, useBoundsForWidth) as? StaticLayout.Builder
137+
} catch (_: ReflectiveOperationException) {
138+
null
139+
}
140+
141+
private val setShiftDrawingOffsetForStartOverhangMethod: java.lang.reflect.Method? by lazy {
142+
try {
143+
StaticLayout.Builder::class
144+
.java
145+
.getMethod(
146+
"setShiftDrawingOffsetForStartOverhang",
147+
Boolean::class.javaPrimitiveType,
148+
)
149+
} catch (_: ReflectiveOperationException) {
150+
null
151+
}
152+
}
153+
154+
private fun setShiftDrawingOffsetForStartOverhang(
155+
builder: StaticLayout.Builder,
156+
shiftDrawingOffsetForStartOverhang: Boolean,
157+
): StaticLayout.Builder? =
158+
try {
159+
setShiftDrawingOffsetForStartOverhangMethod?.invoke(
160+
builder,
161+
shiftDrawingOffsetForStartOverhang,
162+
) as? StaticLayout.Builder
163+
} catch (_: ReflectiveOperationException) {
164+
null
165+
}
166+
167+
private val computeDrawingBoundingBoxMethod: java.lang.reflect.Method? by lazy {
168+
try {
169+
Layout::class.java.getMethod("computeDrawingBoundingBox")
170+
} catch (_: ReflectiveOperationException) {
171+
null
172+
}
173+
}
174+
175+
private fun computeDrawingBoundingBox(layout: Layout): RectF? =
176+
try {
177+
computeDrawingBoundingBoxMethod?.invoke(layout) as? RectF
178+
} catch (_: ReflectiveOperationException) {
179+
null
180+
}
181+
117182
fun setCachedSpannableForTag(reactTag: Int, sp: Spannable) {
118183
tagToSpannableCache[reactTag] = sp
119184
}
@@ -875,7 +940,7 @@ internal object TextLayoutManager {
875940
@VisibleForTesting
876941
internal fun getRtlRightOverhang(layout: Layout): Int {
877942
if (
878-
Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM ||
943+
Build.VERSION.SDK_INT < VERSION_CODE_VANILLA_ICE_CREAM ||
879944
layout.lineCount == 0 ||
880945
(0 until layout.lineCount).any {
881946
layout.getParagraphDirection(it) != Layout.DIR_RIGHT_TO_LEFT
@@ -884,7 +949,7 @@ internal object TextLayoutManager {
884949
return 0
885950
}
886951

887-
val drawingBounds = layout.computeDrawingBoundingBox()
952+
val drawingBounds = computeDrawingBoundingBox(layout) ?: return 0
888953

889954
return ceil(drawingBounds.right - layout.width).toInt().coerceAtLeast(0)
890955
}
@@ -925,9 +990,9 @@ internal object TextLayoutManager {
925990
// Android shifts negative (left-side) start overhang itself. RTL start overhang is on the
926991
// right, so createLayout reserves that space in a second pass while preserving the EXACT Yoga
927992
// measurement returned to the caller.
928-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
929-
builder.setUseBoundsForWidth(enableStartOverhang)
930-
builder.setShiftDrawingOffsetForStartOverhang(enableStartOverhang)
993+
if (Build.VERSION.SDK_INT >= VERSION_CODE_VANILLA_ICE_CREAM) {
994+
setUseBoundsForWidth(builder, enableStartOverhang)
995+
setShiftDrawingOffsetForStartOverhang(builder, enableStartOverhang)
931996
}
932997

933998
return builder.build()

0 commit comments

Comments
 (0)