From d64c2a8c38534e433385924795ce43e0fc0c3488 Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Fri, 4 Oct 2024 15:51:48 -0500 Subject: [PATCH] Avoid use of CGColorRef --- .../View/RCTViewComponentView.mm | 38 +++++++---------- .../React/Views/RCTBorderDrawing.h | 10 ++--- .../React/Views/RCTBorderDrawing.m | 42 +++++++++---------- packages/react-native/React/Views/RCTView.m | 28 +++++++------ 4 files changed, 54 insertions(+), 64 deletions(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index b392454c5e5540..9d9a82b0dbb366 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -701,18 +701,10 @@ static RCTCornerRadii RCTCornerRadiiFromBorderRadii(BorderRadii borderRadii) static RCTBorderColors RCTCreateRCTBorderColorsFromBorderColors(BorderColors borderColors) { return RCTBorderColors{ - .top = RCTCreateCGColorRefFromSharedColor(borderColors.top), - .left = RCTCreateCGColorRefFromSharedColor(borderColors.left), - .bottom = RCTCreateCGColorRefFromSharedColor(borderColors.bottom), - .right = RCTCreateCGColorRefFromSharedColor(borderColors.right)}; -} - -static void RCTReleaseRCTBorderColors(RCTBorderColors borderColors) -{ - CGColorRelease(borderColors.top); - CGColorRelease(borderColors.left); - CGColorRelease(borderColors.bottom); - CGColorRelease(borderColors.right); + .top = RCTUIColorFromSharedColor(borderColors.top), + .left = RCTUIColorFromSharedColor(borderColors.left), + .bottom = RCTUIColorFromSharedColor(borderColors.bottom), + .right = RCTUIColorFromSharedColor(borderColors.right)}; } static CALayerCornerCurve CornerCurveFromBorderCurve(BorderCurve borderCurve) @@ -956,11 +948,9 @@ - (void)invalidateLayer (*borderMetrics.borderColors.left).getUIColor() != nullptr)); #if !TARGET_OS_OSX // [macOS] - // background color - CGColorRef backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection].CGColor; + RCTUIColor *backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection]; #else // [macOS - // background color - CGColorRef backgroundColor = _backgroundColor.CGColor; + RCTUIColor *backgroundColor = _backgroundColor; #endif // macOS] // The reason we sometimes do not set self.layer's backgroundColor is because // we want to support non-uniform border radii, which apple does not natively @@ -971,7 +961,7 @@ - (void)invalidateLayer if (useCoreAnimationBorderRendering) { [_backgroundColorLayer removeFromSuperlayer]; _backgroundColorLayer = nil; - layer.backgroundColor = backgroundColor; + layer.backgroundColor = backgroundColor.CGColor; } else { layer.backgroundColor = nil; if (!_backgroundColorLayer) { @@ -981,7 +971,7 @@ - (void)invalidateLayer [self.layer addSublayer:_backgroundColorLayer]; } - _backgroundColorLayer.backgroundColor = backgroundColor; + _backgroundColorLayer.backgroundColor = backgroundColor.CGColor; if (borderMetrics.borderRadii.isUniform()) { _backgroundColorLayer.mask = nil; _backgroundColorLayer.cornerRadius = borderMetrics.borderRadii.topLeft.horizontal; @@ -1002,11 +992,13 @@ - (void)invalidateLayer _borderLayer = nil; layer.borderWidth = (CGFloat)borderMetrics.borderWidths.left; - CGColorRef borderColor = RCTCreateCGColorRefFromSharedColor(borderMetrics.borderColors.left); - layer.borderColor = borderColor; - CGColorRelease(borderColor); + RCTUIColor *borderColor = RCTUIColorFromSharedColor(borderMetrics.borderColors.left); + layer.borderColor = borderColor.CGColor; layer.cornerRadius = (CGFloat)borderMetrics.borderRadii.topLeft.horizontal; + layer.cornerCurve = CornerCurveFromBorderCurve(borderMetrics.borderCurves.topLeft); + + layer.backgroundColor = backgroundColor.CGColor; } else { if (!_borderLayer) { CALayer *borderLayer = [CALayer new]; @@ -1036,12 +1028,10 @@ - (void)invalidateLayer RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii), RCTUIEdgeInsetsFromEdgeInsets(borderMetrics.borderWidths), borderColors, - [RCTUIColor clearColor].CGColor, // [macOS] + [RCTUIColor clearColor], // [macOS] NO, scaleFactor); // [macOS] - RCTReleaseRCTBorderColors(borderColors); - if (image == nil) { _borderLayer.contents = nil; } else { diff --git a/packages/react-native/React/Views/RCTBorderDrawing.h b/packages/react-native/React/Views/RCTBorderDrawing.h index 5fd2ea58c8720d..c7bb3225218be2 100644 --- a/packages/react-native/React/Views/RCTBorderDrawing.h +++ b/packages/react-native/React/Views/RCTBorderDrawing.h @@ -29,10 +29,10 @@ typedef struct { } RCTCornerInsets; typedef struct { - CGColorRef top; - CGColorRef left; - CGColorRef bottom; - CGColorRef right; + RCTUIColor *top; + RCTUIColor *left; + RCTUIColor *bottom; + RCTUIColor *right; } RCTBorderColors; /** @@ -68,6 +68,6 @@ RCT_EXTERN UIImage *RCTGetBorderImage( RCTCornerRadii cornerRadii, UIEdgeInsets borderInsets, RCTBorderColors borderColors, - CGColorRef backgroundColor, + RCTUIColor *backgroundColor, BOOL drawToEdge, CGFloat scaleFactor); // [macOS] diff --git a/packages/react-native/React/Views/RCTBorderDrawing.m b/packages/react-native/React/Views/RCTBorderDrawing.m index 012def8d2578f4..8a2ec5fe3e9d5b 100644 --- a/packages/react-native/React/Views/RCTBorderDrawing.m +++ b/packages/react-native/React/Views/RCTBorderDrawing.m @@ -30,9 +30,9 @@ BOOL RCTCornerRadiiAreEqualAndSymmetrical(RCTCornerRadii cornerRadii) BOOL RCTBorderColorsAreEqual(RCTBorderColors borderColors) { - return CGColorEqualToColor(borderColors.left, borderColors.right) && - CGColorEqualToColor(borderColors.left, borderColors.top) && - CGColorEqualToColor(borderColors.left, borderColors.bottom); + return CGColorEqualToColor(borderColors.left.CGColor, borderColors.right.CGColor) && + CGColorEqualToColor(borderColors.left.CGColor, borderColors.top.CGColor) && + CGColorEqualToColor(borderColors.left.CGColor, borderColors.bottom.CGColor); } RCTCornerInsets RCTGetCornerInsets(RCTCornerRadii cornerRadii, UIEdgeInsets edgeInsets) @@ -181,9 +181,9 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn } static RCTUIGraphicsImageRenderer * // [macOS] -RCTMakeUIGraphicsImageRenderer(CGSize size, CGColorRef backgroundColor, BOOL hasCornerRadii, BOOL drawToEdge) // [macOS] +RCTMakeUIGraphicsImageRenderer(CGSize size, RCTUIColor *backgroundColor, BOOL hasCornerRadii, BOOL drawToEdge) // [macOS] { - const CGFloat alpha = CGColorGetAlpha(backgroundColor); + const CGFloat alpha = CGColorGetAlpha(backgroundColor.CGColor); const BOOL opaque = (drawToEdge || !hasCornerRadii) && alpha == 1.0; RCTUIGraphicsImageRendererFormat *const rendererFormat = [RCTUIGraphicsImageRendererFormat defaultFormat]; // [macOS] rendererFormat.opaque = opaque; @@ -196,7 +196,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn CGSize viewSize, UIEdgeInsets borderInsets, RCTBorderColors borderColors, - CGColorRef backgroundColor, + RCTUIColor *backgroundColor, BOOL drawToEdge, CGFloat scaleFactor // [macOS] ) { @@ -237,18 +237,16 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn RCTUIGraphicsImageRenderer *const imageRenderer = RCTMakeUIGraphicsImageRenderer(size, backgroundColor, hasCornerRadii, drawToEdge); // [macOS] - CGColorRetain(backgroundColor); // [macOS] CGColorRefs are not atuomtically retained when passed into a block UIImage *image = [imageRenderer imageWithActions:^(RCTUIGraphicsImageRendererContext *_Nonnull rendererContext) { // [macOS] const CGContextRef context = rendererContext.CGContext; const CGRect rect = {.size = size}; CGPathRef path = RCTPathCreateOuterOutline(drawToEdge, rect, cornerRadii); if (backgroundColor) { - CGContextSetFillColorWithColor(context, backgroundColor); + CGContextSetFillColorWithColor(context, backgroundColor.CGColor); CGContextAddPath(context, path); CGContextFillPath(context); } - CGColorRelease(backgroundColor); // [macOS] CGContextAddPath(context, path); CGPathRelease(path); @@ -260,7 +258,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn BOOL hasEqualColors = RCTBorderColorsAreEqual(borderColors); if ((drawToEdge || !hasCornerRadii) && hasEqualColors) { - CGContextSetFillColorWithColor(context, borderColors.left); + CGContextSetFillColorWithColor(context, borderColors.left.CGColor); CGContextAddRect(context, rect); CGContextAddPath(context, insetPath); CGContextEOFillPath(context); @@ -325,7 +323,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn } } - CGColorRef currentColor = NULL; + RCTUIColor *currentColor = NULL; // RIGHT if (borderInsets.right > 0) { @@ -349,8 +347,8 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn (CGPoint){size.width, size.height}, }; - if (!CGColorEqualToColor(currentColor, borderColors.bottom)) { - CGContextSetFillColorWithColor(context, currentColor); + if (!CGColorEqualToColor(currentColor.CGColor, borderColors.bottom.CGColor)) { + CGContextSetFillColorWithColor(context, currentColor.CGColor); CGContextFillPath(context); currentColor = borderColors.bottom; } @@ -366,8 +364,8 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn (CGPoint){0, size.height}, }; - if (!CGColorEqualToColor(currentColor, borderColors.left)) { - CGContextSetFillColorWithColor(context, currentColor); + if (!CGColorEqualToColor(currentColor.CGColor, borderColors.left.CGColor)) { + CGContextSetFillColorWithColor(context, currentColor.CGColor); CGContextFillPath(context); currentColor = borderColors.left; } @@ -383,15 +381,15 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn (CGPoint){size.width, 0}, }; - if (!CGColorEqualToColor(currentColor, borderColors.top)) { - CGContextSetFillColorWithColor(context, currentColor); + if (!CGColorEqualToColor(currentColor.CGColor, borderColors.top.CGColor)) { + CGContextSetFillColorWithColor(context, currentColor.CGColor); CGContextFillPath(context); currentColor = borderColors.top; } CGContextAddLines(context, points, sizeof(points) / sizeof(*points)); } - CGContextSetFillColorWithColor(context, currentColor); + CGContextSetFillColorWithColor(context, currentColor.CGColor); CGContextFillPath(context); } @@ -475,7 +473,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn CGSize viewSize, UIEdgeInsets borderInsets, RCTBorderColors borderColors, - CGColorRef backgroundColor, + RCTUIColor *backgroundColor, BOOL drawToEdge, CGFloat scaleFactor // [macOS] ) { @@ -508,7 +506,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn CGContextAddPath(context, outerPath); CGPathRelease(outerPath); - CGContextSetFillColorWithColor(context, backgroundColor); + CGContextSetFillColorWithColor(context, backgroundColor.CGColor); CGContextFillPath(context); } @@ -527,7 +525,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn CGContextSetStrokeColorWithColor(context, [RCTUIColor yellowColor].CGColor); // [macOS] CGContextAddPath(context, path); - CGContextSetStrokeColorWithColor(context, borderColors.top); + CGContextSetStrokeColorWithColor(context, borderColors.top.CGColor); CGContextStrokePath(context); CGPathRelease(path); @@ -540,7 +538,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn RCTCornerRadii cornerRadii, UIEdgeInsets borderInsets, RCTBorderColors borderColors, - CGColorRef backgroundColor, + RCTUIColor *backgroundColor, BOOL drawToEdge, CGFloat scaleFactor // [macOS] ) { diff --git a/packages/react-native/React/Views/RCTView.m b/packages/react-native/React/Views/RCTView.m index 0f11bcd0ef28ce..f60021500a9110 100644 --- a/packages/react-native/React/Views/RCTView.m +++ b/packages/react-native/React/Views/RCTView.m @@ -1162,26 +1162,28 @@ - (void)displayLayer:(CALayer *)layer #else // [macOS const RCTBorderColors borderColors = [self borderColors]; #endif // macOS] + BOOL useIOSBorderRendering = + RCTCornerRadiiAreEqualAndSymmetrical(cornerRadii) && + RCTBorderInsetsAreEqual(borderInsets) && + RCTBorderColorsAreEqual(borderColors) && + _borderStyle == RCTBorderStyleSolid && - BOOL useIOSBorderRendering = RCTCornerRadiiAreEqualAndSymmetrical(cornerRadii) && - RCTBorderInsetsAreEqual(borderInsets) && RCTBorderColorsAreEqual(borderColors) && + // iOS draws borders in front of the content whereas CSS draws them behind + // the content. For this reason, only use iOS border drawing when clipping + // or when the border is hidden. - // iOS draws borders in front of the content whereas CSS draws them behind - // the content. For this reason, only use iOS border drawing when clipping - // or when the border is hidden. - - (borderInsets.top == 0 || (borderColors.top && CGColorGetAlpha(borderColors.top) == 0) || self.clipsToBounds); + (borderInsets.top == 0 || + (borderColors.top && CGColorGetAlpha(borderColors.top.CGColor) == 0) || + self.clipsToBounds); // iOS clips to the outside of the border, but CSS clips to the inside. To // solve this, we'll need to add a container view inside the main view to // correctly clip the subviews. - CGColorRef backgroundColor; - #if !TARGET_OS_OSX // [macOS] - backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection].CGColor; + RCTUIColor *backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection]; #else // [macOS - backgroundColor = [_backgroundColor CGColor]; + RCTUIColor *backgroundColor = _backgroundColor; #endif // macOS] #if TARGET_OS_OSX // [macOS @@ -1199,9 +1201,9 @@ - (void)displayLayer:(CALayer *)layer #endif // macOS] if (useIOSBorderRendering) { layer.cornerRadius = cornerRadii.topLeftHorizontal; - layer.borderColor = borderColors.left; + layer.borderColor = borderColors.left.CGColor; layer.borderWidth = borderInsets.left; - layer.backgroundColor = backgroundColor; + layer.backgroundColor = backgroundColor.CGColor; layer.contents = nil; layer.needsDisplayOnBoundsChange = NO; layer.mask = nil;