Swiftgram/AsyncDisplayKit/TextKit/ASTextKitContext.mm
rcancro 7f6f2fed11 Added ASTextNodeWordKerner support to ASTextNode
* Added a member to `ASTextKitAttributes` that is an optional delegate to the struct's NSLayoutManager.
* Changed ASTextNode to set this delegate to an instance of ASTextNodeWordKerner.
* Updated init method of `ASTextKitContext` to take an optional NSLayoutManager delegate
* Added the files in TextKit folder to the public headers (so we can include ASTextNodeTypes.h)
2016-01-28 08:38:22 -08:00

73 lines
2.7 KiB
Plaintext
Executable File

/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import <mutex>
#import "ASTextKitContext.h"
@implementation ASTextKitContext
{
// All TextKit operations (even non-mutative ones) must be executed serially.
std::mutex _textKitMutex;
NSLayoutManager *_layoutManager;
NSTextStorage *_textStorage;
NSTextContainer *_textContainer;
}
- (instancetype)initWithAttributedString:(NSAttributedString *)attributedString
lineBreakMode:(NSLineBreakMode)lineBreakMode
maximumNumberOfLines:(NSUInteger)maximumNumberOfLines
exclusionPaths:(NSArray *)exclusionPaths
constrainedSize:(CGSize)constrainedSize
layoutManagerFactory:(NSLayoutManager*(*)(void))layoutManagerFactory
layoutManagerDelegate:(id<NSLayoutManagerDelegate>)layoutManagerDelegate
{
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() : [[NSLayoutManager alloc] init];
_layoutManager.usesFontLeading = NO;
_layoutManager.delegate = layoutManagerDelegate;
[_textStorage addLayoutManager:_layoutManager];
_textContainer = [[NSTextContainer alloc] initWithSize:constrainedSize];
// We want the text laid out up to the very edges of the container.
_textContainer.lineFragmentPadding = 0;
_textContainer.lineBreakMode = lineBreakMode;
_textContainer.maximumNumberOfLines = maximumNumberOfLines;
_textContainer.exclusionPaths = exclusionPaths;
[_layoutManager addTextContainer:_textContainer];
}
return self;
}
- (CGSize)constrainedSize
{
return _textContainer.size;
}
- (void)setConstrainedSize:(CGSize)constrainedSize
{
_textContainer.size = constrainedSize;
}
- (void)performBlockWithLockedTextKitComponents:(void (^)(NSLayoutManager *,
NSTextStorage *,
NSTextContainer *))block
{
std::lock_guard<std::mutex> l(_textKitMutex);
block(_layoutManager, _textStorage, _textContainer);
}
@end