diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 94336f09c0924a..118fb0dc62b660 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -647,6 +647,7 @@ public class com/facebook/react/bridge/ColorPropConverter { public fun ()V public static fun getColor (Ljava/lang/Object;Landroid/content/Context;)Ljava/lang/Integer; public static fun getColor (Ljava/lang/Object;Landroid/content/Context;I)Ljava/lang/Integer; + public static fun getColorInstance (Ljava/lang/Object;Landroid/content/Context;)Landroid/graphics/Color; public static fun resolveResourcePath (Landroid/content/Context;Ljava/lang/String;)Ljava/lang/Integer; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ColorPropConverter.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ColorPropConverter.java index afc690dedaabbf..3c0491e07aef06 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ColorPropConverter.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ColorPropConverter.java @@ -9,7 +9,11 @@ import android.content.Context; import android.content.res.Resources; +import android.graphics.Color; +import android.graphics.ColorSpace; +import android.os.Build; import android.util.TypedValue; +import androidx.annotation.ColorLong; import androidx.annotation.Nullable; import androidx.core.content.res.ResourcesCompat; import com.facebook.common.logging.FLog; @@ -24,13 +28,17 @@ public class ColorPropConverter { private static final String ATTR = "attr"; private static final String ATTR_SEGMENT = "attr/"; - public static Integer getColor(Object value, Context context) { + private static Boolean apiSupportWideGamut() { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; + } + + public static Color getColorInstance(Object value, Context context) { if (value == null) { return null; } - if (value instanceof Double) { - return ((Double) value).intValue(); + if (apiSupportWideGamut() && value instanceof Double) { + return Color.valueOf(((Double) value).intValue()); } if (context == null) { @@ -39,6 +47,22 @@ public static Integer getColor(Object value, Context context) { if (value instanceof ReadableMap) { ReadableMap map = (ReadableMap) value; + + // handle color(space r g b a) value + if (apiSupportWideGamut() && map.hasKey("space")) { + String rawColorSpace = map.getString("space"); + boolean isDisplayP3 = rawColorSpace.equals("display-p3"); + ColorSpace space = + ColorSpace.get(isDisplayP3 ? ColorSpace.Named.DISPLAY_P3 : ColorSpace.Named.SRGB); + float r = (float) map.getDouble("r"); + float g = (float) map.getDouble("g"); + float b = (float) map.getDouble("b"); + float a = (float) map.getDouble("a"); + + @ColorLong long color = Color.pack(r, g, b, a, space); + return Color.valueOf(color); + } + ReadableArray resourcePaths = map.getArray(JSON_KEY); if (resourcePaths == null) { @@ -48,8 +72,8 @@ public static Integer getColor(Object value, Context context) { for (int i = 0; i < resourcePaths.size(); i++) { Integer result = resolveResourcePath(context, resourcePaths.getString(i)); - if (result != null) { - return result; + if (apiSupportWideGamut() && result != null) { + return Color.valueOf(result); } } @@ -63,6 +87,17 @@ public static Integer getColor(Object value, Context context) { "ColorValue: the value must be a number or Object."); } + public static Integer getColor(Object value, Context context) { + Color color = getColorInstance(value, context); + if (color == null) { + return null; + } + if (apiSupportWideGamut()) { + return color.toArgb(); + } + return null; + } + public static Integer getColor(Object value, Context context, int defaultInt) { try { return getColor(value, context); @@ -89,8 +124,9 @@ public static Integer resolveResourcePath(Context context, @Nullable String reso return resolveThemeAttribute(context, resourcePath); } } catch (Resources.NotFoundException exception) { - // The resource could not be found so do nothing to allow the for loop to continue and - // try the next fallback resource in the array. If none of the fallbacks are + // The resource could not be found so do nothing to allow the for loop to + // continue and + // try the next fallback resource in the array. If none of the fallbacks are // found then the exception immediately after the for loop will be thrown. } return null;