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/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-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/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..b501873adb85 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/graphics/CMakeLists.txt @@ -23,13 +23,16 @@ 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_css 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..21beee0c7fba 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,8 @@ Pod::Spec.new do |s| s.dependency "React-featureflags" 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/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.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 7bd48ce15b46..71cff8430265 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h @@ -5,76 +5,22 @@ * LICENSE file in the root directory of this source tree. */ -#include -#include +#pragma once + +#include #include -#include -#include #include #include -#pragma once - 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/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.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 47b2bafe5dbd..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 @@ -7,116 +7,24 @@ #pragma once -#include "configurePlatformColorCacheInvalidationHook.h" - -#include -#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/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.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 3a0e863fda0d..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 @@ -7,29 +7,19 @@ #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; +SharedColor parsePlatformColor(const ContextContainer &contextContainer, int32_t surfaceId, const RawValue &value); - return {colorFromComponents({red, green, blue, alpha})}; -} - -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/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..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 @@ -7,20 +7,19 @@ #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 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/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 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: [],