static void YGTransferLayoutOutputsRecursive()

in java/jni/YGJNIVanilla.cpp [271:355]


static void YGTransferLayoutOutputsRecursive(
    JNIEnv* env,
    jobject thiz,
    YGNodeRef root,
    void* layoutContext) {
  if (!root->getHasNewLayout()) {
    return;
  }
  auto obj = YGNodeJobject(root, layoutContext);
  if (!obj) {
    Log::log(
        root,
        YGLogLevelError,
        nullptr,
        "Java YGNode was GCed during layout calculation\n");
    return;
  }

  auto edgesSet = YGNodeEdges{root};

  bool marginFieldSet = edgesSet.has(YGNodeEdges::MARGIN);
  bool paddingFieldSet = edgesSet.has(YGNodeEdges::PADDING);
  bool borderFieldSet = edgesSet.has(YGNodeEdges::BORDER);

  int fieldFlags = edgesSet.get();
  fieldFlags |= HAS_NEW_LAYOUT;
  if (YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(root)) {
    fieldFlags |= DOES_LEGACY_STRETCH_BEHAVIOUR;
  }

  const int arrSize = 6 + (marginFieldSet ? 4 : 0) + (paddingFieldSet ? 4 : 0) +
      (borderFieldSet ? 4 : 0);
  float arr[18];
  arr[LAYOUT_EDGE_SET_FLAG_INDEX] = fieldFlags;
  arr[LAYOUT_WIDTH_INDEX] = YGNodeLayoutGetWidth(root);
  arr[LAYOUT_HEIGHT_INDEX] = YGNodeLayoutGetHeight(root);
  arr[LAYOUT_LEFT_INDEX] = YGNodeLayoutGetLeft(root);
  arr[LAYOUT_TOP_INDEX] = YGNodeLayoutGetTop(root);
  arr[LAYOUT_DIRECTION_INDEX] =
      static_cast<jint>(YGNodeLayoutGetDirection(root));
  if (marginFieldSet) {
    arr[LAYOUT_MARGIN_START_INDEX] = YGNodeLayoutGetMargin(root, YGEdgeLeft);
    arr[LAYOUT_MARGIN_START_INDEX + 1] = YGNodeLayoutGetMargin(root, YGEdgeTop);
    arr[LAYOUT_MARGIN_START_INDEX + 2] =
        YGNodeLayoutGetMargin(root, YGEdgeRight);
    arr[LAYOUT_MARGIN_START_INDEX + 3] =
        YGNodeLayoutGetMargin(root, YGEdgeBottom);
  }
  if (paddingFieldSet) {
    int paddingStartIndex =
        LAYOUT_PADDING_START_INDEX - (marginFieldSet ? 0 : 4);
    arr[paddingStartIndex] = YGNodeLayoutGetPadding(root, YGEdgeLeft);
    arr[paddingStartIndex + 1] = YGNodeLayoutGetPadding(root, YGEdgeTop);
    arr[paddingStartIndex + 2] = YGNodeLayoutGetPadding(root, YGEdgeRight);
    arr[paddingStartIndex + 3] = YGNodeLayoutGetPadding(root, YGEdgeBottom);
  }

  if (borderFieldSet) {
    int borderStartIndex = LAYOUT_BORDER_START_INDEX -
        (marginFieldSet ? 0 : 4) - (paddingFieldSet ? 0 : 4);
    arr[borderStartIndex] = YGNodeLayoutGetBorder(root, YGEdgeLeft);
    arr[borderStartIndex + 1] = YGNodeLayoutGetBorder(root, YGEdgeTop);
    arr[borderStartIndex + 2] = YGNodeLayoutGetBorder(root, YGEdgeRight);
    arr[borderStartIndex + 3] = YGNodeLayoutGetBorder(root, YGEdgeBottom);
  }

  // Don't change this field name without changing the name of the field in
  // Database.java
  auto objectClass = facebook::yoga::vanillajni::make_local_ref(
      env, env->GetObjectClass(obj.get()));
  static const jfieldID arrField = facebook::yoga::vanillajni::getFieldId(
      env, objectClass.get(), "arr", "[F");

  ScopedLocalRef<jfloatArray> arrFinal =
      make_local_ref(env, env->NewFloatArray(arrSize));
  env->SetFloatArrayRegion(arrFinal.get(), 0, arrSize, arr);
  env->SetObjectField(obj.get(), arrField, arrFinal.get());

  root->setHasNewLayout(false);

  for (uint32_t i = 0; i < YGNodeGetChildCount(root); i++) {
    YGTransferLayoutOutputsRecursive(
        env, thiz, YGNodeGetChild(root, i), layoutContext);
  }
}