Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduction of ASGraphicsCreateImageWithTraitCollectionAndOptions #1675

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion AsyncDisplayKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@
CC3B208E1C3F7D0A00798563 /* ASWeakSetTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.mm */; };
CC3B20901C3F892D00798563 /* ASBridgedPropertiesTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */; };
CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.mm */; };
CC4E8DAF232C2883007C3182 /* ASGraphicsContextTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC4E8DAE232C2882007C3182 /* ASGraphicsContextTests.mm */; };
CC54A81C1D70079800296A24 /* ASDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = CC54A81B1D70077A00296A24 /* ASDispatch.h */; settings = {ATTRIBUTES = (Private, ); }; };
CC54A81E1D7008B300296A24 /* ASDispatchTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC54A81D1D7008B300296A24 /* ASDispatchTests.mm */; };
CC55A70D1E529FA200594372 /* UIResponder+AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -434,7 +435,7 @@
CCCCCCE41EC3EF060087FE10 /* NSParagraphStyle+ASText.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCD41EC3EF060087FE10 /* NSParagraphStyle+ASText.mm */; };
CCCCCCE71EC3F0FC0087FE10 /* NSAttributedString+ASText.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCE51EC3F0FC0087FE10 /* NSAttributedString+ASText.h */; };
CCCCCCE81EC3F0FC0087FE10 /* NSAttributedString+ASText.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCE61EC3F0FC0087FE10 /* NSAttributedString+ASText.mm */; };
CCDC9B4D200991D10063C1F8 /* ASGraphicsContext.h in Headers */ = {isa = PBXBuildFile; fileRef = CCDC9B4B200991D10063C1F8 /* ASGraphicsContext.h */; };
CCDC9B4D200991D10063C1F8 /* ASGraphicsContext.h in Headers */ = {isa = PBXBuildFile; fileRef = CCDC9B4B200991D10063C1F8 /* ASGraphicsContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
CCDC9B4E200991D10063C1F8 /* ASGraphicsContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCDC9B4C200991D10063C1F8 /* ASGraphicsContext.mm */; };
CCDD148B1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCDD148A1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.mm */; };
CCE4F9B31F0D60AC00062E4E /* ASIntegerMapTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCE4F9B21F0D60AC00062E4E /* ASIntegerMapTests.mm */; };
Expand Down Expand Up @@ -892,6 +893,7 @@
CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTableViewThrashTests.mm; sourceTree = "<group>"; };
CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSIndexSet+ASHelpers.h"; sourceTree = "<group>"; };
CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSIndexSet+ASHelpers.mm"; sourceTree = "<group>"; };
CC4E8DAE232C2882007C3182 /* ASGraphicsContextTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASGraphicsContextTests.mm; sourceTree = "<group>"; };
CC512B841DAC45C60054848E /* ASTableView+Undeprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASTableView+Undeprecated.h"; sourceTree = "<group>"; };
CC54A81B1D70077A00296A24 /* ASDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASDispatch.h; sourceTree = "<group>"; };
CC54A81D1D7008B300296A24 /* ASDispatchTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDispatchTests.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
Expand Down Expand Up @@ -1335,6 +1337,7 @@
058D0A31195D057000B7D73C /* ASDisplayNodeTestsHelper.mm */,
F3F698D1211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm */,
697B31591CFE4B410049936F /* ASEditableTextNodeTests.mm */,
CC4E8DAE232C2882007C3182 /* ASGraphicsContextTests.mm */,
471D04B0224CB98600649215 /* ASImageNodeBackingSizeTests.mm */,
056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.mm */,
D99F9157232990F30083CC8E /* ASImageNodeTests.m */,
Expand Down Expand Up @@ -2324,6 +2327,7 @@
4E9127691F64157600499623 /* ASRunLoopQueueTests.mm in Sources */,
CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.mm in Sources */,
CC54A81E1D7008B300296A24 /* ASDispatchTests.mm in Sources */,
CC4E8DAF232C2883007C3182 /* ASGraphicsContextTests.mm in Sources */,
F3F698D2211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm in Sources */,
CCE4F9B31F0D60AC00062E4E /* ASIntegerMapTests.mm in Sources */,
058D0A3B195D057000B7D73C /* ASDisplayNodeTestsHelper.mm in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Source/AsyncDisplayKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,4 @@
#import <AsyncDisplayKit/IGListAdapter+AsyncDisplayKit.h>
#import <AsyncDisplayKit/AsyncDisplayKit+IGListKitMethods.h>
#import <AsyncDisplayKit/ASLayout+IGListKit.h>
#import <AsyncDisplayKit/ASGraphicsContext.h>
18 changes: 17 additions & 1 deletion Source/Details/ASGraphicsContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import <UIKit/UIKit.h>
#import <AsyncDisplayKit/ASBaseDefines.h>
#import <AsyncDisplayKit/ASBlockTypes.h>
#import <AsyncDisplayKit/ASTraitCollection.h>

NS_ASSUME_NONNULL_BEGIN

Expand All @@ -27,6 +28,21 @@ NS_ASSUME_NONNULL_BEGIN
*
* @return The rendered image. You can also render intermediary images using UIGraphicsGetImageFromCurrentImageContext.
*/
AS_EXTERN UIImage *ASGraphicsCreateImageWithOptions(CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, asdisplaynode_iscancelled_block_t NS_NOESCAPE _Nullable isCancelled, void (NS_NOESCAPE ^work)());
AS_EXTERN UIImage *ASGraphicsCreateImageWithOptions(CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, asdisplaynode_iscancelled_block_t NS_NOESCAPE _Nullable isCancelled, void (NS_NOESCAPE ^work)(void));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we deprecate? There is ASDISPLAYNODE_DEPRECATED_MSG which can be used here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is appropriate to deprecate since it the existing interface is insufficient for correctness.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just talked to @vovasty and we'll deprecate in a follow-up PR


