Skip to content

Commit bb8b045

Browse files
author
Kamil Paradowski
committed
feat(android): storing computed margin and padding information
1 parent 81c2ec8 commit bb8b045

16 files changed

Lines changed: 498 additions & 217 deletions

File tree

‎packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,16 @@ public Map<String, Long> getPerformanceCounters() {
13341334
return performanceCounters;
13351335
}
13361336

1337+
@Nullable
1338+
public float[] getComputedMarginInsets(int surfaceId, int viewTag) {
1339+
return mBinding != null ? mBinding.getComputedMarginInsets(surfaceId, viewTag) : null;
1340+
}
1341+
1342+
@Nullable
1343+
public float[] getComputedPaddingInsets(int surfaceId, int viewTag) {
1344+
return mBinding != null ? mBinding.getComputedPaddingInsets(surfaceId, viewTag) : null;
1345+
}
1346+
13371347
private class MountItemDispatchListener implements MountItemDispatcher.ItemDispatchListener {
13381348
@UiThread
13391349
@ThreadConfined(UI)

‎packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManagerBinding.kt‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ internal class FabricUIManagerBinding : HybridClassBase() {
8383

8484
external fun reportMount(surfaceId: Int)
8585

86+
external fun getComputedMarginInsets(surfaceId: Int, viewTag: Int): FloatArray?
87+
88+
external fun getComputedPaddingInsets(surfaceId: Int, viewTag: Int): FloatArray?
89+
8690
fun register(
8791
runtimeExecutor: RuntimeExecutor,
8892
runtimeScheduler: RuntimeScheduler,

‎packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt‎

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -486,32 +486,35 @@ public object BackgroundStyleApplicator {
486486
@JvmStatic
487487
public fun applyClipPathIfPresent(view: View, canvas: Canvas) {
488488
val clipPath = getClipPath(view) ?: return
489-
val bounds = getGeometryBoxBounds(view, clipPath.geometryBox, getComputedBorderInsets(view))
489+
val composite = getCompositeBackgroundDrawable(view)
490+
val computedMarginInsets = UIManagerHelper.getComputedMarginInsets(view)
491+
val computedPaddingInsets = UIManagerHelper.getComputedPaddingInsets(view)
492+
val computedBorderInsets =
493+
composite?.borderInsets?.resolve(composite.layoutDirection, view.context)
494+
val bounds = getGeometryBoxBounds(
495+
view,
496+
clipPath.geometryBox,
497+
computedMarginInsets,
498+
computedPaddingInsets,
499+
computedBorderInsets
500+
)
490501
val drawingRect = Rect()
491502
view.getDrawingRect(drawingRect)
492503
bounds.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat())
493504

494505
val path: Path? = if (clipPath.shape != null) {
495506
ClipPathUtils.createPathFromBasicShape(clipPath.shape, bounds)
496507
} else if (clipPath.geometryBox != null) {
497-
val composite = getCompositeBackgroundDrawable(view)
498508
val borderRadius = composite?.borderRadius
499-
val computedBorderInsets =
500-
composite?.borderInsets?.resolve(composite.layoutDirection, view.context)
501-
502509
if (borderRadius != null) {
503510
val adjustedBorderRadius = GeometryBoxUtil.adjustBorderRadiusForGeometryBox(
504-
clipPath.geometryBox,
505-
borderRadius.resolve(
511+
view, clipPath.geometryBox, borderRadius.resolve(
506512
composite.layoutDirection,
507513
view.context,
508514
PixelUtil.toDIPFromPixel(drawingRect.width().toFloat()),
509515
PixelUtil.toDIPFromPixel(drawingRect.height().toFloat())
510-
),
511-
computedBorderInsets,
512-
view
516+
), computedMarginInsets, computedPaddingInsets, computedBorderInsets
513517
)
514-
515518
if (adjustedBorderRadius != null) {
516519
ClipPathUtils.createRoundedRectPath(bounds, adjustedBorderRadius)
517520
} else {

‎packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.kt‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ package com.facebook.react.uimanager
1111

1212
import android.content.Context
1313
import android.content.ContextWrapper
14+
import android.graphics.RectF
1415
import android.view.View
1516
import android.widget.EditText
1617
import androidx.core.view.ViewCompat
@@ -247,4 +248,35 @@ public object UIManagerHelper {
247248
padding[PADDING_BOTTOM_INDEX] = PixelUtil.toDIPFromPixel(editText.paddingBottom.toFloat())
248249
return padding
249250
}
251+
252+
@JvmStatic
253+
public fun getComputedMarginInsets(view: View): RectF? =
254+
getComputedLayoutMetrics(view) { uiManager, surfaceId, viewTag ->
255+
uiManager.getComputedMarginInsets(surfaceId, viewTag)
256+
}
257+
258+
@JvmStatic
259+
public fun getComputedPaddingInsets(view: View): RectF? =
260+
getComputedLayoutMetrics(view) { uiManager, surfaceId, viewTag ->
261+
uiManager.getComputedPaddingInsets(surfaceId, viewTag)
262+
}
263+
264+
private inline fun getComputedLayoutMetrics(
265+
view: View,
266+
getter: (com.facebook.react.fabric.FabricUIManager, Int, Int) -> FloatArray?
267+
): RectF? {
268+
val viewTag = view.id
269+
if (viewTag == View.NO_ID || getUIManagerType(viewTag) != UIManagerType.FABRIC) {
270+
return null
271+
}
272+
273+
val context = view.context as? ThemedReactContext ?: return null
274+
val surfaceId = getSurfaceId(context)
275+
val uiManager = getUIManager(
276+
context.reactApplicationContext,
277+
UIManagerType.FABRIC
278+
) as? com.facebook.react.fabric.FabricUIManager ?: return null
279+
val array = getter(uiManager, surfaceId, viewTag) ?: return null
280+
return RectF(array[0], array[1], array[2], array[3])
281+
}
250282
}

‎packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/ClipPathUtils.kt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,10 @@ internal object ClipPathUtils {
198198
public fun createRoundedRectPath(bounds: RectF, borderRadius: ComputedBorderRadius): Path {
199199
val path = Path()
200200

201-
val topLeftRadii = borderRadius.topLeft
202-
val topRightRadii = borderRadius.topRight
203-
val bottomRightRadii = borderRadius.bottomRight
204-
val bottomLeftRadii = borderRadius.bottomLeft
201+
val topLeftRadii = borderRadius.topLeft.toPixelFromDIP()
202+
val topRightRadii = borderRadius.topRight.toPixelFromDIP()
203+
val bottomRightRadii = borderRadius.bottomRight.toPixelFromDIP()
204+
val bottomLeftRadii = borderRadius.bottomLeft.toPixelFromDIP()
205205

206206
val radii = floatArrayOf(
207207
topLeftRadii.horizontal, topLeftRadii.vertical,

0 commit comments

Comments
 (0)