From e0f926c86149e426b3765a4dfc26f21e1326fe75 Mon Sep 17 00:00:00 2001 From: Nadine Salter Date: Sun, 25 Jan 2015 16:24:10 -0800 Subject: [PATCH] Switch ASTextKitComponents interface C -> ObjC. --- AsyncDisplayKit/ASEditableTextNode.mm | 6 +-- AsyncDisplayKit/Details/ASTextNodeRenderer.mm | 3 +- .../Details/ASTextNodeTextKitHelpers.h | 35 ++++++++-------- .../Details/ASTextNodeTextKitHelpers.mm | 41 ++++++++++--------- .../ASTextNodeWordKernerTests.mm | 12 +++--- 5 files changed, 50 insertions(+), 47 deletions(-) diff --git a/AsyncDisplayKit/ASEditableTextNode.mm b/AsyncDisplayKit/ASEditableTextNode.mm index 70e02b495b..e5899f51c4 100644 --- a/AsyncDisplayKit/ASEditableTextNode.mm +++ b/AsyncDisplayKit/ASEditableTextNode.mm @@ -74,12 +74,12 @@ _displayingPlaceholder = YES; // Create the scaffolding for the text view. - _textKitComponents = ASTextKitComponentsCreate(nil, CGSizeZero); + _textKitComponents = [ASTextKitComponents componentsWithAttributedSeedString:nil textContainerSize:CGSizeZero]; _textKitComponents.layoutManager.delegate = self; _wordKerner = [[ASTextNodeWordKerner alloc] init]; // Create the placeholder scaffolding. - _placeholderTextKitComponents = ASTextKitComponentsCreate(nil, CGSizeZero); + _placeholderTextKitComponents = [ASTextKitComponents componentsWithAttributedSeedString:nil textContainerSize:CGSizeZero]; _placeholderTextKitComponents.layoutManager.delegate = self; return self; @@ -134,7 +134,7 @@ - (CGSize)calculateSizeThatFits:(CGSize)constrainedSize { ASTextKitComponents *displayedComponents = [self isDisplayingPlaceholder] ? _placeholderTextKitComponents : _textKitComponents; - CGSize textSize = ASTextKitComponentsSizeForConstrainedWidth(displayedComponents, constrainedSize.width); + CGSize textSize = [displayedComponents sizeForConstrainedWidth:constrainedSize.width]; return CGSizeMake(constrainedSize.width, fminf(textSize.height, constrainedSize.height)); } diff --git a/AsyncDisplayKit/Details/ASTextNodeRenderer.mm b/AsyncDisplayKit/Details/ASTextNodeRenderer.mm index 2771b4e549..d422114cf7 100644 --- a/AsyncDisplayKit/Details/ASTextNodeRenderer.mm +++ b/AsyncDisplayKit/Details/ASTextNodeRenderer.mm @@ -505,7 +505,8 @@ static const CGFloat ASTextNodeRendererTextCapHeightPadding = 1.3; CGRect lastLineRect = [_layoutManager lineFragmentRectForGlyphAtIndex:lastVisibleGlyphIndex effectiveRange:NULL]; // Calculate the bounding rectangle for the truncation message - ASTextKitComponents *truncationComponents = ASTextKitComponentsCreate(_truncationString, constrainedRect.size); + ASTextKitComponents *truncationComponents = [ASTextKitComponents componentsWithAttributedSeedString:_truncationString + textContainerSize:constrainedRect.size]; // Size the truncation message [truncationComponents.layoutManager ensureLayoutForTextContainer:truncationComponents.textContainer]; diff --git a/AsyncDisplayKit/Details/ASTextNodeTextKitHelpers.h b/AsyncDisplayKit/Details/ASTextNodeTextKitHelpers.h index 88860971ba..4c69b0b9b7 100644 --- a/AsyncDisplayKit/Details/ASTextNodeTextKitHelpers.h +++ b/AsyncDisplayKit/Details/ASTextNodeTextKitHelpers.h @@ -13,26 +13,27 @@ @interface ASTextKitComponents : NSObject +/** + @abstract Creates the stack of TextKit components. + @param attributedSeedString The attributed string to seed the returned text storage with, or nil to receive an blank text storage. + @param textContainerSize The size of the text-container. Typically, size specifies the constraining width of the layout, and FLT_MAX for height. Pass CGSizeZero if these components will be hooked up to a UITextView, which will manage the text container's size itself. + @return An `ASTextKitComponents` containing the created components. The text view component will be nil. + @discussion The returned components will be hooked up together, so they are ready for use as a system upon return. + */ ++ (ASTextKitComponents *)componentsWithAttributedSeedString:(NSAttributedString *)attributedSeedString + textContainerSize:(CGSize)textContainerSize; + +/** + @abstract Returns the bounding size for the text view's text. + @param components The TextKit components to calculate the constrained size of the text for. + @param constrainedWidth The constraining width to be used during text-sizing. Usually, this value should be the receiver's calculated size. + @result A CGSize representing the bounding size for the receiver's text. + */ +- (CGSize)sizeForConstrainedWidth:(CGFloat)constrainedWidth; + @property (nonatomic, strong) NSTextStorage *textStorage; @property (nonatomic, strong) NSTextContainer *textContainer; @property (nonatomic, strong) NSLayoutManager *layoutManager; @property (nonatomic, strong) UITextView *textView; @end - -// Convenience. -/** - @abstract Creates the stack of TextKit components. - @param attributedSeedString The attributed string to sed the returned text storage with, or nil to receive an blank text storage. - @param textContainerSize The size of the text-container. Typically, size specifies the constraining width of the layout, and FLT_MAX for height. Pass CGSizeZero if these components will be hooked up to a UITextView, which will manage the text container's size itself. - @return A `ASTextKitComponents` containing the created components. The text view component will be nil. - @discussion The returned components will be hooked up together, so they are ready for use as a system upon return. - */ -extern ASTextKitComponents *ASTextKitComponentsCreate(NSAttributedString *attributedSeedString, CGSize textContainerSize); -/** - @abstract Returns the bounding size for the text view's text. - @param components The TextKit components to calculate the constrained size of the text for. - @param constrainedWidth The constraining width to be used during text-sizing. Usually, this value should be the receiver's calculated size. - @result A CGSize representing the bounding size for the receiver's text. - */ -extern CGSize ASTextKitComponentsSizeForConstrainedWidth(ASTextKitComponents *components, CGFloat constrainedWidth); diff --git a/AsyncDisplayKit/Details/ASTextNodeTextKitHelpers.mm b/AsyncDisplayKit/Details/ASTextNodeTextKitHelpers.mm index 421c40082b..b9c697d6d4 100644 --- a/AsyncDisplayKit/Details/ASTextNodeTextKitHelpers.mm +++ b/AsyncDisplayKit/Details/ASTextNodeTextKitHelpers.mm @@ -10,26 +10,8 @@ @implementation ASTextKitComponents -@end - -#pragma mark - Convenience - -CGSize ASTextKitComponentsSizeForConstrainedWidth(ASTextKitComponents *components, CGFloat constrainedWidth) -{ - // If our text-view's width is already the constrained width, we can use our existing TextKit stack for this sizing calculation. - // Otherwise, we create a temporary stack to size for `constrainedWidth`. - if (CGRectGetWidth(components.textView.bounds) != constrainedWidth) { - components = ASTextKitComponentsCreate(components.textStorage, CGSizeMake(constrainedWidth, FLT_MAX)); - } - - // Force glyph generation and layout, which may not have happened yet (and isn't triggered by -usedRectForTextContainer:). - [components.layoutManager ensureLayoutForTextContainer:components.textContainer]; - CGSize textSize = [components.layoutManager usedRectForTextContainer:components.textContainer].size; - - return textSize; -} - -ASTextKitComponents *ASTextKitComponentsCreate(NSAttributedString *attributedSeedString, CGSize textContainerSize) ++ (ASTextKitComponents *)componentsWithAttributedSeedString:(NSAttributedString *)attributedSeedString + textContainerSize:(CGSize)textContainerSize { ASTextKitComponents *components = [[ASTextKitComponents alloc] init]; @@ -45,3 +27,22 @@ ASTextKitComponents *ASTextKitComponentsCreate(NSAttributedString *attributedSee return components; } + +- (CGSize)sizeForConstrainedWidth:(CGFloat)constrainedWidth +{ + ASTextKitComponents *components = self; + + // If our text-view's width is already the constrained width, we can use our existing TextKit stack for this sizing calculation. + // Otherwise, we create a temporary stack to size for `constrainedWidth`. + if (CGRectGetWidth(components.textView.bounds) != constrainedWidth) { + components = [ASTextKitComponents componentsWithAttributedSeedString:components.textStorage textContainerSize:CGSizeMake(constrainedWidth, FLT_MAX)]; + } + + // Force glyph generation and layout, which may not have happened yet (and isn't triggered by -usedRectForTextContainer:). + [components.layoutManager ensureLayoutForTextContainer:components.textContainer]; + CGSize textSize = [components.layoutManager usedRectForTextContainer:components.textContainer].size; + + return textSize; +} + +@end diff --git a/AsyncDisplayKitTests/ASTextNodeWordKernerTests.mm b/AsyncDisplayKitTests/ASTextNodeWordKernerTests.mm index 1aa99966b3..994191ed5a 100644 --- a/AsyncDisplayKitTests/ASTextNodeWordKernerTests.mm +++ b/AsyncDisplayKitTests/ASTextNodeWordKernerTests.mm @@ -37,7 +37,7 @@ NSDictionary *attributes = nil; NSString *seedString = @"Hello world"; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:seedString attributes:attributes]; - _components = ASTextKitComponentsCreate(attributedString, size); + _components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size]; } - (void)setupTextKitComponentsWithWordKerning @@ -46,7 +46,7 @@ NSDictionary *attributes = @{ASTextNodeWordKerningAttributeName: @".5"}; NSString *seedString = @"Hello world"; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:seedString attributes:attributes]; - _components = ASTextKitComponentsCreate(attributedString, size); + _components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size]; } - (void)setupTextKitComponentsWithWordKerningDifferentFontSizes @@ -59,7 +59,7 @@ UIFont *normalFont = [UIFont systemFontOfSize:12]; [attributedString addAttribute:NSFontAttributeName value:bigFont range:NSMakeRange(0, 1)]; [attributedString addAttribute:NSFontAttributeName value:normalFont range:NSMakeRange(1, 1)]; - _components = ASTextKitComponentsCreate(attributedString, size); + _components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size]; } - (void)testSomeGlyphsToChangeIfWordKerning @@ -76,7 +76,7 @@ UIFont *font = [UIFont systemFontOfSize:12.0]; NSDictionary *attributes = @{NSFontAttributeName : font}; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@" " attributes:attributes]; - _components = ASTextKitComponentsCreate(attributedString, size); + _components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size]; CGFloat expectedWidth = [@" " sizeWithAttributes:@{ NSFontAttributeName : font }].width; CGRect boundingBox = [_layoutManagerDelegate layoutManager:_components.layoutManager boundingBoxForControlGlyphAtIndex:0 forTextContainer:_components.textContainer proposedLineFragment:CGRectZero glyphPosition:CGPointZero characterIndex:0]; @@ -93,7 +93,7 @@ NSDictionary *attributes = @{ASTextNodeWordKerningAttributeName: @(kernValue), NSFontAttributeName : font}; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@" " attributes:attributes]; - _components = ASTextKitComponentsCreate(attributedString, size); + _components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size]; CGFloat expectedWidth = [@" " sizeWithAttributes:@{ NSFontAttributeName : font }].width + kernValue; CGRect boundingBox = [_layoutManagerDelegate layoutManager:_components.layoutManager boundingBoxForControlGlyphAtIndex:0 forTextContainer:_components.textContainer proposedLineFragment:CGRectZero glyphPosition:CGPointZero characterIndex:0]; @@ -137,7 +137,7 @@ NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:seedString attributes:attributes]; UIFont *normalFont = [UIFont systemFontOfSize:12]; [attributedString addAttribute:NSFontAttributeName value:normalFont range:NSMakeRange(0, 1)]; - _components = ASTextKitComponentsCreate(attributedString, size); + _components = [ASTextKitComponents componentsWithAttributedSeedString:attributedString textContainerSize:size]; CGPoint glyphPosition = CGPointMake(42, 54);