mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Summary:
Here the deal with the clamp thing:
A layout engine asks nodes to measure their content providing layout constraints (min and max size) and that would be kind from nodes to return a result that in space of those constraints. Sometimes, satisfying that is an additional separate step of that operation, e.g. if we know that the intrinsic size of some node is `{100, 100}`, we need to clamp that to satisfy constraint `[min: {200, 200}, max: {inf, inf}]`.
In case when we need to cache measure information, it becomes tricky enough when we need to make the cache work most efficiently. For the case of measuring Text, we have an insight: the available maximum width is important, the rest three metrics (maximum height and minimum size) are not.
That means that any changes in those three metrics don't affect the actual measurement result but will affect the final value because the actual value will be clamped by constraints that didn't influence measuring in the first place.
That's why moving clamping outside of a cache is the first step into making it more efficient.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D18848584
fbshipit-source-id: 8feeb3f1a9d0e9691abac8be43639487a626fec3
72 lines
2.1 KiB
Plaintext
72 lines
2.1 KiB
Plaintext
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#include "TextLayoutManager.h"
|
|
|
|
#include <react/utils/ManagedObjectWrapper.h>
|
|
|
|
#import "RCTTextLayoutManager.h"
|
|
|
|
namespace facebook {
|
|
namespace react {
|
|
|
|
TextLayoutManager::TextLayoutManager(ContextContainer::Shared const &contextContainer)
|
|
{
|
|
self_ = (__bridge_retained void *)[RCTTextLayoutManager new];
|
|
}
|
|
|
|
TextLayoutManager::~TextLayoutManager()
|
|
{
|
|
CFRelease(self_);
|
|
self_ = nullptr;
|
|
}
|
|
|
|
void *TextLayoutManager::getNativeTextLayoutManager() const
|
|
{
|
|
assert(self_ && "Stored NativeTextLayoutManager must not be null.");
|
|
return self_;
|
|
}
|
|
|
|
Size TextLayoutManager::measure(
|
|
AttributedStringBox attributedStringBox,
|
|
ParagraphAttributes paragraphAttributes,
|
|
LayoutConstraints layoutConstraints) const
|
|
{
|
|
RCTTextLayoutManager *textLayoutManager = (__bridge RCTTextLayoutManager *)self_;
|
|
|
|
auto size = Size{};
|
|
|
|
switch (attributedStringBox.getMode()) {
|
|
case AttributedStringBox::Mode::Value: {
|
|
auto &attributedString = attributedStringBox.getValue();
|
|
|
|
size = measureCache_.get(
|
|
{attributedString, paragraphAttributes, layoutConstraints}, [&](TextMeasureCacheKey const &key) {
|
|
return [textLayoutManager measureAttributedString:attributedString
|
|
paragraphAttributes:paragraphAttributes
|
|
layoutConstraints:layoutConstraints];
|
|
});
|
|
break;
|
|
}
|
|
|
|
case AttributedStringBox::Mode::OpaquePointer: {
|
|
NSAttributedString *nsAttributedString =
|
|
(NSAttributedString *)unwrapManagedObject(attributedStringBox.getOpaquePointer());
|
|
|
|
size = [textLayoutManager measureNSAttributedString:nsAttributedString
|
|
paragraphAttributes:paragraphAttributes
|
|
layoutConstraints:layoutConstraints];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return layoutConstraints.clamp(size);
|
|
}
|
|
|
|
} // namespace react
|
|
} // namespace facebook
|