mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-23 03:50:11 +08:00
Test perf effect of reverting D3269333
Reviewed By: javache Differential Revision: D3346235 fbshipit-source-id: 2008f8fb9df5d61da59bb0067b25acd5a71f256f
This commit is contained in:
committed by
Facebook Github Bot 8
parent
60e0d2c676
commit
a4b5f1bf10
@@ -13,12 +13,12 @@
|
||||
#import "RCTUIManager.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTImageComponent.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTShadowRawText.h"
|
||||
#import "RCTText.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
NSString *const RCTShadowViewAttributeName = @"RCTShadowViewAttributeName";
|
||||
NSString *const RCTIsHighlightedAttributeName = @"IsHighlightedAttributeName";
|
||||
NSString *const RCTReactTagAttributeName = @"ReactTagAttributeName";
|
||||
|
||||
@@ -114,45 +114,6 @@ static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t width
|
||||
[self dirtyPropagation];
|
||||
}
|
||||
|
||||
- (void)applyLayoutToChildren:(css_node_t *)node
|
||||
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
|
||||
absolutePosition:(CGPoint)absolutePosition
|
||||
{
|
||||
// Run layout on subviews.
|
||||
NSTextStorage *textStorage = [self buildTextStorageForWidth:self.frame.size.width widthMode:CSS_MEASURE_MODE_EXACTLY];
|
||||
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
|
||||
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
|
||||
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
|
||||
NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
|
||||
[layoutManager.textStorage enumerateAttribute:RCTShadowViewAttributeName inRange:characterRange options:0 usingBlock:^(RCTShadowView *child, NSRange range, BOOL *_) {
|
||||
if (child != nil) {
|
||||
css_node_t *childNode = child.cssNode;
|
||||
float width = childNode->style.dimensions[CSS_WIDTH];
|
||||
float height = childNode->style.dimensions[CSS_HEIGHT];
|
||||
if (isUndefined(width) || isUndefined(height)) {
|
||||
RCTLogError(@"Views nested within a <Text> must have a width and height");
|
||||
}
|
||||
UIFont *font = [textStorage attribute:NSFontAttributeName atIndex:range.location effectiveRange:nil];
|
||||
CGRect glyphRect = [layoutManager boundingRectForGlyphRange:range inTextContainer:textContainer];
|
||||
CGRect childFrame = {{
|
||||
RCTRoundPixelValue(glyphRect.origin.x),
|
||||
RCTRoundPixelValue(glyphRect.origin.y + glyphRect.size.height - height + font.descender)
|
||||
}, {
|
||||
RCTRoundPixelValue(width),
|
||||
RCTRoundPixelValue(height)
|
||||
}};
|
||||
|
||||
NSRange truncatedGlyphRange = [layoutManager truncatedGlyphRangeInLineFragmentForGlyphAtIndex:range.location];
|
||||
BOOL childIsTruncated = NSIntersectionRange(range, truncatedGlyphRange).length != 0;
|
||||
|
||||
[child collectUpdatedFrames:viewsWithNewFrame
|
||||
withFrame:childFrame
|
||||
hidden:childIsTruncated
|
||||
absolutePosition:absolutePosition];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(css_measure_mode_t)widthMode
|
||||
{
|
||||
if (_cachedTextStorage && width == _cachedTextStorageWidth && widthMode == _cachedTextStorageWidthMode) {
|
||||
@@ -238,48 +199,33 @@ static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t width
|
||||
|
||||
_effectiveLetterSpacing = letterSpacing.doubleValue;
|
||||
|
||||
UIFont *font = [RCTConvert UIFont:nil withFamily:fontFamily
|
||||
size:fontSize weight:fontWeight style:fontStyle
|
||||
scaleMultiplier:_allowFontScaling ? _fontSizeMultiplier : 1.0];
|
||||
|
||||
CGFloat heightOfTallestSubview = 0.0;
|
||||
NSMutableAttributedString *attributedString = [NSMutableAttributedString new];
|
||||
for (RCTShadowView *child in [self reactSubviews]) {
|
||||
if ([child isKindOfClass:[RCTShadowText class]]) {
|
||||
RCTShadowText *shadowText = (RCTShadowText *)child;
|
||||
[attributedString appendAttributedString:
|
||||
[shadowText _attributedStringWithFontFamily:fontFamily
|
||||
fontSize:fontSize
|
||||
fontWeight:fontWeight
|
||||
fontStyle:fontStyle
|
||||
letterSpacing:letterSpacing
|
||||
useBackgroundColor:YES
|
||||
foregroundColor:shadowText.color ?: foregroundColor
|
||||
backgroundColor:shadowText.backgroundColor ?: backgroundColor
|
||||
opacity:opacity * shadowText.opacity]];
|
||||
[child setTextComputed];
|
||||
[shadowText _attributedStringWithFontFamily:fontFamily
|
||||
fontSize:fontSize
|
||||
fontWeight:fontWeight
|
||||
fontStyle:fontStyle
|
||||
letterSpacing:letterSpacing
|
||||
useBackgroundColor:YES
|
||||
foregroundColor:shadowText.color ?: foregroundColor
|
||||
backgroundColor:shadowText.backgroundColor ?: backgroundColor
|
||||
opacity:opacity * shadowText.opacity]];
|
||||
} else if ([child isKindOfClass:[RCTShadowRawText class]]) {
|
||||
RCTShadowRawText *shadowRawText = (RCTShadowRawText *)child;
|
||||
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:shadowRawText.text ?: @""]];
|
||||
[child setTextComputed];
|
||||
} else if ([child conformsToProtocol:@protocol(RCTImageComponent)]) {
|
||||
NSTextAttachment *imageAttachment = [NSTextAttachment new];
|
||||
imageAttachment.image = ((id<RCTImageComponent>)child).image;
|
||||
imageAttachment.bounds = (CGRect){CGPointZero, {RCTZeroIfNaN(child.width), RCTZeroIfNaN(child.height)}};
|
||||
[attributedString appendAttributedString:[NSAttributedString attributedStringWithAttachment:imageAttachment]];
|
||||
} else {
|
||||
float width = child.cssNode->style.dimensions[CSS_WIDTH];
|
||||
float height = child.cssNode->style.dimensions[CSS_HEIGHT];
|
||||
if (isUndefined(width) || isUndefined(height)) {
|
||||
RCTLogError(@"Views nested within a <Text> must have a width and height");
|
||||
}
|
||||
NSTextAttachment *attachment = [NSTextAttachment new];
|
||||
attachment.bounds = (CGRect){CGPointZero, {width, height}};
|
||||
NSMutableAttributedString *attachmentString = [NSMutableAttributedString new];
|
||||
[attachmentString appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
|
||||
[attachmentString addAttribute:RCTShadowViewAttributeName value:child range:(NSRange){0, attachmentString.length}];
|
||||
[attributedString appendAttributedString:attachmentString];
|
||||
if (height > heightOfTallestSubview) {
|
||||
heightOfTallestSubview = height;
|
||||
}
|
||||
// Don't call setTextComputed on this child. RCTTextManager takes care of
|
||||
// processing inline UIViews.
|
||||
RCTLogError(@"<Text> can't have any children except <Text>, <Image> or raw strings");
|
||||
}
|
||||
|
||||
[child setTextComputed];
|
||||
}
|
||||
|
||||
[self _addAttribute:NSForegroundColorAttributeName
|
||||
@@ -295,10 +241,13 @@ static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t width
|
||||
toAttributedString:attributedString];
|
||||
}
|
||||
|
||||
UIFont *font = [RCTConvert UIFont:nil withFamily:fontFamily
|
||||
size:fontSize weight:fontWeight style:fontStyle
|
||||
scaleMultiplier:_allowFontScaling ? _fontSizeMultiplier : 1.0];
|
||||
[self _addAttribute:NSFontAttributeName withValue:font toAttributedString:attributedString];
|
||||
[self _addAttribute:NSKernAttributeName withValue:letterSpacing toAttributedString:attributedString];
|
||||
[self _addAttribute:RCTReactTagAttributeName withValue:self.reactTag toAttributedString:attributedString];
|
||||
[self _setParagraphStyleOnAttributedString:attributedString heightOfTallestSubview:heightOfTallestSubview];
|
||||
[self _setParagraphStyleOnAttributedString:attributedString];
|
||||
|
||||
// create a non-mutable attributedString for use by the Text system which avoids copies down the line
|
||||
_cachedAttributedString = [[NSAttributedString alloc] initWithAttributedString:attributedString];
|
||||
@@ -321,7 +270,6 @@ static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t width
|
||||
* varying lineHeights, we simply take the max.
|
||||
*/
|
||||
- (void)_setParagraphStyleOnAttributedString:(NSMutableAttributedString *)attributedString
|
||||
heightOfTallestSubview:(CGFloat)heightOfTallestSubview
|
||||
{
|
||||
// check if we have lineHeight set on self
|
||||
__block BOOL hasParagraphStyle = NO;
|
||||
@@ -329,7 +277,9 @@ static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t width
|
||||
hasParagraphStyle = YES;
|
||||
}
|
||||
|
||||
__block float newLineHeight = _lineHeight ?: 0.0;
|
||||
if (!_lineHeight) {
|
||||
self.lineHeight = 0.0;
|
||||
}
|
||||
|
||||
CGFloat fontSizeMultiplier = _allowFontScaling ? _fontSizeMultiplier : 1.0;
|
||||
|
||||
@@ -338,25 +288,15 @@ static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t width
|
||||
if (value) {
|
||||
NSParagraphStyle *paragraphStyle = (NSParagraphStyle *)value;
|
||||
CGFloat maximumLineHeight = round(paragraphStyle.maximumLineHeight / fontSizeMultiplier);
|
||||
if (maximumLineHeight > newLineHeight) {
|
||||
newLineHeight = maximumLineHeight;
|
||||
if (maximumLineHeight > self.lineHeight) {
|
||||
self.lineHeight = maximumLineHeight;
|
||||
}
|
||||
hasParagraphStyle = YES;
|
||||
}
|
||||
}];
|
||||
|
||||
if (self.lineHeight != newLineHeight) {
|
||||
self.lineHeight = newLineHeight;
|
||||
}
|
||||
|
||||
NSTextAlignment newTextAlign = _textAlign ?: NSTextAlignmentNatural;
|
||||
if (self.textAlign != newTextAlign) {
|
||||
self.textAlign = newTextAlign;
|
||||
}
|
||||
NSWritingDirection newWritingDirection = _writingDirection ?: NSWritingDirectionNatural;
|
||||
if (self.writingDirection != newWritingDirection) {
|
||||
self.writingDirection = newWritingDirection;
|
||||
}
|
||||
self.textAlign = _textAlign ?: NSTextAlignmentNatural;
|
||||
self.writingDirection = _writingDirection ?: NSWritingDirectionNatural;
|
||||
|
||||
// if we found anything, set it :D
|
||||
if (hasParagraphStyle) {
|
||||
@@ -364,9 +304,6 @@ static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t width
|
||||
paragraphStyle.alignment = _textAlign;
|
||||
paragraphStyle.baseWritingDirection = _writingDirection;
|
||||
CGFloat lineHeight = round(_lineHeight * fontSizeMultiplier);
|
||||
if (heightOfTallestSubview > lineHeight) {
|
||||
lineHeight = ceilf(heightOfTallestSubview);
|
||||
}
|
||||
paragraphStyle.minimumLineHeight = lineHeight;
|
||||
paragraphStyle.maximumLineHeight = lineHeight;
|
||||
[attributedString addAttribute:NSParagraphStyleAttributeName
|
||||
|
||||
@@ -13,17 +13,6 @@
|
||||
#import "RCTUtils.h"
|
||||
#import "UIView+React.h"
|
||||
|
||||
static void collectNonTextDescendants(RCTText *view, NSMutableArray *nonTextDescendants)
|
||||
{
|
||||
for (UIView *child in view.reactSubviews) {
|
||||
if ([child isKindOfClass:[RCTText class]]) {
|
||||
collectNonTextDescendants((RCTText *)child, nonTextDescendants);
|
||||
} else {
|
||||
[nonTextDescendants addObject:child];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@implementation RCTText
|
||||
{
|
||||
NSTextStorage *_textStorage;
|
||||
@@ -130,15 +119,6 @@ static void collectNonTextDescendants(RCTText *view, NSMutableArray *nonTextDesc
|
||||
[_highlightLayer removeFromSuperlayer];
|
||||
_highlightLayer = nil;
|
||||
}
|
||||
|
||||
for (UIView *child in [self subviews]) {
|
||||
[child removeFromSuperview];
|
||||
}
|
||||
NSMutableArray *nonTextDescendants = [NSMutableArray new];
|
||||
collectNonTextDescendants(self, nonTextDescendants);
|
||||
for (UIView *child in nonTextDescendants) {
|
||||
[self addSubview:child];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSNumber *)reactTagAtPoint:(CGPoint)point
|
||||
|
||||
@@ -20,18 +20,6 @@
|
||||
#import "RCTTextView.h"
|
||||
#import "UIView+React.h"
|
||||
|
||||
static void collectDirtyNonTextDescendants(RCTShadowText *shadowView, NSMutableArray *nonTextDescendants) {
|
||||
for (RCTShadowView *child in shadowView.reactSubviews) {
|
||||
if ([child isKindOfClass:[RCTShadowText class]]) {
|
||||
collectDirtyNonTextDescendants((RCTShadowText *)child, nonTextDescendants);
|
||||
} else if ([child isKindOfClass:[RCTShadowRawText class]]) {
|
||||
// no-op
|
||||
} else if ([child isTextDirty]) {
|
||||
[nonTextDescendants addObject:child];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@interface RCTShadowText (Private)
|
||||
|
||||
- (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(css_measure_mode_t)widthMode;
|
||||
@@ -97,7 +85,6 @@ RCT_EXPORT_SHADOW_PROPERTY(textShadowColor, UIColor)
|
||||
if ([shadowView isKindOfClass:[RCTShadowText class]]) {
|
||||
((RCTShadowText *)shadowView).fontSizeMultiplier = self.bridge.accessibilityManager.multiplier;
|
||||
[(RCTShadowText *)shadowView recomputeText];
|
||||
collectDirtyNonTextDescendants((RCTShadowText *)shadowView, queue);
|
||||
} else if ([shadowView isKindOfClass:[RCTShadowRawText class]]) {
|
||||
RCTLogError(@"Raw text cannot be used outside of a <Text> tag. Not rendering string: '%@'",
|
||||
[(RCTShadowRawText *)shadowView text]);
|
||||
|
||||
Reference in New Issue
Block a user