1111#import < CoreGraphics/CoreGraphics.h>
1212#import < QuartzCore/QuartzCore.h>
1313#import < objc/runtime.h>
14+ #import < optional>
1415#import < ranges>
1516
1617#import < RCTSwiftUIWrapper/RCTSwiftUIContainerViewWrapper.h>
1920#import < React/RCTBorderDrawing.h>
2021#import < React/RCTBoxShadow.h>
2122#import < React/RCTConversions.h>
23+ #import < React/RCTLayerCornerConfiguration.h>
2224#import < React/RCTLinearGradient.h>
2325#import < React/RCTLocalizedString.h>
2426#import < React/RCTRadialGradient.h>
@@ -855,110 +857,6 @@ static RCTBorderColors RCTCreateRCTBorderColorsFromBorderColors(BorderColors bor
855857 .right = RCTUIColorFromSharedColor (borderColors.right )};
856858}
857859
858- static CALayerCornerCurve CornerCurveFromBorderCurve (BorderCurve borderCurve)
859- {
860- // The constants are available only starting from iOS 13
861- // CALayerCornerCurve is a typealias on NSString *
862- switch (borderCurve) {
863- case BorderCurve::Continuous:
864- return @" continuous" ; // kCACornerCurveContinuous;
865- case BorderCurve::Circular:
866- return @" circular" ; // kCACornerCurveCircular;
867- }
868- }
869-
870- struct RCTLayerCornerConfiguration {
871- CGFloat cornerRadius{0 };
872- CACornerMask maskedCorners{0 };
873- BorderCurve cornerCurve{BorderCurve::Circular};
874- bool hasRoundedCorner{false };
875- };
876-
877- static bool RCTUpdateLayerCornerConfiguration (
878- const CornerRadii &cornerRadii,
879- BorderCurve cornerCurve,
880- CACornerMask cornerMask,
881- RCTLayerCornerConfiguration &cornerConfiguration)
882- {
883- if (cornerRadii.horizontal != cornerRadii.vertical ) {
884- return false ;
885- }
886-
887- if (cornerRadii.horizontal == 0 ) {
888- return true ;
889- }
890-
891- CGFloat cornerRadius = (CGFloat)cornerRadii.horizontal ;
892- if (cornerConfiguration.hasRoundedCorner ) {
893- if (cornerConfiguration.cornerRadius != cornerRadius) {
894- return false ;
895- }
896-
897- if (cornerConfiguration.cornerCurve != cornerCurve) {
898- return false ;
899- }
900- } else {
901- cornerConfiguration.cornerRadius = cornerRadius;
902- cornerConfiguration.cornerCurve = cornerCurve;
903- cornerConfiguration.hasRoundedCorner = true ;
904- }
905-
906- cornerConfiguration.maskedCorners |= cornerMask;
907- return true ;
908- }
909-
910- static bool RCTGetLayerCornerConfiguration (
911- const BorderMetrics &borderMetrics,
912- RCTLayerCornerConfiguration &cornerConfiguration)
913- {
914- cornerConfiguration = RCTLayerCornerConfiguration{};
915-
916- bool topLeftIsRepresentable = RCTUpdateLayerCornerConfiguration (
917- borderMetrics.borderRadii .topLeft ,
918- borderMetrics.borderCurves .topLeft ,
919- kCALayerMinXMinYCorner ,
920- cornerConfiguration);
921- if (!topLeftIsRepresentable) {
922- return false ;
923- }
924-
925- bool topRightIsRepresentable = RCTUpdateLayerCornerConfiguration (
926- borderMetrics.borderRadii .topRight ,
927- borderMetrics.borderCurves .topRight ,
928- kCALayerMaxXMinYCorner ,
929- cornerConfiguration);
930- if (!topRightIsRepresentable) {
931- return false ;
932- }
933-
934- bool bottomLeftIsRepresentable = RCTUpdateLayerCornerConfiguration (
935- borderMetrics.borderRadii .bottomLeft ,
936- borderMetrics.borderCurves .bottomLeft ,
937- kCALayerMinXMaxYCorner ,
938- cornerConfiguration);
939- if (!bottomLeftIsRepresentable) {
940- return false ;
941- }
942-
943- bool bottomRightIsRepresentable = RCTUpdateLayerCornerConfiguration (
944- borderMetrics.borderRadii .bottomRight ,
945- borderMetrics.borderCurves .bottomRight ,
946- kCALayerMaxXMaxYCorner ,
947- cornerConfiguration);
948- if (!bottomRightIsRepresentable) {
949- return false ;
950- }
951-
952- if (!cornerConfiguration.hasRoundedCorner ) {
953- cornerConfiguration.maskedCorners = kCALayerMinXMinYCorner
954- | kCALayerMaxXMinYCorner
955- | kCALayerMinXMaxYCorner
956- | kCALayerMaxXMaxYCorner ;
957- }
958-
959- return true ;
960- }
961-
962860static RCTBorderStyle RCTBorderStyleFromBorderStyle (BorderStyle borderStyle)
963861{
964862 switch (borderStyle) {
@@ -1134,8 +1032,9 @@ - (void)invalidateLayer
11341032 }
11351033#endif
11361034
1137- RCTLayerCornerConfiguration layerCornerConfiguration;
1138- const bool layerCornersAreRepresentable = RCTGetLayerCornerConfiguration (borderMetrics, layerCornerConfiguration);
1035+ const std::optional<RCTLayerCornerConfiguration> layerCornerConfiguration =
1036+ RCTGetLayerCornerConfiguration (borderMetrics);
1037+ const bool layerCornersAreRepresentable = layerCornerConfiguration.has_value ();
11391038
11401039 const bool useCoreAnimationBorderRendering =
11411040 borderMetrics.borderColors .isUniform () && borderMetrics.borderWidths .isUniform () &&
@@ -1181,9 +1080,7 @@ - (void)invalidateLayer
11811080 layer.borderWidth = (CGFloat)borderMetrics.borderWidths .left ;
11821081 UIColor *borderColor = RCTUIColorFromSharedColor (borderMetrics.borderColors .left );
11831082 layer.borderColor = borderColor.CGColor ;
1184- layer.cornerRadius = layerCornerConfiguration.cornerRadius ;
1185- layer.maskedCorners = layerCornerConfiguration.maskedCorners ;
1186- layer.cornerCurve = CornerCurveFromBorderCurve (layerCornerConfiguration.cornerCurve );
1083+ RCTApplyLayerCornerConfiguration (layer, *layerCornerConfiguration);
11871084 } else {
11881085 if (!_borderLayer) {
11891086 CALayer *borderLayer = [CALayer new ];
@@ -1223,7 +1120,7 @@ - (void)invalidateLayer
12231120 _outlineLayer.frame = CGRectInset (
12241121 layer.bounds , -_props->outlineOffset - _props->outlineWidth , -_props->outlineOffset - _props->outlineWidth );
12251122
1226- if (layerCornersAreRepresentable && layerCornerConfiguration. cornerRadius == 0 ) {
1123+ if (layerCornersAreRepresentable && layerCornerConfiguration-> cornerRadius == 0 ) {
12271124 UIColor *outlineColor = RCTUIColorFromSharedColor (_props->outlineColor );
12281125 _outlineLayer.borderWidth = _props->outlineWidth ;
12291126 _outlineLayer.borderColor = outlineColor.CGColor ;
@@ -1401,9 +1298,7 @@ - (void)invalidateLayer
14011298 BOOL clipToPaddingBox = ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox ();
14021299 if (!clipToPaddingBox) {
14031300 if (layerCornersAreRepresentable) {
1404- currentContainerView.layer .cornerRadius = layerCornerConfiguration.cornerRadius ;
1405- currentContainerView.layer .maskedCorners = layerCornerConfiguration.maskedCorners ;
1406- currentContainerView.layer .cornerCurve = CornerCurveFromBorderCurve (layerCornerConfiguration.cornerCurve );
1301+ RCTApplyLayerCornerConfiguration (currentContainerView.layer , *layerCornerConfiguration);
14071302 } else {
14081303 CALayer *maskLayer =
14091304 [self createMaskLayer: self .bounds
@@ -1439,9 +1334,7 @@ - (void)invalidateLayer
14391334 RCTUIEdgeInsetsFromEdgeInsets (borderMetrics.borderWidths))];
14401335 currentContainerView.layer .mask = maskLayer;
14411336 } else {
1442- currentContainerView.layer .cornerRadius = layerCornerConfiguration.cornerRadius ;
1443- currentContainerView.layer .maskedCorners = layerCornerConfiguration.maskedCorners ;
1444- currentContainerView.layer .cornerCurve = CornerCurveFromBorderCurve (layerCornerConfiguration.cornerCurve );
1337+ RCTApplyLayerCornerConfiguration (currentContainerView.layer , *layerCornerConfiguration);
14451338 }
14461339 }
14471340}
@@ -1453,13 +1346,9 @@ - (void)shapeLayerToMatchView:(CALayer *)layer borderMetrics:(BorderMetrics)bord
14531346 // Bounds is needed here to account for scaling transforms properly and ensure
14541347 // we do not scale twice
14551348 layer.frame = CGRectMake (0 , 0 , self.layer .bounds .size .width , self.layer .bounds .size .height );
1456- RCTLayerCornerConfiguration cornerConfiguration;
1457- const bool cornersAreRepresentable = RCTGetLayerCornerConfiguration (borderMetrics, cornerConfiguration);
1458- if (cornersAreRepresentable) {
1349+ if (const auto cornerConfiguration = RCTGetLayerCornerConfiguration (borderMetrics)) {
14591350 layer.mask = nil ;
1460- layer.cornerRadius = cornerConfiguration.cornerRadius ;
1461- layer.maskedCorners = cornerConfiguration.maskedCorners ;
1462- layer.cornerCurve = CornerCurveFromBorderCurve (cornerConfiguration.cornerCurve );
1351+ RCTApplyLayerCornerConfiguration (layer, *cornerConfiguration);
14631352 } else {
14641353 CAShapeLayer *maskLayer = [self
14651354 createMaskLayer: self .bounds
0 commit comments