diff --git a/yoga/Yoga.c b/yoga/Yoga.c
index 84aa5a75..597fe417 100644
--- a/yoga/Yoga.c
+++ b/yoga/Yoga.c
@@ -839,53 +839,84 @@ static inline bool YGFloatsEqual(const float a, const float b) {
return fabs(a - b) < 0.0001f;
}
-static void YGIndent(const YGNodeRef node, const uint32_t n) {
+typedef struct YGStringStream {
+ char *str;
+ uint32_t length;
+ uint32_t capacity;
+} YGStringStream;
+
+static void YGWriteToStringStream(YGStringStream *stream, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ va_list argsCopy;
+ va_copy(argsCopy, args);
+ int available = stream->capacity - stream->length;
+ int required = vsnprintf(NULL, 0, format, args);
+ va_end(args);
+ if (required >= available) {
+ char *newStr = (char *) realloc(stream->str, sizeof(char) * (stream->capacity) * 2);
+ if (newStr != NULL) {
+ stream->str = newStr;
+ stream->capacity *= 2;
+ available = stream->capacity - stream->length;
+ }
+ };
+ vsnprintf(stream->str + stream->length, available, format, argsCopy);
+ if (required < available) {
+ stream->length += required;
+ } else {
+ stream->length = stream->capacity - 1;
+ }
+ va_end(argsCopy);
+}
+
+static void YGIndent(YGStringStream *stream, const uint32_t n) {
for (uint32_t i = 0; i < n; i++) {
- YGLog(node, YGLogLevelDebug, " ");
+ YGWriteToStringStream(stream, " ");
}
}
-static void YGPrintNumberIfNotUndefinedf(const YGNodeRef node,
+static void YGPrintNumberIfNotUndefinedf(YGStringStream *stream,
const char *str,
const float number) {
if (!YGFloatIsUndefined(number)) {
- YGLog(node, YGLogLevelDebug, "%s: %g; ", str, number);
+ YGWriteToStringStream(stream, "%s: %g; ", str, number);
}
}
-static void YGPrintNumberIfNotUndefined(const YGNodeRef node,
+static void YGPrintNumberIfNotUndefined(YGStringStream *stream,
const char *str,
const YGValue *const number) {
if (number->unit != YGUnitUndefined) {
if (number->unit == YGUnitAuto) {
- YGLog(node, YGLogLevelDebug, "%s: auto; ", str);
+ YGWriteToStringStream(stream, "%s: auto; ", str);
} else {
- const char *unit = number->unit == YGUnitPoint ? "px" : "%";
- YGLog(node, YGLogLevelDebug, "%s: %g%s; ", str, number->value, unit);
+ const char *unit = number->unit == YGUnitPoint ? "px" : "%%";
+ YGWriteToStringStream(stream, "%s: %g%s; ", str, number->value, unit);
}
}
}
-static void YGPrintNumberIfNotAuto(const YGNodeRef node,
+static void YGPrintNumberIfNotAuto(YGStringStream *stream,
const char *str,
const YGValue *const number) {
if (number->unit != YGUnitAuto) {
- YGPrintNumberIfNotUndefined(node, str, number);
+ YGPrintNumberIfNotUndefined(stream, str, number);
}
}
-static void YGPrintEdgeIfNotUndefined(const YGNodeRef node,
+static void YGPrintEdgeIfNotUndefined(YGStringStream *stream,
const char *str,
const YGValue *edges,
const YGEdge edge) {
- YGPrintNumberIfNotUndefined(node, str, YGComputedEdgeValue(edges, edge, &YGValueUndefined));
+ YGPrintNumberIfNotUndefined(stream, str, YGComputedEdgeValue(edges, edge, &YGValueUndefined));
}
-static void YGPrintNumberIfNotZero(const YGNodeRef node,
+static void YGPrintNumberIfNotZero(YGStringStream *stream,
const char *str,
const YGValue *const number) {
if (!YGFloatsEqual(number->value, 0)) {
- YGPrintNumberIfNotUndefined(node, str, number);
+ YGPrintNumberIfNotUndefined(stream, str, number);
}
}
@@ -894,122 +925,133 @@ static bool YGFourValuesEqual(const YGValue four[4]) {
YGValueEqual(four[0], four[3]);
}
-static void YGPrintEdges(const YGNodeRef node, const char *str, const YGValue *edges) {
+static void YGPrintEdges(YGStringStream *stream, const char *str, const YGValue *edges) {
if (YGFourValuesEqual(edges)) {
- YGPrintNumberIfNotZero(node, str, &edges[YGEdgeLeft]);
+ YGPrintNumberIfNotZero(stream, str, &edges[YGEdgeLeft]);
} else {
for (YGEdge edge = YGEdgeLeft; edge < YGEdgeCount; edge++) {
char buf[30];
snprintf(buf, sizeof(buf), "%s-%s", str, YGEdgeToString(edge));
- YGPrintNumberIfNotZero(node, buf, &edges[edge]);
+ YGPrintNumberIfNotZero(stream, buf, &edges[edge]);
}
}
}
-static void YGNodePrintInternal(const YGNodeRef node,
- const YGPrintOptions options,
- const uint32_t level) {
- YGIndent(node, level);
- YGLog(node, YGLogLevelDebug, "
print) {
node->print(node);
}
if (options & YGPrintOptionsLayout) {
- YGLog(node, YGLogLevelDebug, "layout=\"");
- YGLog(node, YGLogLevelDebug, "width: %g; ", node->layout.dimensions[YGDimensionWidth]);
- YGLog(node, YGLogLevelDebug, "height: %g; ", node->layout.dimensions[YGDimensionHeight]);
- YGLog(node, YGLogLevelDebug, "top: %g; ", node->layout.position[YGEdgeTop]);
- YGLog(node, YGLogLevelDebug, "left: %g;", node->layout.position[YGEdgeLeft]);
- YGLog(node, YGLogLevelDebug, "\" ");
+ YGWriteToStringStream(stream, "layout=\"");
+ YGWriteToStringStream(stream, "width: %g; ", node->layout.dimensions[YGDimensionWidth]);
+ YGWriteToStringStream(stream, "height: %g; ", node->layout.dimensions[YGDimensionHeight]);
+ YGWriteToStringStream(stream, "top: %g; ", node->layout.position[YGEdgeTop]);
+ YGWriteToStringStream(stream, "left: %g;", node->layout.position[YGEdgeLeft]);
+ YGWriteToStringStream(stream, "\" ");
}
if (options & YGPrintOptionsStyle) {
- YGLog(node, YGLogLevelDebug, "style=\"");
+ YGWriteToStringStream(stream, "style=\"");
if (node->style.flexDirection != gYGNodeDefaults.style.flexDirection) {
- YGLog(node,
- YGLogLevelDebug,
- "flex-direction: %s; ",
- YGFlexDirectionToString(node->style.flexDirection));
+ YGWriteToStringStream(stream,
+ "flex-direction: %s; ",
+ YGFlexDirectionToString(node->style.flexDirection));
}
if (node->style.justifyContent != gYGNodeDefaults.style.justifyContent) {
- YGLog(node,
- YGLogLevelDebug,
- "justify-content: %s; ",
- YGJustifyToString(node->style.justifyContent));
+ YGWriteToStringStream(stream,
+ "justify-content: %s; ",
+ YGJustifyToString(node->style.justifyContent));
}
if (node->style.alignItems != gYGNodeDefaults.style.alignItems) {
- YGLog(node, YGLogLevelDebug, "align-items: %s; ", YGAlignToString(node->style.alignItems));
+ YGWriteToStringStream(stream, "align-items: %s; ", YGAlignToString(node->style.alignItems));
}
if (node->style.alignContent != gYGNodeDefaults.style.alignContent) {
- YGLog(node, YGLogLevelDebug, "align-content: %s; ", YGAlignToString(node->style.alignContent));
+ YGWriteToStringStream(stream, "align-content: %s; ", YGAlignToString(node->style.alignContent));
}
if (node->style.alignSelf != gYGNodeDefaults.style.alignSelf) {
- YGLog(node, YGLogLevelDebug, "align-self: %s; ", YGAlignToString(node->style.alignSelf));
+ YGWriteToStringStream(stream, "align-self: %s; ", YGAlignToString(node->style.alignSelf));
}
- YGPrintNumberIfNotUndefinedf(node, "flex-grow", node->style.flexGrow);
- YGPrintNumberIfNotUndefinedf(node, "flex-shrink", node->style.flexShrink);
- YGPrintNumberIfNotAuto(node, "flex-basis", &node->style.flexBasis);
- YGPrintNumberIfNotUndefinedf(node, "flex", node->style.flex);
+ YGPrintNumberIfNotUndefinedf(stream, "flex-grow", node->style.flexGrow);
+ YGPrintNumberIfNotUndefinedf(stream, "flex-shrink", node->style.flexShrink);
+ YGPrintNumberIfNotAuto(stream, "flex-basis", &node->style.flexBasis);
+ YGPrintNumberIfNotUndefinedf(stream, "flex", node->style.flex);
if (node->style.flexWrap != gYGNodeDefaults.style.flexWrap) {
- YGLog(node, YGLogLevelDebug, "flexWrap: %s; ", YGWrapToString(node->style.flexWrap));
+ YGWriteToStringStream(stream, "flexWrap: %s; ", YGWrapToString(node->style.flexWrap));
}
if (node->style.overflow != gYGNodeDefaults.style.overflow) {
- YGLog(node, YGLogLevelDebug, "overflow: %s; ", YGOverflowToString(node->style.overflow));
+ YGWriteToStringStream(stream, "overflow: %s; ", YGOverflowToString(node->style.overflow));
}
if (node->style.display != gYGNodeDefaults.style.display) {
- YGLog(node, YGLogLevelDebug, "display: %s; ", YGDisplayToString(node->style.display));
+ YGWriteToStringStream(stream, "display: %s; ", YGDisplayToString(node->style.display));
}
- YGPrintEdges(node, "margin", node->style.margin);
- YGPrintEdges(node, "padding", node->style.padding);
- YGPrintEdges(node, "border", node->style.border);
+ YGPrintEdges(stream, "margin", node->style.margin);
+ YGPrintEdges(stream, "padding", node->style.padding);
+ YGPrintEdges(stream, "border", node->style.border);
- YGPrintNumberIfNotAuto(node, "width", &node->style.dimensions[YGDimensionWidth]);
- YGPrintNumberIfNotAuto(node, "height", &node->style.dimensions[YGDimensionHeight]);
- YGPrintNumberIfNotAuto(node, "max-width", &node->style.maxDimensions[YGDimensionWidth]);
- YGPrintNumberIfNotAuto(node, "max-height", &node->style.maxDimensions[YGDimensionHeight]);
- YGPrintNumberIfNotAuto(node, "min-width", &node->style.minDimensions[YGDimensionWidth]);
- YGPrintNumberIfNotAuto(node, "min-height", &node->style.minDimensions[YGDimensionHeight]);
+ YGPrintNumberIfNotAuto(stream, "width", &node->style.dimensions[YGDimensionWidth]);
+ YGPrintNumberIfNotAuto(stream, "height", &node->style.dimensions[YGDimensionHeight]);
+ YGPrintNumberIfNotAuto(stream, "max-width", &node->style.maxDimensions[YGDimensionWidth]);
+ YGPrintNumberIfNotAuto(stream, "max-height", &node->style.maxDimensions[YGDimensionHeight]);
+ YGPrintNumberIfNotAuto(stream, "min-width", &node->style.minDimensions[YGDimensionWidth]);
+ YGPrintNumberIfNotAuto(stream, "min-height", &node->style.minDimensions[YGDimensionHeight]);
if (node->style.positionType != gYGNodeDefaults.style.positionType) {
- YGLog(node,
- YGLogLevelDebug,
- "position: %s; ",
- YGPositionTypeToString(node->style.positionType));
+ YGWriteToStringStream(stream,
+ "position: %s; ",
+ YGPositionTypeToString(node->style.positionType));
}
- YGPrintEdgeIfNotUndefined(node, "left", node->style.position, YGEdgeLeft);
- YGPrintEdgeIfNotUndefined(node, "right", node->style.position, YGEdgeRight);
- YGPrintEdgeIfNotUndefined(node, "top", node->style.position, YGEdgeTop);
- YGPrintEdgeIfNotUndefined(node, "bottom", node->style.position, YGEdgeBottom);
- YGLog(node, YGLogLevelDebug, "\" ");
+ YGPrintEdgeIfNotUndefined(stream, "left", node->style.position, YGEdgeLeft);
+ YGPrintEdgeIfNotUndefined(stream, "right", node->style.position, YGEdgeRight);
+ YGPrintEdgeIfNotUndefined(stream, "top", node->style.position, YGEdgeTop);
+ YGPrintEdgeIfNotUndefined(stream, "bottom", node->style.position, YGEdgeBottom);
+ YGWriteToStringStream(stream, "\" ");
if (node->measure != NULL) {
- YGLog(node, YGLogLevelDebug, "has-custom-measure=\"true\"");
+ YGWriteToStringStream(stream, "has-custom-measure=\"true\"");
}
}
- YGLog(node, YGLogLevelDebug, ">");
+ YGWriteToStringStream(stream, ">");
const uint32_t childCount = YGNodeListCount(node->children);
if (options & YGPrintOptionsChildren && childCount > 0) {
for (uint32_t i = 0; i < childCount; i++) {
- YGLog(node, YGLogLevelDebug, "\n");
- YGNodePrintInternal(YGNodeGetChild(node, i), options, level + 1);
+ YGWriteToStringStream(stream, "\n");
+ YGNodeToString(stream, YGNodeGetChild(node, i), options, level + 1);
}
- YGIndent(node, level);
- YGLog(node, YGLogLevelDebug, "\n");
+ YGWriteToStringStream(stream, "\n");
+ YGIndent(stream, level);
+ }
+ YGWriteToStringStream(stream, "
");
+}
+
+static void YGNodePrintInternal(const YGNodeRef node,
+ const YGPrintOptions options) {
+ YGStringStream stream;
+ stream.str = (char *) malloc(sizeof(char) * 1024);
+ stream.length = 0;
+ stream.capacity = 1024;
+ if (stream.str != NULL) {
+ YGNodeToString(&stream, node, options, 0);
+ YGLog(node, YGLogLevelDebug, stream.str);
+ free(stream.str);
}
- YGLog(node, YGLogLevelDebug, "");
}
void YGNodePrint(const YGNodeRef node, const YGPrintOptions options) {
- YGNodePrintInternal(node, options, 0);
+ YGNodePrintInternal(node, options);
}
static const YGEdge leading[4] = {