Mimic opacity style of nested Text nodes using alpha color component

Summary: public

Added opacity property to RCTShadowText, and use it to adjust the alpha
color component of nested text nodes when collapsing the RCTShadowText tree
into an NSAttributedString.  The opacity is propagated down the tree,
multiplying the aggregate with the current node's opacity at each step.  Also,
foreground and background colors are propagated down the tree so that in case
a node has an opacity style but no colors, the ancestor's colors can be used
when adjusting the alpha components.

Reviewed By: nicklockwood

Differential Revision: D2600402

fb-gh-sync-id: 2adb7b598b0a73c984bb2edaab545c02ab911c6b
This commit is contained in:
Josh Berdine 2015-11-04 08:52:46 -08:00 committed by facebook-github-bot-3
parent 70c9ee8b1b
commit 6b9e4ec4b2
4 changed files with 100 additions and 8 deletions

View File

@ -239,8 +239,78 @@ exports.examples = [
<Text style={{fontSize: 11, color: '#527fe4'}}>
(and tiny inherited bold blue)
</Text>
),
</Text>
)
</Text>
<Text style={{backgroundColor:'#ffaaaa'}}>
(opacity 1.0 alpha 1.0 back red)
</Text>
<Text style={{backgroundColor:'#ffaaaa'}}>
(back red
<Text style={{opacity:0.5}}>
(opacity 0.5)
</Text>
)
</Text>
<Text style={{backgroundColor:'#ffaaaa'}}>
(back red
<Text style={{color:'rgba(0,0,0,0.5)', backgroundColor:'rgba(255,170,170,0.5)'}}>
(alpha 0.5 back red)
</Text>
)
</Text>
<Text style={{opacity:0.5, backgroundColor:'#ffaaaa'}}>
(opacity 0.5 back red
<Text style={{opacity:0.5}}>
(opacity 0.5)
</Text>
)
</Text>
<Text style={{color:'rgba(0,0,0,0.5)', backgroundColor:'rgba(255,170,170,0.5)'}}>
(alpha 0.5 back red
<Text style={{color:'rgba(0,0,0,0.25)', backgroundColor:'rgba(255,170,170,0.25)'}}>
(alpha 0.25 back red)
</Text>
)
</Text>
<Text style={{opacity:0.5}}>
(opacity 0.5
<Text style={{opacity:0.5, backgroundColor:'#ffaaaa'}}>
(opacity 0.5 back red)
</Text>
)
</Text>
<Text style={{opacity:0.5}}>
(opacity 0.5
<Text style={{backgroundColor:'#ffaaaa'}}>(back red)</Text>
<Text style={{opacity:0.5, backgroundColor:'#ffaaaa'}}>
(opacity 0.5 back red)
</Text>
<Text style={{backgroundColor:'#ffaaaa'}}>(back red)</Text>
)
</Text>
<Text style={{opacity:0.5}}>
(opacity 0.5
<Text style={{backgroundColor:'#ffaaaa'}}>(back red)</Text>
<Text style={{color:'rgba(0,0,0,0.5)', backgroundColor:'rgba(255,170,170,0.5)'}}>
(alpha 0.5 back red)
</Text>
<Text style={{backgroundColor:'#ffaaaa'}}>(back red)</Text>
)
</Text>
<Text style={{opacity:0.5, backgroundColor:'#ffaaaa'}}>
(opacity 0.5 back red
<Text style={{color:'rgba(0,0,0,0.5)', backgroundColor:'rgba(255,170,170,0.5)'}}>
(alpha 0.5 back red)
</Text>
)
</Text>
<Text style={{opacity:0.5, backgroundColor:'#ffaaaa'}}>
(opacity 0.5 back red
<Text style={{color:'rgba(0,0,0,0.5)', backgroundColor:'rgba(170,170,255,0.5)'}}>
(alpha 0.5 back blue)
</Text>
)
</Text>
<Text style={{fontSize: 12}}>

View File

@ -32,6 +32,7 @@ extern NSString *const RCTReactTagAttributeName;
@property (nonatomic, assign) RCTTextDecorationLineType textDecorationLine;
@property (nonatomic, assign) CGFloat fontSizeMultiplier;
@property (nonatomic, assign) BOOL allowFontScaling;
@property (nonatomic, assign) CGFloat opacity;
- (void)recomputeText;

