Move pointscalefactor to config

Summary:
This adds some improvements to the new ```YGConfig```, it tackles #452 and moves the scalefactor into the config.
Closes https://github.com/facebook/yoga/pull/457

Differential Revision: D4675088

Pulled By: emilsjolander

fbshipit-source-id: 99b2c734d6c5139fe1dc8bdeb014bb038f0e337d
This commit is contained in:
Lukas Wöhrl
2017-03-09 07:21:23 -08:00
committed by Facebook Github Bot
parent 0445962bd4
commit 406c8a2117
3 changed files with 34 additions and 37 deletions

View File

@@ -40,35 +40,35 @@ TEST(YogaTest, rounding_feature_with_custom_measure_func_floor) {
YGNodeSetMeasureFunc(root_child0, _measureFloor); YGNodeSetMeasureFunc(root_child0, _measureFloor);
YGNodeInsertChild(root, root_child0, 0); YGNodeInsertChild(root, root_child0, 0);
YGSetPointScaleFactor(0.0); YGConfigSetPointScaleFactor(config, 0.0f);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(10.2, YGNodeLayoutGetWidth(root_child0)); ASSERT_FLOAT_EQ(10.2, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(10.2, YGNodeLayoutGetHeight(root_child0)); ASSERT_FLOAT_EQ(10.2, YGNodeLayoutGetHeight(root_child0));
YGSetPointScaleFactor(1.0); YGConfigSetPointScaleFactor(config, 1.0f);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0));
YGSetPointScaleFactor(2.0); YGConfigSetPointScaleFactor(config, 2.0f);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0));
YGSetPointScaleFactor(4.0); YGConfigSetPointScaleFactor(config, 4.0f);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(10.25, YGNodeLayoutGetWidth(root_child0)); ASSERT_FLOAT_EQ(10.25f, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(10.25, YGNodeLayoutGetHeight(root_child0)); ASSERT_FLOAT_EQ(10.25, YGNodeLayoutGetHeight(root_child0));
YGSetPointScaleFactor(1.0 / 3.0); YGConfigSetPointScaleFactor(config, 1.0f / 3.0f);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
@@ -77,7 +77,6 @@ TEST(YogaTest, rounding_feature_with_custom_measure_func_floor) {
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
YGSetPointScaleFactor(1.0);
YGConfigFree(config); YGConfigFree(config);
} }
@@ -91,7 +90,7 @@ TEST(YogaTest, rounding_feature_with_custom_measure_func_ceil) {
YGNodeSetMeasureFunc(root_child0, _measureCeil); YGNodeSetMeasureFunc(root_child0, _measureCeil);
YGNodeInsertChild(root, root_child0, 0); YGNodeInsertChild(root, root_child0, 0);
YGSetPointScaleFactor(1.0); YGConfigSetPointScaleFactor(config, 1.0f);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
@@ -100,6 +99,5 @@ TEST(YogaTest, rounding_feature_with_custom_measure_func_ceil) {
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
YGSetPointScaleFactor(1.0);
YGConfigFree(config); YGConfigFree(config);
} }

View File

