Make YGNode as c++ struct with properties exposed through accessors

Summary: Moved c implementation of `YGNode` to C++ struct. Not moving to C++ class as the React Classes dependent on `Yoga.h` assume it to be C. Thats why keeping `Yoga.h` C compatible. Sorry for the long diff, didn't thought that it will turn out to be this much big.Will keep an eye on number of lines next time 😉

Reviewed By: emilsjolander

Differential Revision: D6592257

fbshipit-source-id: 641e8b9462ad00731a094511f9f5608b23a6bb21
This commit is contained in:
Pritesh Nandgaonkar
2017-12-19 11:18:00 -08:00
committed by Facebook Github Bot
parent dbf6a12134
commit fbd332dee8
16 changed files with 1957 additions and 1091 deletions

399
yoga/YGNode.cpp Normal file
View File

@@ -0,0 +1,399 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "YGNode.h"
#include <iostream>
void* YGNode::getContext() const {
return context_;
}
YGPrintFunc YGNode::getPrintFunc() const {
return print_;
}
bool YGNode::getHasNewLayout() const {
return hasNewLayout_;
}
YGNodeType YGNode::getNodeType() const {
return nodeType_;
}
YGMeasureFunc YGNode::getMeasure() const {
return measure_;
}
YGBaselineFunc YGNode::getBaseline() const {
return baseline_;
}
YGStyle YGNode::getStyle() const {
return style_;
}
YGLayout YGNode::getLayout() const {
return layout_;
}
YGLayout& YGNode::getLayoutRef() {
return layout_;
}
uint32_t YGNode::getLineIndex() const {
return lineIndex_;
}
YGNodeRef YGNode::getParent() const {
return parent_;
}
YGVector YGNode::getChildren() const {
return children_;
}
YGNodeRef YGNode::getChild(uint32_t index) const {
return children_.at(index);
}
YGNodeRef YGNode::getNextChild() const {
return nextChild_;
}
YGConfigRef YGNode::getConfig() const {
return config_;
}
bool YGNode::isDirty() const {
return isDirty_;
}
YGValue YGNode::getResolvedDimension(int index) {
return resolvedDimensions_[index];
}
std::array<YGValue, 2> YGNode::getResolvedDimensions() const {
return resolvedDimensions_;
}
// Setters
void YGNode::setContext(void* context) {
context_ = context;
}
void YGNode::setPrintFunc(YGPrintFunc printFunc) {
print_ = printFunc;
}
void YGNode::setHasNewLayout(bool hasNewLayout) {
hasNewLayout_ = hasNewLayout;
}
void YGNode::setNodeType(YGNodeType nodeType) {
nodeType_ = nodeType;
}
void YGNode::setStyleFlexDirection(YGFlexDirection direction) {
style_.flexDirection = direction;
}
void YGNode::setStyleAlignContent(YGAlign alignContent) {
style_.alignContent = alignContent;
}
void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) {
if (measureFunc == nullptr) {
measure_ = nullptr;
// TODO: t18095186 Move nodeType to opt-in function and mark appropriate
// places in Litho
nodeType_ = YGNodeTypeDefault;
} else {
YGAssertWithNode(
this,
children_.size() == 0,
"Cannot set measure function: Nodes with measure functions cannot have children.");
measure_ = measureFunc;
// TODO: t18095186 Move nodeType to opt-in function and mark appropriate
// places in Litho
setNodeType(YGNodeTypeText);
}
measure_ = measureFunc;
}
void YGNode::setBaseLineFunc(YGBaselineFunc baseLineFunc) {
baseline_ = baseLineFunc;
}
void YGNode::setStyle(YGStyle style) {
style_ = style;
}
void YGNode::setLayout(YGLayout layout) {
layout_ = layout;
}
void YGNode::setLineIndex(uint32_t lineIndex) {
lineIndex_ = lineIndex;
}
void YGNode::setParent(YGNodeRef parent) {
parent_ = parent;
}
void YGNode::setChildren(YGVector children) {
children_ = children;
}
void YGNode::setNextChild(YGNodeRef nextChild) {
nextChild_ = nextChild;
}
void YGNode::replaceChild(YGNodeRef child, uint32_t index) {
children_[index] = child;
}
void YGNode::insertChild(YGNodeRef child, uint32_t index) {
children_.insert(children_.begin() + index, child);
}
void YGNode::setConfig(YGConfigRef config) {
config_ = config;
}
void YGNode::setDirty(bool isDirty) {
isDirty_ = isDirty;
}
bool YGNode::removeChild(YGNodeRef child) {
std::vector<YGNodeRef>::iterator p =
std::find(children_.begin(), children_.end(), child);
if (p != children_.end()) {
children_.erase(p);
return true;
}
return false;
}
void YGNode::removeChild(uint32_t index) {
children_.erase(children_.begin() + index);
}
void YGNode::setLayoutDirection(YGDirection direction) {
layout_.direction = direction;
}
void YGNode::setLayoutMargin(float margin, int index) {
layout_.margin[index] = margin;
}
void YGNode::setLayoutBorder(float border, int index) {
layout_.border[index] = border;
}
void YGNode::setLayoutPadding(float padding, int index) {
layout_.padding[index] = padding;
}
void YGNode::setLayoutLastParentDirection(YGDirection direction) {
layout_.lastParentDirection = direction;
}
void YGNode::setLayoutComputedFlexBasis(float computedFlexBasis) {
layout_.computedFlexBasis = computedFlexBasis;
}
void YGNode::setLayoutPosition(float position, int index) {
layout_.position[index] = position;
}
void YGNode::setLayoutComputedFlexBasisGeneration(
uint32_t computedFlexBasisGeneration) {
layout_.computedFlexBasisGeneration = computedFlexBasisGeneration;
}
void YGNode::setLayoutMeasuredDimension(float measuredDimension, int index) {
layout_.measuredDimensions[index] = measuredDimension;
}
void YGNode::setLayoutHadOverflow(bool hadOverflow) {
layout_.hadOverflow = hadOverflow;
}
void YGNode::setLayoutDimension(float dimension, int index) {
layout_.dimensions[index] = dimension;
}
YGNode::YGNode()
: context_(nullptr),
print_(nullptr),
hasNewLayout_(true),
nodeType_(YGNodeTypeDefault),
measure_(nullptr),
baseline_(nullptr),
style_(gYGNodeStyleDefaults),
layout_(gYGNodeLayoutDefaults),
lineIndex_(0),
parent_(nullptr),
children_(YGVector()),
nextChild_(nullptr),
config_(nullptr),
isDirty_(false),
resolvedDimensions_({{YGValueUndefined, YGValueUndefined}}) {}
YGNode::YGNode(const YGNode& node)
: context_(node.getContext()),
print_(node.getPrintFunc()),
hasNewLayout_(node.getHasNewLayout()),
nodeType_(node.getNodeType()),
measure_(node.getMeasure()),
baseline_(node.getBaseline()),
style_(node.getStyle()),
layout_(node.getLayout()),
lineIndex_(node.getLineIndex()),
parent_(node.getParent()),
children_(node.getChildren()),
nextChild_(node.getNextChild()),
config_(node.getConfig()),
isDirty_(node.isDirty()),
resolvedDimensions_(node.getResolvedDimensions()) {}
YGNode::YGNode(const YGConfigRef newConfig) : YGNode() {
config_ = newConfig;
}
YGNode::YGNode(
void* context,
YGPrintFunc print,
bool hasNewLayout,
YGNodeType nodeType,
YGMeasureFunc measure,
YGBaselineFunc baseline,
YGStyle style,
YGLayout layout,
uint32_t lineIndex,
YGNodeRef parent,
YGVector children,
YGNodeRef nextChild,
YGConfigRef config,
bool isDirty,
std::array<YGValue, 2> resolvedDimensions)
: context_(context),
print_(print),
hasNewLayout_(hasNewLayout),
nodeType_(nodeType),
measure_(measure),
baseline_(baseline),
style_(style),
layout_(layout),
lineIndex_(lineIndex),
parent_(parent),
children_(children),
nextChild_(nextChild),
config_(config),
isDirty_(isDirty),
resolvedDimensions_(resolvedDimensions) {}
YGNode& YGNode::operator=(const YGNode& node) {
if (&node == this) {
return *this;
}
for (auto child : children_) {
delete child;
}
context_ = node.getContext();
print_ = node.getPrintFunc();
hasNewLayout_ = node.getHasNewLayout();
nodeType_ = node.getNodeType();
measure_ = node.getMeasure();
baseline_ = node.getBaseline();
style_ = node.getStyle();
layout_ = node.getLayout();
lineIndex_ = node.getLineIndex();
parent_ = node.getParent();
children_ = node.getChildren();
nextChild_ = node.getNextChild();
config_ = node.getConfig();
isDirty_ = node.isDirty();
resolvedDimensions_ = node.getResolvedDimensions();
return *this;
}
YGValue YGNode::marginLeadingValue(const YGFlexDirection axis) const {
if (YGFlexDirectionIsRow(axis) &&
getStyle().margin[YGEdgeStart].unit != YGUnitUndefined) {
return getStyle().margin[YGEdgeStart];
} else {
return getStyle().margin[leading[axis]];
}
}
YGValue YGNode::marginTrailingValue(const YGFlexDirection axis) const {
if (YGFlexDirectionIsRow(axis) &&
getStyle().margin[YGEdgeEnd].unit != YGUnitUndefined) {
return getStyle().margin[YGEdgeEnd];
} else {
return getStyle().margin[trailing[axis]];
}
}
YGValue YGNode::resolveFlexBasisPtr() const {
YGValue flexBasis = getStyle().flexBasis;
if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) {
return flexBasis;
}
if (!YGFloatIsUndefined(getStyle().flex) && getStyle().flex > 0.0f) {
return config_->useWebDefaults ? YGValueAuto : YGValueZero;
}
return YGValueAuto;
}
void YGNode::resolveDimension() {
for (uint32_t dim = YGDimensionWidth; dim < YGDimensionCount; dim++) {
if (getStyle().maxDimensions[dim].unit != YGUnitUndefined &&
YGValueEqual(
getStyle().maxDimensions[dim], getStyle().minDimensions[dim])) {
resolvedDimensions_[dim] = getStyle().maxDimensions[dim];
} else {
resolvedDimensions_[dim] = getStyle().dimensions[dim];
}
}
}
void YGNode::clearChildren() {
children_.clear();
children_.shrink_to_fit();
}
YGNode::~YGNode() {
// All the member variables are deallocated externally, so no need to
// deallocate here
}
const YGNode& YGNode::defaultValue() {
static const YGNode n = {nullptr,
nullptr,
true,
YGNodeTypeDefault,
nullptr,
nullptr,
gYGNodeStyleDefaults,
gYGNodeLayoutDefaults,
0,
nullptr,
YGVector(),
nullptr,
nullptr,
false,
{{YGValueUndefined, YGValueUndefined}}};
return n;
}

