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
This commit is contained in:
Joe Vilches
2025-04-14 13:57:54 -07:00
committed by Facebook GitHub Bot
parent ab7ef77120
commit 0929697a6d
@@ -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 ->