From 2fb4aa881c39c34b7704672f95db485dc98351ee Mon Sep 17 00:00:00 2001 From: Ryan Linton Date: Thu, 22 Feb 2024 14:37:24 -0700 Subject: [PATCH 1/2] update Android HostPlatformColor to support color longs --- .../renderer/attributedstring/conversions.h | 8 +-- .../react/renderer/core/graphicsConversions.h | 2 +- .../renderer/graphics/HostPlatformColor.h | 55 +++++++++++++++---- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h index 653528f73c65c2..f5705ad6cbb681 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h @@ -1035,11 +1035,11 @@ inline MapBuffer toMapBuffer(const FontVariant& fontVariant) { inline MapBuffer toMapBuffer(const TextAttributes& textAttributes) { auto builder = MapBufferBuilder(); if (textAttributes.foregroundColor) { - builder.putInt( + builder.putLong( TA_KEY_FOREGROUND_COLOR, toAndroidRepr(textAttributes.foregroundColor)); } if (textAttributes.backgroundColor) { - builder.putInt( + builder.putLong( TA_KEY_BACKGROUND_COLOR, toAndroidRepr(textAttributes.backgroundColor)); } if (!std::isnan(textAttributes.opacity)) { @@ -1095,7 +1095,7 @@ inline MapBuffer toMapBuffer(const TextAttributes& textAttributes) { // Decoration if (textAttributes.textDecorationColor) { - builder.putInt( + builder.putLong( TA_KEY_TEXT_DECORATION_COLOR, toAndroidRepr(textAttributes.textDecorationColor)); } @@ -1116,7 +1116,7 @@ inline MapBuffer toMapBuffer(const TextAttributes& textAttributes) { TA_KEY_TEXT_SHADOW_RADIUS, textAttributes.textShadowRadius); } if (textAttributes.textShadowColor) { - builder.putInt( + builder.putLong( TA_KEY_TEXT_SHADOW_COLOR, toAndroidRepr(textAttributes.textShadowColor)); } diff --git a/packages/react-native/ReactCommon/react/renderer/core/graphicsConversions.h b/packages/react-native/ReactCommon/react/renderer/core/graphicsConversions.h index 8e1ff0a04739bc..15eb9f7995e007 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/graphicsConversions.h +++ b/packages/react-native/ReactCommon/react/renderer/core/graphicsConversions.h @@ -34,7 +34,7 @@ inline void fromRawValue( } #ifdef ANDROID -inline int toAndroidRepr(const SharedColor& color) { +inline int64_t toAndroidRepr(const SharedColor& color) { return *color; } inline folly::dynamic toDynamic(const SharedColor& color) { diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/HostPlatformColor.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/HostPlatformColor.h index 0dd7abe08f05d0..f64a632f628347 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/HostPlatformColor.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/HostPlatformColor.h @@ -12,7 +12,7 @@ namespace facebook::react { -using Color = int32_t; +using Color = int64_t; namespace HostPlatformColor { static const facebook::react::Color UndefinedColor = @@ -20,20 +20,51 @@ static const facebook::react::Color UndefinedColor = } inline Color hostPlatformColorFromComponents(ColorComponents components) { - float ratio = 255; - return ((int)round(components.alpha * ratio) & 0xff) << 24 | - ((int)round(components.red * ratio) & 0xff) << 16 | - ((int)round(components.green * ratio) & 0xff) << 8 | - ((int)round(components.blue * ratio) & 0xff); + if (components.colorSpace == ColorSpace::DisplayP3) { + int ratio = 15360; + int red = static_cast(round(components.red * ratio)) & 0xffff; + int green = static_cast(round(components.green * ratio)) & 0xffff; + int blue = static_cast(round(components.blue * ratio)) & 0xffff; + int alpha = static_cast(round(components.alpha * 0x3ff)) & 0x3ff; + int colorSpace = 7; + int64_t androidColor = (static_cast(red) << 48) | + (static_cast(green) << 32) | + (static_cast(blue) << 16) | + (static_cast(alpha) << 6) | + static_cast(colorSpace); + return androidColor; + } else { + int ratio = 255; + int alpha = static_cast(round(components.alpha * ratio)) & 0xff; + int red = static_cast(round(components.red * ratio)) & 0xff; + int green = static_cast(round(components.green * ratio)) & 0xff; + int blue = static_cast(round(components.blue * ratio)) & 0xff; + int64_t androidColor = (static_cast(alpha) << 56) | + (static_cast(red) << 48) | + (static_cast(green) << 40) | + (static_cast(blue) << 32); + return androidColor; + } } inline ColorComponents colorComponentsFromHostPlatformColor(Color color) { - float ratio = 255; - return ColorComponents{ - (float)((color >> 16) & 0xff) / ratio, - (float)((color >> 8) & 0xff) / ratio, - (float)((color >> 0) & 0xff) / ratio, - (float)((color >> 24) & 0xff) / ratio}; + if ((color & 0x3f) == 7) { + int ratio = 15360; + return ColorComponents{ + (float)((color >> 48) & 0xffff) / ratio, + (float)((color >> 32) & 0xffff) / ratio, + (float)((color >> 16) & 0xffff) / ratio, + (float)((color >> 6) & 0x3ff) / ratio, + ColorSpace::DisplayP3}; + } else { + int ratio = 255; + return ColorComponents{ + (float)((color >> 48) & 0xff) / ratio, + (float)((color >> 40) & 0xff) / ratio, + (float)((color >> 32) & 0xff) / ratio, + (float)((color >> 56) & 0xff) / ratio, + ColorSpace::sRGB}; + } } } // namespace facebook::react From 61ea51de1bcf64abe0b3501ef1865067eace926b Mon Sep 17 00:00:00 2001 From: Ryan Linton Date: Wed, 17 Apr 2024 14:42:48 -0600 Subject: [PATCH 2/2] extract magic numbers into documented constants --- .../renderer/graphics/HostPlatformColor.h | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/HostPlatformColor.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/HostPlatformColor.h index f64a632f628347..f54450ff0c7a79 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/HostPlatformColor.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/HostPlatformColor.h @@ -19,26 +19,30 @@ static const facebook::react::Color UndefinedColor = std::numeric_limits::max(); } +// As defined by Android's ColorSpace.Named +constexpr int kDisplayP3ColorSpace = 7; +// DisplayP3 component range per Android's Color longs +constexpr int kDisplayP3Ratio = 15360; +// sRGB component range +constexpr int kSRGBRatio = 255; + inline Color hostPlatformColorFromComponents(ColorComponents components) { if (components.colorSpace == ColorSpace::DisplayP3) { - int ratio = 15360; - int red = static_cast(round(components.red * ratio)) & 0xffff; - int green = static_cast(round(components.green * ratio)) & 0xffff; - int blue = static_cast(round(components.blue * ratio)) & 0xffff; + int red = static_cast(round(components.red * kDisplayP3Ratio)) & 0xffff; + int green = static_cast(round(components.green * kDisplayP3Ratio)) & 0xffff; + int blue = static_cast(round(components.blue * kDisplayP3Ratio)) & 0xffff; int alpha = static_cast(round(components.alpha * 0x3ff)) & 0x3ff; - int colorSpace = 7; int64_t androidColor = (static_cast(red) << 48) | (static_cast(green) << 32) | (static_cast(blue) << 16) | (static_cast(alpha) << 6) | - static_cast(colorSpace); + static_cast(kDisplayP3ColorSpace); return androidColor; } else { - int ratio = 255; - int alpha = static_cast(round(components.alpha * ratio)) & 0xff; - int red = static_cast(round(components.red * ratio)) & 0xff; - int green = static_cast(round(components.green * ratio)) & 0xff; - int blue = static_cast(round(components.blue * ratio)) & 0xff; + int alpha = static_cast(round(components.alpha * kSRGBRatio)) & 0xff; + int red = static_cast(round(components.red * kSRGBRatio)) & 0xff; + int green = static_cast(round(components.green * kSRGBRatio)) & 0xff; + int blue = static_cast(round(components.blue * kSRGBRatio)) & 0xff; int64_t androidColor = (static_cast(alpha) << 56) | (static_cast(red) << 48) | (static_cast(green) << 40) | @@ -48,21 +52,19 @@ inline Color hostPlatformColorFromComponents(ColorComponents components) { } inline ColorComponents colorComponentsFromHostPlatformColor(Color color) { - if ((color & 0x3f) == 7) { - int ratio = 15360; + if ((color & 0x3f) == kDisplayP3ColorSpace) { return ColorComponents{ - (float)((color >> 48) & 0xffff) / ratio, - (float)((color >> 32) & 0xffff) / ratio, - (float)((color >> 16) & 0xffff) / ratio, - (float)((color >> 6) & 0x3ff) / ratio, + (float)((color >> 48) & 0xffff) / kDisplayP3Ratio, + (float)((color >> 32) & 0xffff) / kDisplayP3Ratio, + (float)((color >> 16) & 0xffff) / kDisplayP3Ratio, + (float)((color >> 6) & 0x3ff) / kDisplayP3Ratio, ColorSpace::DisplayP3}; } else { - int ratio = 255; return ColorComponents{ - (float)((color >> 48) & 0xff) / ratio, - (float)((color >> 40) & 0xff) / ratio, - (float)((color >> 32) & 0xff) / ratio, - (float)((color >> 56) & 0xff) / ratio, + (float)((color >> 48) & 0xff) / kSRGBRatio, + (float)((color >> 40) & 0xff) / kSRGBRatio, + (float)((color >> 32) & 0xff) / kSRGBRatio, + (float)((color >> 56) & 0xff) / kSRGBRatio, ColorSpace::sRGB}; } }