View File

@ -55,6 +55,7 @@ static css_dim_t RCTMeasure(void *context, float width)
_letterSpacing = NAN;
_isHighlighted = NO;
_textDecorationStyle = NSUnderlineStyleSingle;
_opacity = 1.0;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contentSizeMultiplierDidChange:)
name:RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification
@ -152,7 +153,10 @@ static css_dim_t RCTMeasure(void *context, float width)
fontWeight:nil
fontStyle:nil
letterSpacing:nil
useBackgroundColor:NO];
useBackgroundColor:NO
foregroundColor:self.color ?: [UIColor blackColor]
backgroundColor:self.backgroundColor ?: [UIColor whiteColor]
opacity:self.opacity];
}
- (NSAttributedString *)_attributedStringWithFontFamily:(NSString *)fontFamily
@ -161,6 +165,9 @@ static css_dim_t RCTMeasure(void *context, float width)
fontStyle:(NSString *)fontStyle
letterSpacing:(NSNumber *)letterSpacing
useBackgroundColor:(BOOL)useBackgroundColor
foregroundColor:(UIColor *)foregroundColor
backgroundColor:(UIColor *)backgroundColor
opacity:(CGFloat)opacity
{
if (![self isTextDirty] && _cachedAttributedString) {
return _cachedAttributedString;
@ -188,7 +195,16 @@ static css_dim_t RCTMeasure(void *context, float width)
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]];
[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]];
} else if ([child isKindOfClass:[RCTShadowRawText class]]) {
RCTShadowRawText *shadowRawText = (RCTShadowRawText *)child;
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:shadowRawText.text ?: @""]];
@ -208,14 +224,17 @@ static css_dim_t RCTMeasure(void *context, float width)
[child setTextComputed];
}
if (_color) {
[self _addAttribute:NSForegroundColorAttributeName withValue:_color toAttributedString:attributedString];
}
[self _addAttribute:NSForegroundColorAttributeName
withValue:[foregroundColor colorWithAlphaComponent:CGColorGetAlpha(foregroundColor.CGColor) * opacity]
toAttributedString:attributedString];
if (_isHighlighted) {
[self _addAttribute:RCTIsHighlightedAttributeName withValue:@YES toAttributedString:attributedString];
}
if (useBackgroundColor && self.backgroundColor) {
[self _addAttribute:NSBackgroundColorAttributeName withValue:self.backgroundColor toAttributedString:attributedString];
if (useBackgroundColor) {
[self _addAttribute:NSBackgroundColorAttributeName
withValue:[backgroundColor colorWithAlphaComponent:CGColorGetAlpha(backgroundColor.CGColor) * opacity]
toAttributedString:attributedString];
}
UIFont *font = [RCTConvert UIFont:nil withFamily:fontFamily
@ -352,6 +371,7 @@ RCT_TEXT_PROPERTY(TextDecorationColor, _textDecorationColor, UIColor *);
RCT_TEXT_PROPERTY(TextDecorationLine, _textDecorationLine, RCTTextDecorationLineType);
RCT_TEXT_PROPERTY(TextDecorationStyle, _textDecorationStyle, NSUnderlineStyle);
RCT_TEXT_PROPERTY(WritingDirection, _writingDirection, NSWritingDirection)
RCT_TEXT_PROPERTY(Opacity, _opacity, CGFloat)
- (void)setAllowFontScaling:(BOOL)allowFontScaling
{

View File

@ -59,6 +59,7 @@ RCT_EXPORT_SHADOW_PROPERTY(textDecorationColor, UIColor)
RCT_EXPORT_SHADOW_PROPERTY(textDecorationLine, RCTTextDecorationLineType)
RCT_EXPORT_SHADOW_PROPERTY(writingDirection, NSWritingDirection)
RCT_EXPORT_SHADOW_PROPERTY(allowFontScaling, BOOL)
RCT_EXPORT_SHADOW_PROPERTY(opacity, CGFloat)
- (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(RCTSparseArray *)shadowViewRegistry
{