Change NodeToString.cpp to output JSON not html #1563

Closed
joevilches wants to merge 3 commits from export-D52929268 into main
20 changed files with 25071 additions and 445 deletions

View File

@@ -76,6 +76,27 @@ jobs:
run: ./build/benchmark run: ./build/benchmark
working-directory: benchmark working-directory: benchmark
capture:
name: Capture [${{ matrix.toolchain }}]
runs-on: ${{ (matrix.toolchain == 'MSVC') && 'windows-latest' || 'ubuntu-latest' }}
strategy:
matrix:
toolchain: [Clang, GCC, MSVC]
steps:
- uses: actions/checkout@v3
- name: Setup
uses: ./.github/actions/setup-cpp
with:
toolchain: ${{ matrix.toolchain }}
- name: Build capture
run: |
cmake -S . -B build -G Ninja -D CMAKE_BUILD_TYPE=Release
cmake --build build
working-directory: capture
clang-format: clang-format:
name: Format name: Format
runs-on: ubuntu-latest runs-on: ubuntu-latest

23
capture/CMakeLists.txt Normal file
View File

@@ -0,0 +1,23 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
cmake_minimum_required(VERSION 3.13...3.26)
project(capture)
set(CMAKE_VERBOSE_MAKEFILE on)
set(YOGA_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
include(${YOGA_ROOT}/cmake/project-defaults.cmake)
add_subdirectory(${YOGA_ROOT}/yoga ${CMAKE_CURRENT_BINARY_DIR}/yoga)
file(GLOB SOURCES CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
add_library(capture STATIC ${SOURCES})
target_link_libraries(capture yogacore)
target_include_directories(capture
PUBLIC
$<BUILD_INTERFACE:${YOGA_ROOT}/lib>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/yoga/lib>)

259
capture/NodeToString.cpp Normal file
View File

@@ -0,0 +1,259 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <capture/NodeToString.h>
#include <nlohmann/json.hpp>
namespace facebook::yoga {
using namespace nlohmann;
static void appendFloatIfNotDefault(
json& j,
std::string_view key,
float num,
float defaultNum) {
if (num != defaultNum && !YGFloatIsUndefined(num)) {
j["style"][key] = num;
}
}
static void appendYGValueIfNotDefault(
json& j,
std::string_view key,
const YGValue& value,
const YGValue& defaultValue) {
if (value != defaultValue) {
if (value.unit == YGUnitAuto) {
j["style"][key]["unit"] = "auto";
} else if (value.unit == YGUnitUndefined) {
j["style"][key]["unit"] = "undefined";
} else {
std::string unit = value.unit == YGUnitPoint ? "px" : "%%";
j["style"][key]["value"] = value.value;
j["style"][key]["unit"] = unit;
}
}
}
static void appendEnumValueIfNotDefault(
json& j,
std::string_view key,
std::string_view value,
std::string_view defaultValue) {
if (value != defaultValue) {
j["style"][key] = value;
}
}
template <auto Field>
static void appendEdges(
json& j,
const std::string& key,
YGNodeRef node,
YGNodeRef defaultNode) {
appendYGValueIfNotDefault(
j,
key + "-left",
(*Field)(node, YGEdgeLeft),
(*Field)(defaultNode, YGEdgeLeft));
appendYGValueIfNotDefault(
j,
key + "-right",
(*Field)(node, YGEdgeRight),
(*Field)(defaultNode, YGEdgeRight));
appendYGValueIfNotDefault(
j,
key + "-top",
(*Field)(node, YGEdgeTop),
(*Field)(defaultNode, YGEdgeTop));
appendYGValueIfNotDefault(
j,
key + "-bottom",
(*Field)(node, YGEdgeBottom),
(*Field)(defaultNode, YGEdgeBottom));
appendYGValueIfNotDefault(
j,
key + "-all",
(*Field)(node, YGEdgeAll),
(*Field)(defaultNode, YGEdgeAll));
appendYGValueIfNotDefault(
j,
key + "-start",
(*Field)(node, YGEdgeStart),
(*Field)(defaultNode, YGEdgeStart));
appendYGValueIfNotDefault(
j,
key + "-end",
(*Field)(node, YGEdgeEnd),
(*Field)(defaultNode, YGEdgeEnd));
appendYGValueIfNotDefault(
j,
key + "-vertical",
(*Field)(node, YGEdgeVertical),
(*Field)(defaultNode, YGEdgeVertical));
appendYGValueIfNotDefault(
j,
key + "-horizontal",
(*Field)(node, YGEdgeHorizontal),
(*Field)(defaultNode, YGEdgeHorizontal));
}
YGValue borderFloatToYGValue(YGNodeRef node, YGEdge edge) {
float val = YGNodeStyleGetBorder(node, edge);
YGUnit unit = YGFloatIsUndefined(val) ? YGUnitUndefined : YGUnitPoint;
return YGValue{val, unit};
}
static void nodeToStringImpl(json& j, YGNodeRef node, YGPrintOptions options) {
if ((options & YGPrintOptionsLayout) == YGPrintOptionsLayout) {
j["layout"]["width"] = YGNodeStyleGetWidth(node).value;
j["layout"]["height"] = YGNodeStyleGetHeight(node).value;
j["layout"]["top"] = YGNodeStyleGetPosition(node, YGEdgeTop).value;
j["layout"]["left"] = YGNodeStyleGetPosition(node, YGEdgeLeft).value;
}
if ((options & YGPrintOptionsStyle) == YGPrintOptionsStyle) {
const YGNodeRef defaultNode = YGNodeNew();
appendEnumValueIfNotDefault(
j,
"flex-direction",
YGFlexDirectionToString(YGNodeStyleGetFlexDirection(node)),
YGFlexDirectionToString(YGNodeStyleGetFlexDirection(defaultNode)));
appendEnumValueIfNotDefault(
j,
"justify-content",
YGJustifyToString(YGNodeStyleGetJustifyContent(node)),
YGJustifyToString(YGNodeStyleGetJustifyContent(defaultNode)));
appendEnumValueIfNotDefault(
j,
"align-items",
YGAlignToString(YGNodeStyleGetAlignItems(node)),
YGAlignToString(YGNodeStyleGetAlignItems(defaultNode)));
appendEnumValueIfNotDefault(
j,
"align-content",
YGAlignToString(YGNodeStyleGetAlignContent(node)),
YGAlignToString(YGNodeStyleGetAlignContent(defaultNode)));
appendEnumValueIfNotDefault(
j,
"align-self",
YGAlignToString(YGNodeStyleGetAlignSelf(node)),
YGAlignToString(YGNodeStyleGetAlignSelf(defaultNode)));
appendEnumValueIfNotDefault(
j,
"flex-wrap",
YGWrapToString(YGNodeStyleGetFlexWrap(node)),
YGWrapToString(YGNodeStyleGetFlexWrap(defaultNode)));
appendEnumValueIfNotDefault(
j,
"overflow",
YGOverflowToString(YGNodeStyleGetOverflow(node)),
YGOverflowToString(YGNodeStyleGetOverflow(defaultNode)));
appendEnumValueIfNotDefault(
j,
"display",
YGDisplayToString(YGNodeStyleGetDisplay(node)),
YGDisplayToString(YGNodeStyleGetDisplay(defaultNode)));
appendEnumValueIfNotDefault(
j,
"position-type",
YGPositionTypeToString(YGNodeStyleGetPositionType(node)),
YGPositionTypeToString(YGNodeStyleGetPositionType(defaultNode)));
appendFloatIfNotDefault(
j,
"flex-grow",
YGNodeStyleGetFlexGrow(node),
YGNodeStyleGetFlexGrow(defaultNode));
appendFloatIfNotDefault(
j,
"flex-shrink",
YGNodeStyleGetFlexShrink(node),
YGNodeStyleGetFlexShrink(defaultNode));
appendFloatIfNotDefault(
j, "flex", YGNodeStyleGetFlex(node), YGNodeStyleGetFlex(defaultNode));
appendYGValueIfNotDefault(
j,
"flex-basis",
YGNodeStyleGetFlexBasis(node),
YGNodeStyleGetFlexBasis(defaultNode));
appendEdges<&YGNodeStyleGetMargin>(j, "margin", node, defaultNode);
appendEdges<&YGNodeStyleGetPadding>(j, "padding", node, defaultNode);
appendEdges<&borderFloatToYGValue>(j, "border", node, defaultNode);
appendEdges<&YGNodeStyleGetPosition>(j, "position", node, defaultNode);
appendFloatIfNotDefault(
j,
"gap",
YGNodeStyleGetGap(node, YGGutterAll),
YGNodeStyleGetGap(defaultNode, YGGutterAll));
appendFloatIfNotDefault(
j,
"column-gap",
YGNodeStyleGetGap(node, YGGutterColumn),
YGNodeStyleGetGap(defaultNode, YGGutterColumn));
appendFloatIfNotDefault(
j,
"row-gap",
YGNodeStyleGetGap(node, YGGutterRow),
YGNodeStyleGetGap(defaultNode, YGGutterRow));
appendYGValueIfNotDefault(
j,
"width",
YGNodeStyleGetWidth(node),
YGNodeStyleGetWidth(defaultNode));
appendYGValueIfNotDefault(
j,
"height",
YGNodeStyleGetHeight(node),
YGNodeStyleGetHeight(defaultNode));
appendYGValueIfNotDefault(
j,
"max-width",
YGNodeStyleGetMaxWidth(node),
YGNodeStyleGetMaxWidth(defaultNode));
appendYGValueIfNotDefault(
j,
"max-height",
YGNodeStyleGetMaxHeight(node),
YGNodeStyleGetMaxHeight(defaultNode));
appendYGValueIfNotDefault(
j,
"min-width",
YGNodeStyleGetMinWidth(node),
YGNodeStyleGetMinWidth(defaultNode));
appendYGValueIfNotDefault(
j,
"min-height",
YGNodeStyleGetMinHeight(node),
YGNodeStyleGetMinHeight(defaultNode));
if (YGNodeHasMeasureFunc(node)) {
j["style"]["has-custom-measure"] = true;
}
}
const size_t childCount = YGNodeGetChildCount(node);
if ((options & YGPrintOptionsChildren) == YGPrintOptionsChildren &&
childCount > 0) {
for (size_t i = 0; i < childCount; i++) {
j["children"].push_back({});
nodeToStringImpl(j["children"][i], YGNodeGetChild(node, i), options);
}
}
}
void nodeToString(std::string& str, YGNodeRef node, YGPrintOptions options) {
json j;
nodeToStringImpl(j, node, options);
str = j.dump(2);
}
} // namespace facebook::yoga

View File

@@ -5,25 +5,14 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#ifdef DEBUG
#pragma once #pragma once
#include <string> #include <string>
#include <yoga/enums/PrintOptions.h> #include <yoga/Yoga.h>
#include <yoga/node/Node.h>
namespace facebook::yoga { namespace facebook::yoga {
void nodeToString( void nodeToString(std::string& str, YGNodeRef node, YGPrintOptions options);
std::string& str,
const yoga::Node* node,
PrintOptions options,
uint32_t level);
void print(const yoga::Node* node, PrintOptions options);
} // namespace facebook::yoga } // namespace facebook::yoga
#endif

View File

@@ -15,8 +15,6 @@ public abstract class YogaConfig {
public abstract void setUseWebDefaults(boolean useWebDefaults); public abstract void setUseWebDefaults(boolean useWebDefaults);
public abstract void setPrintTreeFlag(boolean enable);
public abstract void setPointScaleFactor(float pixelsInPoint); public abstract void setPointScaleFactor(float pixelsInPoint);
public abstract void setErrata(YogaErrata errata); public abstract void setErrata(YogaErrata errata);

View File

@@ -35,10 +35,6 @@ public abstract class YogaConfigJNIBase extends YogaConfig {
YogaNative.jni_YGConfigSetUseWebDefaultsJNI(mNativePointer, useWebDefaults); YogaNative.jni_YGConfigSetUseWebDefaultsJNI(mNativePointer, useWebDefaults);
} }
public void setPrintTreeFlag(boolean enable) {
YogaNative.jni_YGConfigSetPrintTreeFlagJNI(mNativePointer, enable);
}
public void setPointScaleFactor(float pixelsInPoint) { public void setPointScaleFactor(float pixelsInPoint) {
YogaNative.jni_YGConfigSetPointScaleFactorJNI(mNativePointer, pixelsInPoint); YogaNative.jni_YGConfigSetPointScaleFactorJNI(mNativePointer, pixelsInPoint);
} }

View File

@@ -22,7 +22,6 @@ public class YogaNative {
static native void jni_YGConfigFreeJNI(long nativePointer); static native void jni_YGConfigFreeJNI(long nativePointer);
static native void jni_YGConfigSetExperimentalFeatureEnabledJNI(long nativePointer, int feature, boolean enabled); static native void jni_YGConfigSetExperimentalFeatureEnabledJNI(long nativePointer, int feature, boolean enabled);
static native void jni_YGConfigSetUseWebDefaultsJNI(long nativePointer, boolean useWebDefaults); static native void jni_YGConfigSetUseWebDefaultsJNI(long nativePointer, boolean useWebDefaults);
static native void jni_YGConfigSetPrintTreeFlagJNI(long nativePointer, boolean enable);
static native void jni_YGConfigSetPointScaleFactorJNI(long nativePointer, float pixelsInPoint); static native void jni_YGConfigSetPointScaleFactorJNI(long nativePointer, float pixelsInPoint);
static native void jni_YGConfigSetErrataJNI(long nativePointer, int errata); static native void jni_YGConfigSetErrataJNI(long nativePointer, int errata);
static native int jni_YGConfigGetErrataJNI(long nativePointer); static native int jni_YGConfigGetErrataJNI(long nativePointer);
@@ -111,7 +110,6 @@ public class YogaNative {
static native void jni_YGNodeStyleSetGapJNI(long nativePointer, int gutter, float gapLength); static native void jni_YGNodeStyleSetGapJNI(long nativePointer, int gutter, float gapLength);
static native void jni_YGNodeSetHasMeasureFuncJNI(long nativePointer, boolean hasMeasureFunc); static native void jni_YGNodeSetHasMeasureFuncJNI(long nativePointer, boolean hasMeasureFunc);
static native void jni_YGNodeSetHasBaselineFuncJNI(long nativePointer, boolean hasMeasureFunc); static native void jni_YGNodeSetHasBaselineFuncJNI(long nativePointer, boolean hasMeasureFunc);
static native void jni_YGNodePrintJNI(long nativePointer);
static native void jni_YGNodeSetStyleInputsJNI(long nativePointer, float[] styleInputsArray, int size); static native void jni_YGNodeSetStyleInputsJNI(long nativePointer, float[] styleInputsArray, int size);
static native long jni_YGNodeCloneJNI(long nativePointer); static native long jni_YGNodeCloneJNI(long nativePointer);
static native void jni_YGNodeSetAlwaysFormsContainingBlockJNI(long nativePointer, boolean alwaysFormContainingBlock); static native void jni_YGNodeSetAlwaysFormsContainingBlockJNI(long nativePointer, boolean alwaysFormContainingBlock);

View File

@@ -221,8 +221,6 @@ public abstract class YogaNode implements YogaProps {
@Nullable @Nullable
public abstract Object getData(); public abstract Object getData();
public abstract void print();
public abstract YogaNode cloneWithoutChildren(); public abstract YogaNode cloneWithoutChildren();
public abstract YogaNode cloneWithChildren(); public abstract YogaNode cloneWithChildren();

View File

@@ -556,14 +556,6 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
return mData; return mData;
} }
/**
* Use the set logger (defaults to adb log) to print out the styles, children, and computed layout
* of the tree rooted at this node.
*/
public void print() {
YogaNative.jni_YGNodePrintJNI(mNativePointer);
}
/** /**
* This method replaces the child at childIndex position with the newNode received by parameter. * This method replaces the child at childIndex position with the newNode received by parameter.
* This is different than calling removeChildAt and addChildAt because this method ONLY replaces * This is different than calling removeChildAt and addChildAt because this method ONLY replaces

View File

@@ -66,15 +66,6 @@ static void jni_YGConfigSetUseWebDefaultsJNI(
YGConfigSetUseWebDefaults(config, useWebDefaults); YGConfigSetUseWebDefaults(config, useWebDefaults);
} }
static void jni_YGConfigSetPrintTreeFlagJNI(
JNIEnv* /*env*/,
jobject /*obj*/,
jlong nativePointer,
jboolean enable) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
YGConfigSetPrintTreeFlag(config, enable);
}
static void jni_YGConfigSetPointScaleFactorJNI( static void jni_YGConfigSetPointScaleFactorJNI(
JNIEnv* /*env*/, JNIEnv* /*env*/,
jobject /*obj*/, jobject /*obj*/,
@@ -690,18 +681,6 @@ static void jni_YGNodeSetAlwaysFormsContainingBlockJNI(
_jlong2YGNodeRef(nativePointer), alwaysFormsContainingBlock); _jlong2YGNodeRef(nativePointer), alwaysFormsContainingBlock);
} }
static void
jni_YGNodePrintJNI(JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) {
#ifdef DEBUG
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
YGNodePrint(
node,
(YGPrintOptions)(YGPrintOptionsStyle | YGPrintOptionsLayout | YGPrintOptionsChildren));
#else
(void)nativePointer;
#endif
}
static jlong static jlong
jni_YGNodeCloneJNI(JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { jni_YGNodeCloneJNI(JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) {
auto node = _jlong2YGNodeRef(nativePointer); auto node = _jlong2YGNodeRef(nativePointer);
@@ -744,9 +723,6 @@ static JNINativeMethod methods[] = {
{"jni_YGConfigSetUseWebDefaultsJNI", {"jni_YGConfigSetUseWebDefaultsJNI",
"(JZ)V", "(JZ)V",
(void*)jni_YGConfigSetUseWebDefaultsJNI}, (void*)jni_YGConfigSetUseWebDefaultsJNI},
{"jni_YGConfigSetPrintTreeFlagJNI",
"(JZ)V",
(void*)jni_YGConfigSetPrintTreeFlagJNI},
{"jni_YGConfigSetPointScaleFactorJNI", {"jni_YGConfigSetPointScaleFactorJNI",
"(JF)V", "(JF)V",
(void*)jni_YGConfigSetPointScaleFactorJNI}, (void*)jni_YGConfigSetPointScaleFactorJNI},
@@ -970,7 +946,6 @@ static JNINativeMethod methods[] = {
{"jni_YGNodeSetAlwaysFormsContainingBlockJNI", {"jni_YGNodeSetAlwaysFormsContainingBlockJNI",
"(JZ)V", "(JZ)V",
(void*)jni_YGNodeSetAlwaysFormsContainingBlockJNI}, (void*)jni_YGNodeSetAlwaysFormsContainingBlockJNI},
{"jni_YGNodePrintJNI", "(J)V", (void*)jni_YGNodePrintJNI},
{"jni_YGNodeCloneJNI", "(J)J", (void*)jni_YGNodeCloneJNI}, {"jni_YGNodeCloneJNI", "(J)J", (void*)jni_YGNodeCloneJNI},
}; };

24766
lib/nlohmann/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,137 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <gtest/gtest.h>
#include <stdarg.h>
#include <yoga/Yoga.h>
#if DEBUG
namespace {
char writeBuffer[4096];
int _unmanagedLogger(
const YGConfigConstRef /*config*/,
const YGNodeConstRef /*node*/,
YGLogLevel /*level*/,
const char* format,
va_list args) {
return vsnprintf(
writeBuffer + strlen(writeBuffer),
sizeof(writeBuffer) - strlen(writeBuffer),
format,
args);
}
} // namespace
TEST(YogaTest, config_print_tree_enabled) {
writeBuffer[0] = '\0';
const YGConfigRef config = YGConfigNew();
YGConfigSetPrintTreeFlag(config, true);
YGConfigSetLogger(config, _unmanagedLogger);
const YGNodeRef root = YGNodeNewWithConfig(config);
const YGNodeRef child0 = YGNodeNewWithConfig(config);
const YGNodeRef child1 = YGNodeNewWithConfig(config);
YGNodeInsertChild(root, child0, 0);
YGNodeInsertChild(root, child1, 1);
YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR);
YGConfigSetLogger(config, NULL);
YGNodeFreeRecursive(root);
const char* expected =
"<div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"\" >\n "
"<div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"\" "
"></div>\n <div layout=\"width: 0; height: 0; top: 0; left: 0;\" "
"style=\"\" ></div>\n</div>";
ASSERT_STREQ(expected, writeBuffer);
}
TEST(YogaTest, config_print_tree_disabled) {
writeBuffer[0] = '\0';
const YGConfigRef config = YGConfigNew();
YGConfigSetPrintTreeFlag(config, false);
YGConfigSetLogger(config, _unmanagedLogger);
const YGNodeRef root = YGNodeNewWithConfig(config);
const YGNodeRef child0 = YGNodeNewWithConfig(config);
const YGNodeRef child1 = YGNodeNewWithConfig(config);
YGNodeInsertChild(root, child0, 0);
YGNodeInsertChild(root, child1, 1);
YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR);
YGConfigSetLogger(config, NULL);
YGNodeFreeRecursive(root);
const char* expected = "";
ASSERT_STREQ(expected, writeBuffer);
}
TEST(YogaTest, logger_default_node_should_print_no_style_info) {
writeBuffer[0] = '\0';
const YGConfigRef config = YGConfigNew();
YGConfigSetLogger(config, _unmanagedLogger);
const YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR);
YGNodePrint(
root,
(YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle));
YGConfigSetLogger(config, NULL);
YGNodeFree(root);
const char* expected =
"<div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"\" "
"></div>";
ASSERT_STREQ(expected, writeBuffer);
}
TEST(YogaTest, logger_node_with_percentage_absolute_position_and_margin) {
writeBuffer[0] = '\0';
const YGConfigRef config = YGConfigNew();
YGConfigSetLogger(config, _unmanagedLogger);
const YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidthPercent(root, 50);
YGNodeStyleSetHeightPercent(root, 75);
YGNodeStyleSetFlex(root, 1);
YGNodeStyleSetMargin(root, YGEdgeRight, 10);
YGNodeStyleSetMarginAuto(root, YGEdgeLeft);
YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR);
YGNodePrint(
root,
(YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle));
YGConfigSetLogger(config, NULL);
YGNodeFree(root);
const char* expected =
"<div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"flex: 1; "
"margin-left: auto; margin-right: 10px; width: 50%; height: 75%; "
"position: absolute; \" ></div>";
ASSERT_STREQ(expected, writeBuffer);
}
TEST(YogaTest, logger_node_with_children_should_print_indented) {
writeBuffer[0] = '\0';
const YGConfigRef config = YGConfigNew();
YGConfigSetLogger(config, _unmanagedLogger);
const YGNodeRef root = YGNodeNewWithConfig(config);
const YGNodeRef child0 = YGNodeNewWithConfig(config);
const YGNodeRef child1 = YGNodeNewWithConfig(config);
YGNodeInsertChild(root, child0, 0);
YGNodeInsertChild(root, child1, 1);
YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR);
YGNodePrint(
root,
(YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle));
YGConfigSetLogger(config, NULL);
YGNodeFreeRecursive(root);
const char* expected =
"<div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"\" >\n "
"<div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"\" "
"></div>\n <div layout=\"width: 0; height: 0; top: 0; left: 0;\" "
"style=\"\" ></div>\n</div>";
ASSERT_STREQ(expected, writeBuffer);
}
#endif

