From 66e587e55d7ce2f56806eca60ae6473fcf237379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Tue, 20 May 2025 08:55:12 -0700 Subject: [PATCH] Fix incorrect view flattening when using a specific not fully transparent color (#51379) Summary: Changelog: [General][Fixed] Fix incorrect flattening / non-rendering of views with backgroundColor set to `rgba(255, 255, 255, 127/256)` Fixes #51378. ## Context When testing some unrelated things with Fantom is realized that the color for some text that I wasn't explicitly defining was being set to `rgba(255, 255, 255, 127)`, like here: https://github.com/facebook/react-native/blob/249a24ac756275eadbe3b4df1ff9c974af1671d2/packages/react-native-fantom/src/__tests__/Fantom-itest.js#L540-L542 When digging a bit more about why, I realized that was actually the value for `UndefinedColor`. When looking a bit deeper, I saw that the value for that constant was being set like this: ``` using Color = int32_t; namespace HostPlatformColor { static const facebook::react::Color UndefinedColor = std::numeric_limits::max(); } ``` I'm not sure what the logic could've been here: - Defining it as a value out of bounds for all valid colors? In this case, it's a 32 bit value so all the range of values are actually valid RGBA colors. - Defining it as a fully opaque white? Seems dangerous for a default because you wouldn't be able to distinguish a explicitly set white color from a non-set color, relevant if you're seeing a white background color in a view on top of another view with any other background color. The result of this existing logic was actually setting `UndefinedColor` to `rgba(255, 255, 255, 127)` because the alpha channel is defined in the first bits of the value, and `Color` being a signed int with 32 bits, the largest value is `01111....1`, so extracting the first 8 bits, you get 127. ## Changes This changes the value set for the `UndefinedColor` constant (which is used, among other things, to determine if a view sets a background color, or otherwise could potentially be flattened). The new value, instead of white with a 127/256 opacity, is black with 0% opacity (or simply the number 0 in `int32_t`). Reviewed By: javache Differential Revision: D74869311 --- .../src/__tests__/Fantom-itest.js | 2 +- .../Components/__tests__/Button-itest.js | 20 +- .../renderer/graphics/HostPlatformColor.h | 3 +- .../renderer/graphics/HostPlatformColor.h | 3 +- .../mounting/__tests__/Mounting-itest.js | 222 ++++++++++-------- 5 files changed, 136 insertions(+), 114 deletions(-) diff --git a/packages/react-native-fantom/src/__tests__/Fantom-itest.js b/packages/react-native-fantom/src/__tests__/Fantom-itest.js index 81195c474f35f9..60e0a0288d5089 100644 --- a/packages/react-native-fantom/src/__tests__/Fantom-itest.js +++ b/packages/react-native-fantom/src/__tests__/Fantom-itest.js @@ -538,7 +538,7 @@ describe('Fantom', () => { }, ], props: { - foregroundColor: 'rgba(255, 255, 255, 127)', + foregroundColor: 'rgba(0, 0, 0, 0)', }, type: 'Paragraph', }); diff --git a/packages/react-native/Libraries/Components/__tests__/Button-itest.js b/packages/react-native/Libraries/Components/__tests__/Button-itest.js index a16688ca7256e5..1ea59a637420ca 100644 --- a/packages/react-native/Libraries/Components/__tests__/Button-itest.js +++ b/packages/react-native/Libraries/Components/__tests__/Button-itest.js @@ -33,9 +33,7 @@ describe('