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]) {
|
||||
// Load default values from superclass.
|
||||
_shadowOffset = [super shadowOffset];
|
||||
CGColorRef superColor = [super shadowColor];
|
||||
if (superColor != NULL) {
|
||||
_shadowColor = CGColorRetain(superColor);
|
||||
}
|
||||
_shadowColor = CGColorRetain([super shadowColor]);
|
||||
_shadowOpacity = [super shadowOpacity];
|
||||
_shadowRadius = [super shadowRadius];
|
||||
|
||||
@@ -140,10 +137,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (_shadowColor != NULL) {
|
||||
CGColorRelease(_shadowColor);
|
||||
}
|
||||
|
||||
CGColorRelease(_shadowColor);
|
||||
|
||||
[self _invalidateRenderer];
|
||||
|
||||
if (_longPressGestureRecognizer) {
|
||||
@@ -548,9 +543,6 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
CGContextTranslateCTM(context, _textContainerInset.left, _textContainerInset.top);
|
||||
|
||||
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
|
||||
if (backgroundColor != nil) {
|
||||
@@ -558,12 +550,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
UIRectFillUsingBlendMode(CGContextGetClipBoundingBox(context), kCGBlendModeCopy);
|
||||
}
|
||||
|
||||
// Draw shadow
|
||||
[renderer.shadower setShadowInContext:context];
|
||||
|
||||
// Draw text
|
||||
bounds.origin = textOrigin;
|
||||
[renderer drawInContext:context bounds:bounds];
|
||||
[renderer drawInContext:context bounds:drawParameterBounds];
|
||||
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
@@ -1133,14 +1121,9 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
|
||||
if (_shadowColor != shadowColor) {
|
||||
if (shadowColor != NULL) {
|
||||
CGColorRetain(shadowColor);
|
||||
}
|
||||
if (_shadowColor != NULL) {
|
||||
CGColorRelease(_shadowColor);
|
||||
}
|
||||
_shadowColor = shadowColor;
|
||||
if (_shadowColor != shadowColor && CGColorEqualToColor(shadowColor, _shadowColor) == NO) {
|
||||
CGColorRelease(_shadowColor);
|
||||
_shadowColor = CGColorRetain(shadowColor);
|
||||
_cachedShadowUIColor = [UIColor colorWithCGColor:shadowColor];
|
||||
[self _invalidateRenderer];
|
||||
[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.
|
||||
*/
|
||||
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
|
||||
positive width means towards the right, and a positive height means towards the bottom.
|
||||
|
||||
@@ -68,10 +68,10 @@ static NSCharacterSet *_defaultAvoidTruncationCharacterSet()
|
||||
{
|
||||
if (!_shadower) {
|
||||
ASTextKitAttributes attributes = _attributes;
|
||||
_shadower = [[ASTextKitShadower alloc] initWithShadowOffset:attributes.shadowOffset
|
||||
shadowColor:attributes.shadowColor
|
||||
shadowOpacity:attributes.shadowOpacity
|
||||
shadowRadius:attributes.shadowRadius];
|
||||
_shadower = [ASTextKitShadower shadowerWithShadowOffset:attributes.shadowOffset
|
||||
shadowColor:attributes.shadowColor
|
||||
shadowOpacity:attributes.shadowOpacity
|
||||
shadowRadius:attributes.shadowRadius];
|
||||
}
|
||||
return _shadower;
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
@interface ASTextKitShadower : NSObject
|
||||
|
||||
- (instancetype)initWithShadowOffset:(CGSize)shadowOffset
|
||||
shadowColor:(UIColor *)shadowColor
|
||||
shadowOpacity:(CGFloat)shadowOpacity
|
||||
shadowRadius:(CGFloat)shadowRadius;
|
||||
+ (ASTextKitShadower *)shadowerWithShadowOffset:(CGSize)shadowOffset
|
||||
shadowColor:(UIColor *)shadowColor
|
||||
shadowOpacity:(CGFloat)shadowOpacity
|
||||
shadowRadius:(CGFloat)shadowRadius;
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
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)
|
||||
@@ -31,6 +33,28 @@ static inline UIEdgeInsets _invertInsets(UIEdgeInsets insets)
|
||||
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
|
||||
shadowColor:(UIColor *)shadowColor
|
||||
shadowOpacity:(CGFloat)shadowOpacity
|
||||
@@ -52,7 +76,7 @@ static inline UIEdgeInsets _invertInsets(UIEdgeInsets insets)
|
||||
*/
|
||||
- (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
|
||||
|
||||
@@ -92,4 +92,16 @@
|
||||
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
|
||||
|
||||
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