@@ -97,6 +97,7 @@ typedef struct YGStyle {
typedef struct YGConfig { typedef struct YGConfig {
bool experimentalFeatures[YGExperimentalFeatureCount + 1]; bool experimentalFeatures[YGExperimentalFeatureCount + 1];
bool useWebDefaults; bool useWebDefaults;
float pointScaleFactor;
} YGConfig; } YGConfig;
typedef struct YGNode { typedef struct YGNode {
@@ -206,6 +207,7 @@ static YGConfig gYGConfigDefaults = {
[YGExperimentalFeatureWebFlexBasis] = false, [YGExperimentalFeatureWebFlexBasis] = false,
}, },
.useWebDefaults = false, .useWebDefaults = false,
.pointScaleFactor = 1.0f
}; };
static void YGNodeMarkDirtyInternal(const YGNodeRef node); static void YGNodeMarkDirtyInternal(const YGNodeRef node);
@@ -307,7 +309,6 @@ static inline float YGValueResolveMargin(const YGValue *const value, const float
int32_t gNodeInstanceCount = 0; int32_t gNodeInstanceCount = 0;
WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) { WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) {
const YGNodeRef node = gYGMalloc(sizeof(YGNode)); const YGNodeRef node = gYGMalloc(sizeof(YGNode));
YG_ASSERT(node, "Could not allocate memory for node"); YG_ASSERT(node, "Could not allocate memory for node");
@@ -1404,7 +1405,7 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
if (!YGFloatIsUndefined(resolvedFlexBasis) && !YGFloatIsUndefined(mainAxisSize)) { if (!YGFloatIsUndefined(resolvedFlexBasis) && !YGFloatIsUndefined(mainAxisSize)) {
if (YGFloatIsUndefined(child->layout.computedFlexBasis) || if (YGFloatIsUndefined(child->layout.computedFlexBasis) ||
(YGConfigIsExperimentalFeatureEnabled(config, YGExperimentalFeatureWebFlexBasis) && (YGConfigIsExperimentalFeatureEnabled(child->config, YGExperimentalFeatureWebFlexBasis) &&
child->layout.computedFlexBasisGeneration != gCurrentGenerationCount)) { child->layout.computedFlexBasisGeneration != gCurrentGenerationCount)) {
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(resolvedFlexBasis, YGNodePaddingAndBorderForAxis(child, mainAxis, parentWidth)); fmaxf(resolvedFlexBasis, YGNodePaddingAndBorderForAxis(child, mainAxis, parentWidth));
@@ -2231,7 +2232,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
availableInnerMainDim = minInnerMainDim; availableInnerMainDim = minInnerMainDim;
} else if (!YGFloatIsUndefined(maxInnerMainDim) && sizeConsumedOnCurrentLine > maxInnerMainDim) { } else if (!YGFloatIsUndefined(maxInnerMainDim) && sizeConsumedOnCurrentLine > maxInnerMainDim) {
availableInnerMainDim = maxInnerMainDim; availableInnerMainDim = maxInnerMainDim;
} else if (YGConfigIsExperimentalFeatureEnabled(config, YGExperimentalFeatureMinFlexFix)) { } else if (YGConfigIsExperimentalFeatureEnabled(node->config, YGExperimentalFeatureMinFlexFix)) {
// TODO: this needs to be moved out of experimental feature, as this is legitimate fix // TODO: this needs to be moved out of experimental feature, as this is legitimate fix
// If the measurement isn't exact, we want to use as little space as possible // If the measurement isn't exact, we want to use as little space as possible
availableInnerMainDim = sizeConsumedOnCurrentLine; availableInnerMainDim = sizeConsumedOnCurrentLine;
@@ -3312,40 +3313,38 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
return (needToVisitNode || cachedResults == NULL); return (needToVisitNode || cachedResults == NULL);
} }
static float gPointScaleFactor = 1.0; void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInPoint) {
void YGSetPointScaleFactor(float pixelsInPoint) {
YG_ASSERT(pixelsInPoint >= 0.0f, "Scale factor should not be less than zero"); YG_ASSERT(pixelsInPoint >= 0.0f, "Scale factor should not be less than zero");
// We store points for Pixel as we will use it for rounding // We store points for Pixel as we will use it for rounding
if (pixelsInPoint == 0.0f) { if (pixelsInPoint == 0.0f) {
// Zero is used to skip rounding // Zero is used to skip rounding
gPointScaleFactor = 0.0f; config->pointScaleFactor = 0.0f;
} else { } else {
gPointScaleFactor = 1.0f / pixelsInPoint; config->pointScaleFactor = 1.0f / pixelsInPoint;
} }
} }
static void YGRoundToPixelGrid(const YGNodeRef node) { static void YGRoundToPixelGrid(const YGNodeRef node, const float pointScaleFactor) {
if (gPointScaleFactor == 0.0f) { if (pointScaleFactor == 0.0f) {
return; return;
} }
const float nodeLeft = node->layout.position[YGEdgeLeft]; const float nodeLeft = node->layout.position[YGEdgeLeft];
const float nodeTop = node->layout.position[YGEdgeTop]; const float nodeTop = node->layout.position[YGEdgeTop];
// To round correctly to the pixel grid, first we calculate left and top coordinates // To round correctly to the pixel grid, first we calculate left and top coordinates
float fractialLeft = fmodf(nodeLeft, gPointScaleFactor); float fractialLeft = fmodf(nodeLeft, pointScaleFactor);
float fractialTop = fmodf(nodeTop, gPointScaleFactor); float fractialTop = fmodf(nodeTop, pointScaleFactor);
float roundedLeft = nodeLeft - fractialLeft; float roundedLeft = nodeLeft - fractialLeft;
float roundedTop = nodeTop - fractialTop; float roundedTop = nodeTop - fractialTop;
// To do the actual rounding we check if leftover fraction is bigger or equal than half of the grid step // To do the actual rounding we check if leftover fraction is bigger or equal than half of the grid step
if (fractialLeft >= gPointScaleFactor / 2.0) { if (fractialLeft >= pointScaleFactor / 2.0f) {
roundedLeft += gPointScaleFactor; roundedLeft += pointScaleFactor;
fractialLeft -= gPointScaleFactor; fractialLeft -= pointScaleFactor;
} }
if (fractialTop >= gPointScaleFactor / 2.0) { if (fractialTop >= pointScaleFactor / 2.0f) {
roundedTop += gPointScaleFactor; roundedTop += pointScaleFactor;
fractialTop -= gPointScaleFactor; fractialTop -= pointScaleFactor;
} }
node->layout.position[YGEdgeLeft] = roundedLeft; node->layout.position[YGEdgeLeft] = roundedLeft;
node->layout.position[YGEdgeTop] = roundedTop; node->layout.position[YGEdgeTop] = roundedTop;
@@ -3353,21 +3352,21 @@ static void YGRoundToPixelGrid(const YGNodeRef node) {
// Now we round width and height in the same way accounting for fractial leftovers from rounding position // Now we round width and height in the same way accounting for fractial leftovers from rounding position
const float adjustedWidth = fractialLeft + node->layout.dimensions[YGDimensionWidth]; const float adjustedWidth = fractialLeft + node->layout.dimensions[YGDimensionWidth];
const float adjustedHeight = fractialTop + node->layout.dimensions[YGDimensionHeight]; const float adjustedHeight = fractialTop + node->layout.dimensions[YGDimensionHeight];
float roundedWidth = adjustedWidth - fmodf(adjustedWidth, gPointScaleFactor); float roundedWidth = adjustedWidth - fmodf(adjustedWidth, pointScaleFactor);
float roundedHeight = adjustedHeight - fmodf(adjustedHeight, gPointScaleFactor); float roundedHeight = adjustedHeight - fmodf(adjustedHeight, pointScaleFactor);
if (adjustedWidth - roundedWidth >= gPointScaleFactor / 2.0) { if (adjustedWidth - roundedWidth >= pointScaleFactor / 2.0f) {
roundedWidth += gPointScaleFactor; roundedWidth += pointScaleFactor;
} }
if (adjustedHeight - roundedHeight >= gPointScaleFactor / 2.0) { if (adjustedHeight - roundedHeight >= pointScaleFactor / 2.0f) {
roundedHeight += gPointScaleFactor; roundedHeight += pointScaleFactor;
} }
node->layout.dimensions[YGDimensionWidth] = roundedWidth; node->layout.dimensions[YGDimensionWidth] = roundedWidth;
node->layout.dimensions[YGDimensionHeight] = roundedHeight; node->layout.dimensions[YGDimensionHeight] = roundedHeight;
const uint32_t childCount = YGNodeListCount(node->children); const uint32_t childCount = YGNodeListCount(node->children);
for (uint32_t i = 0; i < childCount; i++) { for (uint32_t i = 0; i < childCount; i++) {
YGRoundToPixelGrid(YGNodeGetChild(node, i)); YGRoundToPixelGrid(YGNodeGetChild(node, i), pointScaleFactor);
} }
} }
@@ -3427,7 +3426,7 @@ void YGNodeCalculateLayout(const YGNodeRef node,
YGNodeSetPosition(node, node->layout.direction, parentWidth, parentHeight, parentWidth); YGNodeSetPosition(node, node->layout.direction, parentWidth, parentHeight, parentWidth);
if (YGConfigIsExperimentalFeatureEnabled(node->config, YGExperimentalFeatureRounding)) { if (YGConfigIsExperimentalFeatureEnabled(node->config, YGExperimentalFeatureRounding)) {
YGRoundToPixelGrid(node); YGRoundToPixelGrid(node, node->config->pointScaleFactor);
} }
if (gPrintTree) { if (gPrintTree) {

View File

@@ -223,7 +223,7 @@ WIN_EXPORT void YGLog(YGLogLevel level, const char *message, ...);
// Set this to number of pixels in 1 point to round calculation results // Set this to number of pixels in 1 point to round calculation results
// If you want to avoid rounding - set PointScaleFactor to 0 // If you want to avoid rounding - set PointScaleFactor to 0
WIN_EXPORT void YGSetPointScaleFactor(float pixelsInPoint); WIN_EXPORT void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInPoint);
// YGConfig // YGConfig
WIN_EXPORT YGConfigRef YGConfigNew(void); WIN_EXPORT YGConfigRef YGConfigNew(void);