From a298fe29d2d82c21cf9bd87fca134ecaf5632966 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Mon, 24 Jun 2024 07:58:11 -0700 Subject: [PATCH] Create util functions to convert Color <-> uint8_t RGBA values Summary: ## Changelog Sometimes we pass down int RGBA values in [0, 255] to represent color components in ReactNative; and other times we use float. Since we introduce display P3, we probably want to use color depth more than 8bit In the first case, when RGBA are passed down as uint8_t, we can directly calculate Color/SharedColor without normalizing them to [0,1] and scale back to [0, 255] as `colorFromComponents` does; otherwise there could be some precision loss.. So here I'm adding some new utils for that purpose: see `colorFromRGBA`, `redFromColor`, `greenFromColor`, etc [Internal] Examples in codebase: * rgba in [0, 255]: https://www.internalfb.com/code/fbsource/[67148a47147b0e15f0f0748003394040611c2bc2]/xplat/js/react-native-github/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h?lines=28-35 * rgba in [0, 1]: https://www.internalfb.com/code/fbsource/[67148a47147b0e15f0f0748003394040611c2bc2]/xplat/js/react-native-github/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h?lines=37-45 https://www.internalfb.com/code/fbsource/[67148a47147b0e15f0f0748003394040611c2bc2]/xplat/js/react-native-github/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h?lines=47-64 Reviewed By: rshest Differential Revision: D58872165 --- .../react/renderer/graphics/Color.cpp | 2 + .../renderer/graphics/HostPlatformColor.h | 39 +++++++++++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/Color.cpp b/packages/react-native/ReactCommon/react/renderer/graphics/Color.cpp index 8a2db8731511e5..6c18ade185355a 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/Color.cpp +++ b/packages/react-native/ReactCommon/react/renderer/graphics/Color.cpp @@ -17,10 +17,12 @@ bool isColorMeaningful(const SharedColor& color) noexcept { return colorComponentsFromColor(color).alpha > 0; } +// Create Color from float RGBA values in [0, 1] range SharedColor colorFromComponents(ColorComponents components) { return {hostPlatformColorFromComponents(components)}; } +// Read Color components in [0, 1] range ColorComponents colorComponentsFromColor(SharedColor sharedColor) { return colorComponentsFromHostPlatformColor(*sharedColor); } diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/HostPlatformColor.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/HostPlatformColor.h index 6ea3c571ac5929..c79b7abd0a8986 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/HostPlatformColor.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/HostPlatformColor.h @@ -9,6 +9,7 @@ #include #include +#include namespace facebook::react { @@ -19,21 +20,43 @@ static const facebook::react::Color UndefinedColor = std::numeric_limits::max(); } +inline Color +hostPlatformColorFromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { + return (a & 0xff) << 24 | (r & 0xff) << 16 | (g & 0xff) << 8 | (b & 0xff); +} + inline Color hostPlatformColorFromComponents(ColorComponents components) { float ratio = 255; - return ((int)std::round(components.alpha * ratio) & 0xff) << 24 | - ((int)std::round(components.red * ratio) & 0xff) << 16 | - ((int)std::round(components.green * ratio) & 0xff) << 8 | - ((int)std::round(components.blue * ratio) & 0xff); + return hostPlatformColorFromRGBA( + static_cast(std::round(components.red * ratio)), + static_cast(std::round(components.green * ratio)), + static_cast(std::round(components.blue * ratio)), + static_cast(std::round(components.alpha * ratio))); +} + +inline uint8_t alphaFromHostPlatformColor(Color color) { + return static_cast((color >> 24) & 0xff); +} + +inline uint8_t redFromHostPlatformColor(Color color) { + return static_cast((color >> 16) & 0xff); +} + +inline uint8_t greenFromHostPlatformColor(Color color) { + return static_cast((color >> 8) & 0xff); +} + +inline uint8_t blueFromHostPlatformColor(Color color) { + return static_cast((color >> 0) & 0xff); } 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}; + static_cast(redFromHostPlatformColor(color)) / ratio, + static_cast(greenFromHostPlatformColor(color)) / ratio, + static_cast(blueFromHostPlatformColor(color)) / ratio, + static_cast(alphaFromHostPlatformColor(color)) / ratio}; } } // namespace facebook::react