From 83b9d5c682b21d88133f24da0f94dd56bd79e687 Mon Sep 17 00:00:00 2001 From: 单军华 Date: Thu, 19 Jul 2018 13:38:55 +0800 Subject: [PATCH] change --- screendisplay/Pods/YYText/YYText/Utility/YYTextAsyncLayer.m | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 234 insertions(+), 0 deletions(-) diff --git a/screendisplay/Pods/YYText/YYText/Utility/YYTextAsyncLayer.m b/screendisplay/Pods/YYText/YYText/Utility/YYTextAsyncLayer.m new file mode 100755 index 0000000..e94bc47 --- /dev/null +++ b/screendisplay/Pods/YYText/YYText/Utility/YYTextAsyncLayer.m @@ -0,0 +1,234 @@ +// +// YYTextAsyncLayer.m +// YYText <https://github.com/ibireme/YYText> +// +// Created by ibireme on 15/4/11. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYTextAsyncLayer.h" +#import <libkern/OSAtomic.h> + + +/// Global display queue, used for content rendering. +static dispatch_queue_t YYTextAsyncLayerGetDisplayQueue() { +#define MAX_QUEUE_COUNT 16 + static int queueCount; + static dispatch_queue_t queues[MAX_QUEUE_COUNT]; + static dispatch_once_t onceToken; + static int32_t counter = 0; + dispatch_once(&onceToken, ^{ + queueCount = (int)[NSProcessInfo processInfo].activeProcessorCount; + queueCount = queueCount < 1 ? 1 : queueCount > MAX_QUEUE_COUNT ? MAX_QUEUE_COUNT : queueCount; + if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) { + for (NSUInteger i = 0; i < queueCount; i++) { + dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, 0); + queues[i] = dispatch_queue_create("com.ibireme.text.render", attr); + } + } else { + for (NSUInteger i = 0; i < queueCount; i++) { + queues[i] = dispatch_queue_create("com.ibireme.text.render", DISPATCH_QUEUE_SERIAL); + dispatch_set_target_queue(queues[i], dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); + } + } + }); + uint32_t cur = (uint32_t)OSAtomicIncrement32(&counter); + return queues[(cur) % queueCount]; +#undef MAX_QUEUE_COUNT +} + +static dispatch_queue_t YYTextAsyncLayerGetReleaseQueue() { +#ifdef YYDispatchQueuePool_h + return YYDispatchQueueGetForQOS(NSQualityOfServiceDefault); +#else + return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); +#endif +} + + +/// a thread safe incrementing counter. +@interface _YYTextSentinel : NSObject +/// Returns the current value of the counter. +@property (atomic, readonly) int32_t value; +/// Increase the value atomically. @return The new value. +- (int32_t)increase; +@end + +@implementation _YYTextSentinel { + int32_t _value; +} +- (int32_t)value { + return _value; +} +- (int32_t)increase { + return OSAtomicIncrement32(&_value); +} +@end + + +@implementation YYTextAsyncLayerDisplayTask +@end + + +@implementation YYTextAsyncLayer { + _YYTextSentinel *_sentinel; +} + +#pragma mark - Override + ++ (id)defaultValueForKey:(NSString *)key { + if ([key isEqualToString:@"displaysAsynchronously"]) { + return @(YES); + } else { + return [super defaultValueForKey:key]; + } +} + +- (instancetype)init { + self = [super init]; + static CGFloat scale; //global + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + scale = [UIScreen mainScreen].scale; + }); + self.contentsScale = scale; + _sentinel = [_YYTextSentinel new]; + _displaysAsynchronously = YES; + return self; +} + +- (void)dealloc { + [_sentinel increase]; +} + +- (void)setNeedsDisplay { + [self _cancelAsyncDisplay]; + [super setNeedsDisplay]; +} + +- (void)display { + super.contents = super.contents; + [self _displayAsync:_displaysAsynchronously]; +} + +#pragma mark - Private + +- (void)_displayAsync:(BOOL)async { + __strong id<YYTextAsyncLayerDelegate> delegate = (id)self.delegate; + YYTextAsyncLayerDisplayTask *task = [delegate newAsyncDisplayTask]; + if (!task.display) { + if (task.willDisplay) task.willDisplay(self); + self.contents = nil; + if (task.didDisplay) task.didDisplay(self, YES); + return; + } + + if (async) { + if (task.willDisplay) task.willDisplay(self); + _YYTextSentinel *sentinel = _sentinel; + int32_t value = sentinel.value; + BOOL (^isCancelled)() = ^BOOL() { + return value != sentinel.value; + }; + CGSize size = self.bounds.size; + BOOL opaque = self.opaque; + CGFloat scale = self.contentsScale; + CGColorRef backgroundColor = (opaque && self.backgroundColor) ? CGColorRetain(self.backgroundColor) : NULL; + if (size.width < 1 || size.height < 1) { + CGImageRef image = (__bridge_retained CGImageRef)(self.contents); + self.contents = nil; + if (image) { + dispatch_async(YYTextAsyncLayerGetReleaseQueue(), ^{ + CFRelease(image); + }); + } + if (task.didDisplay) task.didDisplay(self, YES); + CGColorRelease(backgroundColor); + return; + } + + dispatch_async(YYTextAsyncLayerGetDisplayQueue(), ^{ + if (isCancelled()) { + CGColorRelease(backgroundColor); + return; + } + UIGraphicsBeginImageContextWithOptions(size, opaque, scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + if (opaque) { + CGContextSaveGState(context); { + if (!backgroundColor || CGColorGetAlpha(backgroundColor) < 1) { + CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); + CGContextAddRect(context, CGRectMake(0, 0, size.width * scale, size.height * scale)); + CGContextFillPath(context); + } + if (backgroundColor) { + CGContextSetFillColorWithColor(context, backgroundColor); + CGContextAddRect(context, CGRectMake(0, 0, size.width * scale, size.height * scale)); + CGContextFillPath(context); + } + } CGContextRestoreGState(context); + CGColorRelease(backgroundColor); + } + task.display(context, size, isCancelled); + if (isCancelled()) { + UIGraphicsEndImageContext(); + dispatch_async(dispatch_get_main_queue(), ^{ + if (task.didDisplay) task.didDisplay(self, NO); + }); + return; + } + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + if (isCancelled()) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (task.didDisplay) task.didDisplay(self, NO); + }); + return; + } + dispatch_async(dispatch_get_main_queue(), ^{ + if (isCancelled()) { + if (task.didDisplay) task.didDisplay(self, NO); + } else { + self.contents = (__bridge id)(image.CGImage); + if (task.didDisplay) task.didDisplay(self, YES); + } + }); + }); + } else { + [_sentinel increase]; + if (task.willDisplay) task.willDisplay(self); + UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, self.contentsScale); + CGContextRef context = UIGraphicsGetCurrentContext(); + if (self.opaque) { + CGSize size = self.bounds.size; + size.width *= self.contentsScale; + size.height *= self.contentsScale; + CGContextSaveGState(context); { + if (!self.backgroundColor || CGColorGetAlpha(self.backgroundColor) < 1) { + CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); + CGContextAddRect(context, CGRectMake(0, 0, size.width, size.height)); + CGContextFillPath(context); + } + if (self.backgroundColor) { + CGContextSetFillColorWithColor(context, self.backgroundColor); + CGContextAddRect(context, CGRectMake(0, 0, size.width, size.height)); + CGContextFillPath(context); + } + } CGContextRestoreGState(context); + } + task.display(context, self.bounds.size, ^{return NO;}); + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + self.contents = (__bridge id)(image.CGImage); + if (task.didDisplay) task.didDisplay(self, YES); + } +} + +- (void)_cancelAsyncDisplay { + [_sentinel increase]; +} + +@end -- Gitblit v1.8.0