YOGA_EXPORT void YGNodeCalculateLayoutWithContext()

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);
  }
}