121
yoga/YGNode.h Normal file
View File

@@ -0,0 +1,121 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <stdio.h>
#include "Yoga-internal.h"
struct YGNode {
private:
void* context_;
YGPrintFunc print_;
bool hasNewLayout_;
YGNodeType nodeType_;
YGMeasureFunc measure_;
YGBaselineFunc baseline_;
YGStyle style_;
YGLayout layout_;
uint32_t lineIndex_;
YGNodeRef parent_;
YGVector children_;
YGNodeRef nextChild_;
YGConfigRef config_;
bool isDirty_;
std::array<YGValue, 2> resolvedDimensions_;
public:
YGNode();
~YGNode();
explicit YGNode(const YGConfigRef newConfig);
YGNode(const YGNode& node);
YGNode& operator=(const YGNode& node);
YGNode(
void* context,
YGPrintFunc print,
bool hasNewLayout,
YGNodeType nodeType,
YGMeasureFunc measure,
YGBaselineFunc baseline,
YGStyle style,
YGLayout layout,
uint32_t lineIndex,
YGNodeRef parent,
YGVector children,
YGNodeRef nextChild,
YGConfigRef config,
bool isDirty,
std::array<YGValue, 2> resolvedDimensions);
// Getters
void* getContext() const;
YGPrintFunc getPrintFunc() const;
bool getHasNewLayout() const;
YGNodeType getNodeType() const;
YGMeasureFunc getMeasure() const;
YGBaselineFunc getBaseline() const;
YGStyle getStyle() const;
YGLayout getLayout() const;
YGLayout& getLayoutRef(); // TODO remove its use
uint32_t getLineIndex() const;
YGNodeRef getParent() const;
YGVector getChildren() const;
YGNodeRef getChild(uint32_t index) const;
YGNodeRef getNextChild() const;
YGConfigRef getConfig() const;
bool isDirty() const;
std::array<YGValue, 2> getResolvedDimensions() const;
YGValue getResolvedDimension(int index);
// Setters
void setContext(void* context);
void setPrintFunc(YGPrintFunc printFunc);
void setHasNewLayout(bool hasNewLayout);
void setNodeType(YGNodeType nodeTye);
void setMeasureFunc(YGMeasureFunc measureFunc);
void setBaseLineFunc(YGBaselineFunc baseLineFunc);
void setStyle(YGStyle style);
void setStyleFlexDirection(YGFlexDirection direction);
void setStyleAlignContent(YGAlign alignContent);
void setLayout(YGLayout layout);
void setLineIndex(uint32_t lineIndex);
void setParent(YGNodeRef parent);
void setChildren(YGVector children);
void setNextChild(YGNodeRef nextChild);
void setConfig(YGConfigRef config);
void setDirty(bool isDirty);
void setLayoutLastParentDirection(YGDirection direction);
void setLayoutComputedFlexBasis(float computedFlexBasis);
void setLayoutComputedFlexBasisGeneration(
uint32_t computedFlexBasisGeneration);
void setLayoutMeasuredDimension(float measuredDimension, int index);
void setLayoutHadOverflow(bool hadOverflow);
void setLayoutDimension(float dimension, int index);
// Other methods
YGValue marginLeadingValue(const YGFlexDirection axis) const;
YGValue marginTrailingValue(const YGFlexDirection axis) const;
YGValue resolveFlexBasisPtr() const;
void resolveDimension();
void clearChildren();
void replaceChild(YGNodeRef child, uint32_t index);
void insertChild(YGNodeRef child, uint32_t index);
/// Removes the first occurrence of child
bool removeChild(YGNodeRef child);
void removeChild(uint32_t index);
void setLayoutDirection(YGDirection direction);
void setLayoutMargin(float margin, int index);
void setLayoutBorder(float border, int index);
void setLayoutPadding(float padding, int index);
void setLayoutPosition(float position, int index);
// Static methods
static const YGNode& defaultValue();
};

