Skip to content

Commit 8661085

Browse files
ryanlntnfacebook-github-bot
authored andcommitted
Update ColorPropConverterto support color function values (facebook#43031)
Summary: This adds support for color function values to ColorPropConverter per the wide gamut color [RFC](react-native-community/discussions-and-proposals#738). It updates the color conversion code so that it returns a Color instance before ultimately being converted to an Integer in preparation for returning long values as needed. bypass-github-export-checks ## Changelog: [ANDROID] [ADDED] - Update ColorPropConverter to support color function values Pull Request resolved: facebook#43031 Test Plan: Colors should work exactly the same as before. Follow test steps from facebook#42831 to test support for color() function syntax. While colors specified with color() function syntax will not yet render in DisplayP3 color space they will not be misrecognized as resource path colors but will instead fallback to their sRGB color space values. Differential Revision: D55749058
1 parent d59de54 commit 8661085

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ public class com/facebook/react/bridge/ColorPropConverter {
647647
public fun <init> ()V
648648
public static fun getColor (Ljava/lang/Object;Landroid/content/Context;)Ljava/lang/Integer;
649649
public static fun getColor (Ljava/lang/Object;Landroid/content/Context;I)Ljava/lang/Integer;
650+
public static fun getColorInstance (Ljava/lang/Object;Landroid/content/Context;)Landroid/graphics/Color;
650651
public static fun resolveResourcePath (Landroid/content/Context;Ljava/lang/String;)Ljava/lang/Integer;
651652
}
652653

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ColorPropConverter.java

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99

1010
import android.content.Context;
1111
import android.content.res.Resources;
12+
import android.graphics.Color;
13+
import android.graphics.ColorSpace;
14+
import android.os.Build;
1215
import android.util.TypedValue;
16+
import androidx.annotation.ColorLong;
1317
import androidx.annotation.Nullable;
1418
import androidx.core.content.res.ResourcesCompat;
1519
import com.facebook.common.logging.FLog;
@@ -24,13 +28,17 @@ public class ColorPropConverter {
2428
private static final String ATTR = "attr";
2529
private static final String ATTR_SEGMENT = "attr/";
2630

27-
public static Integer getColor(Object value, Context context) {
31+
private static Boolean apiSupportWideGamut() {
32+
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
33+
}
34+
35+
public static Color getColorInstance(Object value, Context context) {
2836
if (value == null) {
2937
return null;
3038
}
3139

32-
if (value instanceof Double) {
33-
return ((Double) value).intValue();
40+
if (apiSupportWideGamut() && value instanceof Double) {
41+
return Color.valueOf(((Double) value).intValue());
3442
}
3543

3644
if (context == null) {
@@ -39,6 +47,22 @@ public static Integer getColor(Object value, Context context) {
3947

4048
if (value instanceof ReadableMap) {
4149
ReadableMap map = (ReadableMap) value;
50+
51+
// handle color(space r g b a) value
52+
if (apiSupportWideGamut() && map.hasKey("space")) {
53+
String rawColorSpace = map.getString("space");
54+
boolean isDisplayP3 = rawColorSpace.equals("display-p3");
55+
ColorSpace space =
56+
ColorSpace.get(isDisplayP3 ? ColorSpace.Named.DISPLAY_P3 : ColorSpace.Named.SRGB);
57+
float r = (float) map.getDouble("r");
58+
float g = (float) map.getDouble("g");
59+
float b = (float) map.getDouble("b");
60+
float a = (float) map.getDouble("a");
61+
62+
@ColorLong long color = Color.pack(r, g, b, a, space);
63+
return Color.valueOf(color);
64+
}
65+
4266
ReadableArray resourcePaths = map.getArray(JSON_KEY);
4367

4468
if (resourcePaths == null) {
@@ -48,8 +72,8 @@ public static Integer getColor(Object value, Context context) {
4872

4973
for (int i = 0; i < resourcePaths.size(); i++) {
5074
Integer result = resolveResourcePath(context, resourcePaths.getString(i));
51-
if (result != null) {
52-
return result;
75+
if (apiSupportWideGamut() && result != null) {
76+
return Color.valueOf(result);
5377
}
5478
}
5579

@@ -63,6 +87,17 @@ public static Integer getColor(Object value, Context context) {
6387
"ColorValue: the value must be a number or Object.");
6488
}
6589

90+
public static Integer getColor(Object value, Context context) {
91+
Color color = getColorInstance(value, context);
92+
if (color == null) {
93+
return null;
94+
}
95+
if (apiSupportWideGamut()) {
96+
return color.toArgb();
97+
}
98+
return null;
99+
}
100+
66101
public static Integer getColor(Object value, Context context, int defaultInt) {
67102
try {
68103
return getColor(value, context);
@@ -89,8 +124,9 @@ public static Integer resolveResourcePath(Context context, @Nullable String reso
89124
return resolveThemeAttribute(context, resourcePath);
90125
}
91126
} catch (Resources.NotFoundException exception) {
92-
// The resource could not be found so do nothing to allow the for loop to continue and
93-
// try the next fallback resource in the array. If none of the fallbacks are
127+
// The resource could not be found so do nothing to allow the for loop to
128+
// continue and
129+
// try the next fallback resource in the array. If none of the fallbacks are
94130
// found then the exception immediately after the for loop will be thrown.
95131
}
96132
return null;

0 commit comments

Comments
 (0)