mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-12 17:30:34 +00:00
Optimize drawing code + add examples how to round corners (#996)
* Use CoreGraphics for drawing and cropping of node content * Smaller fixes
This commit is contained in:
parent
4880b54db0
commit
eb4c21c545
@ -109,7 +109,7 @@
|
|||||||
509E68631B3AEDB4009B9150 /* ASCollectionViewLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */; };
|
509E68631B3AEDB4009B9150 /* ASCollectionViewLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */; };
|
||||||
509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.m */; };
|
509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.m */; };
|
||||||
509E68651B3AEDC5009B9150 /* CoreGraphics+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
509E68651B3AEDC5009B9150 /* CoreGraphics+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
509E68661B3AEDD7009B9150 /* CoreGraphics+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.m */; };
|
509E68661B3AEDD7009B9150 /* CoreGraphics+ASConvenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.mm */; };
|
||||||
636EA1A41C7FF4EC00EE152F /* NSArray+Diffing.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBC452DA1C5BF64600B16017 /* NSArray+Diffing.mm */; };
|
636EA1A41C7FF4EC00EE152F /* NSArray+Diffing.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBC452DA1C5BF64600B16017 /* NSArray+Diffing.mm */; };
|
||||||
636EA1A51C7FF4EF00EE152F /* ASDefaultPlayButton.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */; };
|
636EA1A51C7FF4EF00EE152F /* ASDefaultPlayButton.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */; };
|
||||||
680346941CE4052A0009FEB4 /* ASNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
680346941CE4052A0009FEB4 /* ASNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
@ -176,7 +176,7 @@
|
|||||||
7AB338671C55B3460055FDE8 /* ASRelativeLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A06A7391C35F08800FE8DAA /* ASRelativeLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
7AB338671C55B3460055FDE8 /* ASRelativeLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A06A7391C35F08800FE8DAA /* ASRelativeLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
7AB338691C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7AB338681C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm */; };
|
7AB338691C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7AB338681C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm */; };
|
||||||
8021EC1D1D2B00B100799119 /* UIImage+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 8021EC1A1D2B00B100799119 /* UIImage+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
8021EC1D1D2B00B100799119 /* UIImage+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 8021EC1A1D2B00B100799119 /* UIImage+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
8021EC1F1D2B00B100799119 /* UIImage+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.m */; };
|
8021EC1F1D2B00B100799119 /* UIImage+ASConvenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.mm */; };
|
||||||
81E95C141D62639600336598 /* ASTextNodeSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 81E95C131D62639600336598 /* ASTextNodeSnapshotTests.m */; };
|
81E95C141D62639600336598 /* ASTextNodeSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 81E95C131D62639600336598 /* ASTextNodeSnapshotTests.m */; };
|
||||||
83A7D95B1D44547700BF333E /* ASWeakMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A7D9591D44542100BF333E /* ASWeakMap.m */; };
|
83A7D95B1D44547700BF333E /* ASWeakMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A7D9591D44542100BF333E /* ASWeakMap.m */; };
|
||||||
83A7D95C1D44548100BF333E /* ASWeakMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A7D9581D44542100BF333E /* ASWeakMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
83A7D95C1D44548100BF333E /* ASWeakMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A7D9581D44542100BF333E /* ASWeakMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||||
@ -621,7 +621,7 @@
|
|||||||
205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewLayoutController.h; sourceTree = "<group>"; };
|
205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewLayoutController.h; sourceTree = "<group>"; };
|
||||||
205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewLayoutController.m; sourceTree = "<group>"; };
|
205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewLayoutController.m; sourceTree = "<group>"; };
|
||||||
205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CoreGraphics+ASConvenience.h"; sourceTree = "<group>"; };
|
205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CoreGraphics+ASConvenience.h"; sourceTree = "<group>"; };
|
||||||
205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CoreGraphics+ASConvenience.m"; sourceTree = "<group>"; };
|
205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "CoreGraphics+ASConvenience.mm"; sourceTree = "<group>"; };
|
||||||
242995D21B29743C00090100 /* ASBasicImageDownloaderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASBasicImageDownloaderTests.m; sourceTree = "<group>"; };
|
242995D21B29743C00090100 /* ASBasicImageDownloaderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASBasicImageDownloaderTests.m; sourceTree = "<group>"; };
|
||||||
2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASCollectionViewFlowLayoutInspectorTests.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASCollectionViewFlowLayoutInspectorTests.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||||
254C6B511BF8FE6D003EC431 /* ASTextKitTruncationTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextKitTruncationTests.mm; sourceTree = "<group>"; };
|
254C6B511BF8FE6D003EC431 /* ASTextKitTruncationTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextKitTruncationTests.mm; sourceTree = "<group>"; };
|
||||||
@ -734,7 +734,7 @@
|
|||||||
7A06A7391C35F08800FE8DAA /* ASRelativeLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRelativeLayoutSpec.h; sourceTree = "<group>"; };
|
7A06A7391C35F08800FE8DAA /* ASRelativeLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRelativeLayoutSpec.h; sourceTree = "<group>"; };
|
||||||
7AB338681C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRelativeLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
|
7AB338681C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRelativeLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
|
||||||
8021EC1A1D2B00B100799119 /* UIImage+ASConvenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+ASConvenience.h"; sourceTree = "<group>"; };
|
8021EC1A1D2B00B100799119 /* UIImage+ASConvenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+ASConvenience.h"; sourceTree = "<group>"; };
|
||||||
8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ASConvenience.m"; sourceTree = "<group>"; };
|
8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UIImage+ASConvenience.mm"; sourceTree = "<group>"; };
|
||||||
81E95C131D62639600336598 /* ASTextNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextNodeSnapshotTests.m; sourceTree = "<group>"; };
|
81E95C131D62639600336598 /* ASTextNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextNodeSnapshotTests.m; sourceTree = "<group>"; };
|
||||||
81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASRunLoopQueue.h; path = ../ASRunLoopQueue.h; sourceTree = "<group>"; };
|
81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASRunLoopQueue.h; path = ../ASRunLoopQueue.h; sourceTree = "<group>"; };
|
||||||
81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRunLoopQueue.mm; path = ../ASRunLoopQueue.mm; sourceTree = "<group>"; };
|
81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRunLoopQueue.mm; path = ../ASRunLoopQueue.mm; sourceTree = "<group>"; };
|
||||||
@ -1234,7 +1234,7 @@
|
|||||||
68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */,
|
68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */,
|
||||||
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */,
|
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */,
|
||||||
8021EC1A1D2B00B100799119 /* UIImage+ASConvenience.h */,
|
8021EC1A1D2B00B100799119 /* UIImage+ASConvenience.h */,
|
||||||
8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.m */,
|
8021EC1B1D2B00B100799119 /* UIImage+ASConvenience.mm */,
|
||||||
CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */,
|
CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */,
|
||||||
CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */,
|
CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */,
|
||||||
);
|
);
|
||||||
@ -1422,7 +1422,7 @@
|
|||||||
CC3B20871C3F7A5400798563 /* ASWeakSet.h */,
|
CC3B20871C3F7A5400798563 /* ASWeakSet.h */,
|
||||||
CC3B20881C3F7A5400798563 /* ASWeakSet.m */,
|
CC3B20881C3F7A5400798563 /* ASWeakSet.m */,
|
||||||
205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */,
|
205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */,
|
||||||
205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.m */,
|
205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.mm */,
|
||||||
DBC452D91C5BF64600B16017 /* NSArray+Diffing.h */,
|
DBC452D91C5BF64600B16017 /* NSArray+Diffing.h */,
|
||||||
DBC452DA1C5BF64600B16017 /* NSArray+Diffing.mm */,
|
DBC452DA1C5BF64600B16017 /* NSArray+Diffing.mm */,
|
||||||
CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */,
|
CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */,
|
||||||
@ -2405,7 +2405,7 @@
|
|||||||
CCA282C51E9EAE630037E8B7 /* ASLayerBackingTipProvider.m in Sources */,
|
CCA282C51E9EAE630037E8B7 /* ASLayerBackingTipProvider.m in Sources */,
|
||||||
509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.m in Sources */,
|
509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.m in Sources */,
|
||||||
B35061F91B010EFD0018CF92 /* ASControlNode.mm in Sources */,
|
B35061F91B010EFD0018CF92 /* ASControlNode.mm in Sources */,
|
||||||
8021EC1F1D2B00B100799119 /* UIImage+ASConvenience.m in Sources */,
|
8021EC1F1D2B00B100799119 /* UIImage+ASConvenience.mm in Sources */,
|
||||||
CCAA0B80206ADBF30057B336 /* ASRecursiveUnfairLock.m in Sources */,
|
CCAA0B80206ADBF30057B336 /* ASRecursiveUnfairLock.m in Sources */,
|
||||||
CCBDDD0620C62A2D00CBA922 /* ASMainThreadDeallocation.mm in Sources */,
|
CCBDDD0620C62A2D00CBA922 /* ASMainThreadDeallocation.mm in Sources */,
|
||||||
B35062181B010EFD0018CF92 /* ASDataController.mm in Sources */,
|
B35062181B010EFD0018CF92 /* ASDataController.mm in Sources */,
|
||||||
@ -2504,7 +2504,7 @@
|
|||||||
6959433F1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */,
|
6959433F1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */,
|
||||||
68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */,
|
68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */,
|
||||||
CC034A141E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.m in Sources */,
|
CC034A141E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.m in Sources */,
|
||||||
509E68661B3AEDD7009B9150 /* CoreGraphics+ASConvenience.m in Sources */,
|
509E68661B3AEDD7009B9150 /* CoreGraphics+ASConvenience.mm in Sources */,
|
||||||
254C6B871BF94F8A003EC431 /* ASTextKitEntityAttribute.m in Sources */,
|
254C6B871BF94F8A003EC431 /* ASTextKitEntityAttribute.m in Sources */,
|
||||||
34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.m in Sources */,
|
34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.m in Sources */,
|
||||||
254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.m in Sources */,
|
254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.m in Sources */,
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
- Reduced binary size by disabling exception support (which we don't use.) [Adlai Holler](https://github.com/Adlai-Holler)
|
- Reduced binary size by disabling exception support (which we don't use.) [Adlai Holler](https://github.com/Adlai-Holler)
|
||||||
- Create and set delegate for clip corner layers within ASDisplayNode [Michael Schneider](https://github.com/maicki) [#1029](https://github.com/TextureGroup/Texture/pull/1029)
|
- Create and set delegate for clip corner layers within ASDisplayNode [Michael Schneider](https://github.com/maicki) [#1029](https://github.com/TextureGroup/Texture/pull/1029)
|
||||||
- Improve locking situation in ASVideoPlayerNode [Michael Schneider](https://github.com/maicki) [#1042](https://github.com/TextureGroup/Texture/pull/1042)
|
- Improve locking situation in ASVideoPlayerNode [Michael Schneider](https://github.com/maicki) [#1042](https://github.com/TextureGroup/Texture/pull/1042)
|
||||||
|
- Optimize drawing code + add examples how to round corners. [Michael Schneider](https://github.com/maicki)
|
||||||
|
|
||||||
## 2.7
|
## 2.7
|
||||||
- Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877)
|
- Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877)
|
||||||
|
|||||||
@ -53,6 +53,7 @@
|
|||||||
#import <AsyncDisplayKit/ASWeakProxy.h>
|
#import <AsyncDisplayKit/ASWeakProxy.h>
|
||||||
#import <AsyncDisplayKit/ASResponderChainEnumerator.h>
|
#import <AsyncDisplayKit/ASResponderChainEnumerator.h>
|
||||||
#import <AsyncDisplayKit/ASTipsController.h>
|
#import <AsyncDisplayKit/ASTipsController.h>
|
||||||
|
#import <AsyncDisplayKit/CoreGraphics+ASConvenience.h>
|
||||||
|
|
||||||
// Conditionally time these scopes to our debug ivars (only exist in debug/profile builds)
|
// Conditionally time these scopes to our debug ivars (only exist in debug/profile builds)
|
||||||
#if TIME_DISPLAYNODE_OPS
|
#if TIME_DISPLAYNODE_OPS
|
||||||
@ -1508,7 +1509,7 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
|
|||||||
__instanceLock__.lock();
|
__instanceLock__.lock();
|
||||||
if (_placeholderLayer.superlayer && !placeholderShouldPersist) {
|
if (_placeholderLayer.superlayer && !placeholderShouldPersist) {
|
||||||
void (^cleanupBlock)() = ^{
|
void (^cleanupBlock)() = ^{
|
||||||
[_placeholderLayer removeFromSuperlayer];
|
[self->_placeholderLayer removeFromSuperlayer];
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_placeholderFadeDuration > 0.0 && ASInterfaceStateIncludesVisible(self.interfaceState)) {
|
if (_placeholderFadeDuration > 0.0 && ASInterfaceStateIncludesVisible(self.interfaceState)) {
|
||||||
@ -1666,24 +1667,29 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
|||||||
CGSize size = CGSizeMake(radius + 1, radius + 1);
|
CGSize size = CGSizeMake(radius + 1, radius + 1);
|
||||||
ASGraphicsBeginImageContextWithOptions(size, NO, self.contentsScaleForDisplay);
|
ASGraphicsBeginImageContextWithOptions(size, NO, self.contentsScaleForDisplay);
|
||||||
|
|
||||||
CGContextRef ctx = UIGraphicsGetCurrentContext();
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||||
if (isRight == YES) {
|
if (isRight == YES) {
|
||||||
CGContextTranslateCTM(ctx, -radius + 1, 0);
|
CGContextTranslateCTM(context, -radius + 1, 0);
|
||||||
}
|
}
|
||||||
if (isTop == YES) {
|
if (isTop == YES) {
|
||||||
CGContextTranslateCTM(ctx, 0, -radius + 1);
|
CGContextTranslateCTM(context, 0, -radius + 1);
|
||||||
}
|
}
|
||||||
UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, radius * 2, radius * 2) cornerRadius:radius];
|
|
||||||
[roundedRect setUsesEvenOddFillRule:YES];
|
CGMutablePathRef roundedPath = CGPathCreateMutable();
|
||||||
[roundedRect appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(-1, -1, radius * 2 + 1, radius * 2 + 1)]];
|
CGPathRef addedPath = ASCGRoundedPathCreate(CGRectMake(0, 0, radius * 2, radius * 2), radius);
|
||||||
[backgroundColor setFill];
|
CGPathAddPath(roundedPath, NULL, addedPath);
|
||||||
[roundedRect fill];
|
CGPathAddRect(roundedPath, NULL, CGRectMake(-1, -1, radius * 2 + 1, radius * 2 + 1));
|
||||||
|
CGContextAddPath(context, roundedPath);
|
||||||
|
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
|
||||||
|
CGContextEOFillPath(context);
|
||||||
|
|
||||||
// No lock needed, as _clipCornerLayers is only modified on the main thread.
|
// No lock needed, as _clipCornerLayers is only modified on the main thread.
|
||||||
CALayer *clipCornerLayer = _clipCornerLayers[idx];
|
_clipCornerLayers[idx].contents = (id)(ASGraphicsGetImageAndEndCurrentContext().CGImage);
|
||||||
clipCornerLayer.contents = (id)(ASGraphicsGetImageAndEndCurrentContext().CGImage);
|
_clipCornerLayers[idx].bounds = CGRectMake(0.0, 0.0, size.width, size.height);
|
||||||
clipCornerLayer.bounds = CGRectMake(0.0, 0.0, size.width, size.height);
|
_clipCornerLayers[idx].anchorPoint = CGPointMake(isRight ? 1.0 : 0.0, isTop ? 1.0 : 0.0);
|
||||||
clipCornerLayer.anchorPoint = CGPointMake(isRight ? 1.0 : 0.0, isTop ? 1.0 : 0.0);
|
|
||||||
|
CGPathRelease(addedPath);
|
||||||
|
CGPathRelease(roundedPath);
|
||||||
}
|
}
|
||||||
[self _layoutClipCornersIfNeeded];
|
[self _layoutClipCornersIfNeeded];
|
||||||
});
|
});
|
||||||
@ -1868,7 +1874,10 @@ static void _recursivelySetDisplaySuspended(ASDisplayNode *node, CALayer *layer,
|
|||||||
[self displayDidFinish];
|
[self displayDidFinish];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
- (void)displayWillStart {}
|
- (void)displayWillStart {}
|
||||||
|
#pragma clang diagnostic pop
|
||||||
- (void)displayWillStartAsynchronously:(BOOL)asynchronously
|
- (void)displayWillStartAsynchronously:(BOOL)asynchronously
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertMainThread();
|
ASDisplayNodeAssertMainThread();
|
||||||
@ -2979,11 +2988,11 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
|||||||
if (ASInterfaceStateIncludesVisible(self.pendingInterfaceState)) {
|
if (ASInterfaceStateIncludesVisible(self.pendingInterfaceState)) {
|
||||||
void(^exitVisibleInterfaceState)(void) = ^{
|
void(^exitVisibleInterfaceState)(void) = ^{
|
||||||
// This block intentionally retains self.
|
// This block intentionally retains self.
|
||||||
__instanceLock__.lock();
|
self->__instanceLock__.lock();
|
||||||
unsigned isStillInHierarchy = _flags.isInHierarchy;
|
unsigned isStillInHierarchy = self->_flags.isInHierarchy;
|
||||||
BOOL isVisible = ASInterfaceStateIncludesVisible(_pendingInterfaceState);
|
BOOL isVisible = ASInterfaceStateIncludesVisible(self->_pendingInterfaceState);
|
||||||
ASInterfaceState newState = (_pendingInterfaceState & ~ASInterfaceStateVisible);
|
ASInterfaceState newState = (self->_pendingInterfaceState & ~ASInterfaceStateVisible);
|
||||||
__instanceLock__.unlock();
|
self->__instanceLock__.unlock();
|
||||||
if (!isStillInHierarchy && isVisible) {
|
if (!isStillInHierarchy && isVisible) {
|
||||||
#if ENABLE_NEW_EXIT_HIERARCHY_BEHAVIOR
|
#if ENABLE_NEW_EXIT_HIERARCHY_BEHAVIOR
|
||||||
if (![self supportsRangeManagedInterfaceState]) {
|
if (![self supportsRangeManagedInterfaceState]) {
|
||||||
@ -3142,8 +3151,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
|||||||
[self setDisplaySuspended:YES];
|
[self setDisplaySuspended:YES];
|
||||||
//schedule clear contents on next runloop
|
//schedule clear contents on next runloop
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(self->__instanceLock__);
|
||||||
if (ASInterfaceStateIncludesDisplay(_interfaceState) == NO) {
|
if (ASInterfaceStateIncludesDisplay(self->_interfaceState) == NO) {
|
||||||
[self clearContents];
|
[self clearContents];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -3160,8 +3169,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
|||||||
[[self asyncLayer] cancelAsyncDisplay];
|
[[self asyncLayer] cancelAsyncDisplay];
|
||||||
//schedule clear contents on next runloop
|
//schedule clear contents on next runloop
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(self->__instanceLock__);
|
||||||
if (ASInterfaceStateIncludesDisplay(_interfaceState) == NO) {
|
if (ASInterfaceStateIncludesDisplay(self->_interfaceState) == NO) {
|
||||||
[self clearContents];
|
[self clearContents];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -737,19 +737,43 @@ asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat
|
|||||||
{
|
{
|
||||||
return ^(UIImage *originalImage) {
|
return ^(UIImage *originalImage) {
|
||||||
ASGraphicsBeginImageContextWithOptions(originalImage.size, NO, originalImage.scale);
|
ASGraphicsBeginImageContextWithOptions(originalImage.size, NO, originalImage.scale);
|
||||||
UIBezierPath *roundOutline = [UIBezierPath bezierPathWithOvalInRect:(CGRect){CGPointZero, originalImage.size}];
|
|
||||||
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||||
|
|
||||||
|
CGRect rect = (CGRect){CGPointZero, originalImage.size};
|
||||||
|
CGMutablePathRef path = CGPathCreateMutable();
|
||||||
|
|
||||||
|
CGPathAddEllipseInRect(path, NULL, rect);
|
||||||
|
CGContextAddPath(context, path);
|
||||||
|
|
||||||
// Make the image round
|
// Make the image round
|
||||||
[roundOutline addClip];
|
CGContextClip(context);
|
||||||
|
|
||||||
|
// Although drawAtPoint:blendMode: would consider the CTM already, we are using CGContext* functions for drawing
|
||||||
|
// the image instead calling drawAtPoint:blendMode. This will save use 50% of retain calls for the image
|
||||||
|
CGContextSetBlendMode(context, kCGBlendModeCopy);
|
||||||
|
CGContextTranslateCTM(context, 0, CGRectGetMaxY(rect) + CGRectGetMinY(rect));
|
||||||
|
CGContextScaleCTM(context, originalImage.scale, -originalImage.scale);
|
||||||
|
CGContextSetAlpha(context, 1.0);
|
||||||
|
CGContextDrawImage(context, rect, originalImage.CGImage);
|
||||||
|
|
||||||
// Draw the original image
|
CGPathRelease(path);
|
||||||
[originalImage drawAtPoint:CGPointZero blendMode:kCGBlendModeCopy alpha:1];
|
|
||||||
|
|
||||||
// Draw a border on top.
|
// Draw a border on top.
|
||||||
if (borderWidth > 0.0) {
|
if (borderWidth > 0.0) {
|
||||||
[borderColor setStroke];
|
// Begin a new path for the border
|
||||||
[roundOutline setLineWidth:borderWidth];
|
CGContextBeginPath(context);
|
||||||
[roundOutline stroke];
|
|
||||||
|
CGFloat strokeThickness = borderWidth;
|
||||||
|
CGFloat strokeInset = floor((strokeThickness + 1.0f) / 2.0f) - 1.0f;
|
||||||
|
CGPathRef path = CGPathCreateWithEllipseInRect(CGRectInset(rect, strokeInset, strokeInset), NULL);
|
||||||
|
CGContextAddPath(context, path);
|
||||||
|
|
||||||
|
CGContextSetStrokeColorWithColor(context, borderColor.CGColor);
|
||||||
|
CGContextSetLineWidth(context, borderWidth);
|
||||||
|
CGContextStrokePath(context);
|
||||||
|
|
||||||
|
CGPathRelease(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ASGraphicsGetImageAndEndCurrentContext();
|
return ASGraphicsGetImageAndEndCurrentContext();
|
||||||
|
|||||||
@ -130,7 +130,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ASOVERLOADABLE __attribute__((overloadable))
|
#define AS_OVERLOADABLE __attribute__((overloadable))
|
||||||
|
|
||||||
|
|
||||||
#if __has_attribute(noescape)
|
#if __has_attribute(noescape)
|
||||||
|
|||||||
@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
#import <CoreGraphics/CoreGraphics.h>
|
|
||||||
#import <tgmath.h>
|
#import <tgmath.h>
|
||||||
|
#import <UIKit/UIBezierPath.h>
|
||||||
|
|
||||||
#import <AsyncDisplayKit/ASBaseDefines.h>
|
#import <AsyncDisplayKit/ASBaseDefines.h>
|
||||||
|
|
||||||
@ -56,4 +56,11 @@ ASDISPLAYNODE_INLINE BOOL CGSizeEqualToSizeWithIn(CGSize size1, CGSize size2, CG
|
|||||||
return fabs(size1.width - size2.width) < delta && fabs(size1.height - size2.height) < delta;
|
return fabs(size1.width - size2.width) < delta && fabs(size1.height - size2.height) < delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AS_OVERLOADABLE AS_WARN_UNUSED_RESULT AS_EXTERN CGPathRef ASCGRoundedPathCreate(CGRect rect, UIRectCorner corners, CGSize cornerRadii);
|
||||||
|
|
||||||
|
AS_OVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT CGPathRef ASCGRoundedPathCreate(CGRect rect, CGFloat cornerRadius) {
|
||||||
|
return ASCGRoundedPathCreate(rect, UIRectCornerAllCorners, CGSizeMake(cornerRadius, cornerRadius));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
//
|
|
||||||
// CoreGraphics+ASConvenience.m
|
|
||||||
// Texture
|
|
||||||
//
|
|
||||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
|
||||||
// This source code is licensed under the BSD-style license found in the
|
|
||||||
// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional
|
|
||||||
// grant of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
//
|
|
||||||
// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present,
|
|
||||||
// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <AsyncDisplayKit/CoreGraphics+ASConvenience.h>
|
|
||||||
|
|
||||||
64
Source/Details/CoreGraphics+ASConvenience.mm
Normal file
64
Source/Details/CoreGraphics+ASConvenience.mm
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// CoreGraphics+ASConvenience.m
|
||||||
|
// Texture
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional
|
||||||
|
// grant of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
//
|
||||||
|
// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present,
|
||||||
|
// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <AsyncDisplayKit/CoreGraphics+ASConvenience.h>
|
||||||
|
|
||||||
|
AS_OVERLOADABLE CGPathRef ASCGRoundedPathCreate(CGRect rect, UIRectCorner corners, CGSize cornerRadii) {
|
||||||
|
CGMutablePathRef path = CGPathCreateMutable();
|
||||||
|
|
||||||
|
const CGPoint topLeft = rect.origin;
|
||||||
|
const CGPoint topRight = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));
|
||||||
|
const CGPoint bottomRight = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
|
||||||
|
const CGPoint bottomLeft = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect));
|
||||||
|
|
||||||
|
if (corners & UIRectCornerTopLeft) {
|
||||||
|
CGPathMoveToPoint(path, NULL, topLeft.x+cornerRadii.width, topLeft.y);
|
||||||
|
} else {
|
||||||
|
CGPathMoveToPoint(path, NULL, topLeft.x, topLeft.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (corners & UIRectCornerTopRight) {
|
||||||
|
CGPathAddLineToPoint(path, NULL, topRight.x-cornerRadii.width, topRight.y);
|
||||||
|
CGPathAddCurveToPoint(path, NULL, topRight.x, topRight.y, topRight.x, topRight.y+cornerRadii.height, topRight.x, topRight.y+cornerRadii.height);
|
||||||
|
} else {
|
||||||
|
CGPathAddLineToPoint(path, NULL, topRight.x, topRight.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (corners & UIRectCornerBottomRight) {
|
||||||
|
CGPathAddLineToPoint(path, NULL, bottomRight.x, bottomRight.y-cornerRadii.height);
|
||||||
|
CGPathAddCurveToPoint(path, NULL, bottomRight.x, bottomRight.y, bottomRight.x-cornerRadii.width, bottomRight.y, bottomRight.x-cornerRadii.width, bottomRight.y);
|
||||||
|
} else {
|
||||||
|
CGPathAddLineToPoint(path, NULL, bottomRight.x, bottomRight.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (corners & UIRectCornerBottomLeft) {
|
||||||
|
CGPathAddLineToPoint(path, NULL, bottomLeft.x+cornerRadii.width, bottomLeft.y);
|
||||||
|
CGPathAddCurveToPoint(path, NULL, bottomLeft.x, bottomLeft.y, bottomLeft.x, bottomLeft.y-cornerRadii.height, bottomLeft.x, bottomLeft.y-cornerRadii.height);
|
||||||
|
} else {
|
||||||
|
CGPathAddLineToPoint(path, NULL, bottomLeft.x, bottomLeft.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (corners & UIRectCornerTopLeft) {
|
||||||
|
CGPathAddLineToPoint(path, NULL, topLeft.x, topLeft.y+cornerRadii.height);
|
||||||
|
CGPathAddCurveToPoint(path, NULL, topLeft.x, topLeft.y, topLeft.x+cornerRadii.width, topLeft.y, topLeft.x+cornerRadii.width, topLeft.y);
|
||||||
|
} else {
|
||||||
|
CGPathAddLineToPoint(path, NULL, topLeft.x, topLeft.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
CGPathCloseSubpath(path);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
@ -94,7 +94,7 @@ AS_EXTERN ASDimension const ASDimensionAuto;
|
|||||||
/**
|
/**
|
||||||
* Returns a dimension with the specified type and value.
|
* Returns a dimension with the specified type and value.
|
||||||
*/
|
*/
|
||||||
ASOVERLOADABLE ASDISPLAYNODE_INLINE ASDimension ASDimensionMake(ASDimensionUnit unit, CGFloat value)
|
AS_OVERLOADABLE ASDISPLAYNODE_INLINE ASDimension ASDimensionMake(ASDimensionUnit unit, CGFloat value)
|
||||||
{
|
{
|
||||||
if (unit == ASDimensionUnitAuto ) {
|
if (unit == ASDimensionUnitAuto ) {
|
||||||
ASDisplayNodeCAssert(value == 0, @"ASDimension auto value must be 0.");
|
ASDisplayNodeCAssert(value == 0, @"ASDimension auto value must be 0.");
|
||||||
@ -112,7 +112,7 @@ ASOVERLOADABLE ASDISPLAYNODE_INLINE ASDimension ASDimensionMake(ASDimensionUnit
|
|||||||
/**
|
/**
|
||||||
* Returns a dimension with the specified points value.
|
* Returns a dimension with the specified points value.
|
||||||
*/
|
*/
|
||||||
ASOVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASDimension ASDimensionMake(CGFloat points)
|
AS_OVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASDimension ASDimensionMake(CGFloat points)
|
||||||
{
|
{
|
||||||
return ASDimensionMake(ASDimensionUnitPoints, points);
|
return ASDimensionMake(ASDimensionUnitPoints, points);
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ ASOVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASDimension ASDimensio
|
|||||||
* Examples: ASDimensionMake(@"50%") = ASDimensionMake(ASDimensionUnitFraction, 0.5)
|
* Examples: ASDimensionMake(@"50%") = ASDimensionMake(ASDimensionUnitFraction, 0.5)
|
||||||
* ASDimensionMake(@"0.5pt") = ASDimensionMake(ASDimensionUnitPoints, 0.5)
|
* ASDimensionMake(@"0.5pt") = ASDimensionMake(ASDimensionUnitPoints, 0.5)
|
||||||
*/
|
*/
|
||||||
ASOVERLOADABLE AS_WARN_UNUSED_RESULT AS_EXTERN ASDimension ASDimensionMake(NSString *dimension);
|
AS_OVERLOADABLE AS_WARN_UNUSED_RESULT AS_EXTERN ASDimension ASDimensionMake(NSString *dimension);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a dimension with the specified points value.
|
* Returns a dimension with the specified points value.
|
||||||
@ -244,7 +244,7 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASSizeRangeHasSignificantArea(AS
|
|||||||
/**
|
/**
|
||||||
* Creates an ASSizeRange with provided min and max size.
|
* Creates an ASSizeRange with provided min and max size.
|
||||||
*/
|
*/
|
||||||
ASOVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASSizeRange ASSizeRangeMake(CGSize min, CGSize max)
|
AS_OVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASSizeRange ASSizeRangeMake(CGSize min, CGSize max)
|
||||||
{
|
{
|
||||||
ASDisplayNodeCAssertPositiveReal(@"Range min width", min.width);
|
ASDisplayNodeCAssertPositiveReal(@"Range min width", min.width);
|
||||||
ASDisplayNodeCAssertPositiveReal(@"Range min height", min.height);
|
ASDisplayNodeCAssertPositiveReal(@"Range min height", min.height);
|
||||||
@ -263,7 +263,7 @@ ASOVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASSizeRange ASSizeRang
|
|||||||
/**
|
/**
|
||||||
* Creates an ASSizeRange with provided size as both min and max.
|
* Creates an ASSizeRange with provided size as both min and max.
|
||||||
*/
|
*/
|
||||||
ASOVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASSizeRange ASSizeRangeMake(CGSize exactSize)
|
AS_OVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASSizeRange ASSizeRangeMake(CGSize exactSize)
|
||||||
{
|
{
|
||||||
return ASSizeRangeMake(exactSize, exactSize);
|
return ASSizeRangeMake(exactSize, exactSize);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
ASDimension const ASDimensionAuto = {ASDimensionUnitAuto, 0};
|
ASDimension const ASDimensionAuto = {ASDimensionUnitAuto, 0};
|
||||||
|
|
||||||
ASOVERLOADABLE ASDimension ASDimensionMake(NSString *dimension)
|
AS_OVERLOADABLE ASDimension ASDimensionMake(NSString *dimension)
|
||||||
{
|
{
|
||||||
if (dimension.length > 0) {
|
if (dimension.length > 0) {
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
#import <AsyncDisplayKit/ASInternalHelpers.h>
|
#import <AsyncDisplayKit/ASInternalHelpers.h>
|
||||||
#import <AsyncDisplayKit/ASSignpost.h>
|
#import <AsyncDisplayKit/ASSignpost.h>
|
||||||
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
|
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
|
||||||
|
#import <AsyncDisplayKit/CoreGraphics+ASConvenience.h>
|
||||||
|
|
||||||
|
|
||||||
@interface ASDisplayNode () <_ASDisplayLayerDelegate>
|
@interface ASDisplayNode () <_ASDisplayLayerDelegate>
|
||||||
@ -111,10 +112,13 @@
|
|||||||
|
|
||||||
CGContextTranslateCTM(context, frame.origin.x, frame.origin.y);
|
CGContextTranslateCTM(context, frame.origin.x, frame.origin.y);
|
||||||
|
|
||||||
//support cornerRadius
|
// Support cornerRadius
|
||||||
if (rasterizingFromAscendent && clipsToBounds) {
|
if (rasterizingFromAscendent && clipsToBounds) {
|
||||||
if (cornerRadius) {
|
if (cornerRadius) {
|
||||||
[[UIBezierPath bezierPathWithRoundedRect:bounds cornerRadius:cornerRadius] addClip];
|
CGPathRef cornerRadiusPath = ASCGRoundedPathCreate(bounds, cornerRadius);
|
||||||
|
CGContextAddPath(context, cornerRadiusPath);
|
||||||
|
CGContextClip(context);
|
||||||
|
CGPathRelease(cornerRadiusPath);
|
||||||
} else {
|
} else {
|
||||||
CGContextClipToRect(context, bounds);
|
CGContextClipToRect(context, bounds);
|
||||||
}
|
}
|
||||||
@ -127,13 +131,18 @@
|
|||||||
CGContextFillRect(context, bounds);
|
CGContextFillRect(context, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a display block, call it to get the image, then copy the image into the current context (which is the rasterized container's backing store).
|
// If there is a display block, call it to get the image, then copy the image into the current context (which
|
||||||
|
// is the rasterized container's backing store).
|
||||||
if (displayBlock) {
|
if (displayBlock) {
|
||||||
UIImage *image = (UIImage *)displayBlock();
|
UIImage *image = (UIImage *)displayBlock();
|
||||||
if (image) {
|
if (image) {
|
||||||
BOOL opaque = ASImageAlphaInfoIsOpaque(CGImageGetAlphaInfo(image.CGImage));
|
BOOL opaque = ASImageAlphaInfoIsOpaque(CGImageGetAlphaInfo(image.CGImage));
|
||||||
CGBlendMode blendMode = opaque ? kCGBlendModeCopy : kCGBlendModeNormal;
|
CGBlendMode blendMode = opaque ? kCGBlendModeCopy : kCGBlendModeNormal;
|
||||||
[image drawInRect:bounds blendMode:blendMode alpha:1];
|
CGContextSetBlendMode(context, blendMode);
|
||||||
|
CGContextTranslateCTM(context, 0, CGRectGetMaxY(bounds) + CGRectGetMinY(bounds));
|
||||||
|
CGContextScaleCTM(context, 1, -1);
|
||||||
|
CGContextSetAlpha(context, 1.0);
|
||||||
|
CGContextDrawImage(context, bounds, image.CGImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -295,7 +304,10 @@
|
|||||||
ASDisplayNodeAssert(context == UIGraphicsGetCurrentContext(), @"context is expected to be pushed on UIGraphics stack %@", self);
|
ASDisplayNodeAssert(context == UIGraphicsGetCurrentContext(), @"context is expected to be pushed on UIGraphics stack %@", self);
|
||||||
// TODO: This clip path should be removed if we are rasterizing.
|
// TODO: This clip path should be removed if we are rasterizing.
|
||||||
CGRect boundingBox = CGContextGetClipBoundingBox(context);
|
CGRect boundingBox = CGContextGetClipBoundingBox(context);
|
||||||
[[UIBezierPath bezierPathWithRoundedRect:boundingBox cornerRadius:cornerRadius] addClip];
|
CGPathRef cornerRadiusPath = ASCGRoundedPathCreate(boundingBox, cornerRadius);
|
||||||
|
CGContextAddPath(context, cornerRadiusPath);
|
||||||
|
CGContextClip(context);
|
||||||
|
CGPathRelease(cornerRadiusPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (willDisplayNodeContentWithRenderingContext) {
|
if (willDisplayNodeContentWithRenderingContext) {
|
||||||
@ -332,34 +344,58 @@
|
|||||||
CGFloat white = 0.0f, alpha = 0.0f;
|
CGFloat white = 0.0f, alpha = 0.0f;
|
||||||
[backgroundColor getWhite:&white alpha:&alpha];
|
[backgroundColor getWhite:&white alpha:&alpha];
|
||||||
ASGraphicsBeginImageContextWithOptions(bounds.size, (alpha == 1.0f), contentsScale);
|
ASGraphicsBeginImageContextWithOptions(bounds.size, (alpha == 1.0f), contentsScale);
|
||||||
|
context = UIGraphicsGetCurrentContext();
|
||||||
[*image drawInRect:bounds];
|
[*image drawInRect:bounds];
|
||||||
} else {
|
} else {
|
||||||
bounds = CGContextGetClipBoundingBox(context);
|
bounds = CGContextGetClipBoundingBox(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASDisplayNodeAssert(UIGraphicsGetCurrentContext(), @"context is expected to be pushed on UIGraphics stack %@", self);
|
ASDisplayNodeAssert(UIGraphicsGetCurrentContext(), @"context is expected to be pushed on UIGraphics stack %@", self);
|
||||||
|
|
||||||
|
CGContextSaveGState(context);
|
||||||
|
|
||||||
UIBezierPath *roundedHole = [UIBezierPath bezierPathWithRect:bounds];
|
CGMutablePathRef roundedHole = CGPathCreateMutable();
|
||||||
[roundedHole appendPath:[UIBezierPath bezierPathWithRoundedRect:bounds cornerRadius:cornerRadius * contentsScale]];
|
CGPathAddRect(roundedHole, NULL, bounds);
|
||||||
roundedHole.usesEvenOddFillRule = YES;
|
|
||||||
|
CGPathRef additionalPath = ASCGRoundedPathCreate(bounds, cornerRadius * contentsScale);
|
||||||
UIBezierPath *roundedPath = nil;
|
CGPathAddPath(roundedHole, NULL, additionalPath);
|
||||||
if (borderWidth > 0.0f) { // Don't create roundedPath and stroke if borderWidth is 0.0
|
|
||||||
CGFloat strokeThickness = borderWidth * contentsScale;
|
CGContextAddPath(context, roundedHole);
|
||||||
CGFloat strokeInset = ((strokeThickness + 1.0f) / 2.0f) - 1.0f;
|
|
||||||
roundedPath = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(bounds, strokeInset, strokeInset)
|
|
||||||
cornerRadius:_cornerRadius * contentsScale];
|
|
||||||
roundedPath.lineWidth = strokeThickness;
|
|
||||||
[[UIColor colorWithCGColor:borderColor] setStroke];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Punch out the corners by copying the backgroundColor over them.
|
// Punch out the corners by copying the backgroundColor over them.
|
||||||
// This works for everything from clearColor to opaque colors.
|
// This works for everything from clearColor to opaque colors.
|
||||||
[backgroundColor setFill];
|
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
|
||||||
[roundedHole fillWithBlendMode:kCGBlendModeCopy alpha:1.0f];
|
|
||||||
|
|
||||||
[roundedPath stroke]; // Won't do anything if borderWidth is 0 and roundedPath is nil.
|
CGContextSetAlpha(context, 1.0);
|
||||||
|
CGContextSetBlendMode(context, kCGBlendModeCopy);
|
||||||
|
CGContextEOFillPath(context);
|
||||||
|
|
||||||
|
CGPathRelease(additionalPath);
|
||||||
|
CGPathRelease(roundedHole);
|
||||||
|
|
||||||
|
CGContextRestoreGState(context);
|
||||||
|
|
||||||
|
// Drawing borders with ASCornerRoundingTypePrecomposited set has some problems at the moment. If the borderWidth is
|
||||||
|
// set, besides we are drawing the border with the given corner radius, the CALayer also picks up the borderWidth
|
||||||
|
// value and draws the border without the cornerRadius.
|
||||||
|
if (borderWidth > 0.0f) { // Don't create roundedPath and stroke if borderWidth is 0.0
|
||||||
|
CGContextSaveGState(context);
|
||||||
|
|
||||||
|
CGFloat strokeThickness = borderWidth * contentsScale;
|
||||||
|
CGFloat strokeInset = ((strokeThickness + 1.0f) / 2.0f) - 1.0f;
|
||||||
|
CGPathRef roundedPath = ASCGRoundedPathCreate(CGRectInset(bounds, strokeInset, strokeInset), _cornerRadius * contentsScale);
|
||||||
|
CGContextAddPath(context, roundedPath);
|
||||||
|
|
||||||
|
CGContextSetLineWidth(context, strokeThickness);
|
||||||
|
CGContextSetStrokeColorWithColor(context, borderColor);
|
||||||
|
|
||||||
|
CGContextStrokePath(context);
|
||||||
|
|
||||||
|
CGPathRelease(roundedPath);
|
||||||
|
|
||||||
|
CGContextRestoreGState(context);
|
||||||
|
}
|
||||||
|
|
||||||
if (*image) {
|
if (*image) {
|
||||||
*image = ASGraphicsGetImageAndEndCurrentContext();
|
*image = ASGraphicsGetImageAndEndCurrentContext();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
#import <AsyncDisplayKit/ASGraphicsContext.h>
|
#import <AsyncDisplayKit/ASGraphicsContext.h>
|
||||||
#import <AsyncDisplayKit/ASInternalHelpers.h>
|
#import <AsyncDisplayKit/ASInternalHelpers.h>
|
||||||
#import <AsyncDisplayKit/ASAssert.h>
|
#import <AsyncDisplayKit/ASAssert.h>
|
||||||
|
#import <AsyncDisplayKit/CoreGraphics+ASConvenience.h>
|
||||||
|
|
||||||
#pragma mark - ASDKFastImageNamed
|
#pragma mark - ASDKFastImageNamed
|
||||||
|
|
||||||
@ -114,9 +115,9 @@ UIImage *cachedImageNamed(NSString *imageName, UITraitCollection *traitCollectio
|
|||||||
// UIBezierPath objects are fairly small and these are equally sized. 20 should be plenty for many different parameters.
|
// UIBezierPath objects are fairly small and these are equally sized. 20 should be plenty for many different parameters.
|
||||||
__pathCache.countLimit = 20;
|
__pathCache.countLimit = 20;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Treat clear background color as no background color
|
// Treat clear background color as no background color
|
||||||
if ([cornerColor isEqual:[UIColor clearColor]]) {
|
if (CGColorGetAlpha(cornerColor.CGColor) == 0) {
|
||||||
cornerColor = nil;
|
cornerColor = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,33 +141,46 @@ UIImage *cachedImageNamed(NSString *imageName, UITraitCollection *traitCollectio
|
|||||||
// We should probably check if the background color has any alpha component but that
|
// We should probably check if the background color has any alpha component but that
|
||||||
// might be expensive due to needing to check mulitple color spaces.
|
// might be expensive due to needing to check mulitple color spaces.
|
||||||
ASGraphicsBeginImageContextWithOptions(bounds.size, cornerColor != nil, scale);
|
ASGraphicsBeginImageContextWithOptions(bounds.size, cornerColor != nil, scale);
|
||||||
|
|
||||||
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||||
|
|
||||||
|
// Draw Corners
|
||||||
BOOL contextIsClean = YES;
|
BOOL contextIsClean = YES;
|
||||||
if (cornerColor) {
|
if (cornerColor) {
|
||||||
contextIsClean = NO;
|
contextIsClean = NO;
|
||||||
[cornerColor setFill];
|
|
||||||
|
CGContextSetFillColorWithColor(context, cornerColor.CGColor);
|
||||||
// Copy "blend" mode is extra fast because it disregards any value currently in the buffer and overrides directly.
|
// Copy "blend" mode is extra fast because it disregards any value currently in the buffer and overrides directly.
|
||||||
UIRectFillUsingBlendMode(bounds, kCGBlendModeCopy);
|
CGContextSetBlendMode(context, kCGBlendModeCopy);
|
||||||
|
CGContextFillRect(context, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw fill
|
||||||
BOOL canUseCopy = contextIsClean || (CGColorGetAlpha(fillColor.CGColor) == 1);
|
BOOL canUseCopy = contextIsClean || (CGColorGetAlpha(fillColor.CGColor) == 1);
|
||||||
[fillColor setFill];
|
CGContextSetFillColorWithColor(context, fillColor.CGColor);
|
||||||
[path fillWithBlendMode:(canUseCopy ? kCGBlendModeCopy : kCGBlendModeNormal) alpha:1];
|
CGContextSetBlendMode(context, canUseCopy ? kCGBlendModeCopy : kCGBlendModeNormal);
|
||||||
|
CGContextSetAlpha(context, 1.0);
|
||||||
|
CGContextAddPath(context, path.CGPath);
|
||||||
|
CGContextFillPath(context);
|
||||||
|
|
||||||
|
// Add a border
|
||||||
if (borderColor) {
|
if (borderColor) {
|
||||||
[borderColor setStroke];
|
|
||||||
|
|
||||||
// Inset border fully inside filled path (not halfway on each side of path)
|
// Inset border fully inside filled path (not halfway on each side of path)
|
||||||
CGRect strokeRect = CGRectInset(bounds, borderWidth / 2.0, borderWidth / 2.0);
|
CGRect strokeRect = CGRectInset(bounds, borderWidth / 2.0, borderWidth / 2.0);
|
||||||
|
|
||||||
// It is rarer to have a stroke path, and our cache key only handles rounded rects for the exact-stretchable
|
// It is rarer to have a stroke path, and our cache key only handles rounded rects for the exact-stretchable
|
||||||
// size calculated by cornerRadius, so we won't bother caching this path. Profiling validates this decision.
|
// size calculated by cornerRadius, so we won't bother caching this path. Profiling validates this decision.
|
||||||
UIBezierPath *strokePath = [UIBezierPath bezierPathWithRoundedRect:strokeRect
|
CGPathRef strokePath = ASCGRoundedPathCreate(strokeRect, roundedCorners, cornerRadii);
|
||||||
byRoundingCorners:roundedCorners
|
|
||||||
cornerRadii:cornerRadii];
|
CGContextSetStrokeColorWithColor(context, borderColor.CGColor);
|
||||||
[strokePath setLineWidth:borderWidth];
|
CGContextSetLineWidth(context, borderWidth);
|
||||||
|
CGContextSetAlpha(context, 1.0);
|
||||||
BOOL canUseCopy = (CGColorGetAlpha(borderColor.CGColor) == 1);
|
BOOL canUseCopy = (CGColorGetAlpha(borderColor.CGColor) == 1);
|
||||||
[strokePath strokeWithBlendMode:(canUseCopy ? kCGBlendModeCopy : kCGBlendModeNormal) alpha:1];
|
CGContextSetBlendMode(context, (canUseCopy ? kCGBlendModeCopy : kCGBlendModeNormal));
|
||||||
|
CGContextAddPath(context, strokePath);
|
||||||
|
CGContextStrokePath(context);
|
||||||
|
|
||||||
|
CGPathRelease(strokePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
UIImage *result = ASGraphicsGetImageAndEndCurrentContext();
|
UIImage *result = ASGraphicsGetImageAndEndCurrentContext();
|
||||||
@ -83,7 +83,9 @@
|
|||||||
layer.shadowColor = [UIColor blackColor].CGColor;
|
layer.shadowColor = [UIColor blackColor].CGColor;
|
||||||
layer.shadowRadius = 12.0;
|
layer.shadowRadius = 12.0;
|
||||||
layer.shadowOpacity = 0.45;
|
layer.shadowOpacity = 0.45;
|
||||||
layer.shadowPath = [UIBezierPath bezierPathWithRect:self.layer.bounds].CGPath;
|
CGPathRef shadowPath = CGPathCreateWithRect(self.layer.bounds, NULL);
|
||||||
|
layer.shadowPath = shadowPath;
|
||||||
|
CGPathRelease(shadowPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setDefaultFocusAppearance
|
- (void)setDefaultFocusAppearance
|
||||||
@ -93,7 +95,9 @@
|
|||||||
layer.shadowColor = [UIColor blackColor].CGColor;
|
layer.shadowColor = [UIColor blackColor].CGColor;
|
||||||
layer.shadowRadius = 0;
|
layer.shadowRadius = 0;
|
||||||
layer.shadowOpacity = 0;
|
layer.shadowOpacity = 0;
|
||||||
layer.shadowPath = [UIBezierPath bezierPathWithRect:self.layer.bounds].CGPath;
|
CGPathRef shadowPath = CGPathCreateWithRect(self.layer.bounds, NULL);
|
||||||
|
layer.shadowPath = shadowPath;
|
||||||
|
CGPathRelease(shadowPath);
|
||||||
self.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 1);
|
self.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 1);
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|||||||
@ -169,7 +169,9 @@
|
|||||||
layer.shadowColor = [UIColor blackColor].CGColor;
|
layer.shadowColor = [UIColor blackColor].CGColor;
|
||||||
layer.shadowRadius = 12.0;
|
layer.shadowRadius = 12.0;
|
||||||
layer.shadowOpacity = 0.45;
|
layer.shadowOpacity = 0.45;
|
||||||
layer.shadowPath = [UIBezierPath bezierPathWithRect:self.layer.bounds].CGPath;
|
CGPathRef shadowPath = CGPathCreateWithRect(self.layer.bounds, NULL);
|
||||||
|
layer.shadowPath = shadowPath;
|
||||||
|
CGPathRelease(shadowPath);
|
||||||
view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.25, 1.25);
|
view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.25, 1.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@ -79,8 +79,8 @@
|
|||||||
_photoImageNode.delegate = self;
|
_photoImageNode.delegate = self;
|
||||||
_photoImageNode.URL = photo.URL;
|
_photoImageNode.URL = photo.URL;
|
||||||
_photoImageNode.layerBacked = YES;
|
_photoImageNode.layerBacked = YES;
|
||||||
|
|
||||||
_userNameLabel = [[ASTextNode alloc] init];
|
_userNameLabel = [[ASTextNode alloc] init];
|
||||||
_userNameLabel.attributedText = [photo.ownerUserProfile usernameAttributedStringWithFontSize:FONT_SIZE];
|
_userNameLabel.attributedText = [photo.ownerUserProfile usernameAttributedStringWithFontSize:FONT_SIZE];
|
||||||
|
|
||||||
_photoLocationLabel = [[ASTextNode alloc] init];
|
_photoLocationLabel = [[ASTextNode alloc] init];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user