in yoga/Yoga.cpp [1635:1738]
static void YGNodeWithMeasureFuncSetMeasuredDimensions(
const YGNodeRef node,
float availableWidth,
float availableHeight,
const YGMeasureMode widthMeasureMode,
const YGMeasureMode heightMeasureMode,
const float ownerWidth,
const float ownerHeight,
LayoutData& layoutMarkerData,
void* const layoutContext,
const LayoutPassReason reason) {
YGAssertWithNode(
node,
node->hasMeasureFunc(),
"Expected node to have custom measure function");
if (widthMeasureMode == YGMeasureModeUndefined) {
availableWidth = YGUndefined;
}
if (heightMeasureMode == YGMeasureModeUndefined) {
availableHeight = YGUndefined;
}
const auto& padding = node->getLayout().padding;
const auto& border = node->getLayout().border;
const float paddingAndBorderAxisRow = padding[YGEdgeLeft] +
padding[YGEdgeRight] + border[YGEdgeLeft] + border[YGEdgeRight];
const float paddingAndBorderAxisColumn = padding[YGEdgeTop] +
padding[YGEdgeBottom] + border[YGEdgeTop] + border[YGEdgeBottom];
// We want to make sure we don't call measure with negative size
const float innerWidth = YGFloatIsUndefined(availableWidth)
? availableWidth
: YGFloatMax(0, availableWidth - paddingAndBorderAxisRow);
const float innerHeight = YGFloatIsUndefined(availableHeight)
? availableHeight
: YGFloatMax(0, availableHeight - paddingAndBorderAxisColumn);
if (widthMeasureMode == YGMeasureModeExactly &&
heightMeasureMode == YGMeasureModeExactly) {
// Don't bother sizing the text if both dimensions are already defined.
node->setLayoutMeasuredDimension(
YGNodeBoundAxis(
node, YGFlexDirectionRow, availableWidth, ownerWidth, ownerWidth),
YGDimensionWidth);
node->setLayoutMeasuredDimension(
YGNodeBoundAxis(
node,
YGFlexDirectionColumn,
availableHeight,
ownerHeight,
ownerWidth),
YGDimensionHeight);
} else {
Event::publish<Event::MeasureCallbackStart>(node);
// Measure the text under the current constraints.
const YGSize measuredSize = node->measure(
innerWidth,
widthMeasureMode,
innerHeight,
heightMeasureMode,
layoutContext);
layoutMarkerData.measureCallbacks += 1;
layoutMarkerData.measureCallbackReasonsCount[static_cast<size_t>(reason)] +=
1;
Event::publish<Event::MeasureCallbackEnd>(
node,
{layoutContext,
innerWidth,
widthMeasureMode,
innerHeight,
heightMeasureMode,
measuredSize.width,
measuredSize.height,
reason});
node->setLayoutMeasuredDimension(
YGNodeBoundAxis(
node,
YGFlexDirectionRow,
(widthMeasureMode == YGMeasureModeUndefined ||
widthMeasureMode == YGMeasureModeAtMost)
? measuredSize.width + paddingAndBorderAxisRow
: availableWidth,
ownerWidth,
ownerWidth),
YGDimensionWidth);
node->setLayoutMeasuredDimension(
YGNodeBoundAxis(
node,
YGFlexDirectionColumn,
(heightMeasureMode == YGMeasureModeUndefined ||
heightMeasureMode == YGMeasureModeAtMost)
? measuredSize.height + paddingAndBorderAxisColumn
: availableHeight,
ownerHeight,
ownerWidth),
YGDimensionHeight);
}
}