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

feat: Add logical border radius implementation #35572

Closed
Show file tree
Hide file tree
Changes from 4 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
4 changes: 4 additions & 0 deletions Libraries/Animated/NativeAnimatedHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -391,11 +391,15 @@ const SUPPORTED_STYLES = {
borderBottomLeftRadius: true,
borderBottomRightRadius: true,
borderBottomStartRadius: true,
borderEndEndRadius: true,
borderEndStartRadius: true,
borderRadius: true,
borderTopEndRadius: true,
borderTopLeftRadius: true,
borderTopRightRadius: true,
borderTopStartRadius: true,
borderStartEndRadius: true,
borderStartStartRadius: true,
elevation: true,
opacity: true,
transform: true,
Expand Down
4 changes: 4 additions & 0 deletions Libraries/Components/View/ReactNativeStyleAttributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,14 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
borderColor: colorAttributes,
borderCurve: true,
borderEndColor: colorAttributes,
borderEndEndRadius: true,
borderEndStartRadius: true,
borderLeftColor: colorAttributes,
borderRadius: true,
borderRightColor: colorAttributes,
borderStartColor: colorAttributes,
borderStartEndRadius: true,
borderStartStartRadius: true,
borderStyle: true,
borderTopColor: colorAttributes,
borderTopEndRadius: true,
Expand Down
5 changes: 4 additions & 1 deletion Libraries/Components/View/ViewNativeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
borderTopEndRadius: true,
borderBottomStartRadius: true,
borderBottomEndRadius: true,

borderEndEndRadius: true,
borderEndStartRadius: true,
borderStartEndRadius: true,
borderStartStartRadius: true,
borderStyle: true,
hitSlop: true,
pointerEvents: true,
Expand Down
4 changes: 4 additions & 0 deletions Libraries/NativeComponent/BaseViewConfig.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ const validAttributesForNonEventProps = {
borderBottomRightRadius: true,
borderBottomStartRadius: true,
borderBottomEndRadius: true,
borderEndEndRadius: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

cc @yungsters who recently updated these for prop-types support facebook/react-native-deprecated-modules@5902411

RN's exported prop-types for View aren't enforced by RN itself, like it does for Text or Image. But I suspect we might still want to update ViewPropTypes before RN re-ejects it.

borderEndStartRadius: true,
borderStartEndRadius: true,
borderStartStartRadius: true,
display: true,
zIndex: true,

Expand Down
4 changes: 4 additions & 0 deletions Libraries/StyleSheet/StyleSheetTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,16 @@ export interface ViewStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle {
borderBottomWidth?: number | undefined;
borderColor?: ColorValue | undefined;
borderEndColor?: ColorValue | undefined;
borderEndEndRadius?: number | undefined;
borderEndStartRadius?: number | undefined;
borderLeftColor?: ColorValue | undefined;
borderLeftWidth?: number | undefined;
borderRadius?: number | undefined;
borderRightColor?: ColorValue | undefined;
borderRightWidth?: number | undefined;
borderStartColor?: ColorValue | undefined;
borderStartEndRadius?: number | undefined;
borderStartStartRadius?: number | undefined;
borderStyle?: 'solid' | 'dotted' | 'dashed' | undefined;
borderTopColor?: ColorValue | undefined;
borderTopEndRadius?: number | undefined;
Expand Down
4 changes: 4 additions & 0 deletions Libraries/StyleSheet/StyleSheetTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,10 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
borderBottomLeftRadius?: number | AnimatedNode,
borderBottomRightRadius?: number | AnimatedNode,
borderBottomStartRadius?: number | AnimatedNode,
borderEndEndRadius?: number | AnimatedNode,
borderEndStartRadius?: number | AnimatedNode,
borderStartEndRadius?: number | AnimatedNode,
borderStartStartRadius?: number | AnimatedNode,
borderTopEndRadius?: number | AnimatedNode,
borderTopLeftRadius?: number | AnimatedNode,
borderTopRightRadius?: number | AnimatedNode,
Expand Down
4 changes: 4 additions & 0 deletions React/Views/RCTView.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
@property (nonatomic, assign) CGFloat borderBottomRightRadius;
@property (nonatomic, assign) CGFloat borderBottomStartRadius;
@property (nonatomic, assign) CGFloat borderBottomEndRadius;
@property (nonatomic, assign) CGFloat borderEndEndRadius;
@property (nonatomic, assign) CGFloat borderEndStartRadius;
@property (nonatomic, assign) CGFloat borderStartEndRadius;
@property (nonatomic, assign) CGFloat borderStartStartRadius;

/**
* Border colors (actually retained).
Expand Down
23 changes: 14 additions & 9 deletions React/Views/RCTView.m
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ - (instancetype)initWithFrame:(CGRect)frame
_borderBottomRightRadius = -1;
_borderBottomStartRadius = -1;
_borderBottomEndRadius = -1;
_borderEndEndRadius = -1;
_borderEndStartRadius = -1;
_borderStartEndRadius = -1;
_borderStartStartRadius = -1;
_borderCurve = RCTBorderCurveCircular;
_borderStyle = RCTBorderStyleSolid;
_hitTestEdgeInsets = UIEdgeInsetsZero;
Expand Down Expand Up @@ -668,10 +672,10 @@ - (RCTCornerRadii)cornerRadii
CGFloat bottomRightRadius;

if ([[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL]) {
const CGFloat topStartRadius = RCTDefaultIfNegativeTo(_borderTopLeftRadius, _borderTopStartRadius);
const CGFloat topEndRadius = RCTDefaultIfNegativeTo(_borderTopRightRadius, _borderTopEndRadius);
const CGFloat bottomStartRadius = RCTDefaultIfNegativeTo(_borderBottomLeftRadius, _borderBottomStartRadius);
const CGFloat bottomEndRadius = RCTDefaultIfNegativeTo(_borderBottomRightRadius, _borderBottomEndRadius);
const CGFloat topStartRadius = RCTDefaultIfNegativeTo(_borderTopLeftRadius, _borderStartStartRadius > 0 ? _borderStartStartRadius: _borderTopStartRadius);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think > 0 is the correct check, since it would mean we would ignore something setting the value to 0. On this line it looks like RCTDefaultIfNegativeTo is also already being used to set precedence, so mixing it with a ternary doing the same is a little confusing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah good point, I guess we could check for > -1 as all _border**Radius variables are initialized using -1, but I've refactored this a bit to remove the ternaries and now everything is using RCTDefaultIfNegativeTo

const CGFloat topEndRadius = RCTDefaultIfNegativeTo(_borderTopRightRadius, _borderStartEndRadius > 0 ? _borderStartEndRadius: _borderTopEndRadius);
const CGFloat bottomStartRadius = RCTDefaultIfNegativeTo(_borderBottomLeftRadius, _borderEndStartRadius > 0 ? _borderEndStartRadius: _borderBottomStartRadius);
Copy link
Contributor

Choose a reason for hiding this comment

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

For consistency with other properties here (and Yoga's stylesheet behavior), we should give preference to the cardinal direction over the flow relative one. E.g. Top should be taken instead of Start when both are present.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Makes sense, I've just updated it

const CGFloat bottomEndRadius = RCTDefaultIfNegativeTo(_borderBottomRightRadius, _borderEndEndRadius > 0 ? _borderEndEndRadius: _borderBottomEndRadius);

const CGFloat directionAwareTopLeftRadius = isRTL ? topEndRadius : topStartRadius;
const CGFloat directionAwareTopRightRadius = isRTL ? topStartRadius : topEndRadius;
Expand All @@ -683,10 +687,10 @@ - (RCTCornerRadii)cornerRadii
bottomLeftRadius = RCTDefaultIfNegativeTo(radius, directionAwareBottomLeftRadius);
bottomRightRadius = RCTDefaultIfNegativeTo(radius, directionAwareBottomRightRadius);
} else {
const CGFloat directionAwareTopLeftRadius = isRTL ? _borderTopEndRadius : _borderTopStartRadius;
const CGFloat directionAwareTopRightRadius = isRTL ? _borderTopStartRadius : _borderTopEndRadius;
const CGFloat directionAwareBottomLeftRadius = isRTL ? _borderBottomEndRadius : _borderBottomStartRadius;
const CGFloat directionAwareBottomRightRadius = isRTL ? _borderBottomStartRadius : _borderBottomEndRadius;
const CGFloat directionAwareTopLeftRadius = isRTL ? _borderStartEndRadius > 0 ? _borderStartEndRadius: _borderTopEndRadius : _borderStartStartRadius > 0 ? _borderStartStartRadius: _borderTopStartRadius;
const CGFloat directionAwareTopRightRadius = isRTL ? _borderStartStartRadius > 0 ? _borderStartStartRadius: _borderTopStartRadius : _borderStartEndRadius > 0 ? _borderStartEndRadius: _borderTopEndRadius;
const CGFloat directionAwareBottomLeftRadius = isRTL ? _borderEndEndRadius > 0 ? _borderEndEndRadius: _borderBottomEndRadius : _borderEndStartRadius > 0 ? _borderEndStartRadius: _borderBottomStartRadius;
const CGFloat directionAwareBottomRightRadius = isRTL ? _borderEndStartRadius > 0 ? _borderEndStartRadius: _borderBottomStartRadius : _borderEndEndRadius > 0 ? _borderEndEndRadius: _borderBottomEndRadius;

topLeftRadius =
RCTDefaultIfNegativeTo(radius, RCTDefaultIfNegativeTo(_borderTopLeftRadius, directionAwareTopLeftRadius));
Expand Down Expand Up @@ -946,7 +950,8 @@ -(void)setBorder##side##Radius : (CGFloat)radius \

setBorderRadius() setBorderRadius(TopLeft) setBorderRadius(TopRight) setBorderRadius(TopStart)
setBorderRadius(TopEnd) setBorderRadius(BottomLeft) setBorderRadius(BottomRight)
setBorderRadius(BottomStart) setBorderRadius(BottomEnd)
setBorderRadius(BottomStart) setBorderRadius(BottomEnd) setBorderRadius(EndEnd)
setBorderRadius(EndStart) setBorderRadius(StartEnd) setBorderRadius(StartStart)

#pragma mark - Border Curve

Expand Down
4 changes: 4 additions & 0 deletions React/Views/RCTViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,10 @@ - (RCTShadowView *)shadowView
RCT_VIEW_BORDER_RADIUS_PROPERTY(BottomRight)
RCT_VIEW_BORDER_RADIUS_PROPERTY(BottomStart)
RCT_VIEW_BORDER_RADIUS_PROPERTY(BottomEnd)
RCT_VIEW_BORDER_RADIUS_PROPERTY(EndEnd)
RCT_VIEW_BORDER_RADIUS_PROPERTY(EndStart)
RCT_VIEW_BORDER_RADIUS_PROPERTY(StartEnd)
RCT_VIEW_BORDER_RADIUS_PROPERTY(StartStart)

RCT_REMAP_VIEW_PROPERTY(display, reactDisplay, YGDisplay)
RCT_REMAP_VIEW_PROPERTY(zIndex, reactZIndex, NSInteger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ public class ViewProps {
public static final String BORDER_TOP_END_RADIUS = "borderTopEndRadius";
public static final String BORDER_BOTTOM_START_RADIUS = "borderBottomStartRadius";
public static final String BORDER_BOTTOM_END_RADIUS = "borderBottomEndRadius";
public static final String BORDER_END_END_RADIUS= "borderEndEndRadius";
public static final String BORDER_END_START_RADIUS = "borderEndStartRadius";
public static final String BORDER_START_END_RADIUS = "borderStartEndRadius";
public static final String BORDER_START_START_RADIUS = "borderStartStartRadius";
public static final String BORDER_START_COLOR = "borderStartColor";
public static final String BORDER_END_COLOR = "borderEndColor";
public static final String ON_LAYOUT = "onLayout";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ object ReactMapBufferPropSetter {
private const val CORNER_BOTTOM_END = 6
private const val CORNER_BOTTOM_START = 7
private const val CORNER_ALL = 8
private const val CORNER_END_END = 9
private const val CORNER_END_START = 10
private const val CORNER_START_END = 11
private const val CORNER_START_START = 12

private const val NATIVE_DRAWABLE_KIND = 0
private const val NATIVE_DRAWABLE_ATTRIBUTE = 1
Expand Down Expand Up @@ -365,6 +369,10 @@ object ReactMapBufferPropSetter {
CORNER_TOP_END -> 6
CORNER_BOTTOM_START -> 7
CORNER_BOTTOM_END -> 8
CORNER_END_END -> 9
CORNER_END_START -> 10
CORNER_START_END -> 11
CORNER_START_START -> 12
else -> throw IllegalArgumentException("Unknown key for border style: $key")
}
val borderRadius = entry.doubleValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ public enum BorderRadiusLocation {
TOP_START,
TOP_END,
BOTTOM_START,
BOTTOM_END
BOTTOM_END,
END_END,
END_START,
START_END,
START_START
}

public ReactViewBackgroundDrawable(Context context) {
Expand Down Expand Up @@ -271,7 +275,7 @@ public void setRadius(float radius) {

public void setRadius(float radius, int position) {
if (mBorderCornerRadii == null) {
mBorderCornerRadii = new float[8];
mBorderCornerRadii = new float[12];
Arrays.fill(mBorderCornerRadii, YogaConstants.UNDEFINED);
}

Expand Down Expand Up @@ -581,8 +585,13 @@ private void updatePath() {
float bottomStartRadius = getBorderRadius(BorderRadiusLocation.BOTTOM_START);
float bottomEndRadius = getBorderRadius(BorderRadiusLocation.BOTTOM_END);

float endEndRadius = getBorderRadius(BorderRadiusLocation.END_END);
float endStartRadius = getBorderRadius(BorderRadiusLocation.END_START);
float startEndRadius = getBorderRadius(BorderRadiusLocation.START_END);
float startStartRadius = getBorderRadius(BorderRadiusLocation.START_START);

if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(mContext)) {
if (YogaConstants.isUndefined(topStartRadius)) {
if (YogaConstants.isUndefined(topStartRadius)) {
topStartRadius = topLeftRadius;
}

Expand All @@ -598,20 +607,30 @@ private void updatePath() {
bottomEndRadius = bottomRightRadius;
}

final float directionAwareTopLeftRadius = isRTL ? topEndRadius : topStartRadius;
final float directionAwareTopRightRadius = isRTL ? topStartRadius : topEndRadius;
final float directionAwareBottomLeftRadius = isRTL ? bottomEndRadius : bottomStartRadius;
final float directionAwareBottomRightRadius = isRTL ? bottomStartRadius : bottomEndRadius;
final float logicalTopStartRadius = !YogaConstants.isUndefined(startStartRadius) ? startStartRadius : topStartRadius;
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above re reversing the precedence here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, updated

final float logicalTopEndRadius = !YogaConstants.isUndefined(startEndRadius) ? startEndRadius : topEndRadius;
final float logicalBottomStartRadius = !YogaConstants.isUndefined(endStartRadius) ? endStartRadius : bottomStartRadius;
final float logicalBottomEndRadius = !YogaConstants.isUndefined(endEndRadius) ? endEndRadius : bottomEndRadius;

final float directionAwareTopLeftRadius = isRTL ? logicalTopEndRadius : logicalTopStartRadius;
final float directionAwareTopRightRadius = isRTL ? logicalTopStartRadius : logicalTopEndRadius;
final float directionAwareBottomLeftRadius = isRTL ? logicalBottomEndRadius : logicalBottomStartRadius;
final float directionAwareBottomRightRadius = isRTL ? logicalBottomStartRadius : logicalBottomEndRadius;

topLeftRadius = directionAwareTopLeftRadius;
topRightRadius = directionAwareTopRightRadius;
bottomLeftRadius = directionAwareBottomLeftRadius;
bottomRightRadius = directionAwareBottomRightRadius;
} else {
final float directionAwareTopLeftRadius = isRTL ? topEndRadius : topStartRadius;
final float directionAwareTopRightRadius = isRTL ? topStartRadius : topEndRadius;
final float directionAwareBottomLeftRadius = isRTL ? bottomEndRadius : bottomStartRadius;
final float directionAwareBottomRightRadius = isRTL ? bottomStartRadius : bottomEndRadius;
final float logicalTopStartRadius = !YogaConstants.isUndefined(startStartRadius) ? startStartRadius : topStartRadius;
final float logicalTopEndRadius = !YogaConstants.isUndefined(startEndRadius) ? startEndRadius : topEndRadius;
final float logicalBottomStartRadius = !YogaConstants.isUndefined(endStartRadius) ? endStartRadius : bottomStartRadius;
final float logicalBottomEndRadius = !YogaConstants.isUndefined(endEndRadius) ? endEndRadius : bottomEndRadius;

final float directionAwareTopLeftRadius = isRTL ? logicalTopEndRadius : logicalTopStartRadius;
final float directionAwareTopRightRadius = isRTL ? logicalTopStartRadius : logicalTopEndRadius;
final float directionAwareBottomLeftRadius = isRTL ? logicalBottomEndRadius : logicalBottomStartRadius;
final float directionAwareBottomRightRadius = isRTL ? logicalBottomStartRadius : logicalBottomEndRadius;

if (!YogaConstants.isUndefined(directionAwareTopLeftRadius)) {
topLeftRadius = directionAwareTopLeftRadius;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ public void nextFocusUp(ReactViewGroup view, int viewId) {
ViewProps.BORDER_TOP_END_RADIUS,
ViewProps.BORDER_BOTTOM_START_RADIUS,
ViewProps.BORDER_BOTTOM_END_RADIUS,
ViewProps.BORDER_END_END_RADIUS,
ViewProps.BORDER_END_START_RADIUS,
ViewProps.BORDER_START_END_RADIUS,
ViewProps.BORDER_START_START_RADIUS,
},
defaultFloat = YogaConstants.UNDEFINED)
public void setBorderRadius(ReactViewGroup view, int index, float borderRadius) {
Expand Down
10 changes: 9 additions & 1 deletion ReactAndroid/src/main/jni/react/fabric/viewPropConversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ constexpr MapBuffer::Key CORNER_TOP_END = 5;
constexpr MapBuffer::Key CORNER_BOTTOM_END = 6;
constexpr MapBuffer::Key CORNER_BOTTOM_START = 7;
constexpr MapBuffer::Key CORNER_ALL = 8;
constexpr MapBuffer::Key CORNER_END_END = 9;
constexpr MapBuffer::Key CORNER_END_START = 10;
constexpr MapBuffer::Key CORNER_START_END = 11;
constexpr MapBuffer::Key CORNER_START_START = 12;

inline void putOptionalFloat(
MapBufferBuilder &builder,
Expand All @@ -122,7 +126,7 @@ inline void putOptionalFloat(
}

MapBuffer convertBorderRadii(CascadedBorderRadii const &radii) {
MapBufferBuilder builder(9);
MapBufferBuilder builder(13);
putOptionalFloat(builder, CORNER_TOP_LEFT, radii.topLeft);
putOptionalFloat(builder, CORNER_TOP_RIGHT, radii.topRight);
putOptionalFloat(builder, CORNER_BOTTOM_RIGHT, radii.bottomRight);
Expand All @@ -132,6 +136,10 @@ MapBuffer convertBorderRadii(CascadedBorderRadii const &radii) {
putOptionalFloat(builder, CORNER_BOTTOM_END, radii.bottomEnd);
putOptionalFloat(builder, CORNER_BOTTOM_START, radii.bottomStart);
putOptionalFloat(builder, CORNER_ALL, radii.all);
putOptionalFloat(builder, CORNER_END_END, radii.endEnd);
putOptionalFloat(builder, CORNER_END_START, radii.endStart);
putOptionalFloat(builder, CORNER_START_END, radii.startEnd);
putOptionalFloat(builder, CORNER_START_START, radii.startStart);
return builder.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,26 @@ void YogaLayoutableShadowNode::swapLeftAndRightInViewProps(
auto &props = const_cast<ViewProps &>(typedCasting);

// Swap border node values, borderRadii, borderColors and borderStyles.
if (props.borderRadii.startEnd.has_value()) {
props.borderRadii.topEnd = props.borderRadii.startEnd;
props.borderRadii.startEnd.reset();
}

if (props.borderRadii.startStart.has_value()) {
props.borderRadii.topStart = props.borderRadii.startStart;
props.borderRadii.startStart.reset();
}

if (props.borderRadii.endEnd.has_value()) {
props.borderRadii.bottomEnd = props.borderRadii.endEnd;
props.borderRadii.endEnd.reset();
}

if (props.borderRadii.endStart.has_value()) {
props.borderRadii.bottomStart = props.borderRadii.endStart;
props.borderRadii.endStart.reset();
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at the examples below, they are always changing a left-or-right cardinal direction to a flow-relative one. E.g. nothing is done to borderRadii.topStart. But the added code seems to be doing the opposite? E.g. changing start/end to a top-bottom direction.

Are you sure the added code here is needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for the review @NickGerleman, I did some investigation and actually, this code is not necessary, everything works just fine without it. I've pushed another commit and now all comments should've been addressed

if (props.borderRadii.topLeft.has_value()) {
props.borderRadii.topStart = props.borderRadii.topLeft;
props.borderRadii.topLeft.reset();
Expand Down
32 changes: 26 additions & 6 deletions ReactCommon/react/renderer/components/view/primitives.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,24 @@ struct CascadedRectangleCorners {
OptionalT bottomStart{};
OptionalT bottomEnd{};
OptionalT all{};
OptionalT endEnd{};
OptionalT endStart{};
OptionalT startEnd{};
OptionalT startStart{};

Counterpart resolve(bool isRTL, T defaults) const {
const auto topLeading = isRTL ? topEnd : topStart;
const auto topTrailing = isRTL ? topStart : topEnd;
const auto bottomLeading = isRTL ? bottomEnd : bottomStart;
const auto bottomTrailing = isRTL ? bottomStart : bottomEnd;
const auto topLeading = isRTL ? startEnd ? startEnd : topEnd
: startStart ? startStart
: topStart;
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as elsewhere about precedence, but this ternary is a bit hard to read as-is. Could we avoid the nested ternary (or maybe this is fine when formatted)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah that logic was pretty confusing, I've just updated it making things a bit easier to read

const auto topTrailing = isRTL ? startStart ? startStart : topStart
: startEnd ? startEnd
: topEnd;
const auto bottomLeading = isRTL ? endEnd ? endEnd : bottomEnd
: endStart ? endStart
: bottomStart;
const auto bottomTrailing = isRTL ? endStart ? endStart : bottomStart
: endEnd ? endEnd
: bottomEnd;

return {
/* .topLeft = */ topLeft.value_or(
Expand All @@ -189,7 +201,11 @@ struct CascadedRectangleCorners {
this->topEnd,
this->bottomStart,
this->bottomEnd,
this->all) ==
this->all,
this->endEnd,
this->endStart,
this->startEnd,
this->startStart) ==
std::tie(
rhs.topLeft,
rhs.topRight,
Expand All @@ -199,7 +215,11 @@ struct CascadedRectangleCorners {
rhs.topEnd,
rhs.bottomStart,
rhs.bottomEnd,
rhs.all);
rhs.all,
rhs.endEnd,
rhs.endStart,
rhs.startEnd,
rhs.startStart);
}

bool operator!=(const CascadedRectangleCorners<T> &rhs) const {
Expand Down
Loading