View File

@@ -90,7 +90,3 @@ void YGConfigSetCloneNodeFunc(
const YGCloneNodeFunc callback) { const YGCloneNodeFunc callback) {
resolveRef(config)->setCloneNodeCallback(callback); resolveRef(config)->setCloneNodeCallback(callback);
} }
void YGConfigSetPrintTreeFlag(YGConfigRef config, bool enabled) {
resolveRef(config)->setShouldPrintTree(enabled);
}

View File

@@ -155,9 +155,4 @@ YG_EXPORT void YGConfigSetCloneNodeFunc(
YGConfigRef config, YGConfigRef config,
YGCloneNodeFunc callback); YGCloneNodeFunc callback);
/**
* Allows printing the Yoga node tree during layout for debugging purposes.
*/
YG_EXPORT void YGConfigSetPrintTreeFlag(YGConfigRef config, bool enabled);
YG_EXTERN_C_END YG_EXTERN_C_END

View File

@@ -11,7 +11,6 @@
#include <yoga/algorithm/CalculateLayout.h> #include <yoga/algorithm/CalculateLayout.h>
#include <yoga/debug/AssertFatal.h> #include <yoga/debug/AssertFatal.h>
#include <yoga/debug/Log.h> #include <yoga/debug/Log.h>
#include <yoga/debug/NodeToString.h>
#include <yoga/event/event.h> #include <yoga/event/event.h>
#include <yoga/node/Node.h> #include <yoga/node/Node.h>
@@ -330,12 +329,6 @@ void YGNodeSetAlwaysFormsContainingBlock(
resolveRef(node)->setAlwaysFormsContainingBlock(alwaysFormsContainingBlock); resolveRef(node)->setAlwaysFormsContainingBlock(alwaysFormsContainingBlock);
} }
#ifdef DEBUG
void YGNodePrint(const YGNodeConstRef node, const YGPrintOptions options) {
yoga::print(resolveRef(node), scopedEnum(options));
}
#endif
// TODO: This leaks internal details to the public API. Remove after removing // TODO: This leaks internal details to the public API. Remove after removing
// ComponentKit usage of it. // ComponentKit usage of it.
bool YGNodeCanUseCachedMeasurement( bool YGNodeCanUseCachedMeasurement(

View File

@@ -273,11 +273,6 @@ YG_EXPORT void YGNodeSetAlwaysFormsContainingBlock(
YGNodeRef node, YGNodeRef node,
bool alwaysFormsContainingBlock); bool alwaysFormsContainingBlock);
/**
* Print a node to log output.
*/
YG_EXPORT void YGNodePrint(YGNodeConstRef node, YGPrintOptions options);
/** /**
* @deprecated * @deprecated
*/ */

View File

@@ -26,7 +26,6 @@
#include <yoga/algorithm/TrailingPosition.h> #include <yoga/algorithm/TrailingPosition.h>
#include <yoga/debug/AssertFatal.h> #include <yoga/debug/AssertFatal.h>
#include <yoga/debug/Log.h> #include <yoga/debug/Log.h>
#include <yoga/debug/NodeToString.h>
#include <yoga/event/event.h> #include <yoga/event/event.h>
#include <yoga/node/Node.h> #include <yoga/node/Node.h>
#include <yoga/numeric/Comparison.h> #include <yoga/numeric/Comparison.h>
@@ -2366,14 +2365,6 @@ void calculateLayout(
node->setPosition( node->setPosition(
node->getLayout().direction(), ownerWidth, ownerHeight, ownerWidth); node->getLayout().direction(), ownerWidth, ownerHeight, ownerWidth);
roundLayoutResultsToPixelGrid(node, 0.0f, 0.0f); roundLayoutResultsToPixelGrid(node, 0.0f, 0.0f);
#ifdef DEBUG
if (node->getConfig()->shouldPrintTree()) {
yoga::print(
node,
PrintOptions::Layout | PrintOptions::Children | PrintOptions::Style);
}
#endif
} }
Event::publish<Event::LayoutPassEnd>(node, {&markerData}); Event::publish<Event::LayoutPassEnd>(node, {&markerData});

