From 5cc57f7ce1bfd290fe6a0489a30585b7f5145e48 Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Thu, 20 Aug 2026 13:02:55 +0200 Subject: [PATCH 1/2] Require mobile ^4.2 for the renderer symbols this package already imports --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9ec414c..266a9ab 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ ], "require": { "php": "^8.2", - "nativephp/mobile": "^4.0" + "nativephp/mobile": "^4.2" }, "autoload": { "psr-4": { From fab41d6e2e6f17668362070b52d168151ea0e1ce Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Thu, 20 Aug 2026 13:02:55 +0200 Subject: [PATCH 2/2] Clip images through nodeShape so per-corner radii match containers on Android --- resources/android/ImageRenderer.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/resources/android/ImageRenderer.kt b/resources/android/ImageRenderer.kt index df312a2..27fcf7c 100644 --- a/resources/android/ImageRenderer.kt +++ b/resources/android/ImageRenderer.kt @@ -1,15 +1,14 @@ package com.nativephp.plugins.native_ui.ui -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.nativephp.mobile.ui.nativerender.NativeUINode import com.nativephp.mobile.ui.nativerender.argbToComposeColor +import com.nativephp.mobile.ui.nativerender.nodeShape object ImageRenderer { @Composable @@ -21,10 +20,13 @@ object ImageRenderer { val tintArgb = p.getColor("tint_color", 0) val radius = node.style?.borderRadius ?: 0f - // Images need explicit clip for rounded corners (nodeStyle doesn't clip globally) - val imgModifier = if (radius > 0f) { - modifier.clip(RoundedCornerShape(radius.dp)) - } else modifier + // Images need an explicit clip for rounded corners: nodeStyle shapes the + // background and border but never clips content. `nodeShape` is the same + // helper containers use, so per-corner classes (`rounded-br-none`) land + // on an image exactly as they do on a column. A node carrying only + // per-corner radii has no uniform radius, hence the props check. + val hasCorners = p.has("radius_tl") || radius > 0f + val imgModifier = if (hasCorners) modifier.clip(nodeShape(radius, p)) else modifier if (src.isNotEmpty()) { AsyncImage(