@@ -116,8 +116,8 @@ internal object TextLayoutManager {
116116
117117 private val tagToSpannableCache = ConcurrentHashMap <Int , Spannable >()
118118
119- // Lazily cached methods for showing glyph ink that overhangs the start of a line (API 35+).
120- // Reflection is needed because some internal targets compile against an SDK older than 35 .
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 .
121121 private val setUseBoundsForWidthMethod: java.lang.reflect.Method ? by lazy {
122122 try {
123123 StaticLayout .Builder ::class
@@ -128,6 +128,16 @@ internal object TextLayoutManager {
128128 }
129129 }
130130
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+
131141 private val setShiftDrawingOffsetForStartOverhangMethod: java.lang.reflect.Method ? by lazy {
132142 try {
133143 StaticLayout .Builder ::class
@@ -141,6 +151,19 @@ internal object TextLayoutManager {
141151 }
142152 }
143153
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+
144167 private val computeDrawingBoundingBoxMethod: java.lang.reflect.Method ? by lazy {
145168 try {
146169 Layout ::class .java.getMethod(" computeDrawingBoundingBox" )
@@ -149,6 +172,13 @@ internal object TextLayoutManager {
149172 }
150173 }
151174
175+ private fun computeDrawingBoundingBox (layout : Layout ): RectF ? =
176+ try {
177+ computeDrawingBoundingBoxMethod?.invoke(layout) as ? RectF
178+ } catch (_: ReflectiveOperationException ) {
179+ null
180+ }
181+
152182 fun setCachedSpannableForTag (reactTag : Int , sp : Spannable ) {
153183 tagToSpannableCache[reactTag] = sp
154184 }
@@ -919,12 +949,7 @@ internal object TextLayoutManager {
919949 return 0
920950 }
921951
922- val drawingBounds =
923- try {
924- computeDrawingBoundingBoxMethod?.invoke(layout) as ? RectF
925- } catch (_: ReflectiveOperationException ) {
926- null
927- } ? : return 0
952+ val drawingBounds = computeDrawingBoundingBox(layout) ? : return 0
928953
929954 return ceil(drawingBounds.right - layout.width).toInt().coerceAtLeast(0 )
930955 }
@@ -966,8 +991,8 @@ internal object TextLayoutManager {
966991 // right, so createLayout reserves that space in a second pass while preserving the EXACT Yoga
967992 // measurement returned to the caller.
968993 if (Build .VERSION .SDK_INT >= VERSION_CODE_VANILLA_ICE_CREAM ) {
969- setUseBoundsForWidthMethod?.invoke (builder, enableStartOverhang)
970- setShiftDrawingOffsetForStartOverhangMethod?.invoke (builder, enableStartOverhang)
994+ setUseBoundsForWidth (builder, enableStartOverhang)
995+ setShiftDrawingOffsetForStartOverhang (builder, enableStartOverhang)
971996 }
972997
973998 return builder.build()
0 commit comments