View File

@@ -32,14 +32,6 @@ bool Config::useWebDefaults() const {
return useWebDefaults_; return useWebDefaults_;
} }
void Config::setShouldPrintTree(bool printTree) {
printTree_ = printTree;
}
bool Config::shouldPrintTree() const {
return printTree_;
}
void Config::setExperimentalFeatureEnabled( void Config::setExperimentalFeatureEnabled(
ExperimentalFeature feature, ExperimentalFeature feature,
bool enabled) { bool enabled) {

View File

@@ -37,9 +37,6 @@ class YG_EXPORT Config : public ::YGConfig {
void setUseWebDefaults(bool useWebDefaults); void setUseWebDefaults(bool useWebDefaults);
bool useWebDefaults() const; bool useWebDefaults() const;
void setShouldPrintTree(bool printTree);
bool shouldPrintTree() const;
void setExperimentalFeatureEnabled(ExperimentalFeature feature, bool enabled); void setExperimentalFeatureEnabled(ExperimentalFeature feature, bool enabled);
bool isExperimentalFeatureEnabled(ExperimentalFeature feature) const; bool isExperimentalFeatureEnabled(ExperimentalFeature feature) const;
ExperimentalFeatureSet getEnabledExperiments() const; ExperimentalFeatureSet getEnabledExperiments() const;
@@ -74,7 +71,6 @@ class YG_EXPORT Config : public ::YGConfig {
YGLogger logger_; YGLogger logger_;
bool useWebDefaults_ : 1 = false; bool useWebDefaults_ : 1 = false;
bool printTree_ : 1 = false;
ExperimentalFeatureSet experimentalFeatures_{}; ExperimentalFeatureSet experimentalFeatures_{};
Errata errata_ = Errata::None; Errata errata_ = Errata::None;

View File

@@ -1,210 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#ifdef DEBUG
#include <stdarg.h>
#include <yoga/debug/Log.h>
#include <yoga/debug/NodeToString.h>
#include <yoga/numeric/Comparison.h>
namespace facebook::yoga {
static void indent(std::string& base, uint32_t level) {
for (uint32_t i = 0; i < level; ++i) {
base.append(" ");
}
}
static void appendFormattedString(std::string& str, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
va_list argsCopy;
va_copy(argsCopy, args);
std::vector<char> buf(1 + static_cast<size_t>(vsnprintf(NULL, 0, fmt, args)));
va_end(args);
vsnprintf(buf.data(), buf.size(), fmt, argsCopy);
va_end(argsCopy);
std::string result = std::string(buf.begin(), buf.end() - 1);
str.append(result);
}
static void appendFloatOptionalIfDefined(
std::string& base,
const std::string key,
const FloatOptional num) {
if (num.isDefined()) {
appendFormattedString(base, "%s: %g; ", key.c_str(), num.unwrap());
}
}
static void appendNumberIfNotUndefined(
std::string& base,
const std::string key,
const Style::Length& number) {
if (number.unit() != Unit::Undefined) {
if (number.unit() == Unit::Auto) {
base.append(key + ": auto; ");
} else {
std::string unit = number.unit() == Unit::Point ? "px" : "%%";
appendFormattedString(
base,
"%s: %g%s; ",
key.c_str(),
number.value().unwrap(),
unit.c_str());
}
}
}
static void appendNumberIfNotAuto(
std::string& base,
const std::string& key,
const Style::Length& number) {
if (number.unit() != Unit::Auto) {
appendNumberIfNotUndefined(base, key, number);
}
}
static void appendNumberIfNotZero(
std::string& base,
const std::string& str,
const Style::Length& number) {
if (number.unit() == Unit::Auto) {
base.append(str + ": auto; ");
} else if (!yoga::inexactEquals(number.value().unwrap(), 0)) {
appendNumberIfNotUndefined(base, str, number);
}
}
template <auto Field>
static void
appendEdges(std::string& base, const std::string& key, const Style& style) {
for (auto edge : ordinals<Edge>()) {
std::string str = key + "-" + toString(edge);
appendNumberIfNotZero(base, str, (style.*Field)(edge));
}
}
void nodeToString(
std::string& str,
const yoga::Node* node,
PrintOptions options,
uint32_t level) {
indent(str, level);
appendFormattedString(str, "<div ");
if ((options & PrintOptions::Layout) == PrintOptions::Layout) {
appendFormattedString(str, "layout=\"");
appendFormattedString(
str, "width: %g; ", node->getLayout().dimension(Dimension::Width));
appendFormattedString(
str, "height: %g; ", node->getLayout().dimension(Dimension::Height));
appendFormattedString(
str, "top: %g; ", node->getLayout().position(PhysicalEdge::Top));
appendFormattedString(
str, "left: %g;", node->getLayout().position(PhysicalEdge::Left));
appendFormattedString(str, "\" ");
}
if ((options & PrintOptions::Style) == PrintOptions::Style) {
appendFormattedString(str, "style=\"");
const auto& style = node->style();
if (style.flexDirection() != yoga::Style{}.flexDirection()) {
appendFormattedString(
str, "flex-direction: %s; ", toString(style.flexDirection()));
}
if (style.justifyContent() != yoga::Style{}.justifyContent()) {
appendFormattedString(
str, "justify-content: %s; ", toString(style.justifyContent()));
}
if (style.alignItems() != yoga::Style{}.alignItems()) {
appendFormattedString(
str, "align-items: %s; ", toString(style.alignItems()));
}
if (style.alignContent() != yoga::Style{}.alignContent()) {
appendFormattedString(
str, "align-content: %s; ", toString(style.alignContent()));
}
if (style.alignSelf() != yoga::Style{}.alignSelf()) {
appendFormattedString(
str, "align-self: %s; ", toString(style.alignSelf()));
}
appendFloatOptionalIfDefined(str, "flex-grow", style.flexGrow());
appendFloatOptionalIfDefined(str, "flex-shrink", style.flexShrink());
appendNumberIfNotAuto(str, "flex-basis", style.flexBasis());
appendFloatOptionalIfDefined(str, "flex", style.flex());
if (style.flexWrap() != yoga::Style{}.flexWrap()) {
appendFormattedString(str, "flex-wrap: %s; ", toString(style.flexWrap()));
}
if (style.overflow() != yoga::Style{}.overflow()) {
appendFormattedString(str, "overflow: %s; ", toString(style.overflow()));
}
if (style.display() != yoga::Style{}.display()) {
appendFormattedString(str, "display: %s; ", toString(style.display()));
}
appendEdges<&Style::margin>(str, "margin", style);
appendEdges<&Style::padding>(str, "padding", style);
appendEdges<&Style::border>(str, "border", style);
if (style.gap(Gutter::All).isDefined()) {
appendNumberIfNotUndefined(str, "gap", style.gap(Gutter::All));
} else {
appendNumberIfNotUndefined(str, "column-gap", style.gap(Gutter::Column));
appendNumberIfNotUndefined(str, "row-gap", style.gap(Gutter::Row));
}
appendNumberIfNotAuto(str, "width", style.dimension(Dimension::Width));
appendNumberIfNotAuto(str, "height", style.dimension(Dimension::Height));
appendNumberIfNotAuto(
str, "max-width", style.maxDimension(Dimension::Width));
appendNumberIfNotAuto(
str, "max-height", style.maxDimension(Dimension::Height));
appendNumberIfNotAuto(
str, "min-width", style.minDimension(Dimension::Width));
appendNumberIfNotAuto(
str, "min-height", style.minDimension(Dimension::Height));
if (style.positionType() != yoga::Style{}.positionType()) {
appendFormattedString(
str, "position: %s; ", toString(style.positionType()));
}
appendEdges<&Style::position>(str, "position", style);
appendFormattedString(str, "\" ");
if (node->hasMeasureFunc()) {
appendFormattedString(str, "has-custom-measure=\"true\"");
}
}
appendFormattedString(str, ">");
const size_t childCount = node->getChildCount();
if ((options & PrintOptions::Children) == PrintOptions::Children &&
childCount > 0) {
for (size_t i = 0; i < childCount; i++) {
appendFormattedString(str, "\n");
nodeToString(str, node->getChild(i), options, level + 1);
}
appendFormattedString(str, "\n");
indent(str, level);
}
appendFormattedString(str, "</div>");
}
void print(const yoga::Node* node, PrintOptions options) {
std::string str;
yoga::nodeToString(str, node, options, 0);
yoga::log(node, LogLevel::Debug, str.c_str());
}
} // namespace facebook::yoga
#endif