Platform specific PargraphState (#50890)

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

With Facsimile, we are introducing some new concept of `PreparedText`, where platform TextLayoutManager which implement, can lead to additional optimizations.

`#ifdef ANDROID` is not a workable pattern for this. Apart from react-native-cxx getting hooked into it, and all of the existing bugs there, it is bad for editor environment, and hard to reason about.

This splits up `ParagraphState`, so that we can control platform specific bits more easily. We do not split `ParagraphShadowNode`, which will use concepts (e.g. `TextLayoutManagerWithPreparedText`) to control which paths it takes, based on platform capaibilities.

Changelog: [internal]

Reviewed By: rshest

Differential Revision: D73555441

fbshipit-source-id: fd585eb99d26b0b6966efb1867d03fbd5cc7e7e2
This commit is contained in:
Nick Gerleman
2025-04-24 20:10:57 -07:00
committed by Facebook GitHub Bot
parent fcb3ef3f76
commit eb459a9f42
8 changed files with 67 additions and 20 deletions
@@ -71,6 +71,7 @@ Pod::Spec.new do |s|
])
add_dependency(s, "React-FabricComponents", :additional_framework_paths => [
"react/renderer/textlayoutmanager/platform/ios",
"react/renderer/components/text/platform/cxx",
"react/renderer/components/textinput/platform/ios",
]);
@@ -78,6 +78,7 @@ Pod::Spec.new do |s|
if ENV['USE_FRAMEWORKS']
header_search_path = header_search_path + [
"\"$(PODS_TARGET_SRCROOT)/react/renderer/textlayoutmanager/platform/ios\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/text/platform/cxx\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/textinput/platform/ios\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/view/platform/cxx\"",
]
@@ -30,6 +30,7 @@ Pod::Spec.new do |s|
header_search_path = header_search_path + [
"\"$(PODS_TARGET_SRCROOT)/react/renderer/textlayoutmanager/platform/ios\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/textinput/platform/ios\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/text/platform/cxx\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/view/platform/cxx\"",
]
end
@@ -111,8 +112,8 @@ Pod::Spec.new do |s|
end
ss.subspec "text" do |sss|
sss.source_files = "react/renderer/components/text/**/*.{m,mm,cpp,h}"
sss.exclude_files = "react/renderer/components/text/tests"
sss.source_files = "react/renderer/components/text/*.{m,mm,cpp,h}",
"react/renderer/components/text/platform/cxx/**/*.{m,mm,cpp,h}"
sss.header_dir = "react/renderer/components/text"
end
@@ -27,6 +27,7 @@ if ENV['USE_FRAMEWORKS']
header_search_path = header_search_path + [
"\"$(PODS_TARGET_SRCROOT)\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/textlayoutmanager/platform/ios\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/text/platform/cxx\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/textinput/platform/ios\"",
# "\"$(PODS_CONFIGURATION_BUILD_DIR)/ReactCodegen/ReactCodegen.framework/Headers\"",
]
@@ -8,10 +8,18 @@ set(CMAKE_VERBOSE_MAKEFILE on)
include(${REACT_COMMON_DIR}/cmake-utils/react-native-flags.cmake)
file(GLOB rrc_text_SRC CONFIGURE_DEPENDS *.cpp)
file(GLOB rrc_text_SRC CONFIGURE_DEPENDS
*.cpp
platform/android/react/renderer/components/text/*.cpp)
add_library(rrc_text OBJECT ${rrc_text_SRC})
target_include_directories(rrc_text PUBLIC ${REACT_COMMON_DIR})
target_include_directories(rrc_text PUBLIC
${REACT_COMMON_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/platform/android/)
target_include_directories(rrc_text PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/platform/android/react/renderer/components/text/)
target_link_libraries(rrc_text
glog
@@ -12,7 +12,6 @@
namespace facebook::react {
#ifdef ANDROID
folly::dynamic ParagraphState::getDynamic() const {
LOG(FATAL) << "ParagraphState may only be serialized to MapBuffer";
}
@@ -20,6 +19,5 @@ folly::dynamic ParagraphState::getDynamic() const {
MapBuffer ParagraphState::getMapBuffer() const {
return toMapBuffer(*this);
}
#endif
} // namespace facebook::react
@@ -12,21 +12,19 @@
#include <react/renderer/attributedstring/ParagraphAttributes.h>
#include <react/renderer/textlayoutmanager/TextLayoutManager.h>
#ifdef ANDROID
#include <folly/dynamic.h>
#include <react/renderer/mapbuffer/MapBuffer.h>
#endif
#include <utility>
namespace facebook::react {
#ifdef ANDROID
// constants for Text State serialization
constexpr static MapBuffer::Key TX_STATE_KEY_ATTRIBUTED_STRING = 0;
constexpr static MapBuffer::Key TX_STATE_KEY_PARAGRAPH_ATTRIBUTES = 1;
// Used for TextInput only
constexpr static MapBuffer::Key TX_STATE_KEY_HASH = 2;
constexpr static MapBuffer::Key TX_STATE_KEY_MOST_RECENT_EVENT_COUNT = 3;
#endif
/*
* State for <Paragraph> component.
@@ -49,28 +47,25 @@ class ParagraphState final {
* `TextLayoutManager` provides a connection to platform-specific
* text rendering infrastructure which is capable to render the
* `AttributedString`.
* This is not on every platform. This is not used on Android, but is
* used on the iOS mounting layer.
*/
std::weak_ptr<const TextLayoutManager> layoutManager;
#ifdef ANDROID
ParagraphState(
const AttributedString& attributedString,
const ParagraphAttributes& paragraphAttributes,
AttributedString attributedString,
ParagraphAttributes paragraphAttributes,
const std::weak_ptr<const TextLayoutManager>& layoutManager)
: attributedString(attributedString),
paragraphAttributes(paragraphAttributes),
: attributedString(std::move(attributedString)),
paragraphAttributes(std::move(paragraphAttributes)),
layoutManager(layoutManager) {}
ParagraphState() = default;
ParagraphState(
const ParagraphState& previousState,
const folly::dynamic& data) {
const ParagraphState& /*previousState*/,
const folly::dynamic& /*data*/) {
react_native_assert(false && "Not supported");
};
folly::dynamic getDynamic() const;
MapBuffer getMapBuffer() const;
#endif
};
} // namespace facebook::react
@@ -0,0 +1,42 @@
/*
* 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
#include <react/debug/react_native_assert.h>
#include <react/renderer/attributedstring/AttributedString.h>
#include <react/renderer/attributedstring/ParagraphAttributes.h>
#include <react/renderer/textlayoutmanager/TextLayoutManager.h>
namespace facebook::react {
/*
* State for <Paragraph> component.
* Represents what to render and how to render.
*/
class ParagraphState final {
public:
/*
* All content of <Paragraph> component represented as an `AttributedString`.
*/
AttributedString attributedString;
/*
* Represents all visual attributes of a paragraph of text represented as
* a ParagraphAttributes.
*/
ParagraphAttributes paragraphAttributes;
/*
* `TextLayoutManager` provides a connection to platform-specific
* text rendering infrastructure which is capable to render the
* `AttributedString`.
*/
std::weak_ptr<const TextLayoutManager> layoutManager;
};
} // namespace facebook::react