in yoga/Yoga.cpp [4118:4264]
YOGA_EXPORT void YGNodeCalculateLayoutWithContext(
const YGNodeRef node,
const float ownerWidth,
const float ownerHeight,
const YGDirection ownerDirection,
void* layoutContext) {
Event::publish<Event::LayoutPassStart>(node, {layoutContext});
LayoutData markerData = {};
// Increment the generation count. This will force the recursive routine to
// visit all dirty nodes at least once. Subsequent visits will be skipped if
// the input parameters don't change.
gCurrentGenerationCount.fetch_add(1, std::memory_order_relaxed);
node->resolveDimension();
float width = YGUndefined;
YGMeasureMode widthMeasureMode = YGMeasureModeUndefined;
const auto& maxDimensions = node->getStyle().maxDimensions();
if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) {
width =
(YGResolveValue(
node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) +
node->getMarginForAxis(YGFlexDirectionRow, ownerWidth))
.unwrap();
widthMeasureMode = YGMeasureModeExactly;
} else if (!YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth)
.isUndefined()) {
width =
YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap();
widthMeasureMode = YGMeasureModeAtMost;
} else {
width = ownerWidth;
widthMeasureMode = YGFloatIsUndefined(width) ? YGMeasureModeUndefined
: YGMeasureModeExactly;
}
float height = YGUndefined;
YGMeasureMode heightMeasureMode = YGMeasureModeUndefined;
if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) {
height = (YGResolveValue(
node->getResolvedDimension(dim[YGFlexDirectionColumn]),
ownerHeight) +
node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth))
.unwrap();
heightMeasureMode = YGMeasureModeExactly;
} else if (!YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight)
.isUndefined()) {
height =
YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight).unwrap();
heightMeasureMode = YGMeasureModeAtMost;
} else {
height = ownerHeight;
heightMeasureMode = YGFloatIsUndefined(height) ? YGMeasureModeUndefined
: YGMeasureModeExactly;
}
if (YGLayoutNodeInternal(
node,
width,
height,
ownerDirection,
widthMeasureMode,
heightMeasureMode,
ownerWidth,
ownerHeight,
true,
LayoutPassReason::kInitial,
node->getConfig(),
markerData,
layoutContext,
0, // tree root
gCurrentGenerationCount.load(std::memory_order_relaxed))) {
node->setPosition(
node->getLayout().direction(), ownerWidth, ownerHeight, ownerWidth);
YGRoundToPixelGrid(node, node->getConfig()->pointScaleFactor, 0.0f, 0.0f);
#ifdef DEBUG
if (node->getConfig()->printTree) {
YGNodePrint(
node,
(YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle));
}
#endif
}
Event::publish<Event::LayoutPassEnd>(node, {layoutContext, &markerData});
// We want to get rid off `useLegacyStretchBehaviour` from YGConfig. But we
// aren't sure whether client's of yoga have gotten rid off this flag or not.
// So logging this in YGLayout would help to find out the call sites depending
// on this flag. This check would be removed once we are sure no one is
// dependent on this flag anymore. The flag
// `shouldDiffLayoutWithoutLegacyStretchBehaviour` in YGConfig will help to
// run experiments.
if (node->getConfig()->shouldDiffLayoutWithoutLegacyStretchBehaviour &&
node->didUseLegacyFlag()) {
const YGNodeRef nodeWithoutLegacyFlag = YGNodeDeepClone(node);
nodeWithoutLegacyFlag->resolveDimension();
// Recursively mark nodes as dirty
nodeWithoutLegacyFlag->markDirtyAndPropogateDownwards();
gCurrentGenerationCount.fetch_add(1, std::memory_order_relaxed);
// Rerun the layout, and calculate the diff
unsetUseLegacyFlagRecursively(nodeWithoutLegacyFlag);
LayoutData layoutMarkerData = {};
if (YGLayoutNodeInternal(
nodeWithoutLegacyFlag,
width,
height,
ownerDirection,
widthMeasureMode,
heightMeasureMode,
ownerWidth,
ownerHeight,
true,
LayoutPassReason::kInitial,
nodeWithoutLegacyFlag->getConfig(),
layoutMarkerData,
layoutContext,
0, // tree root
gCurrentGenerationCount.load(std::memory_order_relaxed))) {
nodeWithoutLegacyFlag->setPosition(
nodeWithoutLegacyFlag->getLayout().direction(),
ownerWidth,
ownerHeight,
ownerWidth);
YGRoundToPixelGrid(
nodeWithoutLegacyFlag,
nodeWithoutLegacyFlag->getConfig()->pointScaleFactor,
0.0f,
0.0f);
// Set whether the two layouts are different or not.
auto neededLegacyStretchBehaviour =
!nodeWithoutLegacyFlag->isLayoutTreeEqualToNode(*node);
node->setLayoutDoesLegacyFlagAffectsLayout(neededLegacyStretchBehaviour);
#ifdef DEBUG
if (nodeWithoutLegacyFlag->getConfig()->printTree) {
YGNodePrint(
nodeWithoutLegacyFlag,
(YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle));
}
#endif
}
YGConfigFreeRecursive(nodeWithoutLegacyFlag);
YGNodeFreeRecursive(nodeWithoutLegacyFlag);
}
}