/**
* A wrapper for the UIKit drawing APIs.
*
* @param traitCollection Trait collection. The `work` block will be executed with this trait collection, so it will affect dynamic colors, etc.
* @param size The size of the context.
* @param opaque Whether the context should be opaque or not.
* @param scale The scale of the context. 0 uses main screen scale.
* @param sourceImage If you are planning to render a UIImage into this context, provide it here and we will use its
* preferred renderer format if we are using UIGraphicsImageRenderer.
* @param work A block, wherein the current UIGraphics context is set based on the arguments.
*
* @return The rendered image. You can also render intermediary images using UIGraphicsGetImageFromCurrentImageContext.
*/
AS_EXTERN UIImage *ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, void (NS_NOESCAPE ^work)(void));

NS_ASSUME_NONNULL_END
18 changes: 18 additions & 0 deletions Source/Details/ASGraphicsContext.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import <AsyncDisplayKit/ASAssert.h>
#import <AsyncDisplayKit/ASConfigurationInternal.h>
#import <AsyncDisplayKit/ASInternalHelpers.h>
#import <AsyncDisplayKit/ASAvailability.h>

NS_AVAILABLE_IOS(10)
NS_INLINE void ASConfigureExtendedRange(UIGraphicsImageRendererFormat *format)
Expand Down Expand Up @@ -94,3 +95,20 @@ NS_INLINE void ASConfigureExtendedRange(UIGraphicsImageRendererFormat *format)
UIGraphicsEndImageContext();
return image;
}

UIImage *ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * sourceImage, void (NS_NOESCAPE ^work)()) {
#if AS_AT_LEAST_IOS13
if (@available(iOS 13.0, *)) {
UITraitCollection *uiTraitCollection = ASPrimitiveTraitCollectionToUITraitCollection(traitCollection);
return ASGraphicsCreateImageWithOptions(size, opaque, scale, sourceImage, nil, ^{
[uiTraitCollection performAsCurrentTraitCollection:^{
work();
}];
});
} else {
return ASGraphicsCreateImageWithOptions(size, opaque, scale, sourceImage, nil, work);
}
#else
return ASGraphicsCreateImageWithOptions(size, opaque, scale, sourceImage, nil, work);
#endif
}
5 changes: 5 additions & 0 deletions Source/Details/ASTraitCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ AS_EXTERN ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault(void)
*/
AS_EXTERN ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITraitCollection *traitCollection);

/**
* Creates a UITraitCollection from a given ASPrimitiveTraitCollection.
*/
AS_EXTERN UITraitCollection * ASPrimitiveTraitCollectionToUITraitCollection(ASPrimitiveTraitCollection traitCollection);


