diff --git a/Source/Details/_ASDisplayLayer.mm b/Source/Details/_ASDisplayLayer.mm index e7f7a9a15..679ed691f 100644 --- a/Source/Details/_ASDisplayLayer.mm +++ b/Source/Details/_ASDisplayLayer.mm @@ -39,6 +39,26 @@ - (void)setDisplaySuspended:(BOOL)displaySuspended } } +- (void)setPosition:(CGPoint)position +{ + BOOL valid = ASDisplayNodeAssertNonFatal(ASIsCGPositionValidForLayout(position), @"Caught attempt to set invalid position %@ on %@.", NSStringFromCGPoint(position), self); + if (!valid) { + return; + } + + [super setPosition:position]; +} + +- (void)setTransform:(CATransform3D)transform +{ + BOOL valid = ASDisplayNodeAssertNonFatal(ASIsTransformValidForLayout(transform), @"Caught attempt to set invalid transform on %@.", self); + if (!valid) { + return; + } + + [super setTransform:transform]; +} + - (void)setBounds:(CGRect)bounds { BOOL valid = ASDisplayNodeAssertNonFatal(ASIsCGRectValidForLayout(bounds), @"Caught attempt to set invalid bounds %@ on %@.", NSStringFromCGRect(bounds), self); diff --git a/Source/Layout/ASDimension.h b/Source/Layout/ASDimension.h index ab0717bad..855ab4f46 100644 --- a/Source/Layout/ASDimension.h +++ b/Source/Layout/ASDimension.h @@ -12,6 +12,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -54,6 +55,14 @@ ASDISPLAYNODE_INLINE BOOL ASIsCGRectValidForLayout(CGRect rect) return (ASIsCGPositionValidForLayout(rect.origin) && ASIsCGSizeValidForLayout(rect.size)); } +ASDISPLAYNODE_INLINE BOOL ASIsTransformValidForLayout(CATransform3D t) +{ + return !isnan(t.m11) && !isnan(t.m12) && !isnan(t.m13) && !isnan(t.m14) && + !isnan(t.m21) && !isnan(t.m22) && !isnan(t.m23) && !isnan(t.m24) && + !isnan(t.m31) && !isnan(t.m32) && !isnan(t.m33) && !isnan(t.m34) && + !isnan(t.m41) && !isnan(t.m42) && !isnan(t.m43) && !isnan(t.m44); +} + #pragma mark - ASDimension /** diff --git a/Tests/ASDisplayLayerTests.mm b/Tests/ASDisplayLayerTests.mm index 2e03eb6da..853941776 100644 --- a/Tests/ASDisplayLayerTests.mm +++ b/Tests/ASDisplayLayerTests.mm @@ -595,4 +595,117 @@ - (void)testSuspendResumeSync [self checkSuspendResume:NO]; } +- (void)testSetPosition +{ + _ASDisplayLayer *layer = [[_ASDisplayLayer alloc] init]; + CGPoint origin = CGPointMake(20, 20); + layer.position = CGPointZero; // Make sure CGPointZero doesn't throw + + layer.position = origin; + XCTAssertTrue(CGPointEqualToPoint(layer.position, origin)); + + XCTAssertThrows(layer.position = CGPointMake(NAN, 50)); + XCTAssertTrue(CGPointEqualToPoint(layer.position, origin)); + + XCTAssertThrows(layer.position = CGPointMake(NAN, NAN)); + XCTAssertTrue(CGPointEqualToPoint(layer.position, origin)); + + XCTAssertThrows(layer.position = CGPointMake(50, NAN)); + XCTAssertTrue(CGPointEqualToPoint(layer.position, origin)); + + origin = CGPointMake(10, 10); + layer.position = origin; + XCTAssertTrue(CGPointEqualToPoint(layer.position, origin)); +} + +- (void)testSetTransform +{ + _ASDisplayLayer *layer = [[_ASDisplayLayer alloc] init]; + + CATransform3D transform = CATransform3DIdentity; + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + + transform.m11 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m12 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m13 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m14 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m21 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m22 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m23 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m24 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m31 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m32 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m33 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m34 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m41 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m42 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m43 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + transform.m44 = NAN; + XCTAssertThrows(layer.transform = transform); + XCTAssertTrue(CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity)); + transform = CATransform3DIdentity; + + layer.transform = transform; +} + @end