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
This commit is contained in:
Valentin Shergin 2018-01-07 18:21:39 -08:00 committed by Facebook Github Bot
parent af226ef949
commit d9e5b313bb
2 changed files with 41 additions and 8 deletions

View File

@ -11,6 +11,13 @@
#import <React/RCTShadowView.h>
/**
* Converts float values between Yoga and CoreGraphics representations,
* especially in terms of edge cases.
*/
RCT_EXTERN float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value);
RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value);
@interface RCTShadowView (Layout)
#pragma mark - Computed Layout-Inferred Metrics

View File

@ -11,6 +11,32 @@
#import <yoga/Yoga.h>
/**
* 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.
*/
float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value)
{
if (value == CGFLOAT_MAX || isnan(value) || isinf(value)) {
return YGUndefined;
}
return value;
}
CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value)
{
if (value == YGUndefined || isnan(value) || isinf(value)) {
return CGFLOAT_MAX;
}
return value;
}
@implementation RCTShadowView (Layout)
#pragma mark - Computed Layout-Inferred Metrics
@ -19,10 +45,10 @@
{
YGNodeRef yogaNode = self.yogaNode;
return (UIEdgeInsets){
YGNodeLayoutGetPadding(yogaNode, YGEdgeTop),
YGNodeLayoutGetPadding(yogaNode, YGEdgeLeft),
YGNodeLayoutGetPadding(yogaNode, YGEdgeBottom),
YGNodeLayoutGetPadding(yogaNode, YGEdgeRight)
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeTop)),
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeLeft)),
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeBottom)),
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeRight))
};
}
@ -30,10 +56,10 @@
{
YGNodeRef yogaNode = self.yogaNode;
return (UIEdgeInsets){
YGNodeLayoutGetBorder(yogaNode, YGEdgeTop),
YGNodeLayoutGetBorder(yogaNode, YGEdgeLeft),
YGNodeLayoutGetBorder(yogaNode, YGEdgeBottom),
YGNodeLayoutGetBorder(yogaNode, YGEdgeRight)
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeTop)),
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeLeft)),
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeBottom)),
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeRight))
};
}