Fabric: Caching for `NSAttributedString`s in RCTTextLayoutManager

Summary:
Creation NSAttributedString from attributedString is not so cheap process, so with this simple cache we hopefully can save a couple milliseconds.
The same string is used at least two times: first time for measuring and second for drawing.

Reviewed By: mdvacca

Differential Revision: D14296514

fbshipit-source-id: 6313aa2c6e9f63d873868131750f61c02d64d2de
This commit is contained in:
Valentin Shergin 2019-03-03 12:04:03 -08:00 коммит произвёл Facebook Github Bot
Родитель 15ee4545f4
Коммит 17cb6a8aeb
1 изменённых файлов: 27 добавлений и 16 удалений

Просмотреть файл

@ -10,9 +10,13 @@
#import "NSTextStorage+FontScaling.h"
#import "RCTAttributedTextUtils.h"
#import <react/utils/SimpleThreadSafeCache.h>
using namespace facebook::react;
@implementation RCTTextLayoutManager
@implementation RCTTextLayoutManager {
SimpleThreadSafeCache<AttributedString, std::shared_ptr<const void>, 256> _cache;
}
static NSLineBreakMode RCTNSLineBreakModeFromWritingDirection(
EllipsizeMode ellipsizeMode) {
@ -34,11 +38,10 @@ static NSLineBreakMode RCTNSLineBreakModeFromWritingDirection(
layoutConstraints:(LayoutConstraints)layoutConstraints {
CGSize maximumSize = CGSize{layoutConstraints.maximumSize.width,
layoutConstraints.maximumSize.height};
NSTextStorage *textStorage =
[self _textStorageAndLayoutManagerWithAttributesString:
RCTNSAttributedStringFromAttributedString(attributedString)
paragraphAttributes:paragraphAttributes
size:maximumSize];
NSTextStorage *textStorage = [self
_textStorageAndLayoutManagerWithAttributesString:[self _nsAttributedStringFromAttributedString:attributedString]
paragraphAttributes:paragraphAttributes
size:maximumSize];
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
@ -55,11 +58,10 @@ static NSLineBreakMode RCTNSLineBreakModeFromWritingDirection(
- (void)drawAttributedString:(AttributedString)attributedString
paragraphAttributes:(ParagraphAttributes)paragraphAttributes
frame:(CGRect)frame {
NSTextStorage *textStorage =
[self _textStorageAndLayoutManagerWithAttributesString:
RCTNSAttributedStringFromAttributedString(attributedString)
paragraphAttributes:paragraphAttributes
size:frame.size];
NSTextStorage *textStorage = [self
_textStorageAndLayoutManagerWithAttributesString:[self _nsAttributedStringFromAttributedString:attributedString]
paragraphAttributes:paragraphAttributes
size:frame.size];
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
@ -111,11 +113,10 @@ static NSLineBreakMode RCTNSLineBreakModeFromWritingDirection(
paragraphAttributes:(ParagraphAttributes)paragraphAttributes
frame:(CGRect)frame
atPoint:(CGPoint)point {
NSTextStorage *textStorage =
[self _textStorageAndLayoutManagerWithAttributesString:
RCTNSAttributedStringFromAttributedString(attributedString)
paragraphAttributes:paragraphAttributes
size:frame.size];
NSTextStorage *textStorage = [self
_textStorageAndLayoutManagerWithAttributesString:[self _nsAttributedStringFromAttributedString:attributedString]
paragraphAttributes:paragraphAttributes
size:frame.size];
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
@ -140,4 +141,14 @@ static NSLineBreakMode RCTNSLineBreakModeFromWritingDirection(
return nil;
}
- (NSAttributedString *)_nsAttributedStringFromAttributedString:(AttributedString)attributedString
{
auto sharedNSAttributedString = _cache.get(attributedString, [](const AttributedString attributedString) {
return std::shared_ptr<void>(
(__bridge_retained void *)RCTNSAttributedStringFromAttributedString(attributedString), CFRelease);
});
return (__bridge NSAttributedString *)sharedNSAttributedString.get();
}
@end