Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,9 @@ void ParagraphShadowNode::updateStateIfNeeded(const Content& content) {
#endif
}

MeasuredPreparedTextLayout* ParagraphShadowNode::findUsableLayout(
const MeasuredPreparedTextLayout* ParagraphShadowNode::findUsableLayout(
Float pointScaleFactor) {
MeasuredPreparedTextLayout* ret = nullptr;
const MeasuredPreparedTextLayout* ret = nullptr;

if constexpr (TextLayoutManagerExtended::supportsPreparedTextLayout()) {
// We consider the layout to be reusable, if our content measurement,
Expand All @@ -274,7 +274,7 @@ MeasuredPreparedTextLayout* ParagraphShadowNode::findUsableLayout(
// equally sized one carried over from a previous revision.
for (auto it = measuredLayouts_.rbegin(); it != measuredLayouts_.rend();
++it) {
auto& prevLayout = *it;
const auto& prevLayout = **it;
if (prevLayout.pointScaleFactor == pointScaleFactor &&
floatEquality(
prevLayout.measurement.size.width, expectedSize.width) &&
Expand Down Expand Up @@ -312,9 +312,9 @@ Size ParagraphShadowNode::measureContent(
// Layouts carried over from a previous revision may have been prepared
// at another pixel density, which they can't be reused for.
for (const auto& layout : measuredLayouts_) {
if (layout.layoutConstraints == layoutConstraints &&
layout.pointScaleFactor == layoutContext.pointScaleFactor) {
return layout.measurement.size;
if (layout->layoutConstraints == layoutConstraints &&
layout->pointScaleFactor == layoutContext.pointScaleFactor) {
return layout->measurement.size;
}
}
}
Expand All @@ -340,13 +340,15 @@ Size ParagraphShadowNode::measureContent(
preparedLayout, textLayoutContext, layoutConstraints);

measuredLayouts_.push_back(
MeasuredPreparedTextLayout{
.layoutConstraints = layoutConstraints,
.pointScaleFactor = layoutContext.pointScaleFactor,
.measurement = measurement,
// PreparedTextLayout is not trivially copyable on all platforms
// NOLINTNEXTLINE(performance-move-const-arg)
.preparedTextLayout = std::move(preparedLayout)});
std::make_shared<const MeasuredPreparedTextLayout>(
MeasuredPreparedTextLayout{
.layoutConstraints = layoutConstraints,
.pointScaleFactor = layoutContext.pointScaleFactor,
.measurement = measurement,
// PreparedTextLayout is not trivially copyable on all
// platforms
// NOLINTNEXTLINE(performance-move-const-arg)
.preparedTextLayout = std::move(preparedLayout)}));
assert_valid_size(measurement.size, layoutConstraints);
return measurement.size;
}
Expand Down Expand Up @@ -427,12 +429,9 @@ void ParagraphShadowNode::layout(LayoutContext layoutContext) {

// Only this layout can be reused by a later revision (see the copy
// constructor), so drop the others measured for this one.
if (measuredLayouts_.size() > 1) {
auto usedLayout = std::move(*measuredLayout);
measuredLayouts_.clear();
measuredLayouts_.push_back(std::move(usedLayout));
measuredLayout = &measuredLayouts_.back();
}
std::erase_if(measuredLayouts_, [&](const auto& layout) {
return layout.get() != measuredLayout;
});

} else if (ReactNativeFeatureFlags::fixTextLayoutOnPixelDensityChange()) {
MeasuredPreparedTextLayout unpreparedLayout;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class ParagraphShadowNode
* may be used, given the currently assigned layout to the ShadowNode and
* the current pixel density
*/
MeasuredPreparedTextLayout *findUsableLayout(Float pointScaleFactor);
const MeasuredPreparedTextLayout *findUsableLayout(Float pointScaleFactor);

/**
* Returns the final measure of the content frame, before layout rounding
Expand All @@ -145,9 +145,11 @@ class ParagraphShadowNode

/*
* Intermediate layout results generated during measurement, that may be
* reused by the platform.
* reused by the platform. Layouts are immutable once measured, so a clone
* shares them instead of copying them (on Android, copying one creates a
* JNI global reference).
*/
mutable std::vector<MeasuredPreparedTextLayout> measuredLayouts_;
mutable std::vector<std::shared_ptr<const MeasuredPreparedTextLayout>> measuredLayouts_;
};

} // namespace facebook::react
Loading