From 6b9e4ec4b23eec806d7d94564ddd354975e6a6d9 Mon Sep 17 00:00:00 2001 From: Josh Berdine Date: Wed, 4 Nov 2015 08:52:46 -0800 Subject: [PATCH] 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 --- Examples/UIExplorer/TextExample.ios.js | 72 +++++++++++++++++++++++++- Libraries/Text/RCTShadowText.h | 1 + Libraries/Text/RCTShadowText.m | 34 +++++++++--- Libraries/Text/RCTTextManager.m | 1 + 4 files changed, 100 insertions(+), 8 deletions(-) diff --git a/Examples/UIExplorer/TextExample.ios.js b/Examples/UIExplorer/TextExample.ios.js index 0d6e20c10a8..87647da4242 100644 --- a/Examples/UIExplorer/TextExample.ios.js +++ b/Examples/UIExplorer/TextExample.ios.js @@ -239,7 +239,77 @@ exports.examples = [ (and tiny inherited bold blue) - ) + ), + + ) + + + (opacity 1.0 alpha 1.0 back red) + + + (back red + + (opacity 0.5) + + ) + + + (back red + + (alpha 0.5 back red) + + ) + + + (opacity 0.5 back red + + (opacity 0.5) + + ) + + + (alpha 0.5 back red + + (alpha 0.25 back red) + + ) + + + (opacity 0.5 + + (opacity 0.5 back red) + + ) + + + (opacity 0.5 + (back red) + + (opacity 0.5 back red) + + (back red) + ) + + + (opacity 0.5 + (back red) + + (alpha 0.5 back red) + + (back red) + ) + + + (opacity 0.5 back red + + (alpha 0.5 back red) + + ) + + + (opacity 0.5 back red + + (alpha 0.5 back blue) ) diff --git a/Libraries/Text/RCTShadowText.h b/Libraries/Text/RCTShadowText.h index abb11187969..1ded47c93f4 100644 --- a/Libraries/Text/RCTShadowText.h +++ b/Libraries/Text/RCTShadowText.h @@ -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; diff --git a/Libraries/Text/RCTShadowText.m b/Libraries/Text/RCTShadowText.m index b29b5accbb5..e0be76538a1 100644 --- a/Libraries/Text/RCTShadowText.m +++ b/Libraries/Text/RCTShadowText.m @@ -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 { diff --git a/Libraries/Text/RCTTextManager.m b/Libraries/Text/RCTTextManager.m index 4b536cb2967..be63428fcf6 100644 --- a/Libraries/Text/RCTTextManager.m +++ b/Libraries/Text/RCTTextManager.m @@ -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 {