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 "ASEqualityHelpers.h"
|
||||
|
||||
@interface _ASImageNodeDrawParameters : NSObject
|
||||
|
||||
@property (nonatomic, retain) UIImage *image;
|
||||
@property (nonatomic, assign) BOOL opaque;
|
||||
@property (nonatomic, assign) CGRect bounds;
|
||||
@property (nonatomic, assign) CGFloat contentsScale;
|
||||
@property (nonatomic, strong) UIColor *backgroundColor;
|
||||
@property (nonatomic, assign) UIViewContentMode contentMode;
|
||||
|
||||
@end
|
||||
|
||||
// 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
|
||||
struct ASImageNodeDrawParameters {
|
||||
BOOL opaque;
|
||||
CGRect bounds;
|
||||
CGFloat contentsScale;
|
||||
UIColor *backgroundColor;
|
||||
UIViewContentMode contentMode;
|
||||
BOOL cropEnabled;
|
||||
BOOL forceUpscaling;
|
||||
CGRect cropRect;
|
||||
CGRect cropDisplayBounds;
|
||||
asimagenode_modification_block_t imageModificationBlock;
|
||||
};
|
||||
|
||||
@implementation ASImageNode
|
||||
{
|
||||
@@ -75,18 +47,22 @@
|
||||
void (^_displayCompletionBlock)(BOOL canceled);
|
||||
ASDN::RecursiveMutex _imageLock;
|
||||
|
||||
// Drawing
|
||||
ASImageNodeDrawParameters _drawParameter;
|
||||
ASTextNode *_debugLabelNode;
|
||||
|
||||
// Cropping.
|
||||
BOOL _cropEnabled; // Defaults to YES.
|
||||
BOOL _forceUpscaling; //Defaults to NO.
|
||||
CGRect _cropRect; // Defaults to CGRectMake(0.5, 0.5, 0, 0)
|
||||
CGRect _cropDisplayBounds;
|
||||
|
||||
ASTextNode *_debugLabelNode;
|
||||
CGRect _cropDisplayBounds; // Defaults to CGRectNull
|
||||
}
|
||||
|
||||
@synthesize image = _image;
|
||||
@synthesize imageModificationBlock = _imageModificationBlock;
|
||||
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
@@ -124,6 +100,8 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark - Layout and Sizing
|
||||
|
||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
@@ -136,6 +114,8 @@
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
#pragma mark - Setter / Getter
|
||||
|
||||
- (void)setImage:(UIImage *)image
|
||||
{
|
||||
_imageLock.lock();
|
||||
@@ -177,54 +157,72 @@
|
||||
self.placeholderEnabled = placeholderColor != nil;
|
||||
}
|
||||
|
||||
#pragma mark - Drawing
|
||||
|
||||
- (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer
|
||||
{
|
||||
return [[_ASImageNodeDrawParameters alloc] initWithImage:self.image
|
||||
bounds:self.bounds
|
||||
opaque:self.opaque
|
||||
contentsScale:self.contentsScaleForDisplay
|
||||
backgroundColor:self.backgroundColor
|
||||
contentMode:self.contentMode];
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
|
||||
_drawParameter = {
|
||||
.bounds = self.bounds,
|
||||
.opaque = self.opaque,
|
||||
.contentsScale = _contentsScaleForDisplay,
|
||||
.backgroundColor = self.backgroundColor,
|
||||
.contentMode = self.contentMode,
|
||||
.cropEnabled = _cropEnabled,
|
||||
.forceUpscaling = _forceUpscaling,
|
||||
.cropRect = _cropRect,
|
||||
.cropDisplayBounds = _cropDisplayBounds,
|
||||
.imageModificationBlock = _imageModificationBlock
|
||||
};
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSDictionary *)debugLabelAttributes
|
||||
{
|
||||
return @{ NSFontAttributeName: [UIFont systemFontOfSize:15.0],
|
||||
NSForegroundColorAttributeName: [UIColor redColor] };
|
||||
return @{
|
||||
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;
|
||||
if (!image) {
|
||||
UIImage *image = self.image;
|
||||
if (image == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
CGRect drawParameterBounds = CGRectZero;
|
||||
BOOL forceUpscaling = NO;
|
||||
BOOL cropEnabled = NO;
|
||||
BOOL isOpaque = parameters.opaque;
|
||||
UIColor *backgroundColor = parameters.backgroundColor;
|
||||
UIViewContentMode contentMode = parameters.contentMode;
|
||||
BOOL cropEnabled = YES;
|
||||
BOOL isOpaque = NO;
|
||||
UIColor *backgroundColor = nil;
|
||||
UIViewContentMode contentMode = UIViewContentModeScaleAspectFill;
|
||||
CGFloat contentsScale = 0.0;
|
||||
CGRect cropDisplayBounds = CGRectZero;
|
||||
CGRect cropRect = CGRectZero;
|
||||
asimagenode_modification_block_t imageModificationBlock;
|
||||
|
||||
{
|
||||
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.
|
||||
// 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.
|
||||
cropEnabled = _cropEnabled;
|
||||
forceUpscaling = _forceUpscaling;
|
||||
contentsScale = _contentsScaleForDisplay;
|
||||
cropDisplayBounds = _cropDisplayBounds;
|
||||
cropRect = _cropRect;
|
||||
imageModificationBlock = _imageModificationBlock;
|
||||
drawParameterBounds = drawParameter.bounds;
|
||||
forceUpscaling = drawParameter.forceUpscaling;
|
||||
cropEnabled = drawParameter.cropEnabled;
|
||||
isOpaque = drawParameter.opaque;
|
||||
backgroundColor = drawParameter.backgroundColor;
|
||||
contentMode = drawParameter.contentMode;
|
||||
contentsScale = drawParameter.contentsScale;
|
||||
cropDisplayBounds = drawParameter.cropDisplayBounds;
|
||||
cropRect = drawParameter.cropRect;
|
||||
imageModificationBlock = drawParameter.imageModificationBlock;
|
||||
}
|
||||
|
||||
BOOL hasValidCropBounds = cropEnabled && !CGRectIsNull(cropDisplayBounds) && !CGRectIsEmpty(cropDisplayBounds);
|
||||
CGRect bounds = (hasValidCropBounds ? cropDisplayBounds : parameters.bounds);
|
||||
CGRect bounds = (hasValidCropBounds ? cropDisplayBounds : drawParameterBounds);
|
||||
|
||||
ASDisplayNodeContextModifier preContextBlock = self.willDisplayNodeContentWithRenderingContext;
|
||||
ASDisplayNodeContextModifier postContextBlock = self.didDisplayNodeContentWithRenderingContext;
|
||||
@@ -359,7 +357,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
- (void)setNeedsDisplayWithCompletion:(void (^ _Nullable)(BOOL canceled))displayCompletionBlock
|
||||
{
|
||||
if (self.displaySuspended) {
|
||||
@@ -378,6 +375,7 @@
|
||||
}
|
||||
|
||||
#pragma mark - Cropping
|
||||
|
||||
- (BOOL)isCropEnabled
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
@@ -462,6 +460,7 @@
|
||||
}
|
||||
|
||||
#pragma mark - Debug
|
||||
|
||||
- (void)layout
|
||||
{
|
||||
[super layout];
|
||||
@@ -477,6 +476,7 @@
|
||||
@end
|
||||
|
||||
#pragma mark - Extras
|
||||
|
||||
extern asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat borderWidth, UIColor *borderColor)
|
||||
{
|
||||
return ^(UIImage *originalImage) {
|
||||
|
||||
@@ -32,25 +32,10 @@ static const CGFloat ASTextNodeHighlightLightOpacity = 0.11;
|
||||
static const CGFloat ASTextNodeHighlightDarkOpacity = 0.22;
|
||||
static NSString *ASTextNodeTruncationTokenAttributeName = @"ASTextNodeTruncationAttribute";
|
||||
|
||||
@interface ASTextNodeDrawParameters : NSObject
|
||||
|
||||
@property (nonatomic, assign, readonly) CGRect bounds;
|
||||
@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
|
||||
struct ASTextNodeDrawParameter {
|
||||
CGRect bounds;
|
||||
UIColor *backgroundColor;
|
||||
};
|
||||
|
||||
@interface ASTextNode () <UIGestureRecognizerDelegate, NSLayoutManagerDelegate>
|
||||
|
||||
@@ -78,6 +63,8 @@ static NSString *ASTextNodeTruncationTokenAttributeName = @"ASTextNodeTruncation
|
||||
|
||||
ASTextKitRenderer *_renderer;
|
||||
|
||||
ASTextNodeDrawParameter _drawParameter;
|
||||
|
||||
UILongPressGestureRecognizer *_longPressGestureRecognizer;
|
||||
}
|
||||
@dynamic placeholderEnabled;
|
||||
@@ -431,28 +418,38 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
#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);
|
||||
|
||||
ASTextNodeDrawParameter drawParameter = _drawParameter;
|
||||
CGRect drawParameterBounds = drawParameter.bounds;
|
||||
UIColor *backgroundColor = isRasterizing ? nil : drawParameter.backgroundColor;
|
||||
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
ASDisplayNodeAssert(context, @"This is no good without a context.");
|
||||
|
||||
CGContextSaveGState(context);
|
||||
|
||||
ASTextKitRenderer *renderer = [self _rendererWithBounds:parameters.bounds];
|
||||
ASTextKitRenderer *renderer = [self _rendererWithBounds:drawParameterBounds];
|
||||
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);
|
||||
|
||||
// Fill background
|
||||
if (!isRasterizing) {
|
||||
UIColor *backgroundColor = parameters.backgroundColor;
|
||||
if (backgroundColor) {
|
||||
if (backgroundColor != nil) {
|
||||
[backgroundColor setFill];
|
||||
UIRectFillUsingBlendMode(CGContextGetClipBoundingBox(context), kCGBlendModeCopy);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw shadow
|
||||
[renderer.shadower setShadowInContext:context];
|
||||
@@ -464,11 +461,6 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
- (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer
|
||||
{
|
||||
return [[ASTextNodeDrawParameters alloc] initWithBounds:self.threadSafeBounds backgroundColor:self.backgroundColor];
|
||||
}
|
||||
|
||||
#pragma mark - Attributes
|
||||
|
||||
- (id)linkAttributeValueAtPoint:(CGPoint)point
|
||||
|
||||
Reference in New Issue
Block a user