View File

@@ -10,6 +10,7 @@
#include "YGNodePrint.h"
#include <stdarg.h>
#include "YGEnums.h"
#include "YGNode.h"
#include "Yoga-internal.h"
namespace facebook {
@@ -22,7 +23,7 @@ static void indent(string* base, uint32_t level) {
}
}
static bool areFourValuesEqual(const YGValue four[4]) {
static bool areFourValuesEqual(const std::array<YGValue, YGEdgeCount>& four) {
return YGValueEqual(four[0], four[1]) && YGValueEqual(four[0], four[2]) &&
YGValueEqual(four[0], four[3]);
}
@@ -50,54 +51,53 @@ appendFloatIfNotUndefined(string* base, const string key, const float num) {
static void appendNumberIfNotUndefined(
string* base,
const string key,
const YGValue* const number) {
if (number->unit != YGUnitUndefined) {
if (number->unit == YGUnitAuto) {
const YGValue number) {
if (number.unit != YGUnitUndefined) {
if (number.unit == YGUnitAuto) {
base->append(key + ": auto; ");
} else {
string unit = number->unit == YGUnitPoint ? "px" : "%%";
string unit = number.unit == YGUnitPoint ? "px" : "%%";
appendFormatedString(
base, "%s: %g%s; ", key.c_str(), number->value, unit.c_str());
base, "%s: %g%s; ", key.c_str(), number.value, unit.c_str());
}
}
}
static void appendNumberIfNotAuto(
string* base,
const string key,
const YGValue* const number) {
if (number->unit != YGUnitAuto) {
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* const number) {
if (!YGFloatsEqual(number->value, 0)) {
static void
appendNumberIfNotZero(string* base, const string& str, const YGValue number) {
if (!YGFloatsEqual(number.value, 0)) {
appendNumberIfNotUndefined(base, str, number);
}
}
static void appendEdges(string* base, const string key, const YGValue* edges) {
static void appendEdges(
string* base,
const string& key,
const std::array<YGValue, YGEdgeCount>& edges) {
if (areFourValuesEqual(edges)) {
appendNumberIfNotZero(base, key, &edges[YGEdgeLeft]);
appendNumberIfNotZero(base, key, edges[YGEdgeLeft]);
} else {
for (int edge = YGEdgeLeft; edge != YGEdgeAll; ++edge) {
string str = key + "-" + YGEdgeToString(static_cast<YGEdge>(edge));
appendNumberIfNotZero(base, str, &edges[edge]);
appendNumberIfNotZero(base, str, edges[edge]);
}
}
}
static void appendEdgeIfNotUndefined(
string* base,
const string str,
const YGValue* edges,
const string& str,
const std::array<YGValue, YGEdgeCount>& edges,
const YGEdge edge) {
appendNumberIfNotUndefined(
base, str, YGComputedEdgeValue(edges, edge, &YGValueUndefined));
base, str, *YGComputedEdgeValue(edges, edge, &YGValueUndefined));
}
void YGNodeToString(
@@ -107,105 +107,112 @@ void YGNodeToString(
uint32_t level) {
indent(str, level);
appendFormatedString(str, "<div ");
if (node->print != nullptr) {
node->print(node);
if (node->getPrintFunc() != nullptr) {
node->getPrintFunc()(node);
}
if (options & YGPrintOptionsLayout) {
appendFormatedString(str, "layout=\"");
appendFormatedString(
str, "width: %g; ", node->layout.dimensions[YGDimensionWidth]);
str, "width: %g; ", node->getLayout().dimensions[YGDimensionWidth]);
appendFormatedString(
str, "height: %g; ", node->layout.dimensions[YGDimensionHeight]);
appendFormatedString(str, "top: %g; ", node->layout.position[YGEdgeTop]);
appendFormatedString(str, "left: %g;", node->layout.position[YGEdgeLeft]);
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->style.flexDirection != gYGNodeDefaults.style.flexDirection) {
if (node->getStyle().flexDirection != YGNode().getStyle().flexDirection) {
appendFormatedString(
str,
"flex-direction: %s; ",
YGFlexDirectionToString(node->style.flexDirection));
YGFlexDirectionToString(node->getStyle().flexDirection));
}
if (node->style.justifyContent != gYGNodeDefaults.style.justifyContent) {
if (node->getStyle().justifyContent != YGNode().getStyle().justifyContent) {
appendFormatedString(
str,
"justify-content: %s; ",
YGJustifyToString(node->style.justifyContent));
YGJustifyToString(node->getStyle().justifyContent));
}
if (node->style.alignItems != gYGNodeDefaults.style.alignItems) {
if (node->getStyle().alignItems != YGNode().getStyle().alignItems) {
appendFormatedString(
str, "align-items: %s; ", YGAlignToString(node->style.alignItems));
str,
"align-items: %s; ",
YGAlignToString(node->getStyle().alignItems));
}
if (node->style.alignContent != gYGNodeDefaults.style.alignContent) {
if (node->getStyle().alignContent != YGNode().getStyle().alignContent) {
appendFormatedString(
str,
"align-content: %s; ",
YGAlignToString(node->style.alignContent));
YGAlignToString(node->getStyle().alignContent));
}
if (node->style.alignSelf != gYGNodeDefaults.style.alignSelf) {
if (node->getStyle().alignSelf != YGNode().getStyle().alignSelf) {
appendFormatedString(
str, "align-self: %s; ", YGAlignToString(node->style.alignSelf));
str, "align-self: %s; ", YGAlignToString(node->getStyle().alignSelf));
}
appendFloatIfNotUndefined(str, "flex-grow", node->style.flexGrow);
appendFloatIfNotUndefined(str, "flex-shrink", node->style.flexShrink);
appendNumberIfNotAuto(str, "flex-basis", &node->style.flexBasis);
appendFloatIfNotUndefined(str, "flex", node->style.flex);
appendFloatIfNotUndefined(str, "flex-grow", node->getStyle().flexGrow);
appendFloatIfNotUndefined(str, "flex-shrink", node->getStyle().flexShrink);
appendNumberIfNotAuto(str, "flex-basis", node->getStyle().flexBasis);
appendFloatIfNotUndefined(str, "flex", node->getStyle().flex);
if (node->style.flexWrap != gYGNodeDefaults.style.flexWrap) {
if (node->getStyle().flexWrap != YGNode().getStyle().flexWrap) {
appendFormatedString(
str, "flexWrap: %s; ", YGWrapToString(node->style.flexWrap));
str, "flexWrap: %s; ", YGWrapToString(node->getStyle().flexWrap));
}
if (node->style.overflow != gYGNodeDefaults.style.overflow) {
if (node->getStyle().overflow != YGNode().getStyle().overflow) {
appendFormatedString(
str, "overflow: %s; ", YGOverflowToString(node->style.overflow));
str, "overflow: %s; ", YGOverflowToString(node->getStyle().overflow));
}
if (node->style.display != gYGNodeDefaults.style.display) {
if (node->getStyle().display != YGNode().getStyle().display) {
appendFormatedString(
str, "display: %s; ", YGDisplayToString(node->style.display));
str, "display: %s; ", YGDisplayToString(node->getStyle().display));
}
appendEdges(str, "margin", node->style.margin);
appendEdges(str, "padding", node->style.padding);
appendEdges(str, "border", node->style.border);
appendEdges(str, "margin", node->getStyle().margin);
appendEdges(str, "padding", node->getStyle().padding);
appendEdges(str, "border", node->getStyle().border);
appendNumberIfNotAuto(
str, "width", &node->style.dimensions[YGDimensionWidth]);
str, "width", node->getStyle().dimensions[YGDimensionWidth]);
appendNumberIfNotAuto(
str, "height", &node->style.dimensions[YGDimensionHeight]);
str, "height", node->getStyle().dimensions[YGDimensionHeight]);
appendNumberIfNotAuto(
str, "max-width", &node->style.maxDimensions[YGDimensionWidth]);
str, "max-width", node->getStyle().maxDimensions[YGDimensionWidth]);
appendNumberIfNotAuto(
str, "max-height", &node->style.maxDimensions[YGDimensionHeight]);
str, "max-height", node->getStyle().maxDimensions[YGDimensionHeight]);
appendNumberIfNotAuto(
str, "min-width", &node->style.minDimensions[YGDimensionWidth]);
str, "min-width", node->getStyle().minDimensions[YGDimensionWidth]);
appendNumberIfNotAuto(
str, "min-height", &node->style.minDimensions[YGDimensionHeight]);
str, "min-height", node->getStyle().minDimensions[YGDimensionHeight]);
if (node->style.positionType != gYGNodeDefaults.style.positionType) {
if (node->getStyle().positionType != YGNode().getStyle().positionType) {
appendFormatedString(
str,
"position: %s; ",
YGPositionTypeToString(node->style.positionType));
YGPositionTypeToString(node->getStyle().positionType));
}
appendEdgeIfNotUndefined(str, "left", node->style.position, YGEdgeLeft);
appendEdgeIfNotUndefined(str, "right", node->style.position, YGEdgeRight);
appendEdgeIfNotUndefined(str, "top", node->style.position, YGEdgeTop);
appendEdgeIfNotUndefined(str, "bottom", node->style.position, YGEdgeBottom);
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->measure != nullptr) {
if (node->getMeasure() != nullptr) {
appendFormatedString(str, "has-custom-measure=\"true\"");
}
}
appendFormatedString(str, ">");
const uint32_t childCount = node->children.size();
const uint32_t childCount = node->getChildren().size();
if (options & YGPrintOptionsChildren && childCount > 0) {
for (uint32_t i = 0; i < childCount; i++) {
appendFormatedString(str, "\n");

View File

@@ -8,6 +8,9 @@
*/
#pragma once
#include <algorithm>
#include <array>
#include <cmath>
#include <vector>
#include "Yoga.h"
@@ -23,6 +26,25 @@ WIN_EXPORT float YGRoundValueToPixelGrid(const float value,
YG_EXTERN_C_END
extern const std::array<YGEdge, 4> trailing;
extern const std::array<YGEdge, 4> leading;
extern bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection);
extern bool YGValueEqual(const YGValue a, const YGValue b);
extern const YGValue YGValueUndefined;
extern const YGValue YGValueAuto;
extern const YGValue YGValueZero;
template <std::size_t size>
bool YGValueArrayEqual(
const std::array<YGValue, size> val1,
const std::array<YGValue, size> val2) {
bool areEqual = true;
for (uint32_t i = 0; i < size && areEqual; ++i) {
areEqual = YGValueEqual(val1[i], val2[i]);
}
return areEqual;
}
typedef struct YGCachedMeasurement {
float availableWidth;
float availableHeight;
@@ -37,12 +59,12 @@ typedef struct YGCachedMeasurement {
// layouts should not require more than 16 entries to fit within the cache.
#define YG_MAX_CACHED_RESULT_COUNT 16
typedef struct YGLayout {
float position[4];
float dimensions[2];
float margin[6];
float border[6];
float padding[6];
struct YGLayout {
std::array<float, 4> position;
std::array<float, 2> dimensions;
std::array<float, 6> margin;
std::array<float, 6> border;
std::array<float, 6> padding;
YGDirection direction;
uint32_t computedFlexBasisGeneration;
@@ -56,12 +78,12 @@ typedef struct YGLayout {
uint32_t nextCachedMeasurementsIndex;
YGCachedMeasurement cachedMeasurements[YG_MAX_CACHED_RESULT_COUNT];
float measuredDimensions[2];
std::array<float, 2> measuredDimensions;
YGCachedMeasurement cachedLayout;
} YGLayout;
};
typedef struct YGStyle {
struct YGStyle {
YGDirection direction;
YGFlexDirection flexDirection;
YGJustify justifyContent;
@@ -76,17 +98,58 @@ typedef struct YGStyle {
float flexGrow;
float flexShrink;
YGValue flexBasis;
YGValue margin[YGEdgeCount];
YGValue position[YGEdgeCount];
YGValue padding[YGEdgeCount];
YGValue border[YGEdgeCount];
YGValue dimensions[2];
YGValue minDimensions[2];
YGValue maxDimensions[2];
std::array<YGValue, YGEdgeCount> margin;
std::array<YGValue, YGEdgeCount> position;
std::array<YGValue, YGEdgeCount> padding;
std::array<YGValue, YGEdgeCount> border;
std::array<YGValue, 2> dimensions;
std::array<YGValue, 2> minDimensions;
std::array<YGValue, 2> maxDimensions;
// Yoga specific properties, not compatible with flexbox specification
float aspectRatio;
} YGStyle;
bool operator==(YGStyle style) {
bool areNonFloatValuesEqual = direction == style.direction &&
flexDirection == style.flexDirection &&
justifyContent == style.justifyContent &&
alignContent == style.alignContent && alignItems == style.alignItems &&
alignSelf == style.alignSelf && positionType == style.positionType &&
flexWrap == style.flexWrap && overflow == style.overflow &&
display == style.display && YGValueEqual(flexBasis, style.flexBasis) &&
YGValueArrayEqual(margin, style.margin) &&
YGValueArrayEqual(position, style.position) &&
YGValueArrayEqual(padding, style.padding) &&
YGValueArrayEqual(border, style.border) &&
YGValueArrayEqual(dimensions, style.dimensions) &&
YGValueArrayEqual(minDimensions, style.minDimensions) &&
YGValueArrayEqual(maxDimensions, style.maxDimensions);
if (!(std::isnan(flex) && std::isnan(style.flex))) {
areNonFloatValuesEqual = areNonFloatValuesEqual && flex == style.flex;
}
if (!(std::isnan(flexGrow) && std::isnan(style.flexGrow))) {
areNonFloatValuesEqual =
areNonFloatValuesEqual && flexGrow == style.flexGrow;
}
if (!(std::isnan(flexShrink) && std::isnan(style.flexShrink))) {
areNonFloatValuesEqual =
areNonFloatValuesEqual && flexShrink == style.flexShrink;
}
if (!(std::isnan(aspectRatio) && std::isnan(style.aspectRatio))) {
areNonFloatValuesEqual =
areNonFloatValuesEqual && aspectRatio == style.aspectRatio;
}
return areNonFloatValuesEqual;
}
bool operator!=(YGStyle style) {
return !(*this == style);
}
};
typedef struct YGConfig {
bool experimentalFeatures[YGExperimentalFeatureCount + 1];
@@ -98,29 +161,6 @@ typedef struct YGConfig {
void* context;
} YGConfig;
typedef struct YGNode {
YGStyle style;
YGLayout layout;
uint32_t lineIndex;
YGNodeRef parent;
YGVector children;
struct YGNode* nextChild;
YGMeasureFunc measure;
YGBaselineFunc baseline;
YGPrintFunc print;
YGConfigRef config;
void* context;
bool isDirty;
bool hasNewLayout;
YGNodeType nodeType;
YGValue const* resolvedDimensions[2];
} YGNode;
#define YG_UNDEFINED_VALUES \
{ .value = YGUndefined, .unit = YGUnitUndefined }
@@ -167,19 +207,51 @@ static const YGStyle gYGNodeStyleDefaults = {
.flexGrow = YGUndefined,
.flexShrink = YGUndefined,
.flexBasis = YG_AUTO_VALUES,
.margin = YG_DEFAULT_EDGE_VALUES_UNIT,
.position = YG_DEFAULT_EDGE_VALUES_UNIT,
.padding = YG_DEFAULT_EDGE_VALUES_UNIT,
.border = YG_DEFAULT_EDGE_VALUES_UNIT,
.dimensions = YG_DEFAULT_DIMENSION_VALUES_AUTO_UNIT,
.minDimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT,
.maxDimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT,
.margin = {{YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES}},
.position = {{YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES}},
.padding = {{YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES}},
.border = {{YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES,
YG_UNDEFINED_VALUES}},
.dimensions = {{YG_AUTO_VALUES, YG_AUTO_VALUES}},
.minDimensions = {{YG_UNDEFINED_VALUES, YG_UNDEFINED_VALUES}},
.maxDimensions = {{YG_UNDEFINED_VALUES, YG_UNDEFINED_VALUES}},
.aspectRatio = YGUndefined,
};
static const YGLayout gYGNodeLayoutDefaults = {
.position = {},
.dimensions = YG_DEFAULT_DIMENSION_VALUES,
.dimensions = {{YGUndefined, YGUndefined}},
.margin = {},
.border = {},
.padding = {},
@@ -191,7 +263,7 @@ static const YGLayout gYGNodeLayoutDefaults = {
.lastParentDirection = (YGDirection)-1,
.nextCachedMeasurementsIndex = 0,
.cachedMeasurements = {},
.measuredDimensions = YG_DEFAULT_DIMENSION_VALUES,
.measuredDimensions = {{YGUndefined, YGUndefined}},
.cachedLayout =
{
.availableWidth = 0,
@@ -203,28 +275,9 @@ static const YGLayout gYGNodeLayoutDefaults = {
},
};
static const YGNode gYGNodeDefaults = {
.style = gYGNodeStyleDefaults,
.layout = gYGNodeLayoutDefaults,
.lineIndex = 0,
.parent = nullptr,
.children = YGVector(),
.nextChild = nullptr,
.measure = nullptr,
.baseline = nullptr,
.print = nullptr,
.config = nullptr,
.context = nullptr,
.isDirty = false,
.hasNewLayout = true,
.nodeType = YGNodeTypeDefault,
.resolvedDimensions = {[YGDimensionWidth] = &YGValueUndefined,
[YGDimensionHeight] = &YGValueUndefined},
};
extern bool YGFloatsEqual(const float a, const float b);
extern bool YGValueEqual(const YGValue a, const YGValue b);
extern const YGValue* YGComputedEdgeValue(
const YGValue edges[YGEdgeCount],
const std::array<YGValue, YGEdgeCount>& edges,
const YGEdge edge,
const YGValue* const defaultValue);

File diff suppressed because it is too large Load Diff

View File

@@ -43,11 +43,13 @@ typedef struct YGValue {
YGUnit unit;
} YGValue;
static const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined};
static const YGValue YGValueAuto = {YGUndefined, YGUnitAuto};
extern const YGValue YGValueUndefined;
extern const YGValue YGValueAuto;
typedef struct YGConfig *YGConfigRef;
typedef struct YGNode *YGNodeRef;
typedef struct YGNode* YGNodeRef;
typedef YGSize (*YGMeasureFunc)(YGNodeRef node,
float width,
YGMeasureMode widthMode,
@@ -95,7 +97,6 @@ WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node,
// depends on information not known to YG they must perform this dirty
// marking manually.
WIN_EXPORT void YGNodeMarkDirty(const YGNodeRef node);
WIN_EXPORT bool YGNodeIsDirty(const YGNodeRef node);
WIN_EXPORT void YGNodePrint(const YGNodeRef node, const YGPrintOptions options);
@@ -158,12 +159,19 @@ WIN_EXPORT void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode
#define YG_NODE_LAYOUT_EDGE_PROPERTY(type, name) \
WIN_EXPORT type YGNodeLayoutGet##name(const YGNodeRef node, const YGEdge edge);
YG_NODE_PROPERTY(void *, Context, context);
YG_NODE_PROPERTY(YGMeasureFunc, MeasureFunc, measureFunc);
YG_NODE_PROPERTY(YGBaselineFunc, BaselineFunc, baselineFunc)
YG_NODE_PROPERTY(YGPrintFunc, PrintFunc, printFunc);
YG_NODE_PROPERTY(bool, HasNewLayout, hasNewLayout);
YG_NODE_PROPERTY(YGNodeType, NodeType, nodeType);
void* YGNodeGetContext(YGNodeRef node);
void YGNodeSetContext(YGNodeRef node, void* context);
YGMeasureFunc YGNodeGetMeasureFunc(YGNodeRef node);
void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc);
YGBaselineFunc YGNodeGetBaselineFunc(YGNodeRef node);
void YGNodeSetBaselineFunc(YGNodeRef node, YGBaselineFunc baselineFunc);
YGPrintFunc YGNodeGetPrintFunc(YGNodeRef node);
void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc);
bool YGNodeGetHasNewLayout(YGNodeRef node);
void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout);
YGNodeType YGNodeGetNodeType(YGNodeRef node);
void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType);
bool YGNodeIsDirty(YGNodeRef node);
YG_NODE_STYLE_PROPERTY(YGDirection, Direction, direction);
YG_NODE_STYLE_PROPERTY(YGFlexDirection, FlexDirection, flexDirection);