Add support for textContainerInset to ASTextNode (ala UITextView) (#2062)

* Add support for textContainerInset to ASTextNode (ala UITextView)

* Better comment, parens to increase readability. Thanks @schneider!

* Add textContainerInset snapshot test.
This commit is contained in:
Garrett Moon
2016-08-12 12:07:00 -07:00
committed by Adlai Holler
parent 39cb188b9e
commit 2c9e51e8f7
4 changed files with 95 additions and 4 deletions

View File

@@ -48,6 +48,8 @@ struct ASTextNodeDrawParameter {
UIColor *_cachedShadowUIColor;
CGFloat _shadowOpacity;
CGFloat _shadowRadius;
UIEdgeInsets _textContainerInset;
NSArray *_exclusionPaths;
@@ -213,7 +215,15 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
ASDN::MutexLocker l(__instanceLock__);
if (_renderer == nil) {
CGSize constrainedSize = _constrainedSize.width != -INFINITY ? _constrainedSize : bounds.size;
CGSize constrainedSize;
if (_constrainedSize.width != -INFINITY) {
constrainedSize = _constrainedSize;
} else {
constrainedSize = bounds.size;
constrainedSize.width -= (_textContainerInset.left + _textContainerInset.right);
constrainedSize.height -= (_textContainerInset.top + _textContainerInset.bottom);
}
_renderer = [[ASTextKitRenderer alloc] initWithTextKitAttributes:[self _rendererAttributes]
constrainedSize:constrainedSize];
}
@@ -279,6 +289,24 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
#pragma mark - Layout and Sizing
- (void)setTextContainerInset:(UIEdgeInsets)textContainerInset
{
ASDN::MutexLocker l(__instanceLock__);
BOOL needsUpdate = !UIEdgeInsetsEqualToEdgeInsets(textContainerInset, _textContainerInset);
if (needsUpdate) {
_textContainerInset = textContainerInset;
[self invalidateCalculatedLayout];
[self setNeedsLayout];
}
}
- (UIEdgeInsets)textContainerInset
{
ASDN::MutexLocker l(__instanceLock__);
return _textContainerInset;
}
- (BOOL)_needInvalidateRendererForBoundsSize:(CGSize)boundsSize
{
ASDN::MutexLocker l(__instanceLock__);
@@ -291,6 +319,10 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
// a new one. However, there are common cases where the constrained size doesn't need to be the same as calculated.
CGSize rendererConstrainedSize = _renderer.constrainedSize;
//inset bounds
boundsSize.width -= _textContainerInset.left + _textContainerInset.right;
boundsSize.height -= _textContainerInset.top + _textContainerInset.bottom;
if (CGSizeEqualToSize(boundsSize, rendererConstrainedSize)) {
return NO;
} else {
@@ -321,9 +353,14 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
if (layout != nil) {
ASDN::MutexLocker l(__instanceLock__);
if (CGSizeEqualToSize(_constrainedSize, layout.size) == NO) {
_constrainedSize = layout.size;
_renderer.constrainedSize = layout.size;
CGSize layoutSize = layout.size;
//Apply textContainerInset
layoutSize.width -= (_textContainerInset.left + _textContainerInset.right);
layoutSize.height -= (_textContainerInset.top + _textContainerInset.bottom);
if (CGSizeEqualToSize(_constrainedSize, layoutSize) == NO) {
_constrainedSize = layoutSize;
_renderer.constrainedSize = layoutSize;
}
}
}
@@ -335,6 +372,10 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
ASDN::MutexLocker l(__instanceLock__);
//remove textContainerInset
constrainedSize.width -= (_textContainerInset.left + _textContainerInset.right);
constrainedSize.height -= (_textContainerInset.top + _textContainerInset.bottom);
_constrainedSize = constrainedSize;
// Instead of invalidating the renderer, in case this is a new call with a different constrained size,
@@ -353,6 +394,11 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
self.descender *= _renderer.currentScaleFactor;
}
}
//add textContainerInset
size.width += (_textContainerInset.left + _textContainerInset.right);
size.height += (_textContainerInset.top + _textContainerInset.bottom);
return size;
}
@@ -466,6 +512,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
CGContextSaveGState(context);
CGContextTranslateCTM(context, _textContainerInset.left, _textContainerInset.top);
ASTextKitRenderer *renderer = [self _rendererWithBounds:drawParameterBounds];
UIEdgeInsets shadowPadding = [self shadowPaddingWithRenderer:renderer];
CGPoint boundsOrigin = drawParameterBounds.origin;