/** * Copyright (c) Facebook, Inc. and its 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 "YGNodePrint.h" #include #include "YGEnums.h" #include "YGNode.h" #include "Yoga-internal.h" #include "Utils.h" namespace facebook { namespace yoga { typedef std::string string; static void indent(string& base, uint32_t level) { for (uint32_t i = 0; i < level; ++i) { base.append(" "); } } static bool areFourValuesEqual(const YGStyle::Edges& four) { return YGValueEqual(four[0], four[1]) && YGValueEqual(four[0], four[2]) && YGValueEqual(four[0], four[3]); } static void appendFormatedString(string& str, const char* fmt, ...) { va_list args; va_start(args, fmt); va_list argsCopy; va_copy(argsCopy, args); std::vector buf(1 + vsnprintf(NULL, 0, fmt, args)); va_end(args); vsnprintf(buf.data(), buf.size(), fmt, argsCopy); va_end(argsCopy); string result = string(buf.begin(), buf.end() - 1); str.append(result); } static void appendFloatOptionalIfDefined( string& base, const string key, const YGFloatOptional num) { if (!num.isUndefined()) { appendFormatedString(base, "%s: %g; ", key.c_str(), num.unwrap()); } } static void appendNumberIfNotUndefined( string& base, const string key, const YGValue number) { if (number.unit != YGUnitUndefined) { if (number.unit == YGUnitAuto) { base.append(key + ": auto; "); } else { string unit = number.unit == YGUnitPoint ? "px" : "%%"; appendFormatedString( base, "%s: %g%s; ", key.c_str(), number.value, unit.c_str()); } } } static void appendNumberIfNotAuto( string& base, const string& key, const YGValue number) { if (number.unit != YGUnitAuto) { appendNumberIfNotUndefined(base, key, number); } } static void appendNumberIfNotZero( string& base, const string& str, const YGValue number) { if (number.unit == YGUnitAuto) { base.append(str + ": auto; "); } else if (!YGFloatsEqual(number.value, 0)) { appendNumberIfNotUndefined(base, str, number); } } static void appendEdges( string& base, const string& key, const YGStyle::Edges& edges) { if (areFourValuesEqual(edges)) { appendNumberIfNotZero(base, key, edges[YGEdgeLeft]); } else { for (int edge = YGEdgeLeft; edge != YGEdgeAll; ++edge) { string str = key + "-" + YGEdgeToString(static_cast(edge)); appendNumberIfNotZero(base, str, edges[edge]); } } } static void appendEdgeIfNotUndefined( string& base, const string& str, const YGStyle::Edges& edges, const YGEdge edge) { appendNumberIfNotUndefined( base, str, YGComputedEdgeValue(edges, edge, detail::CompactValue::ofUndefined())); } void YGNodeToString( std::string& str, YGNodeRef node, YGPrintOptions options, uint32_t level) { indent(str, level); appendFormatedString(str, "
getLayout().dimensions[YGDimensionWidth]); appendFormatedString( str, "height: %g; ", node->getLayout().dimensions[YGDimensionHeight]); appendFormatedString( str, "top: %g; ", node->getLayout().position[YGEdgeTop]); appendFormatedString( str, "left: %g;", node->getLayout().position[YGEdgeLeft]); appendFormatedString(str, "\" "); } if (options & YGPrintOptionsStyle) { appendFormatedString(str, "style=\""); if (node->getStyle().flexDirection != YGNode().getStyle().flexDirection) { appendFormatedString( str, "flex-direction: %s; ", YGFlexDirectionToString(node->getStyle().flexDirection)); } if (node->getStyle().justifyContent != YGNode().getStyle().justifyContent) { appendFormatedString( str, "justify-content: %s; ", YGJustifyToString(node->getStyle().justifyContent)); } if (node->getStyle().alignItems != YGNode().getStyle().alignItems) { appendFormatedString( str, "align-items: %s; ", YGAlignToString(node->getStyle().alignItems)); } if (node->getStyle().alignContent != YGNode().getStyle().alignContent) { appendFormatedString( str, "align-content: %s; ", YGAlignToString(node->getStyle().alignContent)); } if (node->getStyle().alignSelf != YGNode().getStyle().alignSelf) { appendFormatedString( str, "align-self: %s; ", YGAlignToString(node->getStyle().alignSelf)); } appendFloatOptionalIfDefined(str, "flex-grow", node->getStyle().flexGrow); appendFloatOptionalIfDefined( str, "flex-shrink", node->getStyle().flexShrink); appendNumberIfNotAuto(str, "flex-basis", node->getStyle().flexBasis); appendFloatOptionalIfDefined(str, "flex", node->getStyle().flex); if (node->getStyle().flexWrap != YGNode().getStyle().flexWrap) { appendFormatedString( str, "flex-wrap: %s; ", YGWrapToString(node->getStyle().flexWrap)); } if (node->getStyle().overflow != YGNode().getStyle().overflow) { appendFormatedString( str, "overflow: %s; ", YGOverflowToString(node->getStyle().overflow)); } if (node->getStyle().display != YGNode().getStyle().display) { appendFormatedString( str, "display: %s; ", YGDisplayToString(node->getStyle().display)); } appendEdges(str, "margin", node->getStyle().margin); appendEdges(str, "padding", node->getStyle().padding); appendEdges(str, "border", node->getStyle().border); appendNumberIfNotAuto( str, "width", node->getStyle().dimensions[YGDimensionWidth]); appendNumberIfNotAuto( str, "height", node->getStyle().dimensions[YGDimensionHeight]); appendNumberIfNotAuto( str, "max-width", node->getStyle().maxDimensions[YGDimensionWidth]); appendNumberIfNotAuto( str, "max-height", node->getStyle().maxDimensions[YGDimensionHeight]); appendNumberIfNotAuto( str, "min-width", node->getStyle().minDimensions[YGDimensionWidth]); appendNumberIfNotAuto( str, "min-height", node->getStyle().minDimensions[YGDimensionHeight]); if (node->getStyle().positionType != YGNode().getStyle().positionType) { appendFormatedString( str, "position: %s; ", YGPositionTypeToString(node->getStyle().positionType)); } appendEdgeIfNotUndefined( str, "left", node->getStyle().position, YGEdgeLeft); appendEdgeIfNotUndefined( str, "right", node->getStyle().position, YGEdgeRight); appendEdgeIfNotUndefined(str, "top", node->getStyle().position, YGEdgeTop); appendEdgeIfNotUndefined( str, "bottom", node->getStyle().position, YGEdgeBottom); appendFormatedString(str, "\" "); if (node->hasMeasureFunc()) { appendFormatedString(str, "has-custom-measure=\"true\""); } } appendFormatedString(str, ">"); const uint32_t childCount = static_cast(node->getChildren().size()); if (options & YGPrintOptionsChildren && childCount > 0) { for (uint32_t i = 0; i < childCount; i++) { appendFormatedString(str, "\n"); YGNodeToString(str, YGNodeGetChild(node, i), options, level + 1); } appendFormatedString(str, "\n"); indent(str, level); } appendFormatedString(str, "
"); } } // namespace yoga } // namespace facebook #endif