mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Share a singleton shadower for all cases when shadow isn't drawn, fix issues (#2511)
This commit is contained in:
@@ -102,10 +102,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
|||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
// Load default values from superclass.
|
// Load default values from superclass.
|
||||||
_shadowOffset = [super shadowOffset];
|
_shadowOffset = [super shadowOffset];
|
||||||
CGColorRef superColor = [super shadowColor];
|
_shadowColor = CGColorRetain([super shadowColor]);
|
||||||
if (superColor != NULL) {
|
|
||||||
_shadowColor = CGColorRetain(superColor);
|
|
||||||
}
|
|
||||||
_shadowOpacity = [super shadowOpacity];
|
_shadowOpacity = [super shadowOpacity];
|
||||||
_shadowRadius = [super shadowRadius];
|
_shadowRadius = [super shadowRadius];
|
||||||
|
|
||||||
@@ -140,10 +137,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
|||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
if (_shadowColor != NULL) {
|
CGColorRelease(_shadowColor);
|
||||||
CGColorRelease(_shadowColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
[self _invalidateRenderer];
|
[self _invalidateRenderer];
|
||||||
|
|
||||||
if (_longPressGestureRecognizer) {
|
if (_longPressGestureRecognizer) {
|
||||||
@@ -548,9 +543,6 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
|||||||
CGContextTranslateCTM(context, _textContainerInset.left, _textContainerInset.top);
|
CGContextTranslateCTM(context, _textContainerInset.left, _textContainerInset.top);
|
||||||
|
|
||||||
ASTextKitRenderer *renderer = [self _rendererWithBounds:drawParameterBounds];
|
ASTextKitRenderer *renderer = [self _rendererWithBounds:drawParameterBounds];
|
||||||
UIEdgeInsets shadowPadding = [self shadowPaddingWithRenderer:renderer];
|
|
||||||
CGPoint boundsOrigin = drawParameterBounds.origin;
|
|
||||||
CGPoint textOrigin = CGPointMake(boundsOrigin.x - shadowPadding.left, boundsOrigin.y - shadowPadding.top);
|
|
||||||
|
|
||||||
// Fill background
|
// Fill background
|
||||||
if (backgroundColor != nil) {
|
if (backgroundColor != nil) {
|
||||||
@@ -558,12 +550,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
|||||||
UIRectFillUsingBlendMode(CGContextGetClipBoundingBox(context), kCGBlendModeCopy);
|
UIRectFillUsingBlendMode(CGContextGetClipBoundingBox(context), kCGBlendModeCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw shadow
|
|
||||||
[renderer.shadower setShadowInContext:context];
|
|
||||||
|
|
||||||
// Draw text
|
// Draw text
|
||||||
bounds.origin = textOrigin;
|
[renderer drawInContext:context bounds:drawParameterBounds];
|
||||||
[renderer drawInContext:context bounds:bounds];
|
|
||||||
|
|
||||||
CGContextRestoreGState(context);
|
CGContextRestoreGState(context);
|
||||||
}
|
}
|
||||||
@@ -1133,14 +1121,9 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
|||||||
{
|
{
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
|
|
||||||
if (_shadowColor != shadowColor) {
|
if (_shadowColor != shadowColor && CGColorEqualToColor(shadowColor, _shadowColor) == NO) {
|
||||||
if (shadowColor != NULL) {
|
CGColorRelease(_shadowColor);
|
||||||
CGColorRetain(shadowColor);
|
_shadowColor = CGColorRetain(shadowColor);
|
||||||
}
|
|
||||||
if (_shadowColor != NULL) {
|
|
||||||
CGColorRelease(_shadowColor);
|
|
||||||
}
|
|
||||||
_shadowColor = shadowColor;
|
|
||||||
_cachedShadowUIColor = [UIColor colorWithCGColor:shadowColor];
|
_cachedShadowUIColor = [UIColor colorWithCGColor:shadowColor];
|
||||||
[self _invalidateRenderer];
|
[self _invalidateRenderer];
|
||||||
[self setNeedsDisplay];
|
[self setNeedsDisplay];
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ struct ASTextKitAttributes {
|
|||||||
/**
|
/**
|
||||||
An array of UIBezierPath objects representing the exclusion paths inside the receiver's bounding rectangle. Default value: nil.
|
An array of UIBezierPath objects representing the exclusion paths inside the receiver's bounding rectangle. Default value: nil.
|
||||||
*/
|
*/
|
||||||
NSArray *exclusionPaths;
|
NSArray<UIBezierPath *> *exclusionPaths;
|
||||||
/**
|
/**
|
||||||
The shadow offset for any shadows applied to the text. The coordinate space for this is the same as UIKit, so a
|
The shadow offset for any shadows applied to the text. The coordinate space for this is the same as UIKit, so a
|
||||||
positive width means towards the right, and a positive height means towards the bottom.
|
positive width means towards the right, and a positive height means towards the bottom.
|
||||||
|
|||||||
@@ -68,10 +68,10 @@ static NSCharacterSet *_defaultAvoidTruncationCharacterSet()
|
|||||||
{
|
{
|
||||||
if (!_shadower) {
|
if (!_shadower) {
|
||||||
ASTextKitAttributes attributes = _attributes;
|
ASTextKitAttributes attributes = _attributes;
|
||||||
_shadower = [[ASTextKitShadower alloc] initWithShadowOffset:attributes.shadowOffset
|
_shadower = [ASTextKitShadower shadowerWithShadowOffset:attributes.shadowOffset
|
||||||
shadowColor:attributes.shadowColor
|
shadowColor:attributes.shadowColor
|
||||||
shadowOpacity:attributes.shadowOpacity
|
shadowOpacity:attributes.shadowOpacity
|
||||||
shadowRadius:attributes.shadowRadius];
|
shadowRadius:attributes.shadowRadius];
|
||||||
}
|
}
|
||||||
return _shadower;
|
return _shadower;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
@interface ASTextKitShadower : NSObject
|
@interface ASTextKitShadower : NSObject
|
||||||
|
|
||||||
- (instancetype)initWithShadowOffset:(CGSize)shadowOffset
|
+ (ASTextKitShadower *)shadowerWithShadowOffset:(CGSize)shadowOffset
|
||||||
shadowColor:(UIColor *)shadowColor
|
shadowColor:(UIColor *)shadowColor
|
||||||
shadowOpacity:(CGFloat)shadowOpacity
|
shadowOpacity:(CGFloat)shadowOpacity
|
||||||
shadowRadius:(CGFloat)shadowRadius;
|
shadowRadius:(CGFloat)shadowRadius;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract The offset from the top-left corner at which the shadow starts.
|
* @abstract The offset from the top-left corner at which the shadow starts.
|
||||||
|
|||||||
@@ -14,7 +14,9 @@
|
|||||||
|
|
||||||
static inline CGSize _insetSize(CGSize size, UIEdgeInsets insets)
|
static inline CGSize _insetSize(CGSize size, UIEdgeInsets insets)
|
||||||
{
|
{
|
||||||
return UIEdgeInsetsInsetRect({.size = size}, insets).size;
|
size.width -= (insets.left + insets.right);
|
||||||
|
size.height -= (insets.top + insets.bottom);
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline UIEdgeInsets _invertInsets(UIEdgeInsets insets)
|
static inline UIEdgeInsets _invertInsets(UIEdgeInsets insets)
|
||||||
@@ -31,6 +33,28 @@ static inline UIEdgeInsets _invertInsets(UIEdgeInsets insets)
|
|||||||
UIEdgeInsets _calculatedShadowPadding;
|
UIEdgeInsets _calculatedShadowPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (ASTextKitShadower *)shadowerWithShadowOffset:(CGSize)shadowOffset
|
||||||
|
shadowColor:(UIColor *)shadowColor
|
||||||
|
shadowOpacity:(CGFloat)shadowOpacity
|
||||||
|
shadowRadius:(CGFloat)shadowRadius
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* For all cases where no shadow is drawn, we share this singleton shadower to save resources.
|
||||||
|
*/
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
static ASTextKitShadower *sharedNonShadower;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
sharedNonShadower = [[ASTextKitShadower alloc] initWithShadowOffset:CGSizeZero shadowColor:nil shadowOpacity:0 shadowRadius:0];
|
||||||
|
});
|
||||||
|
|
||||||
|
BOOL hasShadow = shadowOpacity > 0 && (shadowRadius > 0 || CGSizeEqualToSize(shadowOffset, CGSizeZero) == NO) && CGColorGetAlpha(shadowColor.CGColor) > 0;
|
||||||
|
if (hasShadow == NO) {
|
||||||
|
return sharedNonShadower;
|
||||||
|
} else {
|
||||||
|
return [[ASTextKitShadower alloc] initWithShadowOffset:shadowOffset shadowColor:shadowColor shadowOpacity:shadowOpacity shadowRadius:shadowRadius];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)initWithShadowOffset:(CGSize)shadowOffset
|
- (instancetype)initWithShadowOffset:(CGSize)shadowOffset
|
||||||
shadowColor:(UIColor *)shadowColor
|
shadowColor:(UIColor *)shadowColor
|
||||||
shadowOpacity:(CGFloat)shadowOpacity
|
shadowOpacity:(CGFloat)shadowOpacity
|
||||||
@@ -52,7 +76,7 @@ static inline UIEdgeInsets _invertInsets(UIEdgeInsets insets)
|
|||||||
*/
|
*/
|
||||||
- (BOOL)_shouldDrawShadow
|
- (BOOL)_shouldDrawShadow
|
||||||
{
|
{
|
||||||
return _shadowOpacity != 0.0 && _shadowColor != nil && (_shadowRadius != 0 || !CGSizeEqualToSize(_shadowOffset, CGSizeZero));
|
return _shadowOpacity != 0.0 && (_shadowRadius != 0 || !CGSizeEqualToSize(_shadowOffset, CGSizeZero)) && CGColorGetAlpha(_shadowColor.CGColor) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setShadowInContext:(CGContextRef)context
|
- (void)setShadowInContext:(CGContextRef)context
|
||||||
|
|||||||
@@ -92,4 +92,16 @@
|
|||||||
ASSnapshotVerifyNode(textNode, nil);
|
ASSnapshotVerifyNode(textNode, nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)testShadowing
|
||||||
|
{
|
||||||
|
ASTextNode *textNode = [[ASTextNode alloc] init];
|
||||||
|
textNode.attributedText = [[NSAttributedString alloc] initWithString:@"Quality is Important"];
|
||||||
|
textNode.shadowColor = [UIColor blackColor].CGColor;
|
||||||
|
textNode.shadowOpacity = 0.3;
|
||||||
|
textNode.shadowRadius = 3;
|
||||||
|
textNode.shadowOffset = CGSizeMake(0, 1);
|
||||||
|
[textNode layoutThatFits:ASSizeRangeMake(CGSizeZero, CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX))];
|
||||||
|
ASSnapshotVerifyNode(textNode, nil);
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
Reference in New Issue
Block a user