Create util functions to convert Color <-> uint8_t RGBA values (#45139)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45139

## 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

fbshipit-source-id: 748a12a99591c895fed65cda6deeaa2a3e0c3cf5
This commit is contained in:
Zeya Peng
2024-06-25 16:04:56 -07:00
committed by Facebook GitHub Bot
parent 08b05f30c2
commit b5683a7516
2 changed files with 33 additions and 8 deletions
@@ -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);
}
@@ -9,6 +9,7 @@
#include <react/renderer/graphics/ColorComponents.h>
#include <cmath>
#include <cstdint>
namespace facebook::react {
@@ -19,21 +20,43 @@ static const facebook::react::Color UndefinedColor =
std::numeric_limits<facebook::react::Color>::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<uint8_t>(std::round(components.red * ratio)),
static_cast<uint8_t>(std::round(components.green * ratio)),
static_cast<uint8_t>(std::round(components.blue * ratio)),
static_cast<uint8_t>(std::round(components.alpha * ratio)));
}
inline uint8_t alphaFromHostPlatformColor(Color color) {
return static_cast<uint8_t>((color >> 24) & 0xff);
}
inline uint8_t redFromHostPlatformColor(Color color) {
return static_cast<uint8_t>((color >> 16) & 0xff);
}
inline uint8_t greenFromHostPlatformColor(Color color) {
return static_cast<uint8_t>((color >> 8) & 0xff);
}
inline uint8_t blueFromHostPlatformColor(Color color) {
return static_cast<uint8_t>((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<float>(redFromHostPlatformColor(color)) / ratio,
static_cast<float>(greenFromHostPlatformColor(color)) / ratio,
static_cast<float>(blueFromHostPlatformColor(color)) / ratio,
static_cast<float>(alphaFromHostPlatformColor(color)) / ratio};
}
} // namespace facebook::react