diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 75a785ba1f8..1862b3f64bf 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -4491,7 +4491,11 @@ public class com/facebook/react/uimanager/OnLayoutEvent : com/facebook/react/uim public final class com/facebook/react/uimanager/PixelUtil { public static final field INSTANCE Lcom/facebook/react/uimanager/PixelUtil; + public final fun dpToPx (D)F + public final fun dpToPx (F)F public static final fun getDisplayMetricDensity ()F + public final fun pxToDp (D)F + public final fun pxToDp (F)F public static final fun toDIPFromPixel (F)F public static final fun toPixelFromDIP (D)F public static final fun toPixelFromDIP (F)F diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/LayoutMetricsConversions.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/LayoutMetricsConversions.kt index 2bffc5b6945..18def1f5e0a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/LayoutMetricsConversions.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/LayoutMetricsConversions.kt @@ -8,7 +8,7 @@ package com.facebook.react.fabric.mounting import android.view.View.MeasureSpec -import com.facebook.react.uimanager.PixelUtil +import com.facebook.react.uimanager.PixelUtil.dpToPx import com.facebook.yoga.YogaMeasureMode public interface LayoutMetricsConversions { @@ -33,11 +33,11 @@ public interface LayoutMetricsConversions { @JvmStatic public fun getYogaSize(minSize: Float, maxSize: Float): Float = if (minSize == maxSize) { - PixelUtil.toPixelFromDIP(maxSize) + maxSize.dpToPx() } else if (maxSize.isInfinite()) { Float.POSITIVE_INFINITY } else { - PixelUtil.toPixelFromDIP(maxSize) + maxSize.dpToPx() } @JvmStatic diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt index fd4e4520d34..adf081aae0d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt @@ -16,6 +16,8 @@ import android.view.View import androidx.annotation.ColorInt import com.facebook.react.bridge.ReadableArray import com.facebook.react.common.annotations.UnstableReactNativeAPI +import com.facebook.react.uimanager.PixelUtil.dpToPx +import com.facebook.react.uimanager.PixelUtil.pxToDp import com.facebook.react.uimanager.common.UIManagerType import com.facebook.react.uimanager.common.ViewUtil import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable @@ -55,8 +57,7 @@ public object BackgroundStyleApplicator { @JvmStatic public fun setBorderWidth(view: View, edge: LogicalEdge, width: Float?): Unit { - ensureCSSBackground(view) - .setBorderWidth(edge.toSpacingType(), PixelUtil.toPixelFromDIP(width ?: Float.NaN)) + ensureCSSBackground(view).setBorderWidth(edge.toSpacingType(), width?.dpToPx() ?: Float.NaN) if (Build.VERSION.SDK_INT >= MIN_INSET_BOX_SHADOW_SDK_VERSION) { val composite = ensureCompositeBackgroundDrawable(view) @@ -73,7 +74,7 @@ public object BackgroundStyleApplicator { @JvmStatic public fun getBorderWidth(view: View, edge: LogicalEdge): Float? { val width = getCSSBackground(view)?.getBorderWidth(edge.toSpacingType()) - return if (width == null || width.isNaN()) null else PixelUtil.toDIPFromPixel((width)) + return if (width == null || width.isNaN()) null else width.pxToDp() } @JvmStatic diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/FilterHelper.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/FilterHelper.kt index 954b14b61b9..f313110db65 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/FilterHelper.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/FilterHelper.kt @@ -17,6 +17,7 @@ import android.graphics.RenderEffect import android.graphics.Shader import com.facebook.react.bridge.ReadableArray import com.facebook.react.bridge.ReadableMap +import com.facebook.react.uimanager.PixelUtil.dpToPx import kotlin.math.cos import kotlin.math.sin @@ -179,8 +180,8 @@ internal object FilterHelper { filterValues: ReadableMap, chainedEffects: RenderEffect? = null ): RenderEffect { - val offsetX: Float = PixelUtil.toPixelFromDIP(filterValues.getDouble("offsetX").toFloat()) - val offsetY: Float = PixelUtil.toPixelFromDIP(filterValues.getDouble("offsetY").toFloat()) + val offsetX: Float = filterValues.getDouble("offsetX").dpToPx() + val offsetY: Float = filterValues.getDouble("offsetY").dpToPx() val color: Int = if (filterValues.hasKey("color")) filterValues.getInt("color") else Color.BLACK val radius: Float = if (filterValues.hasKey("standardDeviation")) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.kt index 3d379268e8e..75e398cf40d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.kt @@ -67,4 +67,13 @@ public object PixelUtil { @JvmStatic public fun getDisplayMetricDensity(): Float = DisplayMetricsHolder.getWindowDisplayMetrics().density + + /* Kotlin extensions */ + public fun Float.dpToPx(): Float = PixelUtil.toPixelFromDIP(this) + + public fun Double.dpToPx(): Float = PixelUtil.toPixelFromDIP(this) + + public fun Float.pxToDp(): Float = PixelUtil.toDIPFromPixel(this) + + public fun Double.pxToDp(): Float = PixelUtil.toDIPFromPixel(this.toFloat()) } 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 1f7aa5e3f01..44d0cbe4000 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 @@ -18,7 +18,8 @@ import android.graphics.RectF import android.graphics.drawable.Drawable import androidx.annotation.RequiresApi import com.facebook.react.uimanager.FilterHelper -import com.facebook.react.uimanager.PixelUtil +import com.facebook.react.uimanager.PixelUtil.dpToPx +import com.facebook.react.uimanager.PixelUtil.pxToDp import com.facebook.react.uimanager.style.BorderInsets import com.facebook.react.uimanager.style.BorderRadiusStyle import com.facebook.react.uimanager.style.ComputedBorderRadius @@ -109,9 +110,9 @@ internal class InsetBoxShadowDrawable( innerRadius(it.bottomLeft.vertical, computedBorderInsets?.bottom)) } - val x = PixelUtil.toPixelFromDIP(offsetX) - val y = PixelUtil.toPixelFromDIP(offsetY) - val spreadExtent = PixelUtil.toPixelFromDIP(spread) + val x = offsetX.dpToPx() + val y = offsetY.dpToPx() + val spreadExtent = spread.dpToPx() val innerRect = RectF(paddingBoxRect).apply { inset(spreadExtent, spreadExtent) @@ -153,27 +154,27 @@ internal class InsetBoxShadowDrawable( borderRadius?.resolve( layoutDirection, context, - PixelUtil.toDIPFromPixel(bounds.width().toFloat()), - PixelUtil.toDIPFromPixel(bounds.height().toFloat())) + bounds.width().toFloat().pxToDp(), + bounds.height().toFloat().pxToDp()) return if (resolvedBorderRadii?.hasRoundedBorders() == true) { ComputedBorderRadius( topLeft = CornerRadii( - PixelUtil.toPixelFromDIP(resolvedBorderRadii.topLeft.horizontal), - PixelUtil.toPixelFromDIP(resolvedBorderRadii.topLeft.vertical)), + resolvedBorderRadii.topLeft.horizontal.dpToPx(), + resolvedBorderRadii.topLeft.vertical.dpToPx()), topRight = CornerRadii( - PixelUtil.toPixelFromDIP(resolvedBorderRadii.topRight.horizontal), - PixelUtil.toPixelFromDIP(resolvedBorderRadii.topRight.vertical)), + resolvedBorderRadii.topRight.horizontal.dpToPx(), + resolvedBorderRadii.topRight.vertical.dpToPx()), bottomLeft = CornerRadii( - PixelUtil.toPixelFromDIP(resolvedBorderRadii.bottomLeft.horizontal), - PixelUtil.toPixelFromDIP(resolvedBorderRadii.bottomLeft.vertical)), + resolvedBorderRadii.bottomLeft.horizontal.dpToPx(), + resolvedBorderRadii.bottomLeft.vertical.dpToPx()), bottomRight = CornerRadii( - PixelUtil.toPixelFromDIP(resolvedBorderRadii.bottomRight.horizontal), - PixelUtil.toPixelFromDIP(resolvedBorderRadii.bottomRight.vertical)), + resolvedBorderRadii.bottomRight.horizontal.dpToPx(), + resolvedBorderRadii.bottomRight.vertical.dpToPx()), ) } else { null @@ -182,11 +183,7 @@ internal class InsetBoxShadowDrawable( private fun computeBorderInsets(): RectF? = borderInsets?.resolve(layoutDirection, context)?.let { - RectF( - PixelUtil.toPixelFromDIP(it.left), - PixelUtil.toPixelFromDIP(it.top), - PixelUtil.toPixelFromDIP(it.right), - PixelUtil.toPixelFromDIP(it.bottom)) + RectF(it.left.dpToPx(), it.top.dpToPx(), it.right.dpToPx(), it.bottom.dpToPx()) } private fun innerRadius(radius: Float, borderInset: Float?): Float = diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutsetBoxShadowDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutsetBoxShadowDrawable.kt index cfa798a8d1c..2bbb82f2b2f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutsetBoxShadowDrawable.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutsetBoxShadowDrawable.kt @@ -18,7 +18,8 @@ import android.graphics.RectF import android.graphics.drawable.Drawable import androidx.annotation.RequiresApi import com.facebook.react.uimanager.FilterHelper -import com.facebook.react.uimanager.PixelUtil +import com.facebook.react.uimanager.PixelUtil.dpToPx +import com.facebook.react.uimanager.PixelUtil.pxToDp import com.facebook.react.uimanager.style.BorderRadiusStyle import com.facebook.react.uimanager.style.ComputedBorderRadius import com.facebook.react.uimanager.style.CornerRadii @@ -75,35 +76,26 @@ internal class OutsetBoxShadowDrawable( ((shadowPaint.alpha / 255f) / (Color.alpha(shadowColor) / 255f) * 255f).roundToInt() override fun draw(canvas: Canvas) { - val resolutionWidth = PixelUtil.toDIPFromPixel(bounds.width().toFloat()) - val resolutionHeight = PixelUtil.toDIPFromPixel(bounds.height().toFloat()) + val resolutionWidth = bounds.width().toFloat().pxToDp() + val resolutionHeight = bounds.height().toFloat().pxToDp() val computedBorderRadii = borderRadius?.resolve(layoutDirection, context, resolutionWidth, resolutionHeight)?.let { ComputedBorderRadius( - topLeft = - CornerRadii( - PixelUtil.toPixelFromDIP(it.topLeft.horizontal), - PixelUtil.toPixelFromDIP(it.topLeft.vertical)), + topLeft = CornerRadii(it.topLeft.horizontal.dpToPx(), it.topLeft.vertical.dpToPx()), topRight = - CornerRadii( - PixelUtil.toPixelFromDIP(it.topRight.horizontal), - PixelUtil.toPixelFromDIP(it.topRight.vertical)), + CornerRadii(it.topRight.horizontal.dpToPx(), it.topRight.vertical.dpToPx()), bottomLeft = - CornerRadii( - PixelUtil.toPixelFromDIP(it.bottomLeft.horizontal), - PixelUtil.toPixelFromDIP(it.bottomLeft.vertical)), + CornerRadii(it.bottomLeft.horizontal.dpToPx(), it.bottomLeft.vertical.dpToPx()), bottomRight = - CornerRadii( - PixelUtil.toPixelFromDIP(it.bottomRight.horizontal), - PixelUtil.toPixelFromDIP(it.bottomRight.vertical)), + CornerRadii(it.bottomRight.horizontal.dpToPx(), it.bottomRight.vertical.dpToPx()), ) } - val spreadExtent = PixelUtil.toPixelFromDIP(spread) + val spreadExtent = spread.dpToPx() val shadowRect = RectF(bounds).apply { inset(-spreadExtent, -spreadExtent) - offset(PixelUtil.toPixelFromDIP(offsetX), PixelUtil.toPixelFromDIP(offsetY)) + offset(offsetX.dpToPx(), offsetY.dpToPx()) } canvas.save().let { saveCount -> diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager.kt index cb4e0a0482f..80abf619cc8 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/debuggingoverlay/DebuggingOverlayManager.kt @@ -14,7 +14,7 @@ import com.facebook.react.bridge.ReactSoftExceptionLogger import com.facebook.react.bridge.ReadableArray import com.facebook.react.bridge.UnexpectedNativeTypeException import com.facebook.react.module.annotations.ReactModule -import com.facebook.react.uimanager.PixelUtil +import com.facebook.react.uimanager.PixelUtil.dpToPx import com.facebook.react.uimanager.SimpleViewManager import com.facebook.react.uimanager.ThemedReactContext @@ -53,12 +53,7 @@ public class DebuggingOverlayManager : SimpleViewManager() { val right = (left + serializedRectangle.getDouble("width")).toFloat() val bottom = (top + serializedRectangle.getDouble("height")).toFloat() - val rectangle = - RectF( - PixelUtil.toPixelFromDIP(left), - PixelUtil.toPixelFromDIP(top), - PixelUtil.toPixelFromDIP(right), - PixelUtil.toPixelFromDIP(bottom)) + val rectangle = RectF(left.dpToPx(), top.dpToPx(), right.dpToPx(), bottom.dpToPx()) formattedTraceUpdates.add(TraceUpdate(id, rectangle, color)) } catch (ex: Exception) { @@ -98,12 +93,7 @@ public class DebuggingOverlayManager : SimpleViewManager() { val top = element.getDouble("y").toFloat() val right = (left + element.getDouble("width")).toFloat() val bottom = (top + element.getDouble("height")).toFloat() - val rect = - RectF( - PixelUtil.toPixelFromDIP(left), - PixelUtil.toPixelFromDIP(top), - PixelUtil.toPixelFromDIP(right), - PixelUtil.toPixelFromDIP(bottom)) + val rect = RectF(left.dpToPx(), top.dpToPx(), right.dpToPx(), bottom.dpToPx()) elementsRectangles.add(rect) } catch (ex: Exception) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.kt index da51d08186f..e277dc9ad8d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.kt @@ -18,7 +18,7 @@ import com.facebook.react.bridge.ReadableArray import com.facebook.react.bridge.ReadableType import com.facebook.react.common.ReactConstants import com.facebook.react.module.annotations.ReactModule -import com.facebook.react.uimanager.PixelUtil.toPixelFromDIP +import com.facebook.react.uimanager.PixelUtil.dpToPx import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.UIManagerHelper import com.facebook.react.uimanager.ViewGroupManager @@ -103,18 +103,13 @@ public class ReactDrawerLayoutManager : if (width.isNaN()) { ReactDrawerLayout.DEFAULT_DRAWER_WIDTH } else { - Math.round(toPixelFromDIP(width)) + Math.round(width.dpToPx()) } view.setDrawerWidth(widthInPx) } public override fun setDrawerWidth(view: ReactDrawerLayout, width: Float?) { - val widthInPx = - if (width == null) { - ReactDrawerLayout.DEFAULT_DRAWER_WIDTH - } else { - Math.round(toPixelFromDIP(width)) - } + val widthInPx = width?.let { Math.round(it.dpToPx()) } ?: ReactDrawerLayout.DEFAULT_DRAWER_WIDTH view.setDrawerWidth(widthInPx) } @@ -146,7 +141,7 @@ public class ReactDrawerLayoutManager : public override fun setStatusBarBackgroundColor(view: ReactDrawerLayout, value: Int?): Unit = Unit public override fun setElevation(view: ReactDrawerLayout, elevation: Float) { - view.drawerElevation = toPixelFromDIP(elevation) + view.drawerElevation = elevation.dpToPx() } public override fun needsCustomLayoutForChildren(): Boolean { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.kt index 204d4ce4bbd..dd5691fe380 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.kt @@ -21,7 +21,7 @@ import com.facebook.react.module.annotations.ReactModule import com.facebook.react.uimanager.BackgroundStyleApplicator import com.facebook.react.uimanager.LengthPercentage import com.facebook.react.uimanager.LengthPercentageType -import com.facebook.react.uimanager.PixelUtil.toPixelFromDIP +import com.facebook.react.uimanager.PixelUtil.dpToPx import com.facebook.react.uimanager.SimpleViewManager import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.ViewProps @@ -188,7 +188,7 @@ public constructor( } else { val convertedBorderRadius = if (!borderRadius.isNaN()) { - toPixelFromDIP(borderRadius) + borderRadius.dpToPx() } else { borderRadius } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt index b32a9ca4e30..e68fe4bd138 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt @@ -57,8 +57,8 @@ import com.facebook.react.uimanager.BackgroundStyleApplicator import com.facebook.react.uimanager.FloatUtil.floatsEqual import com.facebook.react.uimanager.LengthPercentage import com.facebook.react.uimanager.LengthPercentageType -import com.facebook.react.uimanager.PixelUtil.toDIPFromPixel -import com.facebook.react.uimanager.PixelUtil.toPixelFromDIP +import com.facebook.react.uimanager.PixelUtil.dpToPx +import com.facebook.react.uimanager.PixelUtil.pxToDp import com.facebook.react.uimanager.Spacing import com.facebook.react.uimanager.UIManagerHelper import com.facebook.react.uimanager.style.BorderRadiusProp @@ -202,7 +202,7 @@ public class ReactImageView( public fun setBlurRadius(blurRadius: Float) { // Divide `blurRadius` by 2 to more closely match other platforms. - val pixelBlurRadius = toPixelFromDIP(blurRadius).toInt() / 2 + val pixelBlurRadius = blurRadius.dpToPx().toInt() / 2 iterativeBoxBlurPostProcessor = if (pixelBlurRadius == 0) { null @@ -243,7 +243,7 @@ public class ReactImageView( } public fun setBorderWidth(borderWidth: Float) { - val newBorderWidth = toPixelFromDIP(borderWidth) + val newBorderWidth = borderWidth.dpToPx() if (enableBackgroundStyleApplicator()) { BackgroundStyleApplicator.setBorderWidth(this, LogicalEdge.ALL, borderWidth) } else if (useNewReactImageViewBackgroundDrawing()) { @@ -258,7 +258,7 @@ public class ReactImageView( if (enableBackgroundStyleApplicator()) { val radius = if (borderRadius.isNaN()) null - else LengthPercentage(toDIPFromPixel(borderRadius), LengthPercentageType.POINT) + else LengthPercentage(borderRadius.pxToDp(), LengthPercentageType.POINT) BackgroundStyleApplicator.setBorderRadius(this, BorderRadiusProp.BORDER_RADIUS, radius) } else if (useNewReactImageViewBackgroundDrawing()) { reactBackgroundManager.setBorderRadius(borderRadius) @@ -272,7 +272,7 @@ public class ReactImageView( if (enableBackgroundStyleApplicator()) { val radius = if (borderRadius.isNaN()) null - else LengthPercentage(toDIPFromPixel(borderRadius), LengthPercentageType.POINT) + else LengthPercentage(borderRadius.pxToDp(), LengthPercentageType.POINT) BackgroundStyleApplicator.setBorderRadius(this, BorderRadiusProp.values()[position], radius) } else if (useNewReactImageViewBackgroundDrawing()) { reactBackgroundManager.setBorderRadius(borderRadius, position + 1)