diff --git a/tests/YGRoundingFunctionTest.cpp b/tests/YGRoundingFunctionTest.cpp index 90b15f7e..f7fa7a8a 100644 --- a/tests/YGRoundingFunctionTest.cpp +++ b/tests/YGRoundingFunctionTest.cpp @@ -80,3 +80,45 @@ TEST(YogaTest, consistent_rounding_during_repeated_layouts) { YGConfigFree(config); } + +TEST(YogaTest, per_node_point_scale_factor) { + const YGConfigRef config1 = YGConfigNew(); + YGConfigSetPointScaleFactor(config1, 2); + + const YGConfigRef config2 = YGConfigNew(); + YGConfigSetPointScaleFactor(config2, 1); + + const YGConfigRef config3 = YGConfigNew(); + YGConfigSetPointScaleFactor(config3, 0.5f); + + const YGNodeRef root = YGNodeNewWithConfig(config1); + YGNodeStyleSetWidth(root, 11.5); + YGNodeStyleSetHeight(root, 11.5); + + const YGNodeRef node0 = YGNodeNewWithConfig(config2); + YGNodeStyleSetWidth(node0, 9.5); + YGNodeStyleSetHeight(node0, 9.5); + YGNodeInsertChild(root, node0, 0); + + const YGNodeRef node1 = YGNodeNewWithConfig(config3); + YGNodeStyleSetWidth(node1, 7); + YGNodeStyleSetHeight(node1, 7); + YGNodeInsertChild(node0, node1, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(YGNodeLayoutGetWidth(root), 11.5); + ASSERT_EQ(YGNodeLayoutGetHeight(root), 11.5); + + ASSERT_EQ(YGNodeLayoutGetWidth(node0), 10); + ASSERT_EQ(YGNodeLayoutGetHeight(node0), 10); + + ASSERT_EQ(YGNodeLayoutGetWidth(node1), 8); + ASSERT_EQ(YGNodeLayoutGetHeight(node1), 8); + + YGNodeFreeRecursive(root); + + YGConfigFree(config1); + YGConfigFree(config2); + YGConfigFree(config3); +} diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index c91b3039..e12a46bf 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -2487,7 +2487,7 @@ bool calculateLayoutInternal( layout->cachedLayout.computedHeight, marginAxisRow, marginAxisColumn, - config)) { + node->getConfig())) { cachedResults = &layout->cachedLayout; } else { // Try to use the measurement cache. @@ -2505,7 +2505,7 @@ bool calculateLayoutInternal( layout->cachedMeasurements[i].computedHeight, marginAxisRow, marginAxisColumn, - config)) { + node->getConfig())) { cachedResults = &layout->cachedMeasurements[i]; break; } @@ -2756,8 +2756,7 @@ void calculateLayout( gCurrentGenerationCount.load(std::memory_order_relaxed))) { node->setPosition( node->getLayout().direction(), ownerWidth, ownerHeight, ownerWidth); - roundLayoutResultsToPixelGrid( - node, node->getConfig()->getPointScaleFactor(), 0.0f, 0.0f); + roundLayoutResultsToPixelGrid(node, 0.0f, 0.0f); #ifdef DEBUG if (node->getConfig()->shouldPrintTree()) { diff --git a/yoga/algorithm/PixelGrid.cpp b/yoga/algorithm/PixelGrid.cpp index 0a4bda22..b2749e9f 100644 --- a/yoga/algorithm/PixelGrid.cpp +++ b/yoga/algorithm/PixelGrid.cpp @@ -64,12 +64,9 @@ float roundValueToPixelGrid( void roundLayoutResultsToPixelGrid( yoga::Node* const node, - const double pointScaleFactor, const double absoluteLeft, const double absoluteTop) { - if (pointScaleFactor == 0.0f) { - return; - } + const auto pointScaleFactor = node->getConfig()->getPointScaleFactor(); const double nodeLeft = node->getLayout().position[YGEdgeLeft]; const double nodeTop = node->getLayout().position[YGEdgeTop]; @@ -83,52 +80,52 @@ void roundLayoutResultsToPixelGrid( const double absoluteNodeRight = absoluteNodeLeft + nodeWidth; const double absoluteNodeBottom = absoluteNodeTop + nodeHeight; - // If a node has a custom measure function we never want to round down its - // size as this could lead to unwanted text truncation. - const bool textRounding = node->getNodeType() == YGNodeTypeText; + if (pointScaleFactor != 0.0f) { + // If a node has a custom measure function we never want to round down its + // size as this could lead to unwanted text truncation. + const bool textRounding = node->getNodeType() == YGNodeTypeText; - node->setLayoutPosition( - roundValueToPixelGrid(nodeLeft, pointScaleFactor, false, textRounding), - YGEdgeLeft); + node->setLayoutPosition( + roundValueToPixelGrid(nodeLeft, pointScaleFactor, false, textRounding), + YGEdgeLeft); - node->setLayoutPosition( - roundValueToPixelGrid(nodeTop, pointScaleFactor, false, textRounding), - YGEdgeTop); + node->setLayoutPosition( + roundValueToPixelGrid(nodeTop, pointScaleFactor, false, textRounding), + YGEdgeTop); - // We multiply dimension by scale factor and if the result is close to the - // whole number, we don't have any fraction To verify if the result is close - // to whole number we want to check both floor and ceil numbers - const bool hasFractionalWidth = - !yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 0) && - !yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0); - const bool hasFractionalHeight = - !yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 0) && - !yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0); + // We multiply dimension by scale factor and if the result is close to the + // whole number, we don't have any fraction To verify if the result is close + // to whole number we want to check both floor and ceil numbers + const bool hasFractionalWidth = + !yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 0) && + !yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0); + const bool hasFractionalHeight = + !yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 0) && + !yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0); - node->setLayoutDimension( - roundValueToPixelGrid( - absoluteNodeRight, - pointScaleFactor, - (textRounding && hasFractionalWidth), - (textRounding && !hasFractionalWidth)) - - roundValueToPixelGrid( - absoluteNodeLeft, pointScaleFactor, false, textRounding), - YGDimensionWidth); + node->setLayoutDimension( + roundValueToPixelGrid( + absoluteNodeRight, + pointScaleFactor, + (textRounding && hasFractionalWidth), + (textRounding && !hasFractionalWidth)) - + roundValueToPixelGrid( + absoluteNodeLeft, pointScaleFactor, false, textRounding), + YGDimensionWidth); - node->setLayoutDimension( - roundValueToPixelGrid( - absoluteNodeBottom, - pointScaleFactor, - (textRounding && hasFractionalHeight), - (textRounding && !hasFractionalHeight)) - - roundValueToPixelGrid( - absoluteNodeTop, pointScaleFactor, false, textRounding), - YGDimensionHeight); + node->setLayoutDimension( + roundValueToPixelGrid( + absoluteNodeBottom, + pointScaleFactor, + (textRounding && hasFractionalHeight), + (textRounding && !hasFractionalHeight)) - + roundValueToPixelGrid( + absoluteNodeTop, pointScaleFactor, false, textRounding), + YGDimensionHeight); + } - const size_t childCount = node->getChildCount(); - for (size_t i = 0; i < childCount; i++) { - roundLayoutResultsToPixelGrid( - node->getChild(i), pointScaleFactor, absoluteNodeLeft, absoluteNodeTop); + for (yoga::Node* child : node->getChildren()) { + roundLayoutResultsToPixelGrid(child, absoluteNodeLeft, absoluteNodeTop); } } diff --git a/yoga/algorithm/PixelGrid.h b/yoga/algorithm/PixelGrid.h index 24cb10d0..6bedd3ac 100644 --- a/yoga/algorithm/PixelGrid.h +++ b/yoga/algorithm/PixelGrid.h @@ -23,7 +23,6 @@ float roundValueToPixelGrid( // Round the layout results of a node and its subtree to the pixel grid. void roundLayoutResultsToPixelGrid( yoga::Node* const node, - const double pointScaleFactor, const double absoluteLeft, const double absoluteTop);