Use const where possible

Summary: Use const where possible. This does not use const for all variables as that would require too much refactoring for one diff. It does however use const where currently possible as well as does some small refactoring to enable const usage in more locations. Striving for 100% const usage leads to code with is easier to reason about as a reference will always reference the same value. The compiler will also assist if you accidentally override a reference.

Reviewed By: IanChilds

Differential Revision: D3741999

fbshipit-source-id: 1ba7da5784c3047f2d4c03746890192f724aa65e
This commit is contained in:
Emil Sjolander
2016-08-22 06:58:13 -07:00
committed by Facebook Github Bot 6
parent 4bcefd8845
commit ca72b2b796
10 changed files with 328 additions and 332 deletions

View File

@@ -23,7 +23,8 @@ __forceinline const float fmaxf(const float a, const float b) {
#endif #endif
#endif #endif
static float computedEdgeValue(float edges[CSSEdgeCount], CSSEdge edge, float defaultValue) { static float
computedEdgeValue(const float edges[CSSEdgeCount], const CSSEdge edge, const float defaultValue) {
CSS_ASSERT(edge <= CSSEdgeEnd, "Cannot get computed value of multi-edge shorthands"); CSS_ASSERT(edge <= CSSEdgeEnd, "Cannot get computed value of multi-edge shorthands");
if (!CSSValueIsUndefined(edges[edge])) { if (!CSSValueIsUndefined(edges[edge])) {
@@ -52,19 +53,19 @@ static float computedEdgeValue(float edges[CSSEdgeCount], CSSEdge edge, float de
} }
CSSNodeRef CSSNodeNew() { CSSNodeRef CSSNodeNew() {
CSSNodeRef node = calloc(1, sizeof(CSSNode)); const CSSNodeRef node = calloc(1, sizeof(CSSNode));
CSS_ASSERT(node, "Could not allocate memory for node"); CSS_ASSERT(node, "Could not allocate memory for node");
CSSNodeInit(node); CSSNodeInit(node);
return node; return node;
} }
void CSSNodeFree(CSSNodeRef node) { void CSSNodeFree(const CSSNodeRef node) {
CSSNodeListFree(node->children); CSSNodeListFree(node->children);
free(node); free(node);
} }
void CSSNodeInit(CSSNodeRef node) { void CSSNodeInit(const CSSNodeRef node) {
node->parent = NULL; node->parent = NULL;
node->children = CSSNodeListNew(4); node->children = CSSNodeListNew(4);
node->hasNewLayout = true; node->hasNewLayout = true;
@@ -112,7 +113,7 @@ void CSSNodeInit(CSSNodeRef node) {
node->layout.cached_layout.heightMeasureMode = (CSSMeasureMode) -1; node->layout.cached_layout.heightMeasureMode = (CSSMeasureMode) -1;
} }
void _CSSNodeMarkDirty(CSSNodeRef node) { void _CSSNodeMarkDirty(const CSSNodeRef node) {
if (!node->isDirty) { if (!node->isDirty) {
node->isDirty = true; node->isDirty = true;
if (node->parent) { if (node->parent) {
@@ -121,27 +122,27 @@ void _CSSNodeMarkDirty(CSSNodeRef node) {
} }
} }
void CSSNodeInsertChild(CSSNodeRef node, CSSNodeRef child, uint32_t index) { void CSSNodeInsertChild(const CSSNodeRef node, const CSSNodeRef child, const uint32_t index) {
CSSNodeListInsert(node->children, child, index); CSSNodeListInsert(node->children, child, index);
child->parent = node; child->parent = node;
_CSSNodeMarkDirty(node); _CSSNodeMarkDirty(node);
} }
void CSSNodeRemoveChild(CSSNodeRef node, CSSNodeRef child) { void CSSNodeRemoveChild(const CSSNodeRef node, const CSSNodeRef child) {
CSSNodeListDelete(node->children, child); CSSNodeListDelete(node->children, child);
child->parent = NULL; child->parent = NULL;
_CSSNodeMarkDirty(node); _CSSNodeMarkDirty(node);
} }
CSSNodeRef CSSNodeGetChild(CSSNodeRef node, uint32_t index) { CSSNodeRef CSSNodeGetChild(const CSSNodeRef node, const uint32_t index) {
return CSSNodeListGet(node->children, index); return CSSNodeListGet(node->children, index);
} }
uint32_t CSSNodeChildCount(CSSNodeRef node) { uint32_t CSSNodeChildCount(const CSSNodeRef node) {
return CSSNodeListCount(node->children); return CSSNodeListCount(node->children);
} }
void CSSNodeMarkDirty(CSSNodeRef node) { void CSSNodeMarkDirty(const CSSNodeRef node) {
CSS_ASSERT(node->measure != NULL, CSS_ASSERT(node->measure != NULL,
"Nodes without custom measure functions " "Nodes without custom measure functions "
"should not manually mark themselves as " "should not manually mark themselves as "
@@ -149,11 +150,11 @@ void CSSNodeMarkDirty(CSSNodeRef node) {
_CSSNodeMarkDirty(node); _CSSNodeMarkDirty(node);
} }
bool CSSNodeIsDirty(CSSNodeRef node) { bool CSSNodeIsDirty(const CSSNodeRef node) {
return node->isDirty; return node->isDirty;
} }
void CSSNodeStyleSetFlex(CSSNodeRef node, float flex) { void CSSNodeStyleSetFlex(const CSSNodeRef node, const float flex) {
if (CSSValueIsUndefined(flex) || flex == 0) { if (CSSValueIsUndefined(flex) || flex == 0) {
CSSNodeStyleSetFlexGrow(node, 0); CSSNodeStyleSetFlexGrow(node, 0);
CSSNodeStyleSetFlexShrink(node, 0); CSSNodeStyleSetFlexShrink(node, 0);
@@ -169,7 +170,7 @@ void CSSNodeStyleSetFlex(CSSNodeRef node, float flex) {
} }
} }
float CSSNodeStyleGetFlex(CSSNodeRef node) { float CSSNodeStyleGetFlex(const CSSNodeRef node) {
if (node->style.flexGrow > 0) { if (node->style.flexGrow > 0) {
return node->style.flexGrow; return node->style.flexGrow;
} else if (node->style.flexShrink > 0) { } else if (node->style.flexShrink > 0) {
@@ -180,40 +181,40 @@ float CSSNodeStyleGetFlex(CSSNodeRef node) {
} }
#define CSS_NODE_PROPERTY_IMPL(type, name, paramName, instanceName) \ #define CSS_NODE_PROPERTY_IMPL(type, name, paramName, instanceName) \
void CSSNodeSet##name(CSSNodeRef node, type paramName) { \ void CSSNodeSet##name(const CSSNodeRef node, type paramName) { \
node->instanceName = paramName; \ node->instanceName = paramName; \
} \ } \
\ \
type CSSNodeGet##name(CSSNodeRef node) { \ type CSSNodeGet##name(const CSSNodeRef node) { \
return node->instanceName; \ return node->instanceName; \
} }
#define CSS_NODE_STYLE_PROPERTY_IMPL(type, name, paramName, instanceName) \ #define CSS_NODE_STYLE_PROPERTY_IMPL(type, name, paramName, instanceName) \
void CSSNodeStyleSet##name(CSSNodeRef node, type paramName) { \ void CSSNodeStyleSet##name(const CSSNodeRef node, const type paramName) { \
if (node->style.instanceName != paramName) { \ if (node->style.instanceName != paramName) { \
node->style.instanceName = paramName; \ node->style.instanceName = paramName; \
_CSSNodeMarkDirty(node); \ _CSSNodeMarkDirty(node); \
} \ } \
} \ } \
\ \
type CSSNodeStyleGet##name(CSSNodeRef node) { \ type CSSNodeStyleGet##name(const CSSNodeRef node) { \
return node->style.instanceName; \ return node->style.instanceName; \
} }
#define CSS_NODE_STYLE_EDGE_PROPERTY_IMPL(type, name, paramName, instanceName, defaultValue) \ #define CSS_NODE_STYLE_EDGE_PROPERTY_IMPL(type, name, paramName, instanceName, defaultValue) \
void CSSNodeStyleSet##name(CSSNodeRef node, CSSEdge edge, type paramName) { \ void CSSNodeStyleSet##name(const CSSNodeRef node, const CSSEdge edge, const type paramName) { \
if (node->style.instanceName[edge] != paramName) { \ if (node->style.instanceName[edge] != paramName) { \
node->style.instanceName[edge] = paramName; \ node->style.instanceName[edge] = paramName; \
_CSSNodeMarkDirty(node); \ _CSSNodeMarkDirty(node); \
} \ } \
} \ } \
\ \
type CSSNodeStyleGet##name(CSSNodeRef node, CSSEdge edge) { \ type CSSNodeStyleGet##name(const CSSNodeRef node, const CSSEdge edge) { \
return computedEdgeValue(node->style.instanceName, edge, defaultValue); \ return computedEdgeValue(node->style.instanceName, edge, defaultValue); \
} }
#define CSS_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \ #define CSS_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \
type CSSNodeLayoutGet##name(CSSNodeRef node) { \ type CSSNodeLayoutGet##name(const CSSNodeRef node) { \
return node->layout.instanceName; \ return node->layout.instanceName; \
} }
@@ -258,49 +259,50 @@ CSS_NODE_LAYOUT_PROPERTY_IMPL(CSSDirection, Direction, direction);
uint32_t gCurrentGenerationCount = 0; uint32_t gCurrentGenerationCount = 0;
bool layoutNodeInternal(CSSNode *node, bool layoutNodeInternal(const CSSNodeRef node,
float availableWidth, const float availableWidth,
float availableHeight, const float availableHeight,
CSSDirection parentDirection, const CSSDirection parentDirection,
CSSMeasureMode widthMeasureMode, const CSSMeasureMode widthMeasureMode,
CSSMeasureMode heightMeasureMode, const CSSMeasureMode heightMeasureMode,
bool performLayout, const bool performLayout,
char *reason); const char *reason);
bool CSSValueIsUndefined(float value) { bool CSSValueIsUndefined(const float value) {
return isnan(value); return isnan(value);
} }
static bool eq(float a, float b) { static bool eq(const float a, const float b) {
if (CSSValueIsUndefined(a)) { if (CSSValueIsUndefined(a)) {
return CSSValueIsUndefined(b); return CSSValueIsUndefined(b);
} }
return fabs(a - b) < 0.0001; return fabs(a - b) < 0.0001;
} }
static void indent(uint32_t n) { static void indent(const uint32_t n) {
for (uint32_t i = 0; i < n; ++i) { for (uint32_t i = 0; i < n; i++) {
printf(" "); printf(" ");
} }
} }
static void print_number_0(const char *str, float number) { static void print_number_0(const char *str, const float number) {
if (!eq(number, 0)) { if (!eq(number, 0)) {
printf("%s: %g, ", str, number); printf("%s: %g, ", str, number);
} }
} }
static void print_number_nan(const char *str, float number) { static void print_number_nan(const char *str, const float number) {
if (!isnan(number)) { if (!isnan(number)) {
printf("%s: %g, ", str, number); printf("%s: %g, ", str, number);
} }
} }
static bool four_equal(float four[4]) { static bool four_equal(const float four[4]) {
return eq(four[0], four[1]) && eq(four[0], four[2]) && eq(four[0], four[3]); return eq(four[0], four[1]) && eq(four[0], four[2]) && eq(four[0], four[3]);
} }
static void print_css_node_rec(CSSNode *node, CSSPrintOptions options, uint32_t level) { static void
print_css_node_rec(const CSSNodeRef node, const CSSPrintOptions options, const uint32_t level) {
indent(level); indent(level);
printf("{"); printf("{");
@@ -425,10 +427,10 @@ static void print_css_node_rec(CSSNode *node, CSSPrintOptions options, uint32_t
computedEdgeValue(node->style.position, CSSEdgeBottom, CSSUndefined)); computedEdgeValue(node->style.position, CSSEdgeBottom, CSSUndefined));
} }
uint32_t childCount = CSSNodeListCount(node->children); const uint32_t childCount = CSSNodeListCount(node->children);
if (options & CSSPrintOptionsChildren && childCount > 0) { if (options & CSSPrintOptionsChildren && childCount > 0) {
printf("children: [\n"); printf("children: [\n");
for (uint32_t i = 0; i < childCount; ++i) { for (uint32_t i = 0; i < childCount; i++) {
print_css_node_rec(CSSNodeGetChild(node, i), options, level + 1); print_css_node_rec(CSSNodeGetChild(node, i), options, level + 1);
} }
indent(level); indent(level);
@@ -438,44 +440,44 @@ static void print_css_node_rec(CSSNode *node, CSSPrintOptions options, uint32_t
} }
} }
void CSSNodePrint(CSSNode *node, CSSPrintOptions options) { void CSSNodePrint(const CSSNodeRef node, const CSSPrintOptions options) {
print_css_node_rec(node, options, 0); print_css_node_rec(node, options, 0);
} }
static CSSEdge leading[4] = { static const CSSEdge leading[4] = {
[CSSFlexDirectionColumn] = CSSEdgeTop, [CSSFlexDirectionColumn] = CSSEdgeTop,
[CSSFlexDirectionColumnReverse] = CSSEdgeBottom, [CSSFlexDirectionColumnReverse] = CSSEdgeBottom,
[CSSFlexDirectionRow] = CSSEdgeLeft, [CSSFlexDirectionRow] = CSSEdgeLeft,
[CSSFlexDirectionRowReverse] = CSSEdgeRight, [CSSFlexDirectionRowReverse] = CSSEdgeRight,
}; };
static CSSEdge trailing[4] = { static const CSSEdge trailing[4] = {
[CSSFlexDirectionColumn] = CSSEdgeBottom, [CSSFlexDirectionColumn] = CSSEdgeBottom,
[CSSFlexDirectionColumnReverse] = CSSEdgeTop, [CSSFlexDirectionColumnReverse] = CSSEdgeTop,
[CSSFlexDirectionRow] = CSSEdgeRight, [CSSFlexDirectionRow] = CSSEdgeRight,
[CSSFlexDirectionRowReverse] = CSSEdgeLeft, [CSSFlexDirectionRowReverse] = CSSEdgeLeft,
}; };
static CSSEdge pos[4] = { static const CSSEdge pos[4] = {
[CSSFlexDirectionColumn] = CSSEdgeTop, [CSSFlexDirectionColumn] = CSSEdgeTop,
[CSSFlexDirectionColumnReverse] = CSSEdgeBottom, [CSSFlexDirectionColumnReverse] = CSSEdgeBottom,
[CSSFlexDirectionRow] = CSSEdgeLeft, [CSSFlexDirectionRow] = CSSEdgeLeft,
[CSSFlexDirectionRowReverse] = CSSEdgeRight, [CSSFlexDirectionRowReverse] = CSSEdgeRight,
}; };
static CSSDimension dim[4] = { static const CSSDimension dim[4] = {
[CSSFlexDirectionColumn] = CSSDimensionHeight, [CSSFlexDirectionColumn] = CSSDimensionHeight,
[CSSFlexDirectionColumnReverse] = CSSDimensionHeight, [CSSFlexDirectionColumnReverse] = CSSDimensionHeight,
[CSSFlexDirectionRow] = CSSDimensionWidth, [CSSFlexDirectionRow] = CSSDimensionWidth,
[CSSFlexDirectionRowReverse] = CSSDimensionWidth, [CSSFlexDirectionRowReverse] = CSSDimensionWidth,
}; };
static bool isRowDirection(CSSFlexDirection flexDirection) { static bool isRowDirection(const CSSFlexDirection flexDirection) {
return flexDirection == CSSFlexDirectionRow || flexDirection == CSSFlexDirectionRowReverse; return flexDirection == CSSFlexDirectionRow || flexDirection == CSSFlexDirectionRowReverse;
} }
static bool isColumnDirection(CSSFlexDirection flexDirection) { static bool isColumnDirection(const CSSFlexDirection flexDirection) {
return flexDirection == CSSFlexDirectionColumn || flexDirection == CSSFlexDirectionColumnReverse; return flexDirection == CSSFlexDirectionColumn || flexDirection == CSSFlexDirectionColumnReverse;
} }
static float getLeadingMargin(CSSNode *node, CSSFlexDirection axis) { static float getLeadingMargin(const CSSNodeRef node, const CSSFlexDirection axis) {
if (isRowDirection(axis) && if (isRowDirection(axis) &&
!CSSValueIsUndefined(computedEdgeValue(node->style.margin, CSSEdgeStart, 0))) { !CSSValueIsUndefined(computedEdgeValue(node->style.margin, CSSEdgeStart, 0))) {
return computedEdgeValue(node->style.margin, CSSEdgeStart, 0); return computedEdgeValue(node->style.margin, CSSEdgeStart, 0);
@@ -484,7 +486,7 @@ static float getLeadingMargin(CSSNode *node, CSSFlexDirection axis) {
return computedEdgeValue(node->style.margin, leading[axis], 0); return computedEdgeValue(node->style.margin, leading[axis], 0);
} }
static float getTrailingMargin(CSSNode *node, CSSFlexDirection axis) { static float getTrailingMargin(const CSSNodeRef node, const CSSFlexDirection axis) {
if (isRowDirection(axis) && if (isRowDirection(axis) &&
!CSSValueIsUndefined(computedEdgeValue(node->style.margin, CSSEdgeEnd, 0))) { !CSSValueIsUndefined(computedEdgeValue(node->style.margin, CSSEdgeEnd, 0))) {
return computedEdgeValue(node->style.margin, CSSEdgeEnd, 0); return computedEdgeValue(node->style.margin, CSSEdgeEnd, 0);
@@ -493,7 +495,7 @@ static float getTrailingMargin(CSSNode *node, CSSFlexDirection axis) {
return computedEdgeValue(node->style.margin, trailing[axis], 0); return computedEdgeValue(node->style.margin, trailing[axis], 0);
} }
static float getLeadingPadding(CSSNode *node, CSSFlexDirection axis) { static float getLeadingPadding(const CSSNodeRef node, const CSSFlexDirection axis) {
if (isRowDirection(axis) && if (isRowDirection(axis) &&
!CSSValueIsUndefined(computedEdgeValue(node->style.padding, CSSEdgeStart, 0)) && !CSSValueIsUndefined(computedEdgeValue(node->style.padding, CSSEdgeStart, 0)) &&
computedEdgeValue(node->style.padding, CSSEdgeStart, 0) >= 0) { computedEdgeValue(node->style.padding, CSSEdgeStart, 0) >= 0) {
@@ -507,7 +509,7 @@ static float getLeadingPadding(CSSNode *node, CSSFlexDirection axis) {
return 0; return 0;
} }
static float getTrailingPadding(CSSNode *node, CSSFlexDirection axis) { static float getTrailingPadding(const CSSNodeRef node, const CSSFlexDirection axis) {
if (isRowDirection(axis) && if (isRowDirection(axis) &&
!CSSValueIsUndefined(computedEdgeValue(node->style.padding, CSSEdgeEnd, 0)) && !CSSValueIsUndefined(computedEdgeValue(node->style.padding, CSSEdgeEnd, 0)) &&
computedEdgeValue(node->style.padding, CSSEdgeEnd, 0) >= 0) { computedEdgeValue(node->style.padding, CSSEdgeEnd, 0) >= 0) {
@@ -521,7 +523,7 @@ static float getTrailingPadding(CSSNode *node, CSSFlexDirection axis) {
return 0; return 0;
} }
static float getLeadingBorder(CSSNode *node, CSSFlexDirection axis) { static float getLeadingBorder(const CSSNodeRef node, const CSSFlexDirection axis) {
if (isRowDirection(axis) && if (isRowDirection(axis) &&
!CSSValueIsUndefined(computedEdgeValue(node->style.border, CSSEdgeStart, 0)) && !CSSValueIsUndefined(computedEdgeValue(node->style.border, CSSEdgeStart, 0)) &&
computedEdgeValue(node->style.border, CSSEdgeStart, 0) >= 0) { computedEdgeValue(node->style.border, CSSEdgeStart, 0) >= 0) {
@@ -535,7 +537,7 @@ static float getLeadingBorder(CSSNode *node, CSSFlexDirection axis) {
return 0; return 0;
} }
static float getTrailingBorder(CSSNode *node, CSSFlexDirection axis) { static float getTrailingBorder(const CSSNodeRef node, const CSSFlexDirection axis) {
if (isRowDirection(axis) && if (isRowDirection(axis) &&
!CSSValueIsUndefined(computedEdgeValue(node->style.border, CSSEdgeEnd, 0)) && !CSSValueIsUndefined(computedEdgeValue(node->style.border, CSSEdgeEnd, 0)) &&
computedEdgeValue(node->style.border, CSSEdgeEnd, 0) >= 0) { computedEdgeValue(node->style.border, CSSEdgeEnd, 0) >= 0) {
@@ -549,40 +551,39 @@ static float getTrailingBorder(CSSNode *node, CSSFlexDirection axis) {
return 0; return 0;
} }
static float getLeadingPaddingAndBorder(CSSNode *node, CSSFlexDirection axis) { static float getLeadingPaddingAndBorder(const CSSNodeRef node, const CSSFlexDirection axis) {
return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); return getLeadingPadding(node, axis) + getLeadingBorder(node, axis);
} }
static float getTrailingPaddingAndBorder(CSSNode *node, CSSFlexDirection axis) { static float getTrailingPaddingAndBorder(const CSSNodeRef node, const CSSFlexDirection axis) {
return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); return getTrailingPadding(node, axis) + getTrailingBorder(node, axis);
} }
static float getMarginAxis(CSSNode *node, CSSFlexDirection axis) { static float getMarginAxis(const CSSNodeRef node, const CSSFlexDirection axis) {
return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); return getLeadingMargin(node, axis) + getTrailingMargin(node, axis);
} }
static float getPaddingAndBorderAxis(CSSNode *node, CSSFlexDirection axis) { static float getPaddingAndBorderAxis(const CSSNodeRef node, const CSSFlexDirection axis) {
return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis); return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis);
} }
static CSSAlign getAlignItem(CSSNode *node, CSSNode *child) { static CSSAlign getAlignItem(const CSSNodeRef node, const CSSNodeRef child) {
if (child->style.alignSelf != CSSAlignAuto) { if (child->style.alignSelf != CSSAlignAuto) {
return child->style.alignSelf; return child->style.alignSelf;
} }
return node->style.alignItems; return node->style.alignItems;
} }
static CSSDirection resolveDirection(CSSNode *node, CSSDirection parentDirection) { static CSSDirection resolveDirection(const CSSNodeRef node, const CSSDirection parentDirection) {
CSSDirection direction = node->style.direction; if (node->style.direction == CSSDirectionInherit) {
return parentDirection > CSSDirectionInherit ? parentDirection : CSSDirectionLTR;
if (direction == CSSDirectionInherit) { } else {
direction = parentDirection > CSSDirectionInherit ? parentDirection : CSSDirectionLTR; return node->style.direction;
}
} }
return direction; static CSSFlexDirection resolveAxis(const CSSFlexDirection flexDirection,
} const CSSDirection direction) {
static CSSFlexDirection resolveAxis(CSSFlexDirection flexDirection, CSSDirection direction) {
if (direction == CSSDirectionRTL) { if (direction == CSSDirectionRTL) {
if (flexDirection == CSSFlexDirectionRow) { if (flexDirection == CSSFlexDirectionRow) {
return CSSFlexDirectionRowReverse; return CSSFlexDirectionRowReverse;
@@ -594,8 +595,8 @@ static CSSFlexDirection resolveAxis(CSSFlexDirection flexDirection, CSSDirection
return flexDirection; return flexDirection;
} }
static CSSFlexDirection getCrossFlexDirection(CSSFlexDirection flexDirection, static CSSFlexDirection getCrossFlexDirection(const CSSFlexDirection flexDirection,
CSSDirection direction) { const CSSDirection direction) {
if (isColumnDirection(flexDirection)) { if (isColumnDirection(flexDirection)) {
return resolveAxis(CSSFlexDirectionRow, direction); return resolveAxis(CSSFlexDirectionRow, direction);
} else { } else {
@@ -603,34 +604,34 @@ static CSSFlexDirection getCrossFlexDirection(CSSFlexDirection flexDirection,
} }
} }
static bool isFlex(CSSNode *node) { static bool isFlex(const CSSNodeRef node) {
return (node->style.positionType == CSSPositionTypeRelative && return (node->style.positionType == CSSPositionTypeRelative &&
(node->style.flexGrow != 0 || node->style.flexShrink != 0)); (node->style.flexGrow != 0 || node->style.flexShrink != 0));
} }
static float getDimWithMargin(CSSNode *node, CSSFlexDirection axis) { static float getDimWithMargin(const CSSNodeRef node, const CSSFlexDirection axis) {
return node->layout.measuredDimensions[dim[axis]] + getLeadingMargin(node, axis) + return node->layout.measuredDimensions[dim[axis]] + getLeadingMargin(node, axis) +
getTrailingMargin(node, axis); getTrailingMargin(node, axis);
} }
static bool isStyleDimDefined(CSSNode *node, CSSFlexDirection axis) { static bool isStyleDimDefined(const CSSNodeRef node, const CSSFlexDirection axis) {
float value = node->style.dimensions[dim[axis]]; const float value = node->style.dimensions[dim[axis]];
return !CSSValueIsUndefined(value) && value >= 0.0; return !CSSValueIsUndefined(value) && value >= 0.0;
} }
static bool isLayoutDimDefined(CSSNode *node, CSSFlexDirection axis) { static bool isLayoutDimDefined(const CSSNodeRef node, const CSSFlexDirection axis) {
float value = node->layout.measuredDimensions[dim[axis]]; const float value = node->layout.measuredDimensions[dim[axis]];
return !CSSValueIsUndefined(value) && value >= 0.0; return !CSSValueIsUndefined(value) && value >= 0.0;
} }
static bool isLeadingPosDefined(CSSNode *node, CSSFlexDirection axis) { static bool isLeadingPosDefined(const CSSNodeRef node, const CSSFlexDirection axis) {
return (isRowDirection(axis) && return (isRowDirection(axis) &&
!CSSValueIsUndefined( !CSSValueIsUndefined(
computedEdgeValue(node->style.position, CSSEdgeStart, CSSUndefined))) || computedEdgeValue(node->style.position, CSSEdgeStart, CSSUndefined))) ||
!CSSValueIsUndefined(computedEdgeValue(node->style.position, leading[axis], CSSUndefined)); !CSSValueIsUndefined(computedEdgeValue(node->style.position, leading[axis], CSSUndefined));
} }
static bool isTrailingPosDefined(CSSNode *node, CSSFlexDirection axis) { static bool isTrailingPosDefined(const CSSNodeRef node, const CSSFlexDirection axis) {
return (isRowDirection(axis) && return (isRowDirection(axis) &&
!CSSValueIsUndefined( !CSSValueIsUndefined(
computedEdgeValue(node->style.position, CSSEdgeEnd, CSSUndefined))) || computedEdgeValue(node->style.position, CSSEdgeEnd, CSSUndefined))) ||
@@ -638,7 +639,7 @@ static bool isTrailingPosDefined(CSSNode *node, CSSFlexDirection axis) {
computedEdgeValue(node->style.position, trailing[axis], CSSUndefined)); computedEdgeValue(node->style.position, trailing[axis], CSSUndefined));
} }
static float getLeadingPosition(CSSNode *node, CSSFlexDirection axis) { static float getLeadingPosition(const CSSNodeRef node, const CSSFlexDirection axis) {
if (isRowDirection(axis) && if (isRowDirection(axis) &&
!CSSValueIsUndefined(computedEdgeValue(node->style.position, CSSEdgeStart, CSSUndefined))) { !CSSValueIsUndefined(computedEdgeValue(node->style.position, CSSEdgeStart, CSSUndefined))) {
return computedEdgeValue(node->style.position, CSSEdgeStart, CSSUndefined); return computedEdgeValue(node->style.position, CSSEdgeStart, CSSUndefined);
@@ -649,7 +650,7 @@ static float getLeadingPosition(CSSNode *node, CSSFlexDirection axis) {
return 0; return 0;
} }
static float getTrailingPosition(CSSNode *node, CSSFlexDirection axis) { static float getTrailingPosition(const CSSNodeRef node, const CSSFlexDirection axis) {
if (isRowDirection(axis) && if (isRowDirection(axis) &&
!CSSValueIsUndefined(computedEdgeValue(node->style.position, CSSEdgeEnd, CSSUndefined))) { !CSSValueIsUndefined(computedEdgeValue(node->style.position, CSSEdgeEnd, CSSUndefined))) {
return computedEdgeValue(node->style.position, CSSEdgeEnd, CSSUndefined); return computedEdgeValue(node->style.position, CSSEdgeEnd, CSSUndefined);
@@ -660,7 +661,8 @@ static float getTrailingPosition(CSSNode *node, CSSFlexDirection axis) {
return 0; return 0;
} }
static float boundAxisWithinMinAndMax(CSSNode *node, CSSFlexDirection axis, float value) { static float
boundAxisWithinMinAndMax(const CSSNodeRef node, const CSSFlexDirection axis, const float value) {
float min = CSSUndefined; float min = CSSUndefined;
float max = CSSUndefined; float max = CSSUndefined;
@@ -677,6 +679,7 @@ static float boundAxisWithinMinAndMax(CSSNode *node, CSSFlexDirection axis, floa
if (!CSSValueIsUndefined(max) && max >= 0.0 && boundValue > max) { if (!CSSValueIsUndefined(max) && max >= 0.0 && boundValue > max) {
boundValue = max; boundValue = max;
} }
if (!CSSValueIsUndefined(min) && min >= 0.0 && boundValue < min) { if (!CSSValueIsUndefined(min) && min >= 0.0 && boundValue < min) {
boundValue = min; boundValue = min;
} }
@@ -687,28 +690,29 @@ static float boundAxisWithinMinAndMax(CSSNode *node, CSSFlexDirection axis, floa
// Like boundAxisWithinMinAndMax but also ensures that the value doesn't go // Like boundAxisWithinMinAndMax but also ensures that the value doesn't go
// below the // below the
// padding and border amount. // padding and border amount.
static float boundAxis(CSSNode *node, CSSFlexDirection axis, float value) { static float boundAxis(const CSSNodeRef node, const CSSFlexDirection axis, const float value) {
return fmaxf(boundAxisWithinMinAndMax(node, axis, value), getPaddingAndBorderAxis(node, axis)); return fmaxf(boundAxisWithinMinAndMax(node, axis, value), getPaddingAndBorderAxis(node, axis));
} }
static void setTrailingPosition(CSSNode *node, CSSNode *child, CSSFlexDirection axis) { static void
float size = child->layout.measuredDimensions[dim[axis]]; setTrailingPosition(const CSSNodeRef node, const CSSNodeRef child, const CSSFlexDirection axis) {
const float size = child->layout.measuredDimensions[dim[axis]];
child->layout.position[trailing[axis]] = child->layout.position[trailing[axis]] =
node->layout.measuredDimensions[dim[axis]] - size - child->layout.position[pos[axis]]; node->layout.measuredDimensions[dim[axis]] - size - child->layout.position[pos[axis]];
} }
// If both left and right are defined, then use left. Otherwise return // If both left and right are defined, then use left. Otherwise return
// +left or -right depending on which is defined. // +left or -right depending on which is defined.
static float getRelativePosition(CSSNode *node, CSSFlexDirection axis) { static float getRelativePosition(const CSSNodeRef node, const CSSFlexDirection axis) {
if (isLeadingPosDefined(node, axis)) { if (isLeadingPosDefined(node, axis)) {
return getLeadingPosition(node, axis); return getLeadingPosition(node, axis);
} }
return -getTrailingPosition(node, axis); return -getTrailingPosition(node, axis);
} }
static void setPosition(CSSNode *node, CSSDirection direction) { static void setPosition(const CSSNodeRef node, const CSSDirection direction) {
CSSFlexDirection mainAxis = resolveAxis(node->style.flexDirection, direction); const CSSFlexDirection mainAxis = resolveAxis(node->style.flexDirection, direction);
CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction); const CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction);
node->layout.position[leading[mainAxis]] = node->layout.position[leading[mainAxis]] =
getLeadingMargin(node, mainAxis) + getRelativePosition(node, mainAxis); getLeadingMargin(node, mainAxis) + getRelativePosition(node, mainAxis);
@@ -832,13 +836,13 @@ static void setPosition(CSSNode *node, CSSDirection direction) {
// undefined then it must also pass a measure mode of CSSMeasureModeUndefined // undefined then it must also pass a measure mode of CSSMeasureModeUndefined
// in that dimension. // in that dimension.
// //
static void layoutNodeImpl(CSSNode *node, static void layoutNodeImpl(const CSSNodeRef node,
float availableWidth, const float availableWidth,
float availableHeight, const float availableHeight,
CSSDirection parentDirection, const CSSDirection parentDirection,
CSSMeasureMode widthMeasureMode, const CSSMeasureMode widthMeasureMode,
CSSMeasureMode heightMeasureMode, const CSSMeasureMode heightMeasureMode,
bool performLayout) { const bool performLayout) {
CSS_ASSERT(CSSValueIsUndefined(availableWidth) ? widthMeasureMode == CSSMeasureModeUndefined CSS_ASSERT(CSSValueIsUndefined(availableWidth) ? widthMeasureMode == CSSMeasureModeUndefined
: true, : true,
"availableWidth is indefinite so widthMeasureMode must be " "availableWidth is indefinite so widthMeasureMode must be "
@@ -848,20 +852,20 @@ static void layoutNodeImpl(CSSNode *node,
"availableHeight is indefinite so heightMeasureMode must be " "availableHeight is indefinite so heightMeasureMode must be "
"CSSMeasureModeUndefined"); "CSSMeasureModeUndefined");
float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSSFlexDirectionRow); const float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSSFlexDirectionRow);
float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSSFlexDirectionColumn); const float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSSFlexDirectionColumn);
float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); const float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow);
float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); const float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn);
// Set the resolved resolution in the node's layout. // Set the resolved resolution in the node's layout.
CSSDirection direction = resolveDirection(node, parentDirection); const CSSDirection direction = resolveDirection(node, parentDirection);
node->layout.direction = direction; node->layout.direction = direction;
// For content (text) nodes, determine the dimensions based on the text // For content (text) nodes, determine the dimensions based on the text
// contents. // contents.
if (node->measure) { if (node->measure) {
float innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; const float innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
float innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; const float innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;
if (widthMeasureMode == CSSMeasureModeExactly && heightMeasureMode == CSSMeasureModeExactly) { if (widthMeasureMode == CSSMeasureModeExactly && heightMeasureMode == CSSMeasureModeExactly) {
// Don't bother sizing the text if both dimensions are already defined. // Don't bother sizing the text if both dimensions are already defined.
@@ -877,7 +881,7 @@ static void layoutNodeImpl(CSSNode *node,
boundAxis(node, CSSFlexDirectionColumn, 0); boundAxis(node, CSSFlexDirectionColumn, 0);
} else { } else {
// Measure the text under the current constraints. // Measure the text under the current constraints.
CSSSize measuredSize = node->measure(node->context, const CSSSize measuredSize = node->measure(node->context,
innerWidth, innerWidth,
widthMeasureMode, widthMeasureMode,
@@ -906,7 +910,7 @@ static void layoutNodeImpl(CSSNode *node,
// For nodes with no children, use the available values if they were provided, // For nodes with no children, use the available values if they were provided,
// or // or
// the minimum size as indicated by the padding and border sizes. // the minimum size as indicated by the padding and border sizes.
uint32_t childCount = CSSNodeListCount(node->children); const uint32_t childCount = CSSNodeListCount(node->children);
if (childCount == 0) { if (childCount == 0) {
node->layout.measuredDimensions[CSSDimensionWidth] = node->layout.measuredDimensions[CSSDimensionWidth] =
boundAxis(node, boundAxis(node,
@@ -973,43 +977,42 @@ static void layoutNodeImpl(CSSNode *node,
} }
// STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM
CSSFlexDirection mainAxis = resolveAxis(node->style.flexDirection, direction); const CSSFlexDirection mainAxis = resolveAxis(node->style.flexDirection, direction);
CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction); const CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction);
bool isMainAxisRow = isRowDirection(mainAxis); const bool isMainAxisRow = isRowDirection(mainAxis);
CSSJustify justifyContent = node->style.justifyContent; const CSSJustify justifyContent = node->style.justifyContent;
bool isNodeFlexWrap = node->style.flexWrap == CSSWrapTypeWrap; const bool isNodeFlexWrap = node->style.flexWrap == CSSWrapTypeWrap;
CSSNode *firstAbsoluteChild = NULL; CSSNodeRef firstAbsoluteChild = NULL;
CSSNode *currentAbsoluteChild = NULL; CSSNodeRef currentAbsoluteChild = NULL;
float leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis); const float leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis);
float trailingPaddingAndBorderMain = getTrailingPaddingAndBorder(node, mainAxis); const float trailingPaddingAndBorderMain = getTrailingPaddingAndBorder(node, mainAxis);
float leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis); const float leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis);
float paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis); const float paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis);
float paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis); const float paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis);
CSSMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; const CSSMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode;
CSSMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; const CSSMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode;
// STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS
float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; const float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
float availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; const float availableInnerHeight =
float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;
float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; const float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight;
const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth;
// STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM
CSSNode *child;
uint32_t i;
float childWidth; float childWidth;
float childHeight; float childHeight;
CSSMeasureMode childWidthMeasureMode; CSSMeasureMode childWidthMeasureMode;
CSSMeasureMode childHeightMeasureMode; CSSMeasureMode childHeightMeasureMode;
for (i = 0; i < childCount; i++) { for (uint32_t i = 0; i < childCount; i++) {
child = CSSNodeListGet(node->children, i); const CSSNodeRef child = CSSNodeListGet(node->children, i);
if (performLayout) { if (performLayout) {
// Set the initial position (relative to the parent). // Set the initial position (relative to the parent).
CSSDirection childDirection = resolveDirection(child, direction); const CSSDirection childDirection = resolveDirection(child, direction);
setPosition(child, childDirection); setPosition(child, childDirection);
} }
@@ -1131,7 +1134,7 @@ static void layoutNodeImpl(CSSNode *node,
// Max main dimension of all the lines. // Max main dimension of all the lines.
float maxLineMainDim = 0; float maxLineMainDim = 0;
while (endOfLineIndex < childCount) { for (; endOfLineIndex < childCount; lineCount++, startOfLineIndex = endOfLineIndex) {
// Number of items on the currently line. May be different than the // Number of items on the currently line. May be different than the
// difference // difference
// between start and end indicates because we skip over absolute-positioned // between start and end indicates because we skip over absolute-positioned
@@ -1147,19 +1150,18 @@ static void layoutNodeImpl(CSSNode *node,
float totalFlexGrowFactors = 0; float totalFlexGrowFactors = 0;
float totalFlexShrinkScaledFactors = 0; float totalFlexShrinkScaledFactors = 0;
i = startOfLineIndex;
// Maintain a linked list of the child nodes that can shrink and/or grow. // Maintain a linked list of the child nodes that can shrink and/or grow.
CSSNode *firstRelativeChild = NULL; CSSNodeRef firstRelativeChild = NULL;
CSSNode *currentRelativeChild = NULL; CSSNodeRef currentRelativeChild = NULL;
// Add items to the current line until it's full or we run out of items. // Add items to the current line until it's full or we run out of items.
while (i < childCount) { for (uint32_t i = startOfLineIndex; i < childCount; i++, endOfLineIndex++) {
child = CSSNodeListGet(node->children, i); const CSSNodeRef child = CSSNodeListGet(node->children, i);
child->lineIndex = lineCount; child->lineIndex = lineCount;
if (child->style.positionType != CSSPositionTypeAbsolute) { if (child->style.positionType != CSSPositionTypeAbsolute) {
float outerFlexBasis = child->layout.computedFlexBasis + getMarginAxis(child, mainAxis); const float outerFlexBasis =
child->layout.computedFlexBasis + getMarginAxis(child, mainAxis);
// If this is a multi-line flow and this item pushes us over the // If this is a multi-line flow and this item pushes us over the
// available size, we've // available size, we've
@@ -1193,14 +1195,11 @@ static void layoutNodeImpl(CSSNode *node,
currentRelativeChild = child; currentRelativeChild = child;
child->nextChild = NULL; child->nextChild = NULL;
} }
i++;
endOfLineIndex++;
} }
// If we don't need to measure the cross axis, we can skip the entire flex // If we don't need to measure the cross axis, we can skip the entire flex
// step. // step.
bool canSkipFlex = !performLayout && measureModeCrossDim == CSSMeasureModeExactly; const bool canSkipFlex = !performLayout && measureModeCrossDim == CSSMeasureModeExactly;
// In order to position the elements in the main axis, we have two // In order to position the elements in the main axis, we have two
// controls. The space between the beginning and the first element // controls. The space between the beginning and the first element
@@ -1226,7 +1225,7 @@ static void layoutNodeImpl(CSSNode *node,
remainingFreeSpace = -sizeConsumedOnCurrentLine; remainingFreeSpace = -sizeConsumedOnCurrentLine;
} }
float originalRemainingFreeSpace = remainingFreeSpace; const float originalRemainingFreeSpace = remainingFreeSpace;
float deltaFreeSpace = 0; float deltaFreeSpace = 0;
if (!canSkipFlex) { if (!canSkipFlex) {
@@ -1387,7 +1386,8 @@ static void layoutNodeImpl(CSSNode *node,
} }
} }
bool requiresStretchLayout = !isStyleDimDefined(currentRelativeChild, crossAxis) && const bool requiresStretchLayout =
!isStyleDimDefined(currentRelativeChild, crossAxis) &&
getAlignItem(node, currentRelativeChild) == CSSAlignStretch; getAlignItem(node, currentRelativeChild) == CSSAlignStretch;
// Recursively call the layout algorithm for this child with the updated // Recursively call the layout algorithm for this child with the updated
@@ -1446,8 +1446,8 @@ static void layoutNodeImpl(CSSNode *node,
float mainDim = leadingPaddingAndBorderMain + leadingMainDim; float mainDim = leadingPaddingAndBorderMain + leadingMainDim;
float crossDim = 0; float crossDim = 0;
for (i = startOfLineIndex; i < endOfLineIndex; ++i) { for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) {
child = CSSNodeListGet(node->children, i); const CSSNodeRef child = CSSNodeListGet(node->children, i);
if (child->style.positionType == CSSPositionTypeAbsolute && if (child->style.positionType == CSSPositionTypeAbsolute &&
isLeadingPosDefined(child, mainAxis)) { isLeadingPosDefined(child, mainAxis)) {
@@ -1517,8 +1517,8 @@ static void layoutNodeImpl(CSSNode *node,
// STEP 7: CROSS-AXIS ALIGNMENT // STEP 7: CROSS-AXIS ALIGNMENT
// We can skip child alignment if we're just measuring the container. // We can skip child alignment if we're just measuring the container.
if (performLayout) { if (performLayout) {
for (i = startOfLineIndex; i < endOfLineIndex; ++i) { for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) {
child = CSSNodeListGet(node->children, i); const CSSNodeRef child = CSSNodeListGet(node->children, i);
if (child->style.positionType == CSSPositionTypeAbsolute) { if (child->style.positionType == CSSPositionTypeAbsolute) {
// If the child is absolutely positioned and has a // If the child is absolutely positioned and has a
@@ -1539,25 +1539,25 @@ static void layoutNodeImpl(CSSNode *node,
// For a relative children, we're either using alignItems (parent) or // For a relative children, we're either using alignItems (parent) or
// alignSelf (child) in order to determine the position in the cross // alignSelf (child) in order to determine the position in the cross
// axis // axis
CSSAlign alignItem = getAlignItem(node, child); const CSSAlign alignItem = getAlignItem(node, child);
// If the child uses align stretch, we need to lay it out one more // If the child uses align stretch, we need to lay it out one more
// time, this time // time, this time
// forcing the cross-axis size to be the computed cross size for the // forcing the cross-axis size to be the computed cross size for the
// current line. // current line.
if (alignItem == CSSAlignStretch) { if (alignItem == CSSAlignStretch) {
childWidth = child->layout.measuredDimensions[CSSDimensionWidth] + const bool isCrossSizeDefinite =
getMarginAxis(child, CSSFlexDirectionRow); (isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionColumn)) ||
childHeight = child->layout.measuredDimensions[CSSDimensionHeight] + (!isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionRow));
getMarginAxis(child, CSSFlexDirectionColumn);
bool isCrossSizeDefinite = false;
if (isMainAxisRow) { if (isMainAxisRow) {
isCrossSizeDefinite = isStyleDimDefined(child, CSSFlexDirectionColumn);
childHeight = crossDim; childHeight = crossDim;
childWidth = child->layout.measuredDimensions[CSSDimensionWidth] +
getMarginAxis(child, CSSFlexDirectionRow);
} else { } else {
isCrossSizeDefinite = isStyleDimDefined(child, CSSFlexDirectionRow);
childWidth = crossDim; childWidth = crossDim;
childHeight = child->layout.measuredDimensions[CSSDimensionHeight] +
getMarginAxis(child, CSSFlexDirectionColumn);
} }
// If the child defines a definite size for its cross axis, there's // If the child defines a definite size for its cross axis, there's
@@ -1577,7 +1577,7 @@ static void layoutNodeImpl(CSSNode *node,
"stretch"); "stretch");
} }
} else if (alignItem != CSSAlignFlexStart) { } else if (alignItem != CSSAlignFlexStart) {
float remainingCrossDim = containerCrossAxis - getDimWithMargin(child, crossAxis); const float remainingCrossDim = containerCrossAxis - getDimWithMargin(child, crossAxis);
if (alignItem == CSSAlignCenter) { if (alignItem == CSSAlignCenter) {
leadingCrossDim += remainingCrossDim / 2; leadingCrossDim += remainingCrossDim / 2;
@@ -1594,21 +1594,16 @@ static void layoutNodeImpl(CSSNode *node,
totalLineCrossDim += crossDim; totalLineCrossDim += crossDim;
maxLineMainDim = fmaxf(maxLineMainDim, mainDim); maxLineMainDim = fmaxf(maxLineMainDim, mainDim);
// Reset variables for new line.
lineCount++;
startOfLineIndex = endOfLineIndex;
endOfLineIndex = startOfLineIndex;
} }
// STEP 8: MULTI-LINE CONTENT ALIGNMENT // STEP 8: MULTI-LINE CONTENT ALIGNMENT
if (lineCount > 1 && performLayout && !CSSValueIsUndefined(availableInnerCrossDim)) { if (lineCount > 1 && performLayout && !CSSValueIsUndefined(availableInnerCrossDim)) {
float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim;
float crossDimLead = 0; float crossDimLead = 0;
float currentLead = leadingPaddingAndBorderCross; float currentLead = leadingPaddingAndBorderCross;
CSSAlign alignContent = node->style.alignContent; const CSSAlign alignContent = node->style.alignContent;
if (alignContent == CSSAlignFlexEnd) { if (alignContent == CSSAlignFlexEnd) {
currentLead += remainingAlignContentDim; currentLead += remainingAlignContentDim;
} else if (alignContent == CSSAlignCenter) { } else if (alignContent == CSSAlignCenter) {
@@ -1620,14 +1615,14 @@ static void layoutNodeImpl(CSSNode *node,
} }
uint32_t endIndex = 0; uint32_t endIndex = 0;
for (i = 0; i < lineCount; ++i) { for (uint32_t i = 0; i < lineCount; i++) {
uint32_t startIndex = endIndex; uint32_t startIndex = endIndex;
uint32_t j; uint32_t ii;
// compute the line's height and find the endIndex // compute the line's height and find the endIndex
float lineHeight = 0; float lineHeight = 0;
for (j = startIndex; j < childCount; ++j) { for (ii = startIndex; ii < childCount; ii++) {
child = CSSNodeListGet(node->children, j); const CSSNodeRef child = CSSNodeListGet(node->children, ii);
if (child->style.positionType != CSSPositionTypeRelative) { if (child->style.positionType != CSSPositionTypeRelative) {
continue; continue;
} }
@@ -1640,17 +1635,17 @@ static void layoutNodeImpl(CSSNode *node,
getMarginAxis(child, crossAxis)); getMarginAxis(child, crossAxis));
} }
} }
endIndex = j; endIndex = ii;
lineHeight += crossDimLead; lineHeight += crossDimLead;
if (performLayout) { if (performLayout) {
for (j = startIndex; j < endIndex; ++j) { for (ii = startIndex; ii < endIndex; ii++) {
child = CSSNodeListGet(node->children, j); const CSSNodeRef child = CSSNodeListGet(node->children, ii);
if (child->style.positionType != CSSPositionTypeRelative) { if (child->style.positionType != CSSPositionTypeRelative) {
continue; continue;
} }
CSSAlign alignContentAlignItem = getAlignItem(node, child); const CSSAlign alignContentAlignItem = getAlignItem(node, child);
if (alignContentAlignItem == CSSAlignFlexStart) { if (alignContentAlignItem == CSSAlignFlexStart) {
child->layout.position[pos[crossAxis]] = child->layout.position[pos[crossAxis]] =
currentLead + getLeadingMargin(child, crossAxis); currentLead + getLeadingMargin(child, crossAxis);
@@ -1824,21 +1819,15 @@ static void layoutNodeImpl(CSSNode *node,
// STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN
if (performLayout) { if (performLayout) {
bool needsMainTrailingPos = false; const bool needsMainTrailingPos =
bool needsCrossTrailingPos = false; mainAxis == CSSFlexDirectionRowReverse || mainAxis == CSSFlexDirectionColumnReverse;
const bool needsCrossTrailingPos =
if (mainAxis == CSSFlexDirectionRowReverse || mainAxis == CSSFlexDirectionColumnReverse) { CSSFlexDirectionRowReverse || crossAxis == CSSFlexDirectionColumnReverse;
needsMainTrailingPos = true;
}
if (crossAxis == CSSFlexDirectionRowReverse || crossAxis == CSSFlexDirectionColumnReverse) {
needsCrossTrailingPos = true;
}
// Set trailing position if necessary. // Set trailing position if necessary.
if (needsMainTrailingPos || needsCrossTrailingPos) { if (needsMainTrailingPos || needsCrossTrailingPos) {
for (i = 0; i < childCount; ++i) { for (uint32_t i = 0; i < childCount; i++) {
child = CSSNodeListGet(node->children, i); const CSSNodeRef child = CSSNodeListGet(node->children, i);
if (needsMainTrailingPos) { if (needsMainTrailingPos) {
setTrailingPosition(node, child, mainAxis); setTrailingPosition(node, child, mainAxis);
@@ -1859,15 +1848,16 @@ bool gPrintSkips = false;
static const char *spacer = " "; static const char *spacer = " ";
static const char *getSpacer(unsigned long level) { static const char *getSpacer(const unsigned long level) {
unsigned long spacerLen = strlen(spacer); const unsigned long spacerLen = strlen(spacer);
if (level > spacerLen) { if (level > spacerLen) {
level = spacerLen; return &spacer[0];
} } else {
return &spacer[spacerLen - level]; return &spacer[spacerLen - level];
} }
}
static const char *getModeName(CSSMeasureMode mode, bool performLayout) { static const char *getModeName(const CSSMeasureMode mode, const bool performLayout) {
const char *kMeasureModeNames[CSSMeasureModeCount] = {"UNDEFINED", "EXACTLY", "AT_MOST"}; const char *kMeasureModeNames[CSSMeasureModeCount] = {"UNDEFINED", "EXACTLY", "AT_MOST"};
const char *kLayoutModeNames[CSSMeasureModeCount] = {"LAY_UNDEFINED", const char *kLayoutModeNames[CSSMeasureModeCount] = {"LAY_UNDEFINED",
"LAY_EXACTLY", "LAY_EXACTLY",
@@ -1881,20 +1871,20 @@ static const char *getModeName(CSSMeasureMode mode, bool performLayout) {
return performLayout ? kLayoutModeNames[mode] : kMeasureModeNames[mode]; return performLayout ? kLayoutModeNames[mode] : kMeasureModeNames[mode];
} }
static bool canUseCachedMeasurement(bool isTextNode, static bool canUseCachedMeasurement(const bool isTextNode,
float availableWidth, const float availableWidth,
float availableHeight, const float availableHeight,
float margin_row, const float margin_row,
float margin_column, const float margin_column,
CSSMeasureMode widthMeasureMode, const CSSMeasureMode widthMeasureMode,
CSSMeasureMode heightMeasureMode, const CSSMeasureMode heightMeasureMode,
CSSCachedMeasurement cached_layout) { CSSCachedMeasurement cached_layout) {
bool is_height_same = (cached_layout.heightMeasureMode == CSSMeasureModeUndefined && const bool is_height_same = (cached_layout.heightMeasureMode == CSSMeasureModeUndefined &&
heightMeasureMode == CSSMeasureModeUndefined) || heightMeasureMode == CSSMeasureModeUndefined) ||
(cached_layout.heightMeasureMode == heightMeasureMode && (cached_layout.heightMeasureMode == heightMeasureMode &&
eq(cached_layout.availableHeight, availableHeight)); eq(cached_layout.availableHeight, availableHeight));
bool is_width_same = (cached_layout.widthMeasureMode == CSSMeasureModeUndefined && const bool is_width_same = (cached_layout.widthMeasureMode == CSSMeasureModeUndefined &&
widthMeasureMode == CSSMeasureModeUndefined) || widthMeasureMode == CSSMeasureModeUndefined) ||
(cached_layout.widthMeasureMode == widthMeasureMode && (cached_layout.widthMeasureMode == widthMeasureMode &&
eq(cached_layout.availableWidth, availableWidth)); eq(cached_layout.availableWidth, availableWidth));
@@ -1903,7 +1893,8 @@ static bool canUseCachedMeasurement(bool isTextNode,
return true; return true;
} }
bool is_height_valid = (cached_layout.heightMeasureMode == CSSMeasureModeUndefined && const bool is_height_valid =
(cached_layout.heightMeasureMode == CSSMeasureModeUndefined &&
heightMeasureMode == CSSMeasureModeAtMost && heightMeasureMode == CSSMeasureModeAtMost &&
cached_layout.computedHeight <= (availableHeight - margin_column)) || cached_layout.computedHeight <= (availableHeight - margin_column)) ||
(heightMeasureMode == CSSMeasureModeExactly && (heightMeasureMode == CSSMeasureModeExactly &&
@@ -1913,7 +1904,7 @@ static bool canUseCachedMeasurement(bool isTextNode,
return true; return true;
} }
bool is_width_valid = (cached_layout.widthMeasureMode == CSSMeasureModeUndefined && const bool is_width_valid = (cached_layout.widthMeasureMode == CSSMeasureModeUndefined &&
widthMeasureMode == CSSMeasureModeAtMost && widthMeasureMode == CSSMeasureModeAtMost &&
cached_layout.computedWidth <= (availableWidth - margin_row)) || cached_layout.computedWidth <= (availableWidth - margin_row)) ||
(widthMeasureMode == CSSMeasureModeExactly && (widthMeasureMode == CSSMeasureModeExactly &&
@@ -1975,19 +1966,20 @@ static bool canUseCachedMeasurement(bool isTextNode,
// Input parameters are the same as layoutNodeImpl (see above) // Input parameters are the same as layoutNodeImpl (see above)
// Return parameter is true if layout was performed, false if skipped // Return parameter is true if layout was performed, false if skipped
// //
bool layoutNodeInternal(CSSNode *node, bool layoutNodeInternal(const CSSNodeRef node,
float availableWidth, const float availableWidth,
float availableHeight, const float availableHeight,
CSSDirection parentDirection, const CSSDirection parentDirection,
CSSMeasureMode widthMeasureMode, const CSSMeasureMode widthMeasureMode,
CSSMeasureMode heightMeasureMode, const CSSMeasureMode heightMeasureMode,
bool performLayout, const bool performLayout,
char *reason) { const char *reason) {
CSSLayout *layout = &node->layout; CSSLayout *layout = &node->layout;
gDepth++; gDepth++;
bool needToVisitNode = (node->isDirty && layout->generationCount != gCurrentGenerationCount) || const bool needToVisitNode =
(node->isDirty && layout->generationCount != gCurrentGenerationCount) ||
layout->lastParentDirection != parentDirection; layout->lastParentDirection != parentDirection;
if (needToVisitNode) { if (needToVisitNode) {
@@ -2012,8 +2004,8 @@ bool layoutNodeInternal(CSSNode *node,
// expensive to measure, so it's worth avoiding redundant measurements if at // expensive to measure, so it's worth avoiding redundant measurements if at
// all possible. // all possible.
if (node->measure) { if (node->measure) {
float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); const float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow);
float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); const float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn);
// First, try to use the layout cache. // First, try to use the layout cache.
if (canUseCachedMeasurement(node->isTextNode, if (canUseCachedMeasurement(node->isTextNode,
@@ -2155,10 +2147,10 @@ bool layoutNodeInternal(CSSNode *node,
return (needToVisitNode || cachedResults == NULL); return (needToVisitNode || cachedResults == NULL);
} }
void CSSNodeCalculateLayout(CSSNode *node, void CSSNodeCalculateLayout(const CSSNodeRef node,
float availableWidth, const float availableWidth,
float availableHeight, const float availableHeight,
CSSDirection parentDirection) { const CSSDirection parentDirection) {
// Increment the generation count. This will force the recursive routine to // Increment the generation count. This will force the recursive routine to
// visit // visit
// all dirty nodes at least once. Subsequent visits will be skipped if the // all dirty nodes at least once. Subsequent visits will be skipped if the
@@ -2166,39 +2158,42 @@ void CSSNodeCalculateLayout(CSSNode *node,
// parameters don't change. // parameters don't change.
gCurrentGenerationCount++; gCurrentGenerationCount++;
float width = availableWidth;
float height = availableHeight;
CSSMeasureMode widthMeasureMode = CSSMeasureModeUndefined; CSSMeasureMode widthMeasureMode = CSSMeasureModeUndefined;
CSSMeasureMode heightMeasureMode = CSSMeasureModeUndefined; CSSMeasureMode heightMeasureMode = CSSMeasureModeUndefined;
if (!CSSValueIsUndefined(availableWidth)) { if (!CSSValueIsUndefined(width)) {
widthMeasureMode = CSSMeasureModeExactly; widthMeasureMode = CSSMeasureModeExactly;
} else if (isStyleDimDefined(node, CSSFlexDirectionRow)) { } else if (isStyleDimDefined(node, CSSFlexDirectionRow)) {
availableWidth = width =
node->style.dimensions[dim[CSSFlexDirectionRow]] + getMarginAxis(node, CSSFlexDirectionRow); node->style.dimensions[dim[CSSFlexDirectionRow]] + getMarginAxis(node, CSSFlexDirectionRow);
widthMeasureMode = CSSMeasureModeExactly; widthMeasureMode = CSSMeasureModeExactly;
} else if (node->style.maxDimensions[CSSDimensionWidth] >= 0.0) { } else if (node->style.maxDimensions[CSSDimensionWidth] >= 0.0) {
availableWidth = node->style.maxDimensions[CSSDimensionWidth]; width = node->style.maxDimensions[CSSDimensionWidth];
widthMeasureMode = CSSMeasureModeAtMost; widthMeasureMode = CSSMeasureModeAtMost;
} }
if (!CSSValueIsUndefined(availableHeight)) { if (!CSSValueIsUndefined(height)) {
heightMeasureMode = CSSMeasureModeExactly; heightMeasureMode = CSSMeasureModeExactly;
} else if (isStyleDimDefined(node, CSSFlexDirectionColumn)) { } else if (isStyleDimDefined(node, CSSFlexDirectionColumn)) {
availableHeight = node->style.dimensions[dim[CSSFlexDirectionColumn]] + height = node->style.dimensions[dim[CSSFlexDirectionColumn]] +
getMarginAxis(node, CSSFlexDirectionColumn); getMarginAxis(node, CSSFlexDirectionColumn);
heightMeasureMode = CSSMeasureModeExactly; heightMeasureMode = CSSMeasureModeExactly;
} else if (node->style.maxDimensions[CSSDimensionHeight] >= 0.0) { } else if (node->style.maxDimensions[CSSDimensionHeight] >= 0.0) {
availableHeight = node->style.maxDimensions[CSSDimensionHeight]; height = node->style.maxDimensions[CSSDimensionHeight];
heightMeasureMode = CSSMeasureModeAtMost; heightMeasureMode = CSSMeasureModeAtMost;
} }
if (layoutNodeInternal(node, if (layoutNodeInternal(node,
availableWidth, width,
availableHeight, height,
parentDirection, parentDirection,
widthMeasureMode, widthMeasureMode,
heightMeasureMode, heightMeasureMode,
true, true,
"initial")) { "initia"
"l")) {
setPosition(node, node->layout.direction); setPosition(node, node->layout.direction);
if (gPrintTree) { if (gPrintTree) {

View File

@@ -123,18 +123,18 @@ typedef void (*CSSPrintFunc)(void *context);
// CSSNode // CSSNode
CSSNodeRef CSSNodeNew(); CSSNodeRef CSSNodeNew();
void CSSNodeInit(CSSNodeRef node); void CSSNodeInit(const CSSNodeRef node);
void CSSNodeFree(CSSNodeRef node); void CSSNodeFree(const CSSNodeRef node);
void CSSNodeInsertChild(CSSNodeRef node, CSSNodeRef child, uint32_t index); void CSSNodeInsertChild(const CSSNodeRef node, const CSSNodeRef child, const uint32_t index);
void CSSNodeRemoveChild(CSSNodeRef node, CSSNodeRef child); void CSSNodeRemoveChild(const CSSNodeRef node, const CSSNodeRef child);
CSSNodeRef CSSNodeGetChild(CSSNodeRef node, uint32_t index); CSSNodeRef CSSNodeGetChild(const CSSNodeRef node, const uint32_t index);
uint32_t CSSNodeChildCount(CSSNodeRef node); uint32_t CSSNodeChildCount(const CSSNodeRef node);
void CSSNodeCalculateLayout(CSSNodeRef node, void CSSNodeCalculateLayout(const CSSNodeRef node,
float availableWidth, const float availableWidth,
float availableHeight, const float availableHeight,
CSSDirection parentDirection); const CSSDirection parentDirection);
// Mark a node as dirty. Only valid for nodes with a custom measure function // Mark a node as dirty. Only valid for nodes with a custom measure function
// set. // set.
@@ -142,26 +142,26 @@ void CSSNodeCalculateLayout(CSSNodeRef node,
// measure functions // measure functions
// depends on information not known to CSSLayout they must perform this dirty // depends on information not known to CSSLayout they must perform this dirty
// marking manually. // marking manually.
void CSSNodeMarkDirty(CSSNodeRef node); void CSSNodeMarkDirty(const CSSNodeRef node);
bool CSSNodeIsDirty(CSSNodeRef node); bool CSSNodeIsDirty(const CSSNodeRef node);
void CSSNodePrint(CSSNodeRef node, CSSPrintOptions options); void CSSNodePrint(const CSSNodeRef node, const CSSPrintOptions options);
bool CSSValueIsUndefined(float value); bool CSSValueIsUndefined(const float value);
#define CSS_NODE_PROPERTY(type, name, paramName) \ #define CSS_NODE_PROPERTY(type, name, paramName) \
void CSSNodeSet##name(CSSNodeRef node, type paramName); \ void CSSNodeSet##name(const CSSNodeRef node, type paramName); \
type CSSNodeGet##name(CSSNodeRef node); type CSSNodeGet##name(const CSSNodeRef node);
#define CSS_NODE_STYLE_PROPERTY(type, name, paramName) \ #define CSS_NODE_STYLE_PROPERTY(type, name, paramName) \
void CSSNodeStyleSet##name(CSSNodeRef node, type paramName); \ void CSSNodeStyleSet##name(const CSSNodeRef node, const type paramName); \
type CSSNodeStyleGet##name(CSSNodeRef node); type CSSNodeStyleGet##name(const CSSNodeRef node);
#define CSS_NODE_STYLE_EDGE_PROPERTY(type, name, paramName) \ #define CSS_NODE_STYLE_EDGE_PROPERTY(type, name, paramName) \
void CSSNodeStyleSet##name(CSSNodeRef node, CSSEdge edge, type paramName); \ void CSSNodeStyleSet##name(const CSSNodeRef node, const CSSEdge edge, const type paramName); \
type CSSNodeStyleGet##name(CSSNodeRef node, CSSEdge edge); type CSSNodeStyleGet##name(const CSSNodeRef node, const CSSEdge edge);
#define CSS_NODE_LAYOUT_PROPERTY(type, name) type CSSNodeLayoutGet##name(CSSNodeRef node); #define CSS_NODE_LAYOUT_PROPERTY(type, name) type CSSNodeLayoutGet##name(const CSSNodeRef node);
CSS_NODE_PROPERTY(void *, Context, context); CSS_NODE_PROPERTY(void *, Context, context);
CSS_NODE_PROPERTY(CSSMeasureFunc, MeasureFunc, measureFunc); CSS_NODE_PROPERTY(CSSMeasureFunc, MeasureFunc, measureFunc);

View File

@@ -15,8 +15,8 @@ struct CSSNodeList {
void **items; void **items;
}; };
CSSNodeListRef CSSNodeListNew(uint32_t initialCapacity) { CSSNodeListRef CSSNodeListNew(const uint32_t initialCapacity) {
CSSNodeListRef list = malloc(sizeof(struct CSSNodeList)); const CSSNodeListRef list = malloc(sizeof(struct CSSNodeList));
CSS_ASSERT(list != NULL, "Could not allocate memory for list"); CSS_ASSERT(list != NULL, "Could not allocate memory for list");
list->capacity = initialCapacity; list->capacity = initialCapacity;
@@ -27,20 +27,20 @@ CSSNodeListRef CSSNodeListNew(uint32_t initialCapacity) {
return list; return list;
} }
void CSSNodeListFree(CSSNodeListRef list) { void CSSNodeListFree(const CSSNodeListRef list) {
free(list->items); free(list->items);
free(list); free(list);
} }
uint32_t CSSNodeListCount(CSSNodeListRef list) { uint32_t CSSNodeListCount(const CSSNodeListRef list) {
return list->count; return list->count;
} }
void CSSNodeListAdd(CSSNodeListRef list, CSSNodeRef node) { void CSSNodeListAdd(const CSSNodeListRef list, const CSSNodeRef node) {
CSSNodeListInsert(list, node, list->count); CSSNodeListInsert(list, node, list->count);
} }
void CSSNodeListInsert(CSSNodeListRef list, CSSNodeRef node, uint32_t index) { void CSSNodeListInsert(const CSSNodeListRef list, const CSSNodeRef node, const uint32_t index) {
if (list->count == list->capacity) { if (list->count == list->capacity) {
list->capacity *= 2; list->capacity *= 2;
list->items = realloc(list->items, sizeof(void *) * list->capacity); list->items = realloc(list->items, sizeof(void *) * list->capacity);
@@ -55,8 +55,8 @@ void CSSNodeListInsert(CSSNodeListRef list, CSSNodeRef node, uint32_t index) {
list->items[index] = node; list->items[index] = node;
} }
CSSNodeRef CSSNodeListRemove(CSSNodeListRef list, uint32_t index) { CSSNodeRef CSSNodeListRemove(const CSSNodeListRef list, const uint32_t index) {
CSSNodeRef removed = list->items[index]; const CSSNodeRef removed = list->items[index];
list->items[index] = NULL; list->items[index] = NULL;
for (uint32_t i = index; i < list->count - 1; i++) { for (uint32_t i = index; i < list->count - 1; i++) {
@@ -68,7 +68,7 @@ CSSNodeRef CSSNodeListRemove(CSSNodeListRef list, uint32_t index) {
return removed; return removed;
} }
CSSNodeRef CSSNodeListDelete(CSSNodeListRef list, CSSNodeRef node) { CSSNodeRef CSSNodeListDelete(const CSSNodeListRef list, const CSSNodeRef node) {
for (uint32_t i = 0; i < list->count; i++) { for (uint32_t i = 0; i < list->count; i++) {
if (list->items[i] == node) { if (list->items[i] == node) {
return CSSNodeListRemove(list, i); return CSSNodeListRemove(list, i);
@@ -78,6 +78,6 @@ CSSNodeRef CSSNodeListDelete(CSSNodeListRef list, CSSNodeRef node) {
return NULL; return NULL;
} }
CSSNodeRef CSSNodeListGet(CSSNodeListRef list, uint32_t index) { CSSNodeRef CSSNodeListGet(const CSSNodeListRef list, const uint32_t index) {
return list->items[index]; return list->items[index];
} }

View File

@@ -21,13 +21,13 @@ CSS_EXTERN_C_BEGIN
typedef struct CSSNodeList *CSSNodeListRef; typedef struct CSSNodeList *CSSNodeListRef;
CSSNodeListRef CSSNodeListNew(uint32_t initialCapacity); CSSNodeListRef CSSNodeListNew(const uint32_t initialCapacity);
void CSSNodeListFree(CSSNodeListRef list); void CSSNodeListFree(const CSSNodeListRef list);
uint32_t CSSNodeListCount(CSSNodeListRef list); uint32_t CSSNodeListCount(const CSSNodeListRef list);
void CSSNodeListAdd(CSSNodeListRef list, CSSNodeRef node); void CSSNodeListAdd(const CSSNodeListRef list, const CSSNodeRef node);
void CSSNodeListInsert(CSSNodeListRef list, CSSNodeRef node, uint32_t index); void CSSNodeListInsert(const CSSNodeListRef list, const CSSNodeRef node, const uint32_t index);
CSSNodeRef CSSNodeListRemove(CSSNodeListRef list, uint32_t index); CSSNodeRef CSSNodeListRemove(const CSSNodeListRef list, const uint32_t index);
CSSNodeRef CSSNodeListDelete(CSSNodeListRef list, CSSNodeRef node); CSSNodeRef CSSNodeListDelete(const CSSNodeListRef list, const CSSNodeRef node);
CSSNodeRef CSSNodeListGet(CSSNodeListRef list, uint32_t index); CSSNodeRef CSSNodeListGet(const CSSNodeListRef list, const uint32_t index);
CSS_EXTERN_C_END CSS_EXTERN_C_END

View File

@@ -14,12 +14,12 @@
// Measure functions can be quite slow, for example when measuring text. // Measure functions can be quite slow, for example when measuring text.
// Simulate this by sleeping for 1 millisecond. // Simulate this by sleeping for 1 millisecond.
static CSSSize _measure(void *context, static CSSSize _measure(const void *context,
float width, const float width,
CSSMeasureMode widthMode, const CSSMeasureMode widthMode,
float height, const float height,
CSSMeasureMode heightMode) { const CSSMeasureMode heightMode) {
struct timespec sleeptime = {0, 1000000}; const struct timespec sleeptime = {0, 1000000};
nanosleep(&sleeptime, NULL); nanosleep(&sleeptime, NULL);
return (CSSSize){ return (CSSSize){
.width = widthMode == CSSMeasureModeUndefined ? 10 : width, .width = widthMode == CSSMeasureModeUndefined ? 10 : width,
@@ -30,12 +30,12 @@ static CSSSize _measure(void *context,
CSS_BENCHMARKS({ CSS_BENCHMARKS({
CSS_BENCHMARK("Stack with flex", { CSS_BENCHMARK("Stack with flex", {
CSSNodeRef root = CSSNodeNew(); const CSSNodeRef root = CSSNodeNew();
CSSNodeStyleSetWidth(root, 100); CSSNodeStyleSetWidth(root, 100);
CSSNodeStyleSetHeight(root, 100); CSSNodeStyleSetHeight(root, 100);
for (uint32_t i = 0; i < 10; i++) { for (uint32_t i = 0; i < 10; i++) {
CSSNodeRef child = CSSNodeNew(); const CSSNodeRef child = CSSNodeNew();
CSSNodeSetMeasureFunc(child, _measure); CSSNodeSetMeasureFunc(child, _measure);
CSSNodeStyleSetFlex(child, 1); CSSNodeStyleSetFlex(child, 1);
CSSNodeInsertChild(root, child, 0); CSSNodeInsertChild(root, child, 0);
@@ -45,10 +45,10 @@ CSS_BENCHMARKS({
}); });
CSS_BENCHMARK("Align stretch in undefined axis", { CSS_BENCHMARK("Align stretch in undefined axis", {
CSSNodeRef root = CSSNodeNew(); const CSSNodeRef root = CSSNodeNew();
for (uint32_t i = 0; i < 10; i++) { for (uint32_t i = 0; i < 10; i++) {
CSSNodeRef child = CSSNodeNew(); const CSSNodeRef child = CSSNodeNew();
CSSNodeStyleSetHeight(child, 20); CSSNodeStyleSetHeight(child, 20);
CSSNodeSetMeasureFunc(child, _measure); CSSNodeSetMeasureFunc(child, _measure);
CSSNodeInsertChild(root, child, 0); CSSNodeInsertChild(root, child, 0);
@@ -58,16 +58,16 @@ CSS_BENCHMARKS({
}); });
CSS_BENCHMARK("Nested flex", { CSS_BENCHMARK("Nested flex", {
CSSNodeRef root = CSSNodeNew(); const CSSNodeRef root = CSSNodeNew();
for (uint32_t i = 0; i < 10; i++) { for (uint32_t i = 0; i < 10; i++) {
CSSNodeRef child = CSSNodeNew(); const CSSNodeRef child = CSSNodeNew();
CSSNodeSetMeasureFunc(child, _measure); CSSNodeSetMeasureFunc(child, _measure);
CSSNodeStyleSetFlex(child, 1); CSSNodeStyleSetFlex(child, 1);
CSSNodeInsertChild(root, child, 0); CSSNodeInsertChild(root, child, 0);
for (uint32_t ii = 0; ii < 10; ii++) { for (uint32_t ii = 0; ii < 10; ii++) {
CSSNodeRef grandChild = CSSNodeNew(); const CSSNodeRef grandChild = CSSNodeNew();
CSSNodeSetMeasureFunc(grandChild, _measure); CSSNodeSetMeasureFunc(grandChild, _measure);
CSSNodeStyleSetFlex(grandChild, 1); CSSNodeStyleSetFlex(grandChild, 1);
CSSNodeInsertChild(child, grandChild, 0); CSSNodeInsertChild(child, grandChild, 0);

View File

@@ -89,7 +89,7 @@ function assertTestTree(node, nodeName, parentName) {
function setupTestTree(node, nodeName, parentName, index) { function setupTestTree(node, nodeName, parentName, index) {
var lines = [ var lines = [
'CSSNodeRef ' + nodeName + ' = CSSNodeNew();', 'const CSSNodeRef ' + nodeName + ' = CSSNodeNew();',
]; ];
for (var style in node.style) { for (var style in node.style) {

View File

@@ -100,15 +100,14 @@ static CSSSize _jniMeasureFunc(void *context,
jlong measureResult = jlong measureResult =
(*env)->CallLongMethod(env, context, measureID, width, widthMode, height, heightMode); (*env)->CallLongMethod(env, context, measureID, width, widthMode, height, heightMode);
CSSSize size = {
return (CSSSize){
.width = (int32_t)(measureResult >> 32), .height = (int32_t) measureResult, .width = (int32_t)(measureResult >> 32), .height = (int32_t) measureResult,
}; };
return size;
} }
CSS_NODE_JNI(jlong, CSSNodeNew(JNIEnv *env, jobject thiz) { CSS_NODE_JNI(jlong, CSSNodeNew(JNIEnv *env, jobject thiz) {
CSSNodeRef node = CSSNodeNew(); const CSSNodeRef node = CSSNodeNew();
CSSNodeSetContext(node, (*env)->NewGlobalRef(env, thiz)); CSSNodeSetContext(node, (*env)->NewGlobalRef(env, thiz));
CSSNodeSetPrintFunc(node, _jniPrint); CSSNodeSetPrintFunc(node, _jniPrint);
return (jlong)(intptr_t) node; return (jlong)(intptr_t) node;

View File

@@ -22,19 +22,19 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
TEST(CSSLayoutTest, flex_basis) { TEST(CSSLayoutTest, flex_basis) {
CSSNodeRef root = CSSNodeNew(); const CSSNodeRef root = CSSNodeNew();
CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow); CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow);
CSSNodeStyleSetWidth(root, 300); CSSNodeStyleSetWidth(root, 300);
CSSNodeStyleSetHeight(root, 100); CSSNodeStyleSetHeight(root, 100);
CSSNodeRef root_child0 = CSSNodeNew(); const CSSNodeRef root_child0 = CSSNodeNew();
CSSNodeStyleSetFlexGrow(root_child0, 1); CSSNodeStyleSetFlexGrow(root_child0, 1);
CSSNodeStyleSetFlexBasis(root_child0, 100); CSSNodeStyleSetFlexBasis(root_child0, 100);
CSSNodeStyleSetWidth(root_child0, 200); CSSNodeStyleSetWidth(root_child0, 200);
CSSNodeStyleSetHeight(root_child0, 100); CSSNodeStyleSetHeight(root_child0, 100);
CSSNodeInsertChild(root, root_child0, 0); CSSNodeInsertChild(root, root_child0, 0);
CSSNodeRef root_child1 = CSSNodeNew(); const CSSNodeRef root_child1 = CSSNodeNew();
CSSNodeStyleSetFlexGrow(root_child1, 1); CSSNodeStyleSetFlexGrow(root_child1, 1);
CSSNodeStyleSetWidth(root_child1, 100); CSSNodeStyleSetWidth(root_child1, 100);
CSSNodeStyleSetHeight(root_child1, 100); CSSNodeStyleSetHeight(root_child1, 100);

View File

@@ -26,11 +26,11 @@ __forceinline const float fminf(const float a, const float b) {
#endif #endif
#endif #endif
static bool eq(float a, float b) { static bool eq(const float a, const float b) {
return fabs(a - b) < 0.0001; return fabs(a - b) < 0.0001;
} }
static bool are_layout_equal(CSSNode *a, CSSNode *b) { static bool are_layout_equal(const CSSNodeRef a, const CSSNodeRef b) {
if (!eq(a->layout.dimensions[CSSDimensionWidth], b->layout.dimensions[CSSDimensionWidth]) || if (!eq(a->layout.dimensions[CSSDimensionWidth], b->layout.dimensions[CSSDimensionWidth]) ||
!eq(a->layout.dimensions[CSSDimensionHeight], b->layout.dimensions[CSSDimensionHeight]) || !eq(a->layout.dimensions[CSSDimensionHeight], b->layout.dimensions[CSSDimensionHeight]) ||
!eq(a->layout.position[CSSEdgeTop], b->layout.position[CSSEdgeTop]) || !eq(a->layout.position[CSSEdgeTop], b->layout.position[CSSEdgeTop]) ||
@@ -38,7 +38,7 @@ static bool are_layout_equal(CSSNode *a, CSSNode *b) {
!eq(CSSNodeChildCount(a), CSSNodeChildCount(b))) { !eq(CSSNodeChildCount(a), CSSNodeChildCount(b))) {
return false; return false;
} }
for (int i = 0; i < CSSNodeChildCount(a); ++i) { for (uint32_t i = 0; i < CSSNodeChildCount(a); ++i) {
if (!are_layout_equal(CSSNodeGetChild(a, i), CSSNodeGetChild(b, i))) { if (!are_layout_equal(CSSNodeGetChild(a, i), CSSNodeGetChild(b, i))) {
return false; return false;
} }
@@ -47,12 +47,14 @@ static bool are_layout_equal(CSSNode *a, CSSNode *b) {
} }
CSSSize measure(void *context, CSSSize measure(void *context,
float width, float availableWidth,
CSSMeasureMode widthMode, CSSMeasureMode widthMode,
float height, float availableHeight,
CSSMeasureMode heightMode) { CSSMeasureMode heightMode) {
const char *text = (const char *) context; const char *text = (const char *) context;
CSSSize result; CSSSize result;
float width = availableWidth;
float height = availableHeight;
if (strcmp(text, SMALL_TEXT) == 0) { if (strcmp(text, SMALL_TEXT) == 0) {
if (widthMode == CSSMeasureModeUndefined) { if (widthMode == CSSMeasureModeUndefined) {
width = 1000000; width = 1000000;
@@ -108,18 +110,18 @@ CSSSize measure(void *context,
return result; return result;
} }
bool test(CSSNode *style, CSSNode *expected_layout) { bool test(const CSSNodeRef style, const CSSNodeRef expected_layout) {
CSSNodeCalculateLayout(style, CSSUndefined, CSSUndefined, (CSSDirection) -1); CSSNodeCalculateLayout(style, CSSUndefined, CSSUndefined, (CSSDirection) -1);
return are_layout_equal(style, expected_layout); return are_layout_equal(style, expected_layout);
} }
CSSNode *new_test_css_node(void) { CSSNodeRef new_test_css_node() {
CSSNode *node = CSSNodeNew(); CSSNodeRef node = CSSNodeNew();
return node; return node;
} }
void init_css_node_children(CSSNode *node, int childCount) { void init_css_node_children(const CSSNodeRef node, const uint32_t childCount) {
for (int i = 0; i < childCount; ++i) { for (uint32_t i = 0; i < childCount; ++i) {
CSSNodeInsertChild(node, new_test_css_node(), 0); CSSNodeInsertChild(node, new_test_css_node(), 0);
} }
} }

View File

@@ -33,14 +33,14 @@
CSS_EXTERN_C_BEGIN CSS_EXTERN_C_BEGIN
bool test(CSSNode *style, CSSNode *expected_layout); bool test(const CSSNodeRef style, const CSSNodeRef expected_layout);
CSSSize measure(void *context, CSSSize measure(void *context,
float width, float availableWidth,
CSSMeasureMode widthMode, CSSMeasureMode widthMode,
float height, float availableHeight,
CSSMeasureMode heightMode); CSSMeasureMode heightMode);
void init_css_node_children(CSSNode *node, int childCount); void init_css_node_children(const CSSNodeRef node, const uint32_t childCount);
CSSNode *new_test_css_node(void); CSSNodeRef new_test_css_node();
CSS_EXTERN_C_END CSS_EXTERN_C_END