/**
* Compares two ASPrimitiveTraitCollection to determine if they are the same.
Expand Down
22 changes: 22 additions & 0 deletions Source/Details/ASTraitCollection.mm
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,28 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITra
return environmentTraitCollection;
}

AS_EXTERN UITraitCollection * ASPrimitiveTraitCollectionToUITraitCollection(ASPrimitiveTraitCollection traitCollection) {
NSMutableArray *collections = [[NSMutableArray alloc] initWithArray:@[
[UITraitCollection traitCollectionWithHorizontalSizeClass:traitCollection.horizontalSizeClass],
[UITraitCollection traitCollectionWithVerticalSizeClass:traitCollection.verticalSizeClass],
[UITraitCollection traitCollectionWithDisplayScale:traitCollection.displayScale],
[UITraitCollection traitCollectionWithUserInterfaceIdiom:traitCollection.userInterfaceIdiom],
[UITraitCollection traitCollectionWithForceTouchCapability:traitCollection.forceTouchCapability],
]];

if (AS_AVAILABLE_IOS(10)) {
[collections addObject:[UITraitCollection traitCollectionWithDisplayGamut:traitCollection.displayGamut]];
[collections addObject:[UITraitCollection traitCollectionWithLayoutDirection:traitCollection.layoutDirection]];
[collections addObject:[UITraitCollection traitCollectionWithPreferredContentSizeCategory:traitCollection.preferredContentSizeCategory]];
}
if (AS_AVAILABLE_IOS_TVOS(12, 10)) {
[collections addObject:[UITraitCollection traitCollectionWithUserInterfaceStyle:traitCollection.userInterfaceStyle]];
}

UITraitCollection *result = [UITraitCollection traitCollectionWithTraitsFromCollections:collections];
return result;
}

BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTraitCollection lhs, ASPrimitiveTraitCollection rhs) {
return !memcmp(&lhs, &rhs, sizeof(ASPrimitiveTraitCollection));
}
Expand Down
25 changes: 25 additions & 0 deletions Tests/ASCollectionViewTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,31 @@ - (void)testTraitCollectionChangesMidUpdate
}
}

- (void)testASPrimitiveTraitCollectionToUITraitCollection {
ASPrimitiveTraitCollection collection = ASPrimitiveTraitCollectionMakeDefault();
collection.displayGamut = UIDisplayGamutSRGB;
collection.displayScale = 11;
collection.forceTouchCapability = UIForceTouchCapabilityAvailable;
collection.horizontalSizeClass = UIUserInterfaceSizeClassRegular;
collection.layoutDirection = UITraitEnvironmentLayoutDirectionRightToLeft;
collection.preferredContentSizeCategory = UIContentSizeCategoryMedium;
collection.userInterfaceIdiom = UIUserInterfaceIdiomTV;
if (@available(iOS 12.0, *)) {
collection.userInterfaceStyle = UIUserInterfaceStyleDark;
}
collection.verticalSizeClass = UIUserInterfaceSizeClassRegular;

// create `UITraitCollection` from `ASPrimitiveTraitCollection`
UITraitCollection *uiCollection = ASPrimitiveTraitCollectionToUITraitCollection(collection);

// now convert it back to `ASPrimitiveTraitCollection`
ASPrimitiveTraitCollection newCollection = ASPrimitiveTraitCollectionFromUITraitCollection(uiCollection);

// compare
XCTAssert(ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(collection, newCollection));
}


/**
* This tests an issue where, since subnode insertions aren't applied until the UIKit layout pass,
* which we trigger during the display phase, subnodes like network image nodes are not preloading
Expand Down
58 changes: 58 additions & 0 deletions Tests/ASGraphicsContextTests.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// ASGraphicsContextTests.mm
// Texture
//
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//


#import <XCTest/XCTest.h>
#import <AsyncDisplayKit/ASGraphicsContext.h>
#import <AsyncDisplayKit/ASBaseDefines.h>
#import <AsyncDisplayKit/ASAvailability.h>
#import <AsyncDisplayKit/ASConfigurationInternal.h>

@interface ASGraphicsContextTests : XCTestCase
@end

@implementation ASGraphicsContextTests

- (void)setUp
{
[super setUp];
ASConfiguration *config = [ASConfiguration new];
config.experimentalFeatures = ASExperimentalDrawingGlobal;
[ASConfigurationManager test_resetWithConfiguration:config];
}


#if AS_AT_LEAST_IOS13
- (void)testTraitCollectionPassedToWork
{
if (AS_AVAILABLE_IOS_TVOS(13, 13)) {
CGSize size = CGSize{.width=100, .height=100};

XCTestExpectation *expectationDark = [self expectationWithDescription:@"trait collection dark"];
ASPrimitiveTraitCollection traitCollectionDark = ASPrimitiveTraitCollectionMakeDefault();
traitCollectionDark.userInterfaceStyle = UIUserInterfaceStyleDark;
ASGraphicsCreateImageWithTraitCollectionAndOptions(traitCollectionDark, size, false, 0, nil, ^{
UITraitCollection *currentTraitCollection = [UITraitCollection currentTraitCollection];
XCTAssertEqual(currentTraitCollection.userInterfaceStyle, UIUserInterfaceStyleDark);
[expectationDark fulfill];
});

XCTestExpectation *expectationLight = [self expectationWithDescription:@"trait collection light"];
ASPrimitiveTraitCollection traitCollectionLight = ASPrimitiveTraitCollectionMakeDefault();
traitCollectionLight.userInterfaceStyle = UIUserInterfaceStyleLight;
ASGraphicsCreateImageWithTraitCollectionAndOptions(traitCollectionLight, size, false, 0, nil, ^{
UITraitCollection *currentTraitCollection = [UITraitCollection currentTraitCollection];
XCTAssertEqual(currentTraitCollection.userInterfaceStyle, UIUserInterfaceStyleLight);
[expectationLight fulfill];
});

[self waitForExpectations:@[expectationDark, expectationLight] timeout:1];
}
}
#endif
@end