mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
Move drawing parameters in ASTextNode and ASImageNode to structs
This commit is contained in:
@@ -26,46 +26,18 @@
|
|||||||
#import "ASInternalHelpers.h"
|
#import "ASInternalHelpers.h"
|
||||||
#import "ASEqualityHelpers.h"
|
#import "ASEqualityHelpers.h"
|
||||||
|
|
||||||
@interface _ASImageNodeDrawParameters : NSObject
|
struct ASImageNodeDrawParameters {
|
||||||
|
BOOL opaque;
|
||||||
@property (nonatomic, retain) UIImage *image;
|
CGRect bounds;
|
||||||
@property (nonatomic, assign) BOOL opaque;
|
CGFloat contentsScale;
|
||||||
@property (nonatomic, assign) CGRect bounds;
|
UIColor *backgroundColor;
|
||||||
@property (nonatomic, assign) CGFloat contentsScale;
|
UIViewContentMode contentMode;
|
||||||
@property (nonatomic, strong) UIColor *backgroundColor;
|
BOOL cropEnabled;
|
||||||
@property (nonatomic, assign) UIViewContentMode contentMode;
|
BOOL forceUpscaling;
|
||||||
|
CGRect cropRect;
|
||||||
@end
|
CGRect cropDisplayBounds;
|
||||||
|
asimagenode_modification_block_t imageModificationBlock;
|
||||||
// TODO: eliminate explicit parameters with a set of keys copied from the node
|
};
|
||||||
@implementation _ASImageNodeDrawParameters
|
|
||||||
|
|
||||||
- (instancetype)initWithImage:(UIImage *)image
|
|
||||||
bounds:(CGRect)bounds
|
|
||||||
opaque:(BOOL)opaque
|
|
||||||
contentsScale:(CGFloat)contentsScale
|
|
||||||
backgroundColor:(UIColor *)backgroundColor
|
|
||||||
contentMode:(UIViewContentMode)contentMode
|
|
||||||
{
|
|
||||||
if (!(self = [self init]))
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
_image = image;
|
|
||||||
_opaque = opaque;
|
|
||||||
_bounds = bounds;
|
|
||||||
_contentsScale = contentsScale;
|
|
||||||
_backgroundColor = backgroundColor;
|
|
||||||
_contentMode = contentMode;
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)description
|
|
||||||
{
|
|
||||||
return [NSString stringWithFormat:@"<%@ : %p opaque:%@ bounds:%@ contentsScale:%.2f backgroundColor:%@ contentMode:%@>", [self class], self, @(self.opaque), NSStringFromCGRect(self.bounds), self.contentsScale, self.backgroundColor, ASDisplayNodeNSStringFromUIContentMode(self.contentMode)];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation ASImageNode
|
@implementation ASImageNode
|
||||||
{
|
{
|
||||||
@@ -75,18 +47,22 @@
|
|||||||
void (^_displayCompletionBlock)(BOOL canceled);
|
void (^_displayCompletionBlock)(BOOL canceled);
|
||||||
ASDN::RecursiveMutex _imageLock;
|
ASDN::RecursiveMutex _imageLock;
|
||||||
|
|
||||||
|
// Drawing
|
||||||
|
ASImageNodeDrawParameters _drawParameter;
|
||||||
|
ASTextNode *_debugLabelNode;
|
||||||
|
|
||||||
// Cropping.
|
// Cropping.
|
||||||
BOOL _cropEnabled; // Defaults to YES.
|
BOOL _cropEnabled; // Defaults to YES.
|
||||||
BOOL _forceUpscaling; //Defaults to NO.
|
BOOL _forceUpscaling; //Defaults to NO.
|
||||||
CGRect _cropRect; // Defaults to CGRectMake(0.5, 0.5, 0, 0)
|
CGRect _cropRect; // Defaults to CGRectMake(0.5, 0.5, 0, 0)
|
||||||
CGRect _cropDisplayBounds;
|
CGRect _cropDisplayBounds; // Defaults to CGRectNull
|
||||||
|
|
||||||
ASTextNode *_debugLabelNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@synthesize image = _image;
|
@synthesize image = _image;
|
||||||
@synthesize imageModificationBlock = _imageModificationBlock;
|
@synthesize imageModificationBlock = _imageModificationBlock;
|
||||||
|
|
||||||
|
#pragma mark - NSObject
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
{
|
{
|
||||||
if (!(self = [super init]))
|
if (!(self = [super init]))
|
||||||
@@ -124,6 +100,8 @@
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Layout and Sizing
|
||||||
|
|
||||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_imageLock);
|
ASDN::MutexLocker l(_imageLock);
|
||||||
@@ -136,6 +114,8 @@
|
|||||||
return CGSizeZero;
|
return CGSizeZero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Setter / Getter
|
||||||
|
|
||||||
- (void)setImage:(UIImage *)image
|
- (void)setImage:(UIImage *)image
|
||||||
{
|
{
|
||||||
_imageLock.lock();
|
_imageLock.lock();
|
||||||
@@ -177,54 +157,72 @@
|
|||||||
self.placeholderEnabled = placeholderColor != nil;
|
self.placeholderEnabled = placeholderColor != nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Drawing
|
||||||
|
|
||||||
- (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer
|
- (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer
|
||||||
{
|
{
|
||||||
return [[_ASImageNodeDrawParameters alloc] initWithImage:self.image
|
ASDN::MutexLocker l(_imageLock);
|
||||||
bounds:self.bounds
|
|
||||||
opaque:self.opaque
|
_drawParameter = {
|
||||||
contentsScale:self.contentsScaleForDisplay
|
.bounds = self.bounds,
|
||||||
backgroundColor:self.backgroundColor
|
.opaque = self.opaque,
|
||||||
contentMode:self.contentMode];
|
.contentsScale = _contentsScaleForDisplay,
|
||||||
|
.backgroundColor = self.backgroundColor,
|
||||||
|
.contentMode = self.contentMode,
|
||||||
|
.cropEnabled = _cropEnabled,
|
||||||
|
.forceUpscaling = _forceUpscaling,
|
||||||
|
.cropRect = _cropRect,
|
||||||
|
.cropDisplayBounds = _cropDisplayBounds,
|
||||||
|
.imageModificationBlock = _imageModificationBlock
|
||||||
|
};
|
||||||
|
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *)debugLabelAttributes
|
- (NSDictionary *)debugLabelAttributes
|
||||||
{
|
{
|
||||||
return @{ NSFontAttributeName: [UIFont systemFontOfSize:15.0],
|
return @{
|
||||||
NSForegroundColorAttributeName: [UIColor redColor] };
|
NSFontAttributeName: [UIFont systemFontOfSize:15.0],
|
||||||
|
NSForegroundColorAttributeName: [UIColor redColor]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIImage *)displayWithParameters:(_ASImageNodeDrawParameters *)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled
|
- (UIImage *)displayWithParameters:(id<NSObject> *)parameter isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled
|
||||||
{
|
{
|
||||||
UIImage *image = parameters.image;
|
UIImage *image = self.image;
|
||||||
if (!image) {
|
if (image == nil) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CGRect drawParameterBounds = CGRectZero;
|
||||||
BOOL forceUpscaling = NO;
|
BOOL forceUpscaling = NO;
|
||||||
BOOL cropEnabled = NO;
|
BOOL cropEnabled = YES;
|
||||||
BOOL isOpaque = parameters.opaque;
|
BOOL isOpaque = NO;
|
||||||
UIColor *backgroundColor = parameters.backgroundColor;
|
UIColor *backgroundColor = nil;
|
||||||
UIViewContentMode contentMode = parameters.contentMode;
|
UIViewContentMode contentMode = UIViewContentModeScaleAspectFill;
|
||||||
CGFloat contentsScale = 0.0;
|
CGFloat contentsScale = 0.0;
|
||||||
CGRect cropDisplayBounds = CGRectZero;
|
CGRect cropDisplayBounds = CGRectZero;
|
||||||
CGRect cropRect = CGRectZero;
|
CGRect cropRect = CGRectZero;
|
||||||
asimagenode_modification_block_t imageModificationBlock;
|
asimagenode_modification_block_t imageModificationBlock;
|
||||||
|
|
||||||
|
ASDN::MutexLocker l(_imageLock);
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_imageLock);
|
ASImageNodeDrawParameters drawParameter = _drawParameter;
|
||||||
|
|
||||||
// FIXME: There is a small risk of these values changing between the main thread creation of drawParameters, and the execution of this method.
|
drawParameterBounds = drawParameter.bounds;
|
||||||
// We should package these up into the draw parameters object. Might be easiest to create a struct for the non-objects and make it one property.
|
forceUpscaling = drawParameter.forceUpscaling;
|
||||||
cropEnabled = _cropEnabled;
|
cropEnabled = drawParameter.cropEnabled;
|
||||||
forceUpscaling = _forceUpscaling;
|
isOpaque = drawParameter.opaque;
|
||||||
contentsScale = _contentsScaleForDisplay;
|
backgroundColor = drawParameter.backgroundColor;
|
||||||
cropDisplayBounds = _cropDisplayBounds;
|
contentMode = drawParameter.contentMode;
|
||||||
cropRect = _cropRect;
|
contentsScale = drawParameter.contentsScale;
|
||||||
imageModificationBlock = _imageModificationBlock;
|
cropDisplayBounds = drawParameter.cropDisplayBounds;
|
||||||
|
cropRect = drawParameter.cropRect;
|
||||||
|
imageModificationBlock = drawParameter.imageModificationBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL hasValidCropBounds = cropEnabled && !CGRectIsNull(cropDisplayBounds) && !CGRectIsEmpty(cropDisplayBounds);
|
BOOL hasValidCropBounds = cropEnabled && !CGRectIsNull(cropDisplayBounds) && !CGRectIsEmpty(cropDisplayBounds);
|
||||||
CGRect bounds = (hasValidCropBounds ? cropDisplayBounds : parameters.bounds);
|
CGRect bounds = (hasValidCropBounds ? cropDisplayBounds : drawParameterBounds);
|
||||||
|
|
||||||
ASDisplayNodeContextModifier preContextBlock = self.willDisplayNodeContentWithRenderingContext;
|
ASDisplayNodeContextModifier preContextBlock = self.willDisplayNodeContentWithRenderingContext;
|
||||||
ASDisplayNodeContextModifier postContextBlock = self.didDisplayNodeContentWithRenderingContext;
|
ASDisplayNodeContextModifier postContextBlock = self.didDisplayNodeContentWithRenderingContext;
|
||||||
@@ -359,7 +357,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
|
||||||
- (void)setNeedsDisplayWithCompletion:(void (^ _Nullable)(BOOL canceled))displayCompletionBlock
|
- (void)setNeedsDisplayWithCompletion:(void (^ _Nullable)(BOOL canceled))displayCompletionBlock
|
||||||
{
|
{
|
||||||
if (self.displaySuspended) {
|
if (self.displaySuspended) {
|
||||||
@@ -378,6 +375,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Cropping
|
#pragma mark - Cropping
|
||||||
|
|
||||||
- (BOOL)isCropEnabled
|
- (BOOL)isCropEnabled
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_imageLock);
|
ASDN::MutexLocker l(_imageLock);
|
||||||
@@ -462,6 +460,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Debug
|
#pragma mark - Debug
|
||||||
|
|
||||||
- (void)layout
|
- (void)layout
|
||||||
{
|
{
|
||||||
[super layout];
|
[super layout];
|
||||||
@@ -477,6 +476,7 @@
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
#pragma mark - Extras
|
#pragma mark - Extras
|
||||||
|
|
||||||
extern asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat borderWidth, UIColor *borderColor)
|
extern asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat borderWidth, UIColor *borderColor)
|
||||||
{
|
{
|
||||||
return ^(UIImage *originalImage) {
|
return ^(UIImage *originalImage) {
|
||||||
|
|||||||
@@ -32,25 +32,10 @@ static const CGFloat ASTextNodeHighlightLightOpacity = 0.11;
|
|||||||
static const CGFloat ASTextNodeHighlightDarkOpacity = 0.22;
|
static const CGFloat ASTextNodeHighlightDarkOpacity = 0.22;
|
||||||
static NSString *ASTextNodeTruncationTokenAttributeName = @"ASTextNodeTruncationAttribute";
|
static NSString *ASTextNodeTruncationTokenAttributeName = @"ASTextNodeTruncationAttribute";
|
||||||
|
|
||||||
@interface ASTextNodeDrawParameters : NSObject
|
struct ASTextNodeDrawParameter {
|
||||||
|
CGRect bounds;
|
||||||
@property (nonatomic, assign, readonly) CGRect bounds;
|
UIColor *backgroundColor;
|
||||||
@property (nonatomic, strong, readonly) UIColor *backgroundColor;
|
};
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation ASTextNodeDrawParameters
|
|
||||||
|
|
||||||
- (instancetype)initWithBounds:(CGRect)bounds backgroundColor:(UIColor *)backgroundColor
|
|
||||||
{
|
|
||||||
if (self = [super init]) {
|
|
||||||
_bounds = bounds;
|
|
||||||
_backgroundColor = backgroundColor;
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface ASTextNode () <UIGestureRecognizerDelegate, NSLayoutManagerDelegate>
|
@interface ASTextNode () <UIGestureRecognizerDelegate, NSLayoutManagerDelegate>
|
||||||
|
|
||||||
@@ -78,6 +63,8 @@ static NSString *ASTextNodeTruncationTokenAttributeName = @"ASTextNodeTruncation
|
|||||||
|
|
||||||
ASTextKitRenderer *_renderer;
|
ASTextKitRenderer *_renderer;
|
||||||
|
|
||||||
|
ASTextNodeDrawParameter _drawParameter;
|
||||||
|
|
||||||
UILongPressGestureRecognizer *_longPressGestureRecognizer;
|
UILongPressGestureRecognizer *_longPressGestureRecognizer;
|
||||||
}
|
}
|
||||||
@dynamic placeholderEnabled;
|
@dynamic placeholderEnabled;
|
||||||
@@ -431,27 +418,37 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
|||||||
|
|
||||||
#pragma mark - Drawing
|
#pragma mark - Drawing
|
||||||
|
|
||||||
- (void)drawRect:(CGRect)bounds withParameters:(ASTextNodeDrawParameters *)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing
|
- (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer
|
||||||
|
{
|
||||||
|
_drawParameter = {
|
||||||
|
.backgroundColor = self.backgroundColor,
|
||||||
|
.bounds = self.bounds
|
||||||
|
};
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)drawRect:(CGRect)bounds withParameters:(id <NSObject>)p isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||||
|
|
||||||
|
ASTextNodeDrawParameter drawParameter = _drawParameter;
|
||||||
|
CGRect drawParameterBounds = drawParameter.bounds;
|
||||||
|
UIColor *backgroundColor = isRasterizing ? nil : drawParameter.backgroundColor;
|
||||||
|
|
||||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||||
ASDisplayNodeAssert(context, @"This is no good without a context.");
|
ASDisplayNodeAssert(context, @"This is no good without a context.");
|
||||||
|
|
||||||
CGContextSaveGState(context);
|
CGContextSaveGState(context);
|
||||||
|
|
||||||
ASTextKitRenderer *renderer = [self _rendererWithBounds:parameters.bounds];
|
ASTextKitRenderer *renderer = [self _rendererWithBounds:drawParameterBounds];
|
||||||
UIEdgeInsets shadowPadding = [self shadowPaddingWithRenderer:renderer];
|
UIEdgeInsets shadowPadding = [self shadowPaddingWithRenderer:renderer];
|
||||||
CGPoint boundsOrigin = parameters.bounds.origin;
|
CGPoint boundsOrigin = drawParameterBounds.origin;
|
||||||
CGPoint textOrigin = CGPointMake(boundsOrigin.x - shadowPadding.left, boundsOrigin.y - shadowPadding.top);
|
CGPoint textOrigin = CGPointMake(boundsOrigin.x - shadowPadding.left, boundsOrigin.y - shadowPadding.top);
|
||||||
|
|
||||||
// Fill background
|
// Fill background
|
||||||
if (!isRasterizing) {
|
if (backgroundColor != nil) {
|
||||||
UIColor *backgroundColor = parameters.backgroundColor;
|
[backgroundColor setFill];
|
||||||
if (backgroundColor) {
|
UIRectFillUsingBlendMode(CGContextGetClipBoundingBox(context), kCGBlendModeCopy);
|
||||||
[backgroundColor setFill];
|
|
||||||
UIRectFillUsingBlendMode(CGContextGetClipBoundingBox(context), kCGBlendModeCopy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw shadow
|
// Draw shadow
|
||||||
@@ -464,11 +461,6 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
|||||||
CGContextRestoreGState(context);
|
CGContextRestoreGState(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer
|
|
||||||
{
|
|
||||||
return [[ASTextNodeDrawParameters alloc] initWithBounds:self.threadSafeBounds backgroundColor:self.backgroundColor];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Attributes
|
#pragma mark - Attributes
|
||||||
|
|
||||||
- (id)linkAttributeValueAtPoint:(CGPoint)point
|
- (id)linkAttributeValueAtPoint:(CGPoint)point
|
||||||
|
|||||||
Reference in New Issue
Block a user