Skip to content

Commit d9e5b31

Browse files
sherginfacebook-github-bot
authored andcommitted
Helpers for proper conversion float values between CG and YG representations
Summary: Yoga and CoreGraphics have different opinions about how "infinity" value should be represented. Yoga uses `NAN` which requires additional effort to compare all those values, whereas GoreGraphics uses `GFLOAT_MAX` which can be easyly compared with standard `==` operator. Messing with this can cause super weired bugs like 100% CPU load for couple of seconds somewhere in CoreGraphics. Reviewed By: mmmulani Differential Revision: D6665633 fbshipit-source-id: b6236c6fa50d1f8fb0c9576203922f7b24b7301e
1 parent af226ef commit d9e5b31

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

React/Views/RCTShadowView+Layout.h

+7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111

1212
#import <React/RCTShadowView.h>
1313

14+
/**
15+
* Converts float values between Yoga and CoreGraphics representations,
16+
* especially in terms of edge cases.
17+
*/
18+
RCT_EXTERN float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value);
19+
RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value);
20+
1421
@interface RCTShadowView (Layout)
1522

1623
#pragma mark - Computed Layout-Inferred Metrics

React/Views/RCTShadowView+Layout.m

+34-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,32 @@
1111

1212
#import <yoga/Yoga.h>
1313

14+
/**
15+
* Yoga and CoreGraphics have different opinions about how "infinity" value
16+
* should be represented.
17+
* Yoga uses `NAN` which requires additional effort to compare all those values,
18+
* whereas GoreGraphics uses `GFLOAT_MAX` which can be easyly compared with
19+
* standard `==` operator.
20+
*/
21+
22+
float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value)
23+
{
24+
if (value == CGFLOAT_MAX || isnan(value) || isinf(value)) {
25+
return YGUndefined;
26+
}
27+
28+
return value;
29+
}
30+
31+
CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value)
32+
{
33+
if (value == YGUndefined || isnan(value) || isinf(value)) {
34+
return CGFLOAT_MAX;
35+
}
36+
37+
return value;
38+
}
39+
1440
@implementation RCTShadowView (Layout)
1541

1642
#pragma mark - Computed Layout-Inferred Metrics
@@ -19,21 +45,21 @@ - (UIEdgeInsets)paddingAsInsets
1945
{
2046
YGNodeRef yogaNode = self.yogaNode;
2147
return (UIEdgeInsets){
22-
YGNodeLayoutGetPadding(yogaNode, YGEdgeTop),
23-
YGNodeLayoutGetPadding(yogaNode, YGEdgeLeft),
24-
YGNodeLayoutGetPadding(yogaNode, YGEdgeBottom),
25-
YGNodeLayoutGetPadding(yogaNode, YGEdgeRight)
48+
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeTop)),
49+
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeLeft)),
50+
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeBottom)),
51+
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeRight))
2652
};
2753
}
2854

2955
- (UIEdgeInsets)borderAsInsets
3056
{
3157
YGNodeRef yogaNode = self.yogaNode;
3258
return (UIEdgeInsets){
33-
YGNodeLayoutGetBorder(yogaNode, YGEdgeTop),
34-
YGNodeLayoutGetBorder(yogaNode, YGEdgeLeft),
35-
YGNodeLayoutGetBorder(yogaNode, YGEdgeBottom),
36-
YGNodeLayoutGetBorder(yogaNode, YGEdgeRight)
59+
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeTop)),
60+
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeLeft)),
61+
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeBottom)),
62+
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeRight))
3763
};
3864
}
3965

0 commit comments

Comments
 (0)