@@ -35,34 +35,32 @@ @interface ASTextNodeDrawParameters : NSObject
3535
3636- (instancetype )initWithRenderer : (ASTextKitRenderer *)renderer
3737 textOrigin : (CGPoint)textOrigin
38- backgroundColor : (CGColorRef )backgroundColor ;
38+ backgroundColor : (UIColor * )backgroundColor ;
3939
4040@property (nonatomic , strong , readonly ) ASTextKitRenderer *renderer;
4141
4242@property (nonatomic , assign , readonly ) CGPoint textOrigin;
4343
44- @property (nonatomic , assign , readonly ) CGColorRef backgroundColor;
44+ @property (nonatomic , strong , readonly ) UIColor * backgroundColor;
4545
4646@end
4747
4848@implementation ASTextNodeDrawParameters
4949
5050- (instancetype )initWithRenderer : (ASTextKitRenderer *)renderer
5151 textOrigin : (CGPoint)textOrigin
52- backgroundColor : (CGColorRef )backgroundColor
52+ backgroundColor : (UIColor * )backgroundColor
5353{
5454 if (self = [super init ]) {
5555 _renderer = renderer;
5656 _textOrigin = textOrigin;
57- _backgroundColor = CGColorRetain ( backgroundColor) ;
57+ _backgroundColor = backgroundColor;
5858 }
5959 return self;
6060}
6161
6262- (void )dealloc
6363{
64- CGColorRelease (_backgroundColor);
65-
6664 // Destruction of the layout managers/containers/text storage is quite
6765 // expensive, and can take some time, so we dispatch onto a bg queue to
6866 // actually dealloc.
@@ -182,7 +180,7 @@ - (NSString *)description
182180 NSString *truncationString = [_composedTruncationString string ];
183181 if (plainString.length > 50 )
184182 plainString = [[plainString substringToIndex: 50 ] stringByAppendingString: @" \u2026 " ];
185- return [NSString stringWithFormat: @" <%@ : %p ; text = \" %@ \" ; truncation string = \" %@ \" ; frame = %@ >" , self .class , self, plainString, truncationString, self.nodeLoaded ? NSStringFromCGRect(self .layer.frame) : nil ];
183+ return [NSString stringWithFormat: @" <%@ : %p ; text = \" %@ \" ; truncation string = \" %@ \" ; frame = %@ ; renderer = %p >" , self .class , self, plainString, truncationString, self.nodeLoaded ? NSStringFromCGRect(self .layer.frame) : nil , _renderer ];
186184}
187185
188186#pragma mark - ASDisplayNode
@@ -240,13 +238,13 @@ - (void)didLoad
240238- (void )setFrame : (CGRect)frame
241239{
242240 [super setFrame: frame];
243- [self _invalidateRendererIfNeeded : frame.size];
241+ [self _invalidateRendererIfNeededForBoundsSize : frame.size];
244242}
245243
246244- (void )setBounds : (CGRect)bounds
247245{
248246 [super setBounds: bounds];
249- [self _invalidateRendererIfNeeded : bounds.size];
247+ [self _invalidateRendererIfNeededForBoundsSize : bounds.size];
250248}
251249
252250#pragma mark - Renderer Management
@@ -291,12 +289,12 @@ - (void)_invalidateRenderer
291289
292290- (void )_invalidateRendererIfNeeded
293291{
294- [self _invalidateRendererIfNeeded :self .bounds.size];
292+ [self _invalidateRendererIfNeededForBoundsSize :self .bounds.size];
295293}
296294
297- - (void )_invalidateRendererIfNeeded : (CGSize)newSize
295+ - (void )_invalidateRendererIfNeededForBoundsSize : (CGSize)boundsSize
298296{
299- if ([self _needInvalidateRenderer: newSize ]) {
297+ if ([self _needInvalidateRendererForBoundsSize: boundsSize ]) {
300298 // Our bounds of frame have changed to a size that is not identical to our constraining size,
301299 // so our previous layout information is invalid, and TextKit may draw at the
302300 // incorrect origin.
@@ -305,17 +303,17 @@ - (void)_invalidateRendererIfNeeded:(CGSize)newSize
305303 }
306304}
307305
308- - (BOOL )_needInvalidateRenderer : (CGSize)newSize
306+ - (BOOL )_needInvalidateRendererForBoundsSize : (CGSize)boundsSize
309307{
310308 if (!_renderer) {
311309 return YES ;
312310 }
313311
314312 // If the size is not the same as the constraint we provided to the renderer, start out assuming we need
315313 // a new one. However, there are common cases where the constrained size doesn't need to be the same as calculated.
316- CGSize oldSize = _renderer.constrainedSize ;
314+ CGSize rendererConstrainedSize = _renderer.constrainedSize ;
317315
318- if (CGSizeEqualToSize (newSize, oldSize )) {
316+ if (CGSizeEqualToSize (boundsSize, rendererConstrainedSize )) {
319317 return NO ;
320318 } else {
321319 // It is very common to have a constrainedSize with a concrete, specific width but +Inf height.
@@ -324,7 +322,12 @@ - (BOOL)_needInvalidateRenderer:(CGSize)newSize
324322 // experience truncation and don't need to recreate the renderer with the size it already calculated,
325323 // as this would essentially serve to set its constrainedSize to be its calculatedSize (unnecessary).
326324 ASLayout *layout = self.calculatedLayout ;
327- if (layout != nil && CGSizeEqualToSize (newSize, layout.size )) {
325+ if (layout != nil && CGSizeEqualToSize (boundsSize, layout.size )) {
326+ if (!CGSizeEqualToSize (boundsSize, rendererConstrainedSize)) {
327+ // Don't bother changing _constrainedSize, as ASDisplayNode's -measure: method would have a cache miss
328+ // and ask us to recalculate layout if it were called with the same calculatedSize that got us to this point!
329+ _renderer.constrainedSize = boundsSize;
330+ }
328331 return NO ;
329332 } else {
330333 return YES ;
@@ -409,12 +412,10 @@ + (void)drawRect:(CGRect)bounds withParameters:(ASTextNodeDrawParameters *)param
409412
410413 // Fill background
411414 if (!isRasterizing) {
412- CGColorRef backgroundColor = parameters.backgroundColor ;
415+ UIColor * backgroundColor = parameters.backgroundColor ;
413416 if (backgroundColor) {
414- CGContextSetFillColorWithColor (context, backgroundColor);
415- CGContextSetBlendMode (context, kCGBlendModeCopy );
416- CGContextFillRect (context, CGContextGetClipBoundingBox (context));
417- CGContextSetBlendMode (context, kCGBlendModeNormal );
417+ [backgroundColor setFill ];
418+ UIRectFillUsingBlendMode (CGContextGetClipBoundingBox (context), kCGBlendModeCopy );
418419 }
419420 }
420421
@@ -430,14 +431,15 @@ + (void)drawRect:(CGRect)bounds withParameters:(ASTextNodeDrawParameters *)param
430431
431432- (NSObject *)drawParametersForAsyncLayer : (_ASDisplayLayer *)layer
432433{
433- [self _invalidateRendererIfNeeded ];
434+ CGRect bounds = self.bounds ;
435+ [self _invalidateRendererIfNeededForBoundsSize: bounds.size];
434436
435437 // Offset the text origin by any shadow padding
436438 UIEdgeInsets shadowPadding = [self shadowPadding ];
437- CGPoint textOrigin = CGPointMake (self. bounds .origin .x - shadowPadding.left , self. bounds .origin .y - shadowPadding.top );
439+ CGPoint textOrigin = CGPointMake (bounds.origin .x - shadowPadding.left , bounds.origin .y - shadowPadding.top );
438440 return [[ASTextNodeDrawParameters alloc ] initWithRenderer: [self _renderer ]
439441 textOrigin: textOrigin
440- backgroundColor: self .backgroundColor.CGColor ];
442+ backgroundColor: self .backgroundColor];
441443}
442444
443445#pragma mark - Attributes
0 commit comments