From f075889ec9161e4017e8cda338b0996014f68622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ma=C5=82ecki?= Date: Mon, 14 Sep 2026 08:10:19 -0700 Subject: [PATCH 1/3] Add umbrella for `react/renderer/graphics` subtree Summary: Rolls the umbrella-header + include-guard mechanism across the `react/renderer/graphics` module, classifying the target as public. - Adds ``, re-exporting the module's public interface headers. - Adds `` to 24 root headers and all 18 platform headers. - Wires the umbrella header directory into the Buck, CMake, CocoaPods, Gradle, and iOS prebuild header configurations. `conversions.h` and `Geometry.h` are deliberately left unguarded. Both are deprecation shims whose only content is a `#warning` redirecting to their replacements; guarding them would bury that migration hint under a hard error, and their enforcement is inherited from the headers they forward to. `RCTPlatformColorUtils.h` is guarded but intentionally absent from the umbrella. It is an Objective-C++ header (`UIColor` / `RCTUIColor`, `#import `), so including it would make the umbrella uncompilable from a plain C++ translation unit on Apple platforms. By contrast `configurePlatformColorCacheInvalidationHook.h` is plain C++ but exists only on Android, so it is included behind `#ifdef ANDROID`, following the pattern already used by ``. `PlatformColorParser.h` and `fromRawValueShared.h` include `react/renderer/core/RawValue.h`, which was only reachable on Apple platforms because `react/renderer/core:rawValue` was restricted to `platforms = APPLE`. No source inside the graphics target included those headers off-Apple, so the breakage was latent and invisible; reaching them through the umbrella surfaces it. This change therefore widens `:rawValue` to all platforms and gives graphics an unconditional dependency on it. That target exists specifically to break the core/graphics dependency cycle, so no new cycle is introduced. Also adds `tests/UmbrellaCompileTest.cpp`, which does nothing but include the umbrella. No target compiled any umbrella header before this, so a non-compiling umbrella could previously only be discovered by downstream consumers. Changelog: [General][Added] - Add `` umbrella header for the graphics C++ module [Android][Fixed] - Fix `react/renderer/graphics` failing to compile `PlatformColorParser.h` on Android Differential Revision: D116779866 --- .../ReactAndroid/build.gradle.kts | 1 + .../react/renderer/graphics/BackgroundImage.h | 2 + .../renderer/graphics/BackgroundPosition.h | 2 + .../renderer/graphics/BackgroundRepeat.h | 2 + .../react/renderer/graphics/BackgroundSize.h | 2 + .../react/renderer/graphics/BlendMode.h | 2 + .../react/renderer/graphics/BoxShadow.h | 2 + .../react/renderer/graphics/CMakeLists.txt | 2 + .../react/renderer/graphics/Color.h | 2 + .../react/renderer/graphics/ColorComponents.h | 2 + .../react/renderer/graphics/ColorStop.h | 2 + .../react/renderer/graphics/Filter.h | 2 + .../react/renderer/graphics/Isolation.h | 2 + .../react/renderer/graphics/LinearGradient.h | 2 + .../react/renderer/graphics/Point.h | 2 + .../react/renderer/graphics/RadialGradient.h | 2 + .../renderer/graphics/React-graphics.podspec | 7 ++ .../react/renderer/graphics/React/Graphics.h | 67 +++++++++++++++++++ .../react/renderer/graphics/Rect.h | 2 + .../renderer/graphics/RectangleCorners.h | 2 + .../react/renderer/graphics/RectangleEdges.h | 2 + .../react/renderer/graphics/Size.h | 2 + .../react/renderer/graphics/Transform.h | 2 + .../react/renderer/graphics/TransformUtils.h | 2 + .../react/renderer/graphics/ValueUnit.h | 2 + .../react/renderer/graphics/Vector.h | 2 + .../renderer/graphics/fromRawValueShared.h | 5 +- .../android/react/renderer/graphics/Float.h | 2 + .../renderer/graphics/HostPlatformColor.h | 2 + .../renderer/graphics/PlatformColorParser.h | 2 + ...figurePlatformColorCacheInvalidationHook.h | 2 + .../cxx/react/renderer/graphics/Float.h | 2 + .../renderer/graphics/HostPlatformColor.h | 2 + .../renderer/graphics/PlatformColorParser.h | 2 + .../ios/react/renderer/graphics/Float.h | 2 + .../renderer/graphics/HostPlatformColor.h | 2 + .../renderer/graphics/PlatformColorParser.h | 2 + .../renderer/graphics/RCTPlatformColorUtils.h | 2 + .../react/renderer/graphics/rounding.h | 2 + .../scripts/ios-prebuild/headers-config.js | 12 ++++ 40 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 packages/react-native/ReactCommon/react/renderer/graphics/React/Graphics.h diff --git a/packages/react-native/ReactAndroid/build.gradle.kts b/packages/react-native/ReactAndroid/build.gradle.kts index e96e9c258081..943444a2e211 100644 --- a/packages/react-native/ReactAndroid/build.gradle.kts +++ b/packages/react-native/ReactAndroid/build.gradle.kts @@ -152,6 +152,7 @@ val preparePrefab by Pair("../ReactCommon/react/renderer/debug/", "react/renderer/debug/"), // react_renderer_graphics Pair("../ReactCommon/react/renderer/graphics/", "react/renderer/graphics/"), + Pair("../ReactCommon/react/renderer/graphics/React/", "React/"), Pair("../ReactCommon/react/renderer/graphics/platform/android/", ""), // react_renderer_imagemanager Pair( diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundImage.h b/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundImage.h index d156126f251c..ab0c62e506ca 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundImage.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundImage.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundPosition.h b/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundPosition.h index 37a2693896bc..12d539bf80c6 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundPosition.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundPosition.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundRepeat.h b/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundRepeat.h index 15edff00a407..e018fd395a53 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundRepeat.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundRepeat.h @@ -7,6 +7,8 @@ #pragma once +#include + namespace facebook::react { enum class BackgroundRepeatStyle { diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundSize.h b/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundSize.h index 5b0f52cee7e1..90fd8a335490 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundSize.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/BackgroundSize.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/BlendMode.h b/packages/react-native/ReactCommon/react/renderer/graphics/BlendMode.h index 25a1c91232b6..eefa2bacd969 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/BlendMode.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/BlendMode.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/BoxShadow.h b/packages/react-native/ReactCommon/react/renderer/graphics/BoxShadow.h index f8be37cc06e1..b8664bc44a37 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/BoxShadow.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/BoxShadow.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/graphics/CMakeLists.txt index 7113ce1bcdc6..b0b2bfe607dc 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/graphics/CMakeLists.txt @@ -23,12 +23,14 @@ target_include_directories(react_renderer_graphics ${REACT_COMMON_DIR} ${platform_DIR} ) +target_include_directories(react_renderer_graphics INTERFACE ${REACT_COMMON_DIR}/react/renderer/graphics) react_native_android_selector(fbjni fbjni "") target_link_libraries(react_renderer_graphics glog ${fbjni} folly_runtime + react_cxxstableapi react_debug react_renderer_debug react_utils diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/Color.h b/packages/react-native/ReactCommon/react/renderer/graphics/Color.h index 16905f62a3d2..3e5dd1f5593b 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/Color.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/Color.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/ColorComponents.h b/packages/react-native/ReactCommon/react/renderer/graphics/ColorComponents.h index ce60f7a4074f..37854e31fff6 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/ColorComponents.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/ColorComponents.h @@ -7,6 +7,8 @@ #pragma once +#include + namespace facebook::react { enum class ColorSpace { sRGB, DisplayP3 }; diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/ColorStop.h b/packages/react-native/ReactCommon/react/renderer/graphics/ColorStop.h index b3136d4238b0..1febc2e3495b 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/ColorStop.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/ColorStop.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/Filter.h b/packages/react-native/ReactCommon/react/renderer/graphics/Filter.h index f4c1c2613080..fc18207f93a2 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/Filter.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/Filter.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/Isolation.h b/packages/react-native/ReactCommon/react/renderer/graphics/Isolation.h index 9b9b2a1e630e..296ab737e021 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/Isolation.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/Isolation.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/LinearGradient.h b/packages/react-native/ReactCommon/react/renderer/graphics/LinearGradient.h index 57168c953b19..098f9b466755 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/LinearGradient.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/LinearGradient.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/Point.h b/packages/react-native/ReactCommon/react/renderer/graphics/Point.h index c9bf3297d0b3..da9a67b62e8c 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/Point.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/Point.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/RadialGradient.h b/packages/react-native/ReactCommon/react/renderer/graphics/RadialGradient.h index 012487e7f828..7aa75ef7e29a 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/RadialGradient.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/RadialGradient.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec index a164d8ef3db1..65e1527bbcac 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec +++ b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec @@ -38,6 +38,12 @@ Pod::Spec.new do |s| header_search_paths = header_search_paths + ["\"$(PODS_TARGET_SRCROOT)/platform/ios\""] end + s.subspec "graphicsUmbrella" do |ss| + ss.source_files = "React/*.h" + ss.header_dir = "" + ss.header_mappings_dir = "." + end + resolve_use_frameworks(s, header_mappings_dir: "../../..", module_name: "React_graphics") s.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", @@ -50,6 +56,7 @@ Pod::Spec.new do |s| s.dependency "React-featureflags" s.dependency "React-utils" s.dependency "React-rendererdebug" + s.dependency "React-cxxstableapi" depend_on_js_engine(s) add_rn_third_party_dependencies(s) diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/React/Graphics.h b/packages/react-native/ReactCommon/react/renderer/graphics/React/Graphics.h new file mode 100644 index 000000000000..1301e24a9d4d --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/graphics/React/Graphics.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +// ============================================================================= +// Umbrella header for the `react/renderer/graphics` module - public entry +// point. +// +// #include +// +// Re-exports the module's public interface headers. React Native's own code +// should keep using the fine-grained `` includes; +// only outside consumers use this umbrella. +// ============================================================================= + +// Marks that the following headers are pulled in through the umbrella, so their +// shared guard () accepts them. The marker +// is saved and restored rather than defined and undefined: the scope ends at +// this block, so later *direct* includes in the same TU are still caught, and +// it nests inside an enclosing umbrella rather than disarming it. +#pragma push_macro("RN_UMBRELLA_CONTEXT") +#undef RN_UMBRELLA_CONTEXT +#define RN_UMBRELLA_CONTEXT 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ANDROID +#include +#endif + +#if defined(__APPLE__) && defined(__OBJC__) +#include +#endif + +#undef RN_UMBRELLA_CONTEXT +#pragma pop_macro("RN_UMBRELLA_CONTEXT") diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/Rect.h b/packages/react-native/ReactCommon/react/renderer/graphics/Rect.h index a9a4dcb9057c..9d38462812c5 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/Rect.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/Rect.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/RectangleCorners.h b/packages/react-native/ReactCommon/react/renderer/graphics/RectangleCorners.h index 00b3f9a109ef..d2804b6dc25a 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/RectangleCorners.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/RectangleCorners.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/RectangleEdges.h b/packages/react-native/ReactCommon/react/renderer/graphics/RectangleEdges.h index cccfcbd909a8..7d55d84d2d24 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/RectangleEdges.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/RectangleEdges.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/Size.h b/packages/react-native/ReactCommon/react/renderer/graphics/Size.h index bde0a19f0d27..2e2b80106553 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/Size.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/Size.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/Transform.h b/packages/react-native/ReactCommon/react/renderer/graphics/Transform.h index 2f3a69021426..708593867b88 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/Transform.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/Transform.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/TransformUtils.h b/packages/react-native/ReactCommon/react/renderer/graphics/TransformUtils.h index c12d264a0d36..887447278f3e 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/TransformUtils.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/TransformUtils.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/ValueUnit.h b/packages/react-native/ReactCommon/react/renderer/graphics/ValueUnit.h index ff654387062f..3ed9bc5b7a95 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/ValueUnit.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/ValueUnit.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/Vector.h b/packages/react-native/ReactCommon/react/renderer/graphics/Vector.h index 595856d59e8a..b76354d56355 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/Vector.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/Vector.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h b/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h index 7bd48ce15b46..91d73c080751 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h @@ -5,6 +5,9 @@ * LICENSE file in the root directory of this source tree. */ +#pragma once + +#include #include #include #include @@ -13,8 +16,6 @@ #include #include -#pragma once - namespace facebook::react { using parsePlatformColorFn = SharedColor (*)(const ContextContainer &, int32_t, const RawValue &); diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/Float.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/Float.h index ee0ee3e6a376..673b16a8d878 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/Float.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/Float.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { 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 aec9c6054705..899aa4bad604 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 @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h index 47b2bafe5dbd..4ff0d7577c09 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h @@ -7,6 +7,8 @@ #pragma once +#include + #include "configurePlatformColorCacheInvalidationHook.h" #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/configurePlatformColorCacheInvalidationHook.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/configurePlatformColorCacheInvalidationHook.h index 0ae822a1f396..ac6c743ccb0f 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/configurePlatformColorCacheInvalidationHook.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/configurePlatformColorCacheInvalidationHook.h @@ -5,6 +5,8 @@ * LICENSE file in the root directory of this source tree. */ +#include + #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Float.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Float.h index ee0ee3e6a376..673b16a8d878 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Float.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Float.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { 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 a13540363420..ea2d91867635 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 @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h index 3a0e863fda0d..84b81fec280a 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/Float.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/Float.h index ef09235874e9..361abfda591e 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/Float.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/Float.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/HostPlatformColor.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/HostPlatformColor.h index a7dd98139991..80d61ff89d05 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/HostPlatformColor.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/HostPlatformColor.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.h index 3ff2aa38cfd5..28afc62d43f3 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/RCTPlatformColorUtils.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/RCTPlatformColorUtils.h index ad021c1e413f..bfd96f122819 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/RCTPlatformColorUtils.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/RCTPlatformColorUtils.h @@ -7,6 +7,8 @@ #pragma once +#include + #import #import diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/rounding.h b/packages/react-native/ReactCommon/react/renderer/graphics/rounding.h index be34277849f6..b5f93f2891f5 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/rounding.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/rounding.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { diff --git a/packages/react-native/scripts/ios-prebuild/headers-config.js b/packages/react-native/scripts/ios-prebuild/headers-config.js index 31aa70ef825e..5da3cec7c9c0 100644 --- a/packages/react-native/scripts/ios-prebuild/headers-config.js +++ b/packages/react-native/scripts/ios-prebuild/headers-config.js @@ -534,6 +534,18 @@ const PodspecExceptions /*: {[key: string]: PodSpecConfiguration} */ = { }, ], }, + 'ReactCommon/react/renderer/graphics/React-graphics.podspec': { + name: 'React-graphics', + headerPatterns: ['*.h', 'platform/ios/**/*.h'], + headerDir: 'react/renderer/graphics', + subSpecs: [ + { + name: 'graphicsUmbrella', + headerPatterns: ['React/*.h'], + headerDir: 'React', + }, + ], + }, 'React-Core.podspec': { name: 'React-Core', headerPatterns: [], From 33b70b637262d5f6a1e52dcb7e4d290b2d90c41a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ma=C5=82ecki?= Date: Mon, 14 Sep 2026 08:10:19 -0700 Subject: [PATCH 2/3] Add explicit renderer CSS dependencies Summary: Declare direct CSS dependencies for renderer targets that consume CSS headers instead of relying on View or Graphics to expose them transitively. Cover Buck, CMake, CocoaPods, and SwiftPM without changing header visibility or runtime behavior. Changelog: [Internal] Differential Revision: D119489856 --- packages/react-native/Package.swift | 15 ++++++++++++--- .../react-native/ReactCommon/React-Fabric.podspec | 2 ++ .../renderer/attributedstring/CMakeLists.txt | 1 + .../react/renderer/graphics/CMakeLists.txt | 1 + .../renderer/graphics/React-graphics.podspec | 1 + .../observers/intersection/CMakeLists.txt | 1 + 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/react-native/Package.swift b/packages/react-native/Package.swift index 386ca6958b7f..2cde861bde2c 100644 --- a/packages/react-native/Package.swift +++ b/packages/react-native/Package.swift @@ -287,13 +287,21 @@ let reactJsErrorHandler = RNTarget( dependencies: [.reactNativeDependencies, .jsi, .reactFeatureFlags, .reactDebug, .reactTurboModuleBridging] ) +/// React-renderercss.podspec +let reactRendererCss = RNTarget( + name: .reactRendererCss, + path: "ReactCommon/react/renderer/css", + excludedPaths: ["tests"], + dependencies: [.reactNativeDependencies, .reactDebug, .reactUtils] +) + /// React-graphicsApple /// This represents the React-graphicsApple BUCK module let reactGraphicsApple = RNTarget( name: .reactGraphicsApple, path: "ReactCommon/react/renderer/graphics/platform/ios", linkedFrameworks: ["UIKit", "CoreGraphics"], - dependencies: [.reactDebug, .jsi, .reactUtils, .reactNativeDependencies] + dependencies: [.reactDebug, .jsi, .reactUtils, .reactNativeDependencies, .reactRendererCss] ) /// React-graphics.podspec @@ -301,7 +309,7 @@ let reactGraphics = RNTarget( name: .reactGraphics, path: "ReactCommon/react/renderer/graphics", excludedPaths: ["platform", "tests"], - dependencies: [.reactNativeDependencies, .jsi, .reactJsiExecutor, .reactRendererDebug, .reactUtils, .reactGraphicsApple] + dependencies: [.reactNativeDependencies, .jsi, .reactJsiExecutor, .reactRendererDebug, .reactUtils, .reactGraphicsApple, .reactRendererCss] ) /// ReactCommon.podspec @@ -491,7 +499,7 @@ let reactFabric = RNTarget( "observers/resize/tests", "scheduler/tests", ], - dependencies: [.reactNativeDependencies, .reactJsiExecutor, .rctTypesafety, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .reactRendererDebug, .reactGraphics, .yoga, .reactJsInspectorTracing], + dependencies: [.reactNativeDependencies, .reactJsiExecutor, .rctTypesafety, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .reactRendererDebug, .reactGraphics, .reactRendererCss, .yoga, .reactJsInspectorTracing], sources: ["animated", "animationbackend", "animations", "attributedstring", "core", "componentregistry", "componentregistry/native", "components/root", "components/view", "components/view/platform/cxx", "components/scrollview", "components/scrollview/platform/cxx", "components/scrollview/platform/ios", "components/legacyviewmanagerinterop", "components/legacyviewmanagerinterop/platform/ios", "dom", "scheduler", "mounting", "observers/events", "observers/intersection", "observers/mutation", "observers/resize", "telemetry", "consistency", "leakchecker", "uimanager", "uimanager/consistency", "viewtransition"] ) @@ -713,6 +721,7 @@ let targets = [ reactPerformanceTimeline, reactRuntimeScheduler, rctTypesafety, + reactRendererCss, reactGraphics, reactGraphicsApple, reactImageManager, diff --git a/packages/react-native/ReactCommon/React-Fabric.podspec b/packages/react-native/ReactCommon/React-Fabric.podspec index 19dacf18444e..6be6b10851ed 100644 --- a/packages/react-native/ReactCommon/React-Fabric.podspec +++ b/packages/react-native/ReactCommon/React-Fabric.podspec @@ -77,6 +77,7 @@ Pod::Spec.new do |s| end s.subspec "attributedstring" do |ss| + ss.dependency "React-renderercss" ss.source_files = podspec_sources("react/renderer/attributedstring/**/*.{m,mm,cpp,h}", "react/renderer/attributedstring/**/*.{h}") ss.exclude_files = "react/renderer/attributedstring/tests" ss.header_dir = "react/renderer/attributedstring" @@ -209,6 +210,7 @@ Pod::Spec.new do |s| end ss.subspec "intersection" do |sss| + sss.dependency "React-renderercss" sss.source_files = podspec_sources("react/renderer/observers/intersection/**/*.{m,mm,cpp,h}", "react/renderer/observers/intersection/**/*.h") sss.exclude_files = "react/renderer/observers/intersection/tests" sss.header_dir = "react/renderer/observers/intersection" diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/attributedstring/CMakeLists.txt index a337c84bf388..1b6e6bbfae9b 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/CMakeLists.txt @@ -21,6 +21,7 @@ target_link_libraries(react_renderer_attributedstring react_debug rrc_view react_renderer_core + react_renderer_css react_renderer_debug react_renderer_graphics react_renderer_mapbuffer diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/graphics/CMakeLists.txt index b0b2bfe607dc..b501873adb85 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/graphics/CMakeLists.txt @@ -32,6 +32,7 @@ target_link_libraries(react_renderer_graphics folly_runtime react_cxxstableapi react_debug + react_renderer_css react_renderer_debug react_utils ) diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec index 65e1527bbcac..21beee0c7fba 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec +++ b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec @@ -57,6 +57,7 @@ Pod::Spec.new do |s| s.dependency "React-utils" s.dependency "React-rendererdebug" s.dependency "React-cxxstableapi" + s.dependency "React-renderercss" depend_on_js_engine(s) add_rn_third_party_dependencies(s) diff --git a/packages/react-native/ReactCommon/react/renderer/observers/intersection/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/observers/intersection/CMakeLists.txt index 8892e3bc70a1..701e87132f09 100644 --- a/packages/react-native/ReactCommon/react/renderer/observers/intersection/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/observers/intersection/CMakeLists.txt @@ -19,6 +19,7 @@ target_link_libraries(react_renderer_observers_intersection react_cxxstableapi react_debug react_renderer_core + react_renderer_css react_renderer_graphics react_renderer_mounting react_renderer_runtimescheduler From 2e5f690a839aef8056501e0e0ede9f2bf81d854e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ma=C5=82ecki?= Date: Mon, 14 Sep 2026 08:21:42 -0700 Subject: [PATCH 3/3] Move renderer color parsing out of headers Summary: Move shared and platform-specific Graphics color-parsing implementations from exported headers into owned source files across generic C++, Android, Apple, and Windows targets. Preserve the existing public entry points and parsing behavior. Update Buck source selection so default configurations link the generic C++ parser, and keep the React Native macOS and Windows mirrors synchronized. Changelog: [Internal] Differential Revision: D119500849 --- .../renderer/graphics/fromRawValueShared.cpp | 88 ++++++++++++ .../renderer/graphics/fromRawValueShared.h | 61 +-------- .../renderer/graphics/PlatformColorParser.cpp | 125 ++++++++++++++++++ .../renderer/graphics/PlatformColorParser.h | 110 ++------------- .../renderer/graphics/PlatformColorParser.cpp | 25 ++++ .../renderer/graphics/PlatformColorParser.h | 24 +--- .../renderer/graphics/PlatformColorParser.h | 13 +- 7 files changed, 260 insertions(+), 186 deletions(-) create mode 100644 packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.cpp create mode 100644 packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.cpp create mode 100644 packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.cpp diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.cpp b/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.cpp new file mode 100644 index 000000000000..e9f236d636a2 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include +#include +#include +#include +#include + +namespace facebook::react { + +void fromRawValueShared( + const ContextContainer& contextContainer, + int32_t surfaceId, + const RawValue& value, + SharedColor& result, + parsePlatformColorFn parsePlatformColor) { + ColorComponents colorComponents = { + .red = 0, .green = 0, .blue = 0, .alpha = 0}; + + if (ReactNativeFeatureFlags::enableNativeCSSParsing() && + value.hasType()) { + auto cssColor = parseCSSProperty((std::string)value); + if (std::holds_alternative(cssColor)) { + auto c = std::get(cssColor); + result = hostPlatformColorFromRGBA(c.r, c.g, c.b, c.a); + return; + } + // Unparseable string - fall through to parsePlatformColor + result = parsePlatformColor(contextContainer, surfaceId, value); + } else if (value.hasType()) { + auto argb = (int64_t)value; + auto ratio = 255.f; + colorComponents.alpha = ((argb >> 24) & 0xFF) / ratio; + colorComponents.red = ((argb >> 16) & 0xFF) / ratio; + colorComponents.green = ((argb >> 8) & 0xFF) / ratio; + colorComponents.blue = (argb & 0xFF) / ratio; + + result = colorFromComponents(colorComponents); + } else if (value.hasType>()) { + auto items = (std::vector)value; + auto length = items.size(); + react_native_expect(length == 3 || length == 4); + colorComponents.red = items.at(0); + colorComponents.green = items.at(1); + colorComponents.blue = items.at(2); + colorComponents.alpha = length == 4 ? items.at(3) : 1.0f; + + result = colorFromComponents(colorComponents); + } else { + if (value.hasType>()) { + const auto& items = (std::unordered_map)value; + if (items.find("space") != items.end()) { + colorComponents.red = (float)items.at("r"); + colorComponents.green = (float)items.at("g"); + colorComponents.blue = (float)items.at("b"); + colorComponents.alpha = (float)items.at("a"); + colorComponents.colorSpace = getDefaultColorSpace(); + std::string space = (std::string)items.at("space"); + if (space == "display-p3") { + colorComponents.colorSpace = ColorSpace::DisplayP3; + } else if (space == "srgb") { + colorComponents.colorSpace = ColorSpace::sRGB; + } + result = colorFromComponents(colorComponents); + return; + } + } + result = parsePlatformColor(contextContainer, surfaceId, value); + } +} + +void fromRawValue( + const ContextContainer& contextContainer, + int32_t surfaceId, + const RawValue& value, + SharedColor& result) { + fromRawValueShared( + contextContainer, surfaceId, value, result, parsePlatformColor); +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h b/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h index 91d73c080751..71cff8430265 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h @@ -8,74 +8,19 @@ #pragma once #include -#include -#include #include -#include -#include #include #include namespace facebook::react { + using parsePlatformColorFn = SharedColor (*)(const ContextContainer &, int32_t, const RawValue &); -inline void fromRawValueShared( +void fromRawValueShared( const ContextContainer &contextContainer, int32_t surfaceId, const RawValue &value, SharedColor &result, - parsePlatformColorFn parsePlatformColor) -{ - ColorComponents colorComponents = {0, 0, 0, 0}; - - if (ReactNativeFeatureFlags::enableNativeCSSParsing() && value.hasType()) { - auto cssColor = parseCSSProperty((std::string)value); - if (std::holds_alternative(cssColor)) { - auto c = std::get(cssColor); - result = hostPlatformColorFromRGBA(c.r, c.g, c.b, c.a); - return; - } - // Unparseable string - fall through to parsePlatformColor - result = parsePlatformColor(contextContainer, surfaceId, value); - } else if (value.hasType()) { - auto argb = (int64_t)value; - auto ratio = 255.f; - colorComponents.alpha = ((argb >> 24) & 0xFF) / ratio; - colorComponents.red = ((argb >> 16) & 0xFF) / ratio; - colorComponents.green = ((argb >> 8) & 0xFF) / ratio; - colorComponents.blue = (argb & 0xFF) / ratio; - - result = colorFromComponents(colorComponents); - } else if (value.hasType>()) { - auto items = (std::vector)value; - auto length = items.size(); - react_native_expect(length == 3 || length == 4); - colorComponents.red = items.at(0); - colorComponents.green = items.at(1); - colorComponents.blue = items.at(2); - colorComponents.alpha = length == 4 ? items.at(3) : 1.0f; + parsePlatformColorFn parsePlatformColor); - result = colorFromComponents(colorComponents); - } else { - if (value.hasType>()) { - const auto &items = (std::unordered_map)value; - if (items.find("space") != items.end()) { - colorComponents.red = (float)items.at("r"); - colorComponents.green = (float)items.at("g"); - colorComponents.blue = (float)items.at("b"); - colorComponents.alpha = (float)items.at("a"); - colorComponents.colorSpace = getDefaultColorSpace(); - std::string space = (std::string)items.at("space"); - if (space == "display-p3") { - colorComponents.colorSpace = ColorSpace::DisplayP3; - } else if (space == "srgb") { - colorComponents.colorSpace = ColorSpace::sRGB; - } - result = colorFromComponents(colorComponents); - return; - } - } - result = parsePlatformColor(contextContainer, surfaceId, value); - } -} } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.cpp b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.cpp new file mode 100644 index 000000000000..321b82c5d135 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include "configurePlatformColorCacheInvalidationHook.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace facebook::react { + +size_t hashGetColourArguments( + int32_t surfaceId, + const std::vector& resourcePaths) { + size_t seed = std::hash{}(surfaceId); + for (const auto& path : resourcePaths) { + seed ^= + std::hash{}(path) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } + return seed; +} + +SharedColor parsePlatformColor( + const ContextContainer& contextContainer, + int32_t surfaceId, + const RawValue& value) { + Color color{}; + if (value.hasType>()) { + // Mixed array + string values, so read as a map of RawValue (a map of + // vector would assert on the fallback string). + auto map = (std::unordered_map)value; + + std::vector resourcePaths; + auto resourcePathsIt = map.find("resource_paths"); + if (resourcePathsIt != map.end() && + resourcePathsIt->second.hasType>()) { + resourcePaths = (std::vector)resourcePathsIt->second; + } + + bool resolved = false; + if (!resourcePaths.empty()) { + // Cache the (costly) JNI results. A cached nullopt is an explicit miss, + // distinct from a path that resolves to transparent (ARGB 0). + static std::mutex getColorCacheMutex; + static folly::EvictingCacheMap> + getColorCache(64); + + // Listen for appearance changes, which should invalidate the cache + static std::once_flag setupCacheInvalidation; + std::call_once( + setupCacheInvalidation, + configurePlatformColorCacheInvalidationHook, + [&] { + std::scoped_lock lock(getColorCacheMutex); + getColorCache.clear(); + }); + + auto hash = hashGetColourArguments(surfaceId, resourcePaths); + std::optional resolvedColor; + { + std::scoped_lock lock(getColorCacheMutex); + auto iterator = getColorCache.find(hash); + if (iterator != getColorCache.end()) { + resolvedColor = iterator->second; + } else { + const auto& fabricUIManager = + contextContainer.at>("FabricUIManager"); + // Boxed Integer: null is an explicit miss; a non-null value may be 0 + // (transparent black). + static auto getColorFromJava = + fabricUIManager->getClass() + ->getMethod)>("getColor"); + auto javaResourcePaths = + jni::JArrayClass::newArray(resourcePaths.size()); + + for (int i = 0; i < resourcePaths.size(); i++) { + javaResourcePaths->setElement( + i, *jni::make_jstring(resourcePaths[i])); + } + auto boxedColor = + getColorFromJava(fabricUIManager, surfaceId, *javaResourcePaths); + if (boxedColor) { + resolvedColor = static_cast(boxedColor->value()); + } + getColorCache.set(hash, resolvedColor); + } + } + if (resolvedColor.has_value()) { + color = *resolvedColor; + resolved = true; + } + } + + // No path resolved: parse the raw fallback with the shared CSS parser (the + // same parser iOS Fabric uses). + if (!resolved) { + auto fallbackIt = map.find("fallback"); + if (fallbackIt != map.end() && + fallbackIt->second.hasType()) { + auto cssColor = + parseCSSProperty((std::string)fallbackIt->second); + if (std::holds_alternative(cssColor)) { + const auto& c = std::get(cssColor); + color = hostPlatformColorFromRGBA(c.r, c.g, c.b, c.a); + } + } + } + } + + return color; +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h index 4ff0d7577c09..9012da2fdeb0 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h @@ -8,117 +8,23 @@ #pragma once #include - -#include "configurePlatformColorCacheInvalidationHook.h" - -#include -#include #include -#include -#include #include -#include #include -#include -#include -#include +#include #include -#include #include namespace facebook::react { -inline size_t hashGetColourArguments(int32_t surfaceId, const std::vector &resourcePaths) -{ - size_t seed = std::hash{}(surfaceId); - for (const auto &path : resourcePaths) { - seed ^= std::hash{}(path) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - } - return seed; -} - -inline SharedColor -parsePlatformColor(const ContextContainer &contextContainer, int32_t surfaceId, const RawValue &value) -{ - Color color{}; - if (value.hasType>()) { - // Mixed array + string values, so read as a map of RawValue (a map of - // vector would assert on the fallback string). - auto map = (std::unordered_map)value; - - std::vector resourcePaths; - auto resourcePathsIt = map.find("resource_paths"); - if (resourcePathsIt != map.end() && resourcePathsIt->second.hasType>()) { - resourcePaths = (std::vector)resourcePathsIt->second; - } - - bool resolved = false; - if (!resourcePaths.empty()) { - // Cache the (costly) JNI results. A cached nullopt is an explicit miss, - // distinct from a path that resolves to transparent (ARGB 0). - static std::mutex getColorCacheMutex; - static folly::EvictingCacheMap> getColorCache(64); - - // Listen for appearance changes, which should invalidate the cache - static std::once_flag setupCacheInvalidation; - std::call_once(setupCacheInvalidation, configurePlatformColorCacheInvalidationHook, [&] { - std::scoped_lock lock(getColorCacheMutex); - getColorCache.clear(); - }); - - auto hash = hashGetColourArguments(surfaceId, resourcePaths); - std::optional resolvedColor; - { - std::scoped_lock lock(getColorCacheMutex); - auto iterator = getColorCache.find(hash); - if (iterator != getColorCache.end()) { - resolvedColor = iterator->second; - } else { - const auto &fabricUIManager = contextContainer.at>("FabricUIManager"); - // Boxed Integer: null is an explicit miss; a non-null value may be 0 - // (transparent black). - static auto getColorFromJava = - fabricUIManager->getClass()->getMethod)>( - "getColor"); - auto javaResourcePaths = jni::JArrayClass::newArray(resourcePaths.size()); - - for (int i = 0; i < resourcePaths.size(); i++) { - javaResourcePaths->setElement(i, *jni::make_jstring(resourcePaths[i])); - } - auto boxedColor = getColorFromJava(fabricUIManager, surfaceId, *javaResourcePaths); - if (boxedColor) { - resolvedColor = static_cast(boxedColor->value()); - } - getColorCache.set(hash, resolvedColor); - } - } - if (resolvedColor.has_value()) { - color = *resolvedColor; - resolved = true; - } - } - - // No path resolved: parse the raw fallback with the shared CSS parser (the - // same parser iOS Fabric uses). - if (!resolved) { - auto fallbackIt = map.find("fallback"); - if (fallbackIt != map.end() && fallbackIt->second.hasType()) { - auto cssColor = parseCSSProperty((std::string)fallbackIt->second); - if (std::holds_alternative(cssColor)) { - const auto &c = std::get(cssColor); - color = hostPlatformColorFromRGBA(c.r, c.g, c.b, c.a); - } - } - } - } +size_t hashGetColourArguments(int32_t surfaceId, const std::vector &resourcePaths); - return color; -} +SharedColor parsePlatformColor(const ContextContainer &contextContainer, int32_t surfaceId, const RawValue &value); -inline void -fromRawValue(const ContextContainer &contextContainer, int32_t surfaceId, const RawValue &value, SharedColor &result) -{ - fromRawValueShared(contextContainer, surfaceId, value, result, parsePlatformColor); -} +void fromRawValue( + const ContextContainer &contextContainer, + int32_t surfaceId, + const RawValue &value, + SharedColor &result); } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.cpp b/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.cpp new file mode 100644 index 000000000000..9a2cc748ffe9 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +namespace facebook::react { + +SharedColor parsePlatformColor( + const ContextContainer& /*contextContainer*/, + int32_t /*surfaceId*/, + const RawValue& /*value*/) { + float alpha = 0; + float red = 0; + float green = 0; + float blue = 0; + + return {colorFromComponents( + {.red = red, .green = green, .blue = blue, .alpha = alpha})}; +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h index 84b81fec280a..2b84d9ca9847 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h @@ -8,30 +8,18 @@ #pragma once #include - -#include #include #include -#include #include namespace facebook::react { -inline SharedColor -parsePlatformColor(const ContextContainer & /*contextContainer*/, int32_t /*surfaceId*/, const RawValue & /*value*/) -{ - float alpha = 0; - float red = 0; - float green = 0; - float blue = 0; - - return {colorFromComponents({red, green, blue, alpha})}; -} +SharedColor parsePlatformColor(const ContextContainer &contextContainer, int32_t surfaceId, const RawValue &value); -inline void -fromRawValue(const ContextContainer &contextContainer, int32_t surfaceId, const RawValue &value, SharedColor &result) -{ - fromRawValueShared(contextContainer, surfaceId, value, result, parsePlatformColor); -} +void fromRawValue( + const ContextContainer &contextContainer, + int32_t surfaceId, + const RawValue &value, + SharedColor &result); } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.h b/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.h index 28afc62d43f3..2b84d9ca9847 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.h @@ -8,21 +8,18 @@ #pragma once #include - -#include #include #include -#include #include namespace facebook::react { SharedColor parsePlatformColor(const ContextContainer &contextContainer, int32_t surfaceId, const RawValue &value); -inline void -fromRawValue(const ContextContainer &contextContainer, int32_t surfaceId, const RawValue &value, SharedColor &result) -{ - fromRawValueShared(contextContainer, surfaceId, value, result, parsePlatformColor); -} +void fromRawValue( + const ContextContainer &contextContainer, + int32_t surfaceId, + const RawValue &value, + SharedColor &result); } // namespace facebook::react