Add ability to customize NSLayoutManager and NSTextStorage when created in the ASTextKitContext

This commit is contained in:
rcancro
2016-02-22 13:00:02 -08:00
parent 896f0adcaf
commit 00b0968bf7
10 changed files with 60 additions and 26 deletions

View File

@@ -91,15 +91,20 @@ struct ASTextKitAttributes {
*/
CGFloat currentScaleFactor;
/**
A pointer to a function that that returns a custom layout manager subclass. If nil, defaults to NSLayoutManager.
An optional block that returns a custom layout manager subclass. If nil, defaults to NSLayoutManager.
*/
NSLayoutManager *(*layoutManagerFactory)(void);
NSLayoutManager * (^layoutManagerCreationBlock)(void);
/**
An optional delegate for the NSLayoutManager
*/
id<NSLayoutManagerDelegate> layoutManagerDelegate;
/**
An optional block that returns a custom NSTextStorage for the layout manager.
*/
NSTextStorage * (^textStorageCreationBlock)(NSAttributedString *attributedString);
/**
We provide an explicit copy function so we can use aggregate initializer syntax while providing copy semantics for
the NSObjects inside.
@@ -119,8 +124,9 @@ struct ASTextKitAttributes {
shadowRadius,
pointSizeScaleFactors,
currentScaleFactor,
layoutManagerFactory,
layoutManagerCreationBlock,
layoutManagerDelegate,
textStorageCreationBlock,
};
};
@@ -133,7 +139,8 @@ struct ASTextKitAttributes {
&& shadowRadius == other.shadowRadius
&& [pointSizeScaleFactors isEqualToArray:other.pointSizeScaleFactors]
&& currentScaleFactor == currentScaleFactor
&& layoutManagerFactory == other.layoutManagerFactory
&& layoutManagerCreationBlock == other.layoutManagerCreationBlock
&& textStorageCreationBlock == other.textStorageCreationBlock
&& CGSizeEqualToSize(shadowOffset, other.shadowOffset)
&& _objectsEqual(exclusionPaths, other.exclusionPaths)
&& _objectsEqual(avoidTailTruncationSet, other.avoidTailTruncationSet)

View File

@@ -23,7 +23,8 @@ size_t ASTextKitAttributes::hash() const
[attributedString hash],
[truncationAttributedString hash],
[avoidTailTruncationSet hash],
std::hash<NSUInteger>()((NSUInteger) layoutManagerFactory),
std::hash<NSUInteger>()((NSUInteger) layoutManagerCreationBlock),
std::hash<NSUInteger>()((NSUInteger) textStorageCreationBlock),
std::hash<NSInteger>()(lineBreakMode),
std::hash<NSInteger>()(maximumNumberOfLines),
[exclusionPaths hash],

View File

@@ -28,8 +28,9 @@
maximumNumberOfLines:(NSUInteger)maximumNumberOfLines
exclusionPaths:(NSArray *)exclusionPaths
constrainedSize:(CGSize)constrainedSize
layoutManagerFactory:(NSLayoutManager*(*)(void))layoutManagerFactory
layoutManagerDelegate:(id<NSLayoutManagerDelegate>)layoutManagerDelegate;
layoutManagerCreationBlock:(NSLayoutManager * (^)(void))layoutCreationBlock
layoutManagerDelegate:(id<NSLayoutManagerDelegate>)layoutManagerDelegate
textStorageCreationBlock:(NSTextStorage * (^)(NSAttributedString *attributedString))textStorageCreationBlock;
@property (nonatomic, assign, readwrite) CGSize constrainedSize;

View File

@@ -29,16 +29,22 @@
maximumNumberOfLines:(NSUInteger)maximumNumberOfLines
exclusionPaths:(NSArray *)exclusionPaths
constrainedSize:(CGSize)constrainedSize
layoutManagerFactory:(NSLayoutManager*(*)(void))layoutManagerFactory
layoutManagerCreationBlock:(NSLayoutManager * (^)(void))layoutCreationBlock
layoutManagerDelegate:(id<NSLayoutManagerDelegate>)layoutManagerDelegate
textStorageCreationBlock:(NSTextStorage * (^)(NSAttributedString *attributedString))textStorageCreationBlock
{
if (self = [super init]) {
// Concurrently initialising TextKit components crashes (rdar://18448377) so we use a global lock.
static std::mutex __static_mutex;
std::lock_guard<std::mutex> l(__static_mutex);
// Create the TextKit component stack with our default configuration.
_textStorage = (attributedString ? [[NSTextStorage alloc] initWithAttributedString:attributedString] : [[NSTextStorage alloc] init]);
_layoutManager = layoutManagerFactory ? layoutManagerFactory() : [[ASLayoutManager alloc] init];
if (textStorageCreationBlock) {
_textStorage = textStorageCreationBlock(attributedString);
} else {
_textStorage = (attributedString ? [[NSTextStorage alloc] initWithAttributedString:attributedString] : [[NSTextStorage alloc] init]);
}
_layoutManager = layoutCreationBlock ? layoutCreationBlock() : [[ASLayoutManager alloc] init];
_layoutManager.usesFontLeading = NO;
_layoutManager.delegate = layoutManagerDelegate;
[_textStorage addLayoutManager:_layoutManager];

View File

@@ -81,8 +81,8 @@
static std::mutex __static_mutex;
std::lock_guard<std::mutex> l(__static_mutex);
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];
NSLayoutManager *layoutManager = _attributes.layoutManagerFactory ? _attributes.layoutManagerFactory() : [[ASLayoutManager alloc] init];
NSTextStorage *textStorage = _attributes.textStorageCreationBlock ? _attributes.textStorageCreationBlock(attributedString) : [[NSTextStorage alloc] initWithAttributedString:attributedString];
NSLayoutManager *layoutManager = _attributes.layoutManagerCreationBlock ? _attributes.layoutManagerCreationBlock() : [[ASLayoutManager alloc] init];
layoutManager.usesFontLeading = NO;
[textStorage addLayoutManager:layoutManager];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:_constrainedSize];

View File

@@ -104,8 +104,9 @@ static NSCharacterSet *_defaultAvoidTruncationCharacterSet()
maximumNumberOfLines:attributes.maximumNumberOfLines
exclusionPaths:attributes.exclusionPaths
constrainedSize:shadowConstrainedSize
layoutManagerFactory:attributes.layoutManagerFactory
layoutManagerDelegate:attributes.layoutManagerDelegate];
layoutManagerCreationBlock:attributes.layoutManagerCreationBlock
layoutManagerDelegate:attributes.layoutManagerDelegate
textStorageCreationBlock:attributes.textStorageCreationBlock];
}
return _context;
}

View File

@@ -72,8 +72,9 @@
maximumNumberOfLines:1
exclusionPaths:nil
constrainedSize:constrainedRect.size
layoutManagerFactory:nil
layoutManagerDelegate:nil];
layoutManagerCreationBlock:nil
layoutManagerDelegate:nil
textStorageCreationBlock:nil];
__block CGRect truncationUsedRect;
[truncationContext performBlockWithLockedTextKitComponents:^(NSLayoutManager *truncationLayoutManager, NSTextStorage *truncationTextStorage, NSTextContainer *truncationTextContainer) {