Skip to content

Commit

Permalink
Nullable borderRadius optimization on shadows and outline
Browse files Browse the repository at this point in the history
Differential Revision: D63798853
  • Loading branch information
jorge-cab authored and facebook-github-bot committed Oct 3, 2024
1 parent bb71bb3 commit 85e8e17
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,17 @@ public object BackgroundStyleApplicator {
): Unit {
ensureCSSBackground(view).setBorderRadius(corner, radius)
val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view)
compositeBackgroundDrawable.borderRadius =
compositeBackgroundDrawable.borderRadius ?: BorderRadiusStyle()
compositeBackgroundDrawable.borderRadius?.set(corner, radius)

if (Build.VERSION.SDK_INT >= MIN_OUTSET_BOX_SHADOW_SDK_VERSION) {
val outerShadows = compositeBackgroundDrawable.outerShadows
if (outerShadows != null) {
for (i in 0 until outerShadows.numberOfLayers) {
val shadow = outerShadows.getDrawable(i)
if (shadow is OutsetBoxShadowDrawable) {
shadow.borderRadius = shadow.borderRadius ?: BorderRadiusStyle()
shadow.borderRadius?.set(corner, radius)
shadow.borderRadius = compositeBackgroundDrawable.borderRadius
shadow.invalidateSelf()
}
}
Expand All @@ -130,20 +132,15 @@ public object BackgroundStyleApplicator {
for (i in 0 until innerShadows.numberOfLayers) {
val shadow = innerShadows.getDrawable(i)
if (shadow is InsetBoxShadowDrawable) {
shadow.borderRadius = shadow.borderRadius ?: BorderRadiusStyle()
shadow.borderRadius?.set(corner, radius)
shadow.borderRadius = compositeBackgroundDrawable.borderRadius
shadow.invalidateSelf()
}
}
}
}

val outline = compositeBackgroundDrawable.outline
if (outline != null) {
outline.borderRadius = outline.borderRadius ?: BorderRadiusStyle()
outline.borderRadius?.set(corner, radius)
outline.invalidateSelf()
}
compositeBackgroundDrawable.outline?.borderRadius = compositeBackgroundDrawable.borderRadius
compositeBackgroundDrawable.outline?.invalidateSelf()
}

@JvmStatic
Expand Down Expand Up @@ -219,7 +216,9 @@ public object BackgroundStyleApplicator {
var innerShadows: LayerDrawable? = null
var outerShadows: LayerDrawable? = null

val borderInsets = ensureCompositeBackgroundDrawable(view).borderInsets
val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view)
val borderInsets = compositeBackgroundDrawable.borderInsets
val borderRadius = compositeBackgroundDrawable.borderRadius

for (boxShadow in shadows.asReversed()) {
val offsetX = boxShadow.offsetX
Expand All @@ -236,7 +235,7 @@ public object BackgroundStyleApplicator {
innerShadows.addLayer(
InsetBoxShadowDrawable(
context = view.context,
borderRadius = ensureCSSBackground(view).borderRadius,
borderRadius = borderRadius,
borderInsets = borderInsets,
shadowColor = color,
offsetX = offsetX,
Expand All @@ -250,7 +249,7 @@ public object BackgroundStyleApplicator {
outerShadows.addLayer(
OutsetBoxShadowDrawable(
context = view.context,
borderRadius = ensureCSSBackground(view).borderRadius,
borderRadius = borderRadius,
shadowColor = color,
offsetX = offsetX,
offsetY = offsetY,
Expand Down Expand Up @@ -347,7 +346,7 @@ public object BackgroundStyleApplicator {
outline =
OutlineDrawable(
context = view.context,
borderRadius = ensureCSSBackground(view).borderRadius.copy(),
borderRadius = compositeBackgroundDrawable.borderRadius,
outlineColor = Color.BLACK,
outlineOffset = 0f,
outlineStyle = OutlineStyle.SOLID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.uimanager.style.BorderInsets
import com.facebook.react.uimanager.style.BorderRadiusStyle

/**
* CompositeBackgroundDrawable can overlay multiple different layers, shadows, and native effects
Expand Down Expand Up @@ -58,6 +59,8 @@ internal class CompositeBackgroundDrawable(
.toTypedArray()) {
// Holder value for currently set insets
public var borderInsets: BorderInsets? = null
// Holder value for currently set border radius
public var borderRadius: BorderRadiusStyle? = null

init {
// We want to overlay drawables, instead of placing future drawables within the content area of
Expand All @@ -70,24 +73,55 @@ internal class CompositeBackgroundDrawable(
cssBackground: CSSBackgroundDrawable?
): CompositeBackgroundDrawable {
return CompositeBackgroundDrawable(
originalBackground, outerShadows, cssBackground, feedbackUnderlay, innerShadows, outline)
originalBackground,
outerShadows,
cssBackground,
feedbackUnderlay,
innerShadows,
outline)
.apply {
borderInsets = this@CompositeBackgroundDrawable.borderInsets
borderRadius = this@CompositeBackgroundDrawable.borderRadius
}
}

public fun withNewShadows(
outerShadows: LayerDrawable?,
innerShadows: LayerDrawable?
): CompositeBackgroundDrawable {
return CompositeBackgroundDrawable(
originalBackground, outerShadows, cssBackground, feedbackUnderlay, innerShadows, outline)
originalBackground,
outerShadows,
cssBackground,
feedbackUnderlay,
innerShadows,
outline)
.apply {
borderInsets = this@CompositeBackgroundDrawable.borderInsets
borderRadius = this@CompositeBackgroundDrawable.borderRadius
}
}

public fun withNewOutline(outline: OutlineDrawable): CompositeBackgroundDrawable {
return CompositeBackgroundDrawable(
originalBackground, outerShadows, cssBackground, feedbackUnderlay, innerShadows, outline)
originalBackground,
outerShadows,
cssBackground,
feedbackUnderlay,
innerShadows,
outline)
.apply {
borderInsets = this@CompositeBackgroundDrawable.borderInsets
borderRadius = this@CompositeBackgroundDrawable.borderRadius
}
}

public fun withNewFeedbackUnderlay(newUnderlay: Drawable?): CompositeBackgroundDrawable {
return CompositeBackgroundDrawable(
originalBackground, outerShadows, cssBackground, newUnderlay, innerShadows, outline)
originalBackground, outerShadows, cssBackground, newUnderlay, innerShadows, outline)
.apply {
borderInsets = this@CompositeBackgroundDrawable.borderInsets
borderRadius = this@CompositeBackgroundDrawable.borderRadius
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,14 @@ private val ZERO_RADII = floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f)
@RequiresApi(MIN_INSET_BOX_SHADOW_SDK_VERSION)
internal class InsetBoxShadowDrawable(
private val context: Context,
borderRadius: BorderRadiusStyle? = null,
borderInsets: BorderInsets? = null,
private val shadowColor: Int,
private val offsetX: Float,
private val offsetY: Float,
private val blurRadius: Float,
private val spread: Float,
var borderRadius: BorderRadiusStyle? = null,
var borderInsets: BorderInsets? = null,
) : Drawable() {
public var borderRadius = borderRadius
set(value) {
if (value != field) {
field = value
invalidateSelf()
}
}

public var borderInsets = borderInsets
set(value) {
if (value != field) {
field = value
invalidateSelf()
}
}

private val shadowPaint =
Paint().apply {
color = shadowColor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,11 @@ import com.facebook.react.uimanager.style.ComputedBorderRadius
import com.facebook.react.uimanager.style.CornerRadii
import com.facebook.react.uimanager.style.OutlineStyle
import kotlin.math.roundToInt
import kotlin.properties.ObservableProperty
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

/** Draws outline https://drafts.csswg.org/css-ui/#outline */
internal class OutlineDrawable(
private val context: Context,
borderRadius: BorderRadiusStyle? = null,
var borderRadius: BorderRadiusStyle? = null,
outlineColor: Int,
outlineOffset: Float,
outlineStyle: OutlineStyle,
Expand All @@ -43,17 +40,14 @@ internal class OutlineDrawable(
*/
private val gapBetweenPaths = 0.8f

private fun <T> invalidatingChange(initialValue: T): ReadWriteProperty<Any?, T> =
object : ObservableProperty<T>(initialValue) {
override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) {
if (oldValue != newValue) {
invalidateSelf()
}
}
public var outlineOffset: Float = outlineOffset
set(value) {
if (value != field) {
field = value
invalidateSelf()
}
}

public var borderRadius: BorderRadiusStyle? by invalidatingChange(borderRadius)
public var outlineOffset: Float by invalidatingChange(outlineOffset)
public var outlineStyle: OutlineStyle = outlineStyle
set(value) {
if (value != field) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,13 @@ private const val BLUR_RADIUS_SIGMA_SCALE = 0.5f
@RequiresApi(MIN_OUTSET_BOX_SHADOW_SDK_VERSION)
internal class OutsetBoxShadowDrawable(
private val context: Context,
borderRadius: BorderRadiusStyle? = null,
var borderRadius: BorderRadiusStyle? = null,
private val shadowColor: Int,
private val offsetX: Float,
private val offsetY: Float,
private val blurRadius: Float,
private val spread: Float,
) : Drawable() {
public var borderRadius = borderRadius
set(value) {
if (value != field) {
field = value
invalidateSelf()
}
}

private val shadowPaint =
Paint().apply {
color = shadowColor
Expand Down

0 comments on commit 85e8e17

Please sign in to comment.