Swiftgram/AsyncDisplayKit/TextKit/ASTextKitContext.mm
Hannah Troisi c857e809f4 Clean up header comments (for consistent Facebook licensing info) (#1741)
[Licensing] Clean up header comments (for consistent Facebook licensing info)
2016-06-11 23:31:39 -07:00

82 lines
3.1 KiB
Plaintext
Executable File

//
// ASTextKitContext.mm
// AsyncDisplayKit
//
// 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 "ASTextKitContext.h"
#import "ASThread.h"
#import "ASLayoutManager.h"
@implementation ASTextKitContext
{
// All TextKit operations (even non-mutative ones) must be executed serially.
ASDN::Mutex _textKitMutex;
NSLayoutManager *_layoutManager;
NSTextStorage *_textStorage;
NSTextContainer *_textContainer;
}
- (instancetype)initWithAttributedString:(NSAttributedString *)attributedString
lineBreakMode:(NSLineBreakMode)lineBreakMode
maximumNumberOfLines:(NSUInteger)maximumNumberOfLines
exclusionPaths:(NSArray *)exclusionPaths
constrainedSize:(CGSize)constrainedSize
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 ASDN::Mutex __staticMutex;
ASDN::MutexLocker l(__staticMutex);
// Create the TextKit component stack with our default configuration.
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];
_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
{
ASDN::MutexLocker l(_textKitMutex);
return _textContainer.size;
}
- (void)setConstrainedSize:(CGSize)constrainedSize
{
ASDN::MutexLocker l(_textKitMutex);
_textContainer.size = constrainedSize;
}
- (void)performBlockWithLockedTextKitComponents:(void (^)(NSLayoutManager *,
NSTextStorage *,
NSTextContainer *))block
{
ASDN::MutexLocker l(_textKitMutex);
block(_layoutManager, _textStorage, _textContainer);
}
@end