From 0929697a6df9ab5a3654c0077bb95427eae77b4c Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Mon, 14 Apr 2025 13:57:54 -0700 Subject: [PATCH] Fix some edge cases with box shadow (#50638) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/50638 There were two issues with inset shadows here that I fixed * If spread was big enough it would "invert" the clear region. [RectF's inset](https://developer.android.com/reference/android/graphics/RectF#inset(float,%20float)) method does not bound to a 0x0 rect, it will instead start making the rect bigger if the inset value is large enough. * If the clear region was outside the rect the shadow disappeared. This is because [Canvas's drawDoubleRoundRect](https://developer.android.com/reference/android/graphics/Canvas#drawDoubleRoundRect(android.graphics.RectF,%20float[],%20android.graphics.RectF,%20float[],%20android.graphics.Paint)) will fail to draw if the inner rect is not completely inside of the outer. Changelog: [Android][Fixed] - Fix inset shadow edge cases Reviewed By: GijsWeterings Differential Revision: D72833275 fbshipit-source-id: 3f42fb767630319c51a380f8ea28d682df9771a6 --- .../uimanager/drawable/InsetBoxShadowDrawable.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/InsetBoxShadowDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/InsetBoxShadowDrawable.kt index b0de93e69cd..38fc219b85a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/InsetBoxShadowDrawable.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/InsetBoxShadowDrawable.kt @@ -109,7 +109,11 @@ internal class InsetBoxShadowDrawable( val spreadExtent = spread.dpToPx() val innerRect = RectF(paddingBoxRect).apply { - inset(spreadExtent, spreadExtent) + if (2 * spreadExtent > paddingBoxRect.width()) { + setEmpty() + } else { + inset(spreadExtent, spreadExtent) + } offset(x, y) } @@ -117,12 +121,10 @@ internal class InsetBoxShadowDrawable( // https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/paint/box_painter_base.cc;l=338;drc=0a301506035e13015ea5c8dd39164d0d5954fa60 val blurExtent = FilterHelper.sigmaToRadius(blurRadius) val outerRect = - RectF(paddingBoxRect).apply { + RectF(innerRect).apply { + set(paddingBoxRect) inset(-blurExtent, -blurExtent) - if (spreadExtent < 0) { - inset(spreadExtent, spreadExtent) - } - union(RectF(this).apply { offset(-x, -y) }) + union(RectF(innerRect)) } canvas.save().let { saveCount ->