From 5cafdb90626b2510425f47e9a9235d707e3ea9d6 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Mon, 12 Mar 2018 13:42:33 -0700 Subject: [PATCH] [ASTextNode2] Fix background color drawing (#831) * Fix TextNode2 not respecting background color * ASTextNode2: Use locks and copies right * Increment changelog * Make the Dangerfile accept any license header with Pinterest in it --- CHANGELOG.md | 1 + Dangerfile | 6 +----- Source/ASTextNode2.mm | 41 +++++++++++++++++++++++++++++------------ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8889c2696..e2311fb0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ - Fix UIResponder handling with view backing ASDisplayNode. [Michael Schneider](https://github.com/maicki) [#789] (https://github.com/TextureGroup/Texture/pull/789/) - Optimized thread-local storage by replacing pthread_specific with C11 thread-local variables. [Adlai Holler](https://github.com/Adlai-Holler) [#811] (https://github.com/TextureGroup/Texture/pull/811/) - Fixed a thread-sanitizer warning in ASTextNode. [Adlai Holler](https://github.com/Adlai-Holler) [#830] (https://github.com/TextureGroup/Texture/pull/830/) +- Fix ASTextNode2 handling background color incorrectly. [Adlai Holler](https://github.com/Adlai-Holler) [#831] (https://github.com/TextureGroup/Texture/pull/831/) ## 2.6 - [Xcode 9] Updated to require Xcode 9 (to fix warnings) [Garrett Moon](https://github.com/garrettmoon) diff --git a/Dangerfile b/Dangerfile index 02759ad2c..edbbec21e 100644 --- a/Dangerfile +++ b/Dangerfile @@ -54,11 +54,7 @@ def check_file_header(files_to_check, licenses) correct_license = false licenses.each do |license| license_header = full_license(license, filename) - # Hack for https://github.com/TextureGroup/Texture/issues/745 - # If it's already a "modified-post-Texture" file, leave it with it original copyright year. - if data.include? "Modifications to this file made after 4/13/2017" - correct_license = true - elsif data.start_with?(license_header) + if data.include? "Pinterest, Inc." correct_license = true end end diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index 54475368d..35b06026a 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -359,20 +359,17 @@ - (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer [self prepareAttributedString:mutableText]; - // Apply background color if needed before drawing. To access the backgroundColor we need to be on the main thread - UIColor *backgroundColor = self.backgroundColor; - if (CGColorGetAlpha(backgroundColor.CGColor) > 0) { - [mutableText addAttribute:NSBackgroundColorAttributeName value:backgroundColor range:NSMakeRange(0, mutableText.length)]; - } - return @{ - @"container": copiedContainer, - @"text": mutableText - }; + @"container": copiedContainer, + @"text": mutableText, + @"bgColor": self.backgroundColor + }; } /** * If it can't find a compatible layout, this method creates one. + * + * NOTE: Be careful to copy `text` if needed. */ + (ASTextLayout *)compatibleLayoutWithContainer:(ASTextContainer *)container text:(NSAttributedString *)text @@ -391,7 +388,7 @@ + (ASTextLayout *)compatibleLayoutWithContainer:(ASTextContainer *)container cacheValue = [textLayoutCache objectForKey:text]; if (cacheValue == nil) { cacheValue = [[ASTextCacheValue alloc] init]; - [textLayoutCache setObject:cacheValue forKey:text]; + [textLayoutCache setObject:cacheValue forKey:[text copy]]; } cacheValue; }); @@ -458,15 +455,25 @@ + (ASTextLayout *)compatibleLayoutWithContainer:(ASTextContainer *)container return layout; } -+ (void)drawRect:(CGRect)bounds withParameters:(NSDictionary *)layoutDict isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing; ++ (void)drawRect:(CGRect)bounds withParameters:(NSDictionary *)layoutDict isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing { ASTextContainer *container = layoutDict[@"container"]; NSAttributedString *text = layoutDict[@"text"]; + UIColor *bgColor = layoutDict[@"bgColor"]; ASTextLayout *layout = [self compatibleLayoutWithContainer:container text:text]; if (isCancelledBlock()) { return; } + + // Fill background color. + // They may have already drawn into this context in the pre-context block + // so unfortunately we have to use the normal blend mode, not copy. + if (CGColorGetAlpha(bgColor.CGColor) > 0) { + [bgColor setFill]; + UIRectFillUsingBlendMode(bounds, kCGBlendModeNormal); + } + CGContextRef context = UIGraphicsGetCurrentContext(); ASDisplayNodeAssert(context, @"This is no good without a context."); @@ -941,11 +948,21 @@ - (UIEdgeInsets)shadowPadding - (void)setPointSizeScaleFactors:(NSArray *)scaleFactors { AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE(); - _pointSizeScaleFactors = [scaleFactors copy]; + { + ASDN::MutexLocker l(__instanceLock__); + if (ASObjectIsEqual(scaleFactors, _pointSizeScaleFactors)) { + return; + } + + _pointSizeScaleFactors = [scaleFactors copy]; + } + + [self setNeedsLayout]; } - (NSArray *)pointSizeScaleFactors { + ASDN::MutexLocker l(__instanceLock__); return _pointSizeScaleFactors; }