Skip to content

Commit 823ae58

Browse files
committed
feat(ios): update clip path methods to use marginInsetsFromYogaStylableProps
1 parent 919e983 commit 823ae58

File tree

4 files changed

+53
-46
lines changed

4 files changed

+53
-46
lines changed

packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,19 +1232,21 @@ - (void)invalidateLayer
12321232

12331233
// Handle clip-path property
12341234
if (_props->clipPath.has_value()) {
1235-
CALayer *maskLayer = [RCTClipPathUtils createClipPathLayer:_props->clipPath.value()
1236-
layoutMetrics:_layoutMetrics
1237-
yogaStyle:_props->yogaStyle
1238-
bounds:layer.bounds
1239-
cornerRadii:RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii)];
1240-
if (maskLayer != nil) {
1241-
self.currentContainerView.layer.mask = maskLayer;
1242-
1243-
for (UIView *subview in self.currentContainerView.subviews) {
1244-
if ([subview isKindOfClass:[UIImageView class]]) {
1245-
subview.layer.mask = maskLayer;
1246-
}
1247-
}
1235+
if (auto yogaStylableProps = std::static_pointer_cast<const YogaStylableProps>(_props)) {
1236+
CALayer *maskLayer = [RCTClipPathUtils createClipPathLayer:_props->clipPath.value()
1237+
layoutMetrics:_layoutMetrics
1238+
yogaStylableProps:*yogaStylableProps.get()
1239+
bounds:layer.bounds
1240+
cornerRadii:RCTCornerRadiiFromBorderRadii(borderMetrics.borderRadii)];
1241+
if (maskLayer != nil) {
1242+
self.currentContainerView.layer.mask = maskLayer;
1243+
1244+
for (UIView *subview in self.currentContainerView.subviews) {
1245+
if ([subview isKindOfClass:[UIImageView class]]) {
1246+
subview.layer.mask = maskLayer;
1247+
}
1248+
}
1249+
}
12481250
}
12491251
} else if (self.currentContainerView.clipsToBounds) {
12501252
// Handle regular clipsToBounds clipping when no clip-path is specified

packages/react-native/React/Fabric/Utils/RCTClipPathUtils.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#import <Foundation/Foundation.h>
99
#import <QuartzCore/QuartzCore.h>
1010
#import <React/RCTBorderDrawing.h>
11+
#import <react/renderer/components/view/YogaStylableProps.h>
1112
#import <react/renderer/components/view/primitives.h>
1213
#import <react/renderer/core/LayoutMetrics.h>
1314
#import <react/renderer/graphics/ClipPath.h>
@@ -20,16 +21,16 @@ NS_ASSUME_NONNULL_BEGIN
2021
+ (RCTCornerRadii)adjustCornerRadiiForGeometryBox:(facebook::react::GeometryBox)geometryBox
2122
cornerRadii:(RCTCornerRadii)cornerRadii
2223
layoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
23-
yogaStyle:(const facebook::yoga::Style &)yogaStyle;
24+
yogaStylableProps:(const facebook::react::YogaStylableProps &)yogaStylableProps;
2425

2526
+ (CGRect)getGeometryBoxRect:(facebook::react::GeometryBox)geometryBox
2627
layoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
27-
yogaStyle:(const facebook::yoga::Style &)yogaStyle
28+
yogaStylableProps:(const facebook::react::YogaStylableProps &)yogaStylableProps
2829
bounds:(CGRect)bounds;
2930

3031
+ (CALayer *_Nullable)createClipPathLayer:(const facebook::react::ClipPath &)clipPath
3132
layoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
32-
yogaStyle:(const facebook::yoga::Style &)yogaStyle
33+
yogaStylableProps:(const facebook::react::YogaStylableProps &)yogaStylableProps
3334
bounds:(CGRect)bounds
3435
cornerRadii:(RCTCornerRadii)cornerRadii;
3536

packages/react-native/React/Fabric/Utils/RCTClipPathUtils.mm

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,31 @@
99

1010
#import "RCTBasicShapeUtils.h"
1111
#import <React/RCTConversions.h>
12+
#import <react/renderer/components/view/conversions.h>
1213

1314
using namespace facebook::react;
1415

1516
@implementation RCTClipPathUtils
1617

1718
+ (RCTCornerRadii)adjustCornerRadiiForGeometryBox:(GeometryBox)geometryBox
18-
cornerRadii:(RCTCornerRadii)cornerRadii
19-
layoutMetrics:(const LayoutMetrics &)layoutMetrics
20-
yogaStyle:(const facebook::yoga::Style &)yogaStyle
21-
{
22-
RCTCornerRadii adjustedRadii = cornerRadii;
19+
cornerRadii:(RCTCornerRadii)cornerRadii
20+
layoutMetrics:(const LayoutMetrics &)layoutMetrics
21+
yogaStylableProps:(const YogaStylableProps &)yogaStylableProps
22+
{
23+
RCTCornerRadii adjustedRadii = cornerRadii;
2324

2425
switch (geometryBox) {
2526
case GeometryBox::MarginBox: {
2627
// Margin-box: extend border-radius by margin amount
27-
adjustedRadii.topLeftHorizontal += layoutMetrics.marginInsets.left;
28-
adjustedRadii.topLeftVertical += layoutMetrics.marginInsets.top;
29-
adjustedRadii.topRightHorizontal += layoutMetrics.marginInsets.right;
30-
adjustedRadii.topRightVertical += layoutMetrics.marginInsets.top;
31-
adjustedRadii.bottomLeftHorizontal += layoutMetrics.marginInsets.left;
32-
adjustedRadii.bottomLeftVertical += layoutMetrics.marginInsets.bottom;
33-
adjustedRadii.bottomRightHorizontal += layoutMetrics.marginInsets.right;
34-
adjustedRadii.bottomRightVertical += layoutMetrics.marginInsets.bottom;
28+
auto marginInsets = marginInsetsFromYogaStylableProps(yogaStylableProps);
29+
adjustedRadii.topLeftHorizontal += marginInsets.left;
30+
adjustedRadii.topLeftVertical += marginInsets.top;
31+
adjustedRadii.topRightHorizontal += marginInsets.right;
32+
adjustedRadii.topRightVertical += marginInsets.top;
33+
adjustedRadii.bottomLeftHorizontal += marginInsets.left;
34+
adjustedRadii.bottomLeftVertical += marginInsets.bottom;
35+
adjustedRadii.bottomRightHorizontal += marginInsets.right;
36+
adjustedRadii.bottomRightVertical += marginInsets.bottom;
3537
break;
3638
}
3739
case GeometryBox::BorderBox:
@@ -55,14 +57,15 @@ + (RCTCornerRadii)adjustCornerRadiiForGeometryBox:(GeometryBox)geometryBox
5557
case GeometryBox::ContentBox:
5658
case GeometryBox::FillBox: {
5759
// Content-box: reduce border-radius by border width + padding
58-
adjustedRadii.topLeftHorizontal = MAX(0.0f, cornerRadii.topLeftHorizontal - layoutMetrics.borderWidth.left - layoutMetrics.paddingInsets.left);
59-
adjustedRadii.topLeftVertical = MAX(0.0f, cornerRadii.topLeftVertical - layoutMetrics.borderWidth.top - layoutMetrics.paddingInsets.top);
60-
adjustedRadii.topRightHorizontal = MAX(0.0f, cornerRadii.topRightHorizontal - layoutMetrics.borderWidth.right - layoutMetrics.paddingInsets.right);
61-
adjustedRadii.topRightVertical = MAX(0.0f, cornerRadii.topRightVertical - layoutMetrics.borderWidth.top - layoutMetrics.paddingInsets.top);
62-
adjustedRadii.bottomLeftHorizontal = MAX(0.0f, cornerRadii.bottomLeftHorizontal - layoutMetrics.borderWidth.left - layoutMetrics.paddingInsets.left);
63-
adjustedRadii.bottomLeftVertical = MAX(0.0f, cornerRadii.bottomLeftVertical - layoutMetrics.borderWidth.bottom - layoutMetrics.paddingInsets.bottom);
64-
adjustedRadii.bottomRightHorizontal = MAX(0.0f, cornerRadii.bottomRightHorizontal - layoutMetrics.borderWidth.right - layoutMetrics.paddingInsets.right);
65-
adjustedRadii.bottomRightVertical = MAX(0.0f, cornerRadii.bottomRightVertical - layoutMetrics.borderWidth.bottom - layoutMetrics.paddingInsets.bottom);
60+
// contentInsets = border + padding, so we reduce by full contentInsets
61+
adjustedRadii.topLeftHorizontal = MAX(0.0f, cornerRadii.topLeftHorizontal - layoutMetrics.contentInsets.left);
62+
adjustedRadii.topLeftVertical = MAX(0.0f, cornerRadii.topLeftVertical - layoutMetrics.contentInsets.top);
63+
adjustedRadii.topRightHorizontal = MAX(0.0f, cornerRadii.topRightHorizontal - layoutMetrics.contentInsets.right);
64+
adjustedRadii.topRightVertical = MAX(0.0f, cornerRadii.topRightVertical - layoutMetrics.contentInsets.top);
65+
adjustedRadii.bottomLeftHorizontal = MAX(0.0f, cornerRadii.bottomLeftHorizontal - layoutMetrics.contentInsets.left);
66+
adjustedRadii.bottomLeftVertical = MAX(0.0f, cornerRadii.bottomLeftVertical - layoutMetrics.contentInsets.bottom);
67+
adjustedRadii.bottomRightHorizontal = MAX(0.0f, cornerRadii.bottomRightHorizontal - layoutMetrics.contentInsets.right);
68+
adjustedRadii.bottomRightVertical = MAX(0.0f, cornerRadii.bottomRightVertical - layoutMetrics.contentInsets.bottom);
6669
break;
6770
}
6871
}
@@ -72,7 +75,7 @@ + (RCTCornerRadii)adjustCornerRadiiForGeometryBox:(GeometryBox)geometryBox
7275

7376
+ (CGRect)getGeometryBoxRect:(GeometryBox)geometryBox
7477
layoutMetrics:(const LayoutMetrics &)layoutMetrics
75-
yogaStyle:(const facebook::yoga::Style &)yogaStyle
78+
yogaStylableProps:(const YogaStylableProps &)yogaStylableProps
7679
bounds:(CGRect)bounds
7780
{
7881
switch (geometryBox) {
@@ -86,11 +89,12 @@ + (CGRect)getGeometryBoxRect:(GeometryBox)geometryBox
8689
case GeometryBox::ViewBox:
8790
return bounds;
8891
case GeometryBox::MarginBox:
92+
auto marginInsets = marginInsetsFromYogaStylableProps(yogaStylableProps);
8993
return CGRectMake(
90-
bounds.origin.x - layoutMetrics.marginInsets.left,
91-
bounds.origin.y - layoutMetrics.marginInsets.top,
92-
bounds.size.width + layoutMetrics.marginInsets.left + layoutMetrics.marginInsets.right,
93-
bounds.size.height + layoutMetrics.marginInsets.top + layoutMetrics.marginInsets.bottom
94+
bounds.origin.x - marginInsets.left,
95+
bounds.origin.y - marginInsets.top,
96+
bounds.size.width + marginInsets.left + marginInsets.right,
97+
bounds.size.height + marginInsets.top + marginInsets.bottom
9498
);
9599
}
96100

@@ -99,15 +103,15 @@ + (CGRect)getGeometryBoxRect:(GeometryBox)geometryBox
99103

100104
+ (CALayer *)createClipPathLayer:(const ClipPath &)clipPath
101105
layoutMetrics:(const LayoutMetrics &)layoutMetrics
102-
yogaStyle:(const facebook::yoga::Style &)yogaStyle
106+
yogaStylableProps:(const YogaStylableProps &)yogaStylableProps
103107
bounds:(CGRect)bounds
104108
cornerRadii:(RCTCornerRadii)cornerRadii
105109
{
106110
CGRect box = bounds;
107111
if (clipPath.geometryBox.has_value()) {
108112
box = [self getGeometryBoxRect:clipPath.geometryBox.value()
109113
layoutMetrics:layoutMetrics
110-
yogaStyle:yogaStyle
114+
yogaStylableProps:yogaStylableProps
111115
bounds:bounds];
112116
}
113117

@@ -120,7 +124,7 @@ + (CALayer *)createClipPathLayer:(const ClipPath &)clipPath
120124
RCTCornerRadii adjustedRadii = [self adjustCornerRadiiForGeometryBox:clipPath.geometryBox.value()
121125
cornerRadii:cornerRadii
122126
layoutMetrics:layoutMetrics
123-
yogaStyle:yogaStyle];
127+
yogaStylableProps:yogaStylableProps];
124128
RCTCornerInsets cornerInsets = RCTGetCornerInsets(adjustedRadii, UIEdgeInsetsZero);
125129
CGPathRef cgPath = RCTPathCreateWithRoundedRect(box, cornerInsets, nil, NO);
126130
path = [UIBezierPath bezierPathWithCGPath:cgPath];

packages/react-native/ReactCommon/react/renderer/components/view/conversions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99

1010
#include <glog/logging.h>
1111
#include <react/debug/react_native_expect.h>
12-
#include <react/renderer/components/view/primitives.h>
1312
#include <react/renderer/components/view/YogaStylableProps.h>
13+
#include <react/renderer/components/view/primitives.h>
1414
#include <react/renderer/core/LayoutMetrics.h>
1515
#include <react/renderer/core/PropsParserContext.h>
1616
#include <react/renderer/core/RawProps.h>

0 commit comments

Comments
 (0)