http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9acc1bc4/ios/sdk/WeexSDK/Sources/Layout/Layout.c ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Layout/Layout.c b/ios/sdk/WeexSDK/Sources/Layout/Layout.c deleted file mode 100644 index 6e3214f..0000000 --- a/ios/sdk/WeexSDK/Sources/Layout/Layout.c +++ /dev/null @@ -1,1329 +0,0 @@ - -/** - * Copyright (c) 2014, 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 <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -// in concatenated header, don't include Layout.h it's already at the top -#ifndef CSS_LAYOUT_IMPLEMENTATION -#include "WXLayoutDefine.h" -#endif - -#ifdef _MSC_VER -#include <float.h> -#define isnan _isnan - -/* define fmaxf if < VC12 */ -#if _MSC_VER < 1800 -__forceinline const float fmaxf(const float a, const float b) { - return (a > b) ? a : b; -} -#endif -#endif - -bool isUndefined(float value) { - return isnan(value); -} - -static bool eq(float a, float b) { - if (isUndefined(a)) { - return isUndefined(b); - } - return fabs(a - b) < 0.0001; -} - -void init_css_node(css_node_t *node) { - node->style.align_items = CSS_ALIGN_STRETCH; - node->style.align_content = CSS_ALIGN_FLEX_START; - - node->style.direction = CSS_DIRECTION_INHERIT; - node->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN; - - // Some of the fields default to undefined and not 0 - node->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->style.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - node->style.minDimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->style.minDimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - node->style.maxDimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->style.maxDimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - node->style.position[CSS_LEFT] = CSS_UNDEFINED; - node->style.position[CSS_TOP] = CSS_UNDEFINED; - node->style.position[CSS_RIGHT] = CSS_UNDEFINED; - node->style.position[CSS_BOTTOM] = CSS_UNDEFINED; - - node->style.margin[CSS_START] = CSS_UNDEFINED; - node->style.margin[CSS_END] = CSS_UNDEFINED; - node->style.padding[CSS_START] = CSS_UNDEFINED; - node->style.padding[CSS_END] = CSS_UNDEFINED; - node->style.border[CSS_START] = CSS_UNDEFINED; - node->style.border[CSS_END] = CSS_UNDEFINED; - - node->layout.dimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->layout.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - // Such that the comparison is always going to be false - node->layout.last_requested_dimensions[CSS_WIDTH] = -1; - node->layout.last_requested_dimensions[CSS_HEIGHT] = -1; - node->layout.last_parent_max_width = -1; - node->layout.last_parent_max_height = -1; - node->layout.last_direction = (css_direction_t)-1; - node->layout.should_update = true; -} - -css_node_t *new_css_node() { - css_node_t *node = (css_node_t *)calloc(1, sizeof(*node)); - init_css_node(node); - return node; -} - -void free_css_node(css_node_t *node) { - free(node); -} - -static void indent(int n) { - for (int i = 0; i < n; ++i) { - printf(" "); - } -} - -static void print_number_0(const char *str, float number) { - if (!eq(number, 0)) { - printf("%s: %g, ", str, number); - } -} - -static void print_number_nan(const char *str, float number) { - if (!isnan(number)) { - printf("%s: %g, ", str, number); - } -} - -static bool four_equal(float four[4]) { - return - eq(four[0], four[1]) && - eq(four[0], four[2]) && - eq(four[0], four[3]); -} - - -static void print_css_node_rec( - css_node_t *node, - css_print_options_t options, - int level -) { - indent(level); - printf("{"); - - if (node->print) { - node->print(node->context); - } - - if (options & CSS_PRINT_LAYOUT) { - printf("layout: {"); - printf("width: %g, ", node->layout.dimensions[CSS_WIDTH]); - printf("height: %g, ", node->layout.dimensions[CSS_HEIGHT]); - printf("top: %g, ", node->layout.position[CSS_TOP]); - printf("left: %g", node->layout.position[CSS_LEFT]); - printf("}, "); - } - - if (options & CSS_PRINT_STYLE) { - if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN) { - printf("flexDirection: 'column', "); - } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - printf("flexDirection: 'columnReverse', "); - } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW) { - printf("flexDirection: 'row', "); - } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) { - printf("flexDirection: 'rowReverse', "); - } - - if (node->style.justify_content == CSS_JUSTIFY_CENTER) { - printf("justifyContent: 'center', "); - } else if (node->style.justify_content == CSS_JUSTIFY_FLEX_END) { - printf("justifyContent: 'flex-end', "); - } else if (node->style.justify_content == CSS_JUSTIFY_SPACE_AROUND) { - printf("justifyContent: 'space-around', "); - } else if (node->style.justify_content == CSS_JUSTIFY_SPACE_BETWEEN) { - printf("justifyContent: 'space-between', "); - } - - if (node->style.align_items == CSS_ALIGN_CENTER) { - printf("alignItems: 'center', "); - } else if (node->style.align_items == CSS_ALIGN_FLEX_END) { - printf("alignItems: 'flex-end', "); - } else if (node->style.align_items == CSS_ALIGN_STRETCH) { - printf("alignItems: 'stretch', "); - } - - if (node->style.align_content == CSS_ALIGN_CENTER) { - printf("alignContent: 'center', "); - } else if (node->style.align_content == CSS_ALIGN_FLEX_END) { - printf("alignContent: 'flex-end', "); - } else if (node->style.align_content == CSS_ALIGN_STRETCH) { - printf("alignContent: 'stretch', "); - } - - if (node->style.align_self == CSS_ALIGN_FLEX_START) { - printf("alignSelf: 'flex-start', "); - } else if (node->style.align_self == CSS_ALIGN_CENTER) { - printf("alignSelf: 'center', "); - } else if (node->style.align_self == CSS_ALIGN_FLEX_END) { - printf("alignSelf: 'flex-end', "); - } else if (node->style.align_self == CSS_ALIGN_STRETCH) { - printf("alignSelf: 'stretch', "); - } - - print_number_nan("flex", node->style.flex); - - if (four_equal(node->style.margin)) { - print_number_0("margin", node->style.margin[CSS_LEFT]); - } else { - print_number_0("marginLeft", node->style.margin[CSS_LEFT]); - print_number_0("marginRight", node->style.margin[CSS_RIGHT]); - print_number_0("marginTop", node->style.margin[CSS_TOP]); - print_number_0("marginBottom", node->style.margin[CSS_BOTTOM]); - print_number_0("marginStart", node->style.margin[CSS_START]); - print_number_0("marginEnd", node->style.margin[CSS_END]); - } - - if (four_equal(node->style.padding)) { - print_number_0("padding", node->style.margin[CSS_LEFT]); - } else { - print_number_0("paddingLeft", node->style.padding[CSS_LEFT]); - print_number_0("paddingRight", node->style.padding[CSS_RIGHT]); - print_number_0("paddingTop", node->style.padding[CSS_TOP]); - print_number_0("paddingBottom", node->style.padding[CSS_BOTTOM]); - print_number_0("paddingStart", node->style.padding[CSS_START]); - print_number_0("paddingEnd", node->style.padding[CSS_END]); - } - - if (four_equal(node->style.border)) { - print_number_0("borderWidth", node->style.border[CSS_LEFT]); - } else { - print_number_0("borderLeftWidth", node->style.border[CSS_LEFT]); - print_number_0("borderRightWidth", node->style.border[CSS_RIGHT]); - print_number_0("borderTopWidth", node->style.border[CSS_TOP]); - print_number_0("borderBottomWidth", node->style.border[CSS_BOTTOM]); - print_number_0("borderStartWidth", node->style.border[CSS_START]); - print_number_0("borderEndWidth", node->style.border[CSS_END]); - } - - print_number_nan("width", node->style.dimensions[CSS_WIDTH]); - print_number_nan("height", node->style.dimensions[CSS_HEIGHT]); - - if (node->style.position_type == CSS_POSITION_ABSOLUTE) { - printf("position: 'absolute', "); - } - - print_number_nan("left", node->style.position[CSS_LEFT]); - print_number_nan("right", node->style.position[CSS_RIGHT]); - print_number_nan("top", node->style.position[CSS_TOP]); - print_number_nan("bottom", node->style.position[CSS_BOTTOM]); - } - - if (options & CSS_PRINT_CHILDREN && node->children_count > 0) { - printf("children: [\n"); - for (int i = 0; i < node->children_count; ++i) { - print_css_node_rec(node->get_child(node->context, i), options, level + 1); - } - indent(level); - printf("]},\n"); - } else { - printf("},\n"); - } -} - -void print_css_node(css_node_t *node, css_print_options_t options) { - print_css_node_rec(node, options, 0); -} - - -static css_position_t leading[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT -}; -static css_position_t trailing[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_RIGHT, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_LEFT -}; -static css_position_t pos[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT -}; -static css_dimension_t dim[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_HEIGHT, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_HEIGHT, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_WIDTH, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_WIDTH -}; - -static bool isRowDirection(css_flex_direction_t flex_direction) { - return flex_direction == CSS_FLEX_DIRECTION_ROW || - flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE; -} - -static bool isColumnDirection(css_flex_direction_t flex_direction) { - return flex_direction == CSS_FLEX_DIRECTION_COLUMN || - flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE; -} - -static float getLeadingMargin(css_node_t *node, css_flex_direction_t axis) { - if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_START])) { - return node->style.margin[CSS_START]; - } - - return node->style.margin[leading[axis]]; -} - -static float getTrailingMargin(css_node_t *node, css_flex_direction_t axis) { - if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_END])) { - return node->style.margin[CSS_END]; - } - - return node->style.margin[trailing[axis]]; -} - -static float getLeadingPadding(css_node_t *node, css_flex_direction_t axis) { - if (isRowDirection(axis) && - !isUndefined(node->style.padding[CSS_START]) && - node->style.padding[CSS_START] >= 0) { - return node->style.padding[CSS_START]; - } - - if (node->style.padding[leading[axis]] >= 0) { - return node->style.padding[leading[axis]]; - } - - return 0; -} - -static float getTrailingPadding(css_node_t *node, css_flex_direction_t axis) { - if (isRowDirection(axis) && - !isUndefined(node->style.padding[CSS_END]) && - node->style.padding[CSS_END] >= 0) { - return node->style.padding[CSS_END]; - } - - if (node->style.padding[trailing[axis]] >= 0) { - return node->style.padding[trailing[axis]]; - } - - return 0; -} - -static float getLeadingBorder(css_node_t *node, css_flex_direction_t axis) { - if (isRowDirection(axis) && - !isUndefined(node->style.border[CSS_START]) && - node->style.border[CSS_START] >= 0) { - return node->style.border[CSS_START]; - } - - if (node->style.border[leading[axis]] >= 0) { - return node->style.border[leading[axis]]; - } - - return 0; -} - -static float getTrailingBorder(css_node_t *node, css_flex_direction_t axis) { - if (isRowDirection(axis) && - !isUndefined(node->style.border[CSS_END]) && - node->style.border[CSS_END] >= 0) { - return node->style.border[CSS_END]; - } - - if (node->style.border[trailing[axis]] >= 0) { - return node->style.border[trailing[axis]]; - } - - return 0; -} - -static float getLeadingPaddingAndBorder(css_node_t *node, css_flex_direction_t axis) { - return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); -} - -static float getTrailingPaddingAndBorder(css_node_t *node, css_flex_direction_t axis) { - return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); -} - -static float getBorderAxis(css_node_t *node, css_flex_direction_t axis) { - return getLeadingBorder(node, axis) + getTrailingBorder(node, axis); -} - -static float getMarginAxis(css_node_t *node, css_flex_direction_t axis) { - return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); -} - -static float getPaddingAndBorderAxis(css_node_t *node, css_flex_direction_t axis) { - return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis); -} - -static css_align_t getAlignItem(css_node_t *node, css_node_t *child) { - if (child->style.align_self != CSS_ALIGN_AUTO) { - return child->style.align_self; - } - return node->style.align_items; -} - -static css_direction_t resolveDirection(css_node_t *node, css_direction_t parentDirection) { - css_direction_t direction = node->style.direction; - - if (direction == CSS_DIRECTION_INHERIT) { - direction = parentDirection > CSS_DIRECTION_INHERIT ? parentDirection : CSS_DIRECTION_LTR; - } - - return direction; -} - -static css_flex_direction_t getFlexDirection(css_node_t *node) { - return node->style.flex_direction; -} - -static css_flex_direction_t resolveAxis(css_flex_direction_t flex_direction, css_direction_t direction) { - if (direction == CSS_DIRECTION_RTL) { - if (flex_direction == CSS_FLEX_DIRECTION_ROW) { - return CSS_FLEX_DIRECTION_ROW_REVERSE; - } else if (flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) { - return CSS_FLEX_DIRECTION_ROW; - } - } - - return flex_direction; -} - -static css_flex_direction_t getCrossFlexDirection(css_flex_direction_t flex_direction, css_direction_t direction) { - if (isColumnDirection(flex_direction)) { - return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); - } else { - return CSS_FLEX_DIRECTION_COLUMN; - } -} - -static float getFlex(css_node_t *node) { - return node->style.flex; -} - -static bool isFlex(css_node_t *node) { - return ( - node->style.position_type == CSS_POSITION_RELATIVE && - getFlex(node) > 0 - ); -} - -static bool isFlexWrap(css_node_t *node) { - return node->style.flex_wrap == CSS_WRAP; -} - -static float getDimWithMargin(css_node_t *node, css_flex_direction_t axis) { - return node->layout.dimensions[dim[axis]] + - getLeadingMargin(node, axis) + - getTrailingMargin(node, axis); -} - -static bool isStyleDimDefined(css_node_t *node, css_flex_direction_t axis) { - float value = node->style.dimensions[dim[axis]]; - return !isUndefined(value) && value >= 0.0; -} - -static bool isLayoutDimDefined(css_node_t *node, css_flex_direction_t axis) { - float value = node->layout.dimensions[dim[axis]]; - return !isUndefined(value) && value >= 0.0; -} - -static bool isPosDefined(css_node_t *node, css_position_t position) { - return !isUndefined(node->style.position[position]); -} - -static bool isMeasureDefined(css_node_t *node) { - return node->measure; -} - -static float getPosition(css_node_t *node, css_position_t position) { - float result = node->style.position[position]; - if (!isUndefined(result)) { - return result; - } - return 0; -} - -static float boundAxis(css_node_t *node, css_flex_direction_t axis, float value) { - float min = CSS_UNDEFINED; - float max = CSS_UNDEFINED; - - if (isColumnDirection(axis)) { - min = node->style.minDimensions[CSS_HEIGHT]; - max = node->style.maxDimensions[CSS_HEIGHT]; - } else if (isRowDirection(axis)) { - min = node->style.minDimensions[CSS_WIDTH]; - max = node->style.maxDimensions[CSS_WIDTH]; - } - - float boundValue = value; - - if (!isUndefined(max) && max >= 0.0 && boundValue > max) { - boundValue = max; - } - if (!isUndefined(min) && min >= 0.0 && boundValue < min) { - boundValue = min; - } - - return boundValue; -} - -// When the user specifically sets a value for width or height -static void setDimensionFromStyle(css_node_t *node, css_flex_direction_t axis) { - // The parent already computed us a width or height. We just skip it - if (isLayoutDimDefined(node, axis)) { - return; - } - // We only run if there's a width or height defined - if (!isStyleDimDefined(node, axis)) { - return; - } - - // The dimensions can never be smaller than the padding and border - node->layout.dimensions[dim[axis]] = fmaxf( - boundAxis(node, axis, node->style.dimensions[dim[axis]]), - getPaddingAndBorderAxis(node, axis) - ); -} - -static void setTrailingPosition(css_node_t *node, css_node_t *child, css_flex_direction_t axis) { - child->layout.position[trailing[axis]] = node->layout.dimensions[dim[axis]] - - child->layout.dimensions[dim[axis]] - child->layout.position[pos[axis]]; - } - -// If both left and right are defined, then use left. Otherwise return -// +left or -right depending on which is defined. -static float getRelativePosition(css_node_t *node, css_flex_direction_t axis) { - float lead = node->style.position[leading[axis]]; - if (!isUndefined(lead)) { - return lead; - } - return -getPosition(node, trailing[axis]); -} - -static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentMaxHeight, css_direction_t parentDirection) { - /** START_GENERATED **/ - css_direction_t direction = resolveDirection(node, parentDirection); - css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction); - css_flex_direction_t crossAxis = getCrossFlexDirection(mainAxis, direction); - css_flex_direction_t resolvedRowAxis = resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); - - // Handle width and height style attributes - setDimensionFromStyle(node, mainAxis); - setDimensionFromStyle(node, crossAxis); - - // Set the resolved resolution in the node's layout - node->layout.direction = direction; - - // The position is set by the parent, but we need to complete it with a - // delta composed of the margin and left/top/right/bottom - node->layout.position[leading[mainAxis]] += getLeadingMargin(node, mainAxis) + - getRelativePosition(node, mainAxis); - node->layout.position[trailing[mainAxis]] += getTrailingMargin(node, mainAxis) + - getRelativePosition(node, mainAxis); - node->layout.position[leading[crossAxis]] += getLeadingMargin(node, crossAxis) + - getRelativePosition(node, crossAxis); - node->layout.position[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) + - getRelativePosition(node, crossAxis); - - // Inline immutable values from the target node to avoid excessive method - // invocations during the layout calculation. - int childCount = node->children_count; - float paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis); - float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); - - if (isMeasureDefined(node)) { - bool isResolvedRowDimDefined = isLayoutDimDefined(node, resolvedRowAxis); - - float width = CSS_UNDEFINED; - css_measure_mode_t widthMode = CSS_MEASURE_MODE_UNDEFINED; - if (isStyleDimDefined(node, resolvedRowAxis)) { - width = node->style.dimensions[CSS_WIDTH]; - widthMode = CSS_MEASURE_MODE_EXACTLY; - } else if (isResolvedRowDimDefined) { - width = node->layout.dimensions[dim[resolvedRowAxis]]; - widthMode = CSS_MEASURE_MODE_EXACTLY; - } else { - width = parentMaxWidth - - getMarginAxis(node, resolvedRowAxis); - widthMode = CSS_MEASURE_MODE_AT_MOST; - } - width -= paddingAndBorderAxisResolvedRow; - if (isUndefined(width)) { - widthMode = CSS_MEASURE_MODE_UNDEFINED; - } - - float height = CSS_UNDEFINED; - css_measure_mode_t heightMode = CSS_MEASURE_MODE_UNDEFINED; - if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { - height = node->style.dimensions[CSS_HEIGHT]; - heightMode = CSS_MEASURE_MODE_EXACTLY; - } else if (isLayoutDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { - height = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]; - heightMode = CSS_MEASURE_MODE_EXACTLY; - } else { - height = parentMaxHeight - - getMarginAxis(node, resolvedRowAxis); - heightMode = CSS_MEASURE_MODE_AT_MOST; - } - height -= getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); - if (isUndefined(height)) { - heightMode = CSS_MEASURE_MODE_UNDEFINED; - } - - // We only need to give a dimension for the text if we haven't got any - // for it computed yet. It can either be from the style attribute or because - // the element is flexible. - bool isRowUndefined = !isStyleDimDefined(node, resolvedRowAxis) && !isResolvedRowDimDefined; - bool isColumnUndefined = !isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) && - isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]); - - // Let's not measure the text if we already know both dimensions - if (isRowUndefined || isColumnUndefined) { - css_dim_t measureDim = node->measure( - node->context, - - width, - widthMode, - height, - heightMode - ); - if (isRowUndefined) { - node->layout.dimensions[CSS_WIDTH] = measureDim.dimensions[CSS_WIDTH] + - paddingAndBorderAxisResolvedRow; - } - if (isColumnUndefined) { - node->layout.dimensions[CSS_HEIGHT] = measureDim.dimensions[CSS_HEIGHT] + - paddingAndBorderAxisColumn; - } - } - if (childCount == 0) { - return; - } - } - - bool isNodeFlexWrap = isFlexWrap(node); - - css_justify_t justifyContent = node->style.justify_content; - - float leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis); - float leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis); - float paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis); - float paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis); - - bool isMainDimDefined = isLayoutDimDefined(node, mainAxis); - bool isCrossDimDefined = isLayoutDimDefined(node, crossAxis); - bool isMainRowDirection = isRowDirection(mainAxis); - - int i; - int ii; - css_node_t* child; - css_flex_direction_t axis; - - css_node_t* firstAbsoluteChild = NULL; - css_node_t* currentAbsoluteChild = NULL; - - float definedMainDim = CSS_UNDEFINED; - if (isMainDimDefined) { - definedMainDim = node->layout.dimensions[dim[mainAxis]] - paddingAndBorderAxisMain; - } - - // We want to execute the next two loops one per line with flex-wrap - int startLine = 0; - int endLine = 0; - // int nextOffset = 0; - int alreadyComputedNextLayout = 0; - // We aggregate the total dimensions of the container in those two variables - float linesCrossDim = 0; - float linesMainDim = 0; - int linesCount = 0; - while (endLine < childCount) { - // <Loop A> Layout non flexible children and count children by type - - // mainContentDim is accumulation of the dimensions and margin of all the - // non flexible children. This will be used in order to either set the - // dimensions of the node if none already exist, or to compute the - // remaining space left for the flexible children. - float mainContentDim = 0; - - // There are three kind of children, non flexible, flexible and absolute. - // We need to know how many there are in order to distribute the space. - int flexibleChildrenCount = 0; - float totalFlexible = 0; - int nonFlexibleChildrenCount = 0; - - // Use the line loop to position children in the main axis for as long - // as they are using a simple stacking behaviour. Children that are - // immediately stacked in the initial loop will not be touched again - // in <Loop C>. - bool isSimpleStackMain = - (isMainDimDefined && justifyContent == CSS_JUSTIFY_FLEX_START) || - (!isMainDimDefined && justifyContent != CSS_JUSTIFY_CENTER); - int firstComplexMain = (isSimpleStackMain ? childCount : startLine); - - // Use the initial line loop to position children in the cross axis for - // as long as they are relatively positioned with alignment STRETCH or - // FLEX_START. Children that are immediately stacked in the initial loop - // will not be touched again in <Loop D>. - bool isSimpleStackCross = true; - int firstComplexCross = childCount; - - css_node_t* firstFlexChild = NULL; - css_node_t* currentFlexChild = NULL; - - float mainDim = leadingPaddingAndBorderMain; - float crossDim = 0; - - float maxWidth = CSS_UNDEFINED; - float maxHeight = CSS_UNDEFINED; - for (i = startLine; i < childCount; ++i) { - child = node->get_child(node->context, i); - if (child == NULL) { - return; - } - child->line_index = linesCount; - - child->next_absolute_child = NULL; - child->next_flex_child = NULL; - - css_align_t alignItem = getAlignItem(node, child); - - // Pre-fill cross axis dimensions when the child is using stretch before - // we call the recursive layout pass - if (alignItem == CSS_ALIGN_STRETCH && - child->style.position_type == CSS_POSITION_RELATIVE && - isCrossDimDefined && - !isStyleDimDefined(child, crossAxis)) { - child->layout.dimensions[dim[crossAxis]] = fmaxf( - boundAxis(child, crossAxis, node->layout.dimensions[dim[crossAxis]] - - paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), - // You never want to go smaller than padding - getPaddingAndBorderAxis(child, crossAxis) - ); - } else if (child->style.position_type == CSS_POSITION_ABSOLUTE) { - // Store a private linked list of absolutely positioned children - // so that we can efficiently traverse them later. - if (firstAbsoluteChild == NULL) { - firstAbsoluteChild = child; - } - if (currentAbsoluteChild != NULL) { - currentAbsoluteChild->next_absolute_child = child; - } - currentAbsoluteChild = child; - - // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both - // left and right or top and bottom). - for (ii = 0; ii < 2; ii++) { - axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; - if (isLayoutDimDefined(node, axis) && - !isStyleDimDefined(child, axis) && - isPosDefined(child, leading[axis]) && - isPosDefined(child, trailing[axis])) { - child->layout.dimensions[dim[axis]] = fmaxf( - boundAxis(child, axis, node->layout.dimensions[dim[axis]] - - getPaddingAndBorderAxis(node, axis) - - getMarginAxis(child, axis) - - getPosition(child, leading[axis]) - - getPosition(child, trailing[axis])), - // You never want to go smaller than padding - getPaddingAndBorderAxis(child, axis) - ); - } - } - } - - float nextContentDim = 0; - - // It only makes sense to consider a child flexible if we have a computed - // dimension for the node-> - if (isMainDimDefined && isFlex(child)) { - flexibleChildrenCount++; - totalFlexible += child->style.flex; - - // Store a private linked list of flexible children so that we can - // efficiently traverse them later. - if (firstFlexChild == NULL) { - firstFlexChild = child; - } - if (currentFlexChild != NULL) { - currentFlexChild->next_flex_child = child; - } - currentFlexChild = child; - - // Even if we don't know its exact size yet, we already know the padding, - // border and margin. We'll use this partial information, which represents - // the smallest possible size for the child, to compute the remaining - // available space. - nextContentDim = getPaddingAndBorderAxis(child, mainAxis) + - getMarginAxis(child, mainAxis); - - } else { - maxWidth = CSS_UNDEFINED; - maxHeight = CSS_UNDEFINED; - - if (!isMainRowDirection) { - if (isLayoutDimDefined(node, resolvedRowAxis)) { - maxWidth = node->layout.dimensions[dim[resolvedRowAxis]] - - paddingAndBorderAxisResolvedRow; - } else { - maxWidth = parentMaxWidth - - getMarginAxis(node, resolvedRowAxis) - - paddingAndBorderAxisResolvedRow; - } - } else { - if (isLayoutDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { - maxHeight = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - - paddingAndBorderAxisColumn; - } else { - maxHeight = parentMaxHeight - - getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) - - paddingAndBorderAxisColumn; - } - } - - // This is the main recursive call. We layout non flexible children. - if (alreadyComputedNextLayout == 0) { - layoutNode(child, maxWidth, maxHeight, direction); - } - - // Absolute positioned elements do not take part of the layout, so we - // don't use them to compute mainContentDim - if (child->style.position_type == CSS_POSITION_RELATIVE) { - nonFlexibleChildrenCount++; - // At this point we know the final size and margin of the element. - nextContentDim = getDimWithMargin(child, mainAxis); - } - } - - // The element we are about to add would make us go to the next line - if (isNodeFlexWrap && - isMainDimDefined && - mainContentDim + nextContentDim > definedMainDim && - // If there's only one element, then it's bigger than the content - // and needs its own line - i != startLine) { - nonFlexibleChildrenCount--; - alreadyComputedNextLayout = 1; - break; - } - - // Disable simple stacking in the main axis for the current line as - // we found a non-trivial child-> The remaining children will be laid out - // in <Loop C>. - if (isSimpleStackMain && - (child->style.position_type != CSS_POSITION_RELATIVE || isFlex(child))) { - isSimpleStackMain = false; - firstComplexMain = i; - } - - // Disable simple stacking in the cross axis for the current line as - // we found a non-trivial child-> The remaining children will be laid out - // in <Loop D>. - if (isSimpleStackCross && - (child->style.position_type != CSS_POSITION_RELATIVE || - (alignItem != CSS_ALIGN_STRETCH && alignItem != CSS_ALIGN_FLEX_START) || - (alignItem == CSS_ALIGN_STRETCH && !isCrossDimDefined))) { - isSimpleStackCross = false; - firstComplexCross = i; - } - - if (isSimpleStackMain) { - child->layout.position[pos[mainAxis]] += mainDim; - if (isMainDimDefined) { - setTrailingPosition(node, child, mainAxis); - } - - mainDim += getDimWithMargin(child, mainAxis); - crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis))); - } - - if (isSimpleStackCross) { - child->layout.position[pos[crossAxis]] += linesCrossDim + leadingPaddingAndBorderCross; - if (isCrossDimDefined) { - setTrailingPosition(node, child, crossAxis); - } - } - - alreadyComputedNextLayout = 0; - mainContentDim += nextContentDim; - endLine = i + 1; - } - - // <Loop B> Layout flexible children and allocate empty space - - // In order to position the elements in the main axis, we have two - // controls. The space between the beginning and the first element - // and the space between each two elements. - float leadingMainDim = 0; - float betweenMainDim = 0; - - // The remaining available space that needs to be allocated - float remainingMainDim = 0; - if (isMainDimDefined) { - remainingMainDim = definedMainDim - mainContentDim; - } else { - remainingMainDim = fmaxf(mainContentDim, 0) - mainContentDim; - } - - // If there are flexible children in the mix, they are going to fill the - // remaining space - if (flexibleChildrenCount != 0) { - float flexibleMainDim = remainingMainDim / totalFlexible; - float baseMainDim; - float boundMainDim; - - // If the flex share of remaining space doesn't meet min/max bounds, - // remove this child from flex calculations. - currentFlexChild = firstFlexChild; - while (currentFlexChild != NULL) { - baseMainDim = flexibleMainDim * currentFlexChild->style.flex + - getPaddingAndBorderAxis(currentFlexChild, mainAxis); - boundMainDim = boundAxis(currentFlexChild, mainAxis, baseMainDim); - - if (baseMainDim != boundMainDim) { - remainingMainDim -= boundMainDim; - totalFlexible -= currentFlexChild->style.flex; - } - - currentFlexChild = currentFlexChild->next_flex_child; - } - flexibleMainDim = remainingMainDim / totalFlexible; - - // The non flexible children can overflow the container, in this case - // we should just assume that there is no space available. - if (flexibleMainDim < 0) { - flexibleMainDim = 0; - } - - currentFlexChild = firstFlexChild; - while (currentFlexChild != NULL) { - // At this point we know the final size of the element in the main - // dimension - currentFlexChild->layout.dimensions[dim[mainAxis]] = boundAxis(currentFlexChild, mainAxis, - flexibleMainDim * currentFlexChild->style.flex + - getPaddingAndBorderAxis(currentFlexChild, mainAxis) - ); - - maxWidth = CSS_UNDEFINED; - if (isLayoutDimDefined(node, resolvedRowAxis)) { - maxWidth = node->layout.dimensions[dim[resolvedRowAxis]] - - paddingAndBorderAxisResolvedRow; - } else if (!isMainRowDirection) { - maxWidth = parentMaxWidth - - getMarginAxis(node, resolvedRowAxis) - - paddingAndBorderAxisResolvedRow; - } - maxHeight = CSS_UNDEFINED; - if (isLayoutDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { - maxHeight = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - - paddingAndBorderAxisColumn; - } else if (isMainRowDirection) { - maxHeight = parentMaxHeight - - getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) - - paddingAndBorderAxisColumn; - } - - // And we recursively call the layout algorithm for this child - layoutNode(currentFlexChild, maxWidth, maxHeight, direction); - - child = currentFlexChild; - currentFlexChild = currentFlexChild->next_flex_child; - child->next_flex_child = NULL; - } - - // We use justifyContent to figure out how to allocate the remaining - // space available - } else if (justifyContent != CSS_JUSTIFY_FLEX_START) { - if (justifyContent == CSS_JUSTIFY_CENTER) { - leadingMainDim = remainingMainDim / 2; - } else if (justifyContent == CSS_JUSTIFY_FLEX_END) { - leadingMainDim = remainingMainDim; - } else if (justifyContent == CSS_JUSTIFY_SPACE_BETWEEN) { - remainingMainDim = fmaxf(remainingMainDim, 0); - if (flexibleChildrenCount + nonFlexibleChildrenCount - 1 != 0) { - betweenMainDim = remainingMainDim / - (flexibleChildrenCount + nonFlexibleChildrenCount - 1); - } else { - betweenMainDim = 0; - } - } else if (justifyContent == CSS_JUSTIFY_SPACE_AROUND) { - // Space on the edges is half of the space between elements - betweenMainDim = remainingMainDim / - (flexibleChildrenCount + nonFlexibleChildrenCount); - leadingMainDim = betweenMainDim / 2; - } - } - - // <Loop C> Position elements in the main axis and compute dimensions - - // At this point, all the children have their dimensions set. We need to - // find their position. In order to do that, we accumulate data in - // variables that are also useful to compute the total dimensions of the - // container! - mainDim += leadingMainDim; - - for (i = firstComplexMain; i < endLine; ++i) { - child = node->get_child(node->context, i); - - if (child->style.position_type == CSS_POSITION_ABSOLUTE && - isPosDefined(child, leading[mainAxis])) { - // In case the child is position absolute and has left/top being - // defined, we override the position to whatever the user said - // (and margin/border). - child->layout.position[pos[mainAxis]] = getPosition(child, leading[mainAxis]) + - getLeadingBorder(node, mainAxis) + - getLeadingMargin(child, mainAxis); - } else { - // If the child is position absolute (without top/left) or relative, - // we put it at the current accumulated offset. - child->layout.position[pos[mainAxis]] += mainDim; - - // Define the trailing position accordingly. - if (isMainDimDefined) { - setTrailingPosition(node, child, mainAxis); - } - - // Now that we placed the element, we need to update the variables - // We only need to do that for relative elements. Absolute elements - // do not take part in that phase. - if (child->style.position_type == CSS_POSITION_RELATIVE) { - // The main dimension is the sum of all the elements dimension plus - // the spacing. - mainDim += betweenMainDim + getDimWithMargin(child, mainAxis); - // The cross dimension is the max of the elements dimension since there - // can only be one element in that cross dimension. - crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis))); - } - } - } - - float containerCrossAxis = node->layout.dimensions[dim[crossAxis]]; - if (!isCrossDimDefined) { - containerCrossAxis = fmaxf( - // For the cross dim, we add both sides at the end because the value - // is aggregate via a max function. Intermediate negative values - // can mess this computation otherwise - boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross), - paddingAndBorderAxisCross - ); - } - - // <Loop D> Position elements in the cross axis - for (i = firstComplexCross; i < endLine; ++i) { - child = node->get_child(node->context, i); - - if (child->style.position_type == CSS_POSITION_ABSOLUTE && - isPosDefined(child, leading[crossAxis])) { - // In case the child is absolutely positionned and has a - // top/left/bottom/right being set, we override all the previously - // computed positions to set it correctly. - child->layout.position[pos[crossAxis]] = getPosition(child, leading[crossAxis]) + - getLeadingBorder(node, crossAxis) + - getLeadingMargin(child, crossAxis); - - } else { - float leadingCrossDim = leadingPaddingAndBorderCross; - - // For a relative children, we're either using alignItems (parent) or - // alignSelf (child) in order to determine the position in the cross axis - if (child->style.position_type == CSS_POSITION_RELATIVE) { - /*eslint-disable */ - // This variable is intentionally re-defined as the code is transpiled to a block scope language - css_align_t alignItem = getAlignItem(node, child); - /*eslint-enable */ - if (alignItem == CSS_ALIGN_STRETCH) { - // You can only stretch if the dimension has not already been defined - // previously. - if (!isStyleDimDefined(child, crossAxis)) { - float dimCrossAxis = child->layout.dimensions[dim[crossAxis]]; - child->layout.dimensions[dim[crossAxis]] = fmaxf( - boundAxis(child, crossAxis, containerCrossAxis - - paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), - // You never want to go smaller than padding - getPaddingAndBorderAxis(child, crossAxis) - ); - - // If the size has changed, and this child has children we need to re-layout this child - if (dimCrossAxis != child->layout.dimensions[dim[crossAxis]] && child->children_count > 0) { - // Reset child margins before re-layout as they are added back in layoutNode and would be doubled - child->layout.position[leading[mainAxis]] -= getLeadingMargin(child, mainAxis) + - getRelativePosition(child, mainAxis); - child->layout.position[trailing[mainAxis]] -= getTrailingMargin(child, mainAxis) + - getRelativePosition(child, mainAxis); - child->layout.position[leading[crossAxis]] -= getLeadingMargin(child, crossAxis) + - getRelativePosition(child, crossAxis); - child->layout.position[trailing[crossAxis]] -= getTrailingMargin(child, crossAxis) + - getRelativePosition(child, crossAxis); - - layoutNode(child, maxWidth, maxHeight, direction); - } - } - } else if (alignItem != CSS_ALIGN_FLEX_START) { - // The remaining space between the parent dimensions+padding and child - // dimensions+margin. - float remainingCrossDim = containerCrossAxis - - paddingAndBorderAxisCross - getDimWithMargin(child, crossAxis); - - if (alignItem == CSS_ALIGN_CENTER) { - leadingCrossDim += remainingCrossDim / 2; - } else { // CSS_ALIGN_FLEX_END - leadingCrossDim += remainingCrossDim; - } - } - } - - // And we apply the position - child->layout.position[pos[crossAxis]] += linesCrossDim + leadingCrossDim; - - // Define the trailing position accordingly. - if (isCrossDimDefined) { - setTrailingPosition(node, child, crossAxis); - } - } - } - - linesCrossDim += crossDim; - linesMainDim = fmaxf(linesMainDim, mainDim); - linesCount += 1; - startLine = endLine; - } - - // <Loop E> - // - // Note(prenaux): More than one line, we need to layout the crossAxis - // according to alignContent. - // - // Note that we could probably remove <Loop D> and handle the one line case - // here too, but for the moment this is safer since it won't interfere with - // previously working code. - // - // See specs: - // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm - // section 9.4 - // - if (linesCount > 1 && isCrossDimDefined) { - float nodeCrossAxisInnerSize = node->layout.dimensions[dim[crossAxis]] - - paddingAndBorderAxisCross; - float remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim; - - float crossDimLead = 0; - float currentLead = leadingPaddingAndBorderCross; - - css_align_t alignContent = node->style.align_content; - if (alignContent == CSS_ALIGN_FLEX_END) { - currentLead += remainingAlignContentDim; - } else if (alignContent == CSS_ALIGN_CENTER) { - currentLead += remainingAlignContentDim / 2; - } else if (alignContent == CSS_ALIGN_STRETCH) { - if (nodeCrossAxisInnerSize > linesCrossDim) { - crossDimLead = (remainingAlignContentDim / linesCount); - } - } - - int endIndex = 0; - for (i = 0; i < linesCount; ++i) { - int startIndex = endIndex; - - // compute the line's height and find the endIndex - float lineHeight = 0; - for (ii = startIndex; ii < childCount; ++ii) { - child = node->get_child(node->context, ii); - if (child->style.position_type != CSS_POSITION_RELATIVE) { - continue; - } - if (child->line_index != i) { - break; - } - if (isLayoutDimDefined(child, crossAxis)) { - lineHeight = fmaxf( - lineHeight, - child->layout.dimensions[dim[crossAxis]] + getMarginAxis(child, crossAxis) - ); - } - } - endIndex = ii; - lineHeight += crossDimLead; - - for (ii = startIndex; ii < endIndex; ++ii) { - child = node->get_child(node->context, ii); - if (child->style.position_type != CSS_POSITION_RELATIVE) { - continue; - } - - css_align_t alignContentAlignItem = getAlignItem(node, child); - if (alignContentAlignItem == CSS_ALIGN_FLEX_START) { - child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); - } else if (alignContentAlignItem == CSS_ALIGN_FLEX_END) { - child->layout.position[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child->layout.dimensions[dim[crossAxis]]; - } else if (alignContentAlignItem == CSS_ALIGN_CENTER) { - float childHeight = child->layout.dimensions[dim[crossAxis]]; - child->layout.position[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2; - } else if (alignContentAlignItem == CSS_ALIGN_STRETCH) { - child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); - // TODO(prenaux): Correctly set the height of items with undefined - // (auto) crossAxis dimension. - } - } - - currentLead += lineHeight; - } - } - - bool needsMainTrailingPos = false; - bool needsCrossTrailingPos = false; - - // If the user didn't specify a width or height, and it has not been set - // by the container, then we set it via the children. - if (!isMainDimDefined) { - node->layout.dimensions[dim[mainAxis]] = fmaxf( - // We're missing the last padding at this point to get the final - // dimension - boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)), - // We can never assign a width smaller than the padding and borders - paddingAndBorderAxisMain - ); - - if (mainAxis == CSS_FLEX_DIRECTION_ROW_REVERSE || - mainAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - needsMainTrailingPos = true; - } - } - - if (!isCrossDimDefined) { - node->layout.dimensions[dim[crossAxis]] = fmaxf( - // For the cross dim, we add both sides at the end because the value - // is aggregate via a max function. Intermediate negative values - // can mess this computation otherwise - boundAxis(node, crossAxis, linesCrossDim + paddingAndBorderAxisCross), - paddingAndBorderAxisCross - ); - - if (crossAxis == CSS_FLEX_DIRECTION_ROW_REVERSE || - crossAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - needsCrossTrailingPos = true; - } - } - - // <Loop F> Set trailing position if necessary - if (needsMainTrailingPos || needsCrossTrailingPos) { - for (i = 0; i < childCount; ++i) { - child = node->get_child(node->context, i); - - if (needsMainTrailingPos) { - setTrailingPosition(node, child, mainAxis); - } - - if (needsCrossTrailingPos) { - setTrailingPosition(node, child, crossAxis); - } - } - } - - // <Loop G> Calculate dimensions for absolutely positioned elements - currentAbsoluteChild = firstAbsoluteChild; - while (currentAbsoluteChild != NULL) { - // Pre-fill dimensions when using absolute position and both offsets for - // the axis are defined (either both left and right or top and bottom). - for (ii = 0; ii < 2; ii++) { - axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; - - if (isLayoutDimDefined(node, axis) && - !isStyleDimDefined(currentAbsoluteChild, axis) && - isPosDefined(currentAbsoluteChild, leading[axis]) && - isPosDefined(currentAbsoluteChild, trailing[axis])) { - currentAbsoluteChild->layout.dimensions[dim[axis]] = fmaxf( - boundAxis(currentAbsoluteChild, axis, node->layout.dimensions[dim[axis]] - - getBorderAxis(node, axis) - - getMarginAxis(currentAbsoluteChild, axis) - - getPosition(currentAbsoluteChild, leading[axis]) - - getPosition(currentAbsoluteChild, trailing[axis]) - ), - // You never want to go smaller than padding - getPaddingAndBorderAxis(currentAbsoluteChild, axis) - ); - } - - if (isPosDefined(currentAbsoluteChild, trailing[axis]) && - !isPosDefined(currentAbsoluteChild, leading[axis])) { - currentAbsoluteChild->layout.position[leading[axis]] = - node->layout.dimensions[dim[axis]] - - currentAbsoluteChild->layout.dimensions[dim[axis]] - - getPosition(currentAbsoluteChild, trailing[axis]); - } - } - - child = currentAbsoluteChild; - currentAbsoluteChild = currentAbsoluteChild->next_absolute_child; - child->next_absolute_child = NULL; - } - /** END_GENERATED **/ -} - -void layoutNode(css_node_t *node, float parentMaxWidth, float parentMaxHeight, css_direction_t parentDirection) { - css_layout_t *layout = &node->layout; - css_direction_t direction = node->style.direction; - layout->should_update = true; - - bool skipLayout = - !node->is_dirty(node->context) && - eq(layout->last_requested_dimensions[CSS_WIDTH], layout->dimensions[CSS_WIDTH]) && - eq(layout->last_requested_dimensions[CSS_HEIGHT], layout->dimensions[CSS_HEIGHT]) && - eq(layout->last_parent_max_width, parentMaxWidth) && - eq(layout->last_parent_max_height, parentMaxHeight) && - eq(layout->last_direction, direction); - - if (skipLayout) { - layout->dimensions[CSS_WIDTH] = layout->last_dimensions[CSS_WIDTH]; - layout->dimensions[CSS_HEIGHT] = layout->last_dimensions[CSS_HEIGHT]; - layout->position[CSS_TOP] = layout->last_position[CSS_TOP]; - layout->position[CSS_LEFT] = layout->last_position[CSS_LEFT]; - } else { - layout->last_requested_dimensions[CSS_WIDTH] = layout->dimensions[CSS_WIDTH]; - layout->last_requested_dimensions[CSS_HEIGHT] = layout->dimensions[CSS_HEIGHT]; - layout->last_parent_max_width = parentMaxWidth; - layout->last_parent_max_height = parentMaxHeight; - layout->last_direction = direction; - - for (int i = 0, childCount = node->children_count; i < childCount; i++) { - resetNodeLayout(node->get_child(node->context, i)); - } - - layoutNodeImpl(node, parentMaxWidth, parentMaxHeight, parentDirection); - - layout->last_dimensions[CSS_WIDTH] = layout->dimensions[CSS_WIDTH]; - layout->last_dimensions[CSS_HEIGHT] = layout->dimensions[CSS_HEIGHT]; - layout->last_position[CSS_TOP] = layout->position[CSS_TOP]; - layout->last_position[CSS_LEFT] = layout->position[CSS_LEFT]; - } -} - -void resetNodeLayout(css_node_t *node) { - node->layout.dimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->layout.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - node->layout.position[CSS_LEFT] = 0; - node->layout.position[CSS_TOP] = 0; - node->layout.position[CSS_RIGHT] = 0; - node->layout.position[CSS_BOTTOM] = 0; -}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9acc1bc4/ios/sdk/WeexSDK/Sources/Layout/Layout.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Layout/Layout.h b/ios/sdk/WeexSDK/Sources/Layout/Layout.h deleted file mode 100644 index 1df5822..0000000 --- a/ios/sdk/WeexSDK/Sources/Layout/Layout.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - * Copyright (c) 2014, 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. - */ - -#ifndef __LAYOUT_H -#define __LAYOUT_H - -#include <math.h> -#ifndef __cplusplus -#include <stdbool.h> -#endif - -// Not defined in MSVC++ -#ifndef NAN -static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; -#define NAN (*(const float *)__nan) -#endif - -#define CSS_UNDEFINED NAN - -typedef enum { - CSS_DIRECTION_INHERIT = 0, - CSS_DIRECTION_LTR, - CSS_DIRECTION_RTL -} css_direction_t; - -typedef enum { - CSS_FLEX_DIRECTION_COLUMN = 0, - CSS_FLEX_DIRECTION_COLUMN_REVERSE, - CSS_FLEX_DIRECTION_ROW, - CSS_FLEX_DIRECTION_ROW_REVERSE -} css_flex_direction_t; - -typedef enum { - CSS_JUSTIFY_FLEX_START = 0, - CSS_JUSTIFY_CENTER, - CSS_JUSTIFY_FLEX_END, - CSS_JUSTIFY_SPACE_BETWEEN, - CSS_JUSTIFY_SPACE_AROUND -} css_justify_t; - -// Note: auto is only a valid value for alignSelf. It is NOT a valid value for -// alignItems. -typedef enum { - CSS_ALIGN_AUTO = 0, - CSS_ALIGN_FLEX_START, - CSS_ALIGN_CENTER, - CSS_ALIGN_FLEX_END, - CSS_ALIGN_STRETCH -} css_align_t; - -typedef enum { - CSS_POSITION_RELATIVE = 0, - CSS_POSITION_ABSOLUTE -} css_position_type_t; - -typedef enum { - CSS_NOWRAP = 0, - CSS_WRAP -} css_wrap_type_t; - -// Note: left and top are shared between position[2] and position[4], so -// they have to be before right and bottom. -typedef enum { - CSS_LEFT = 0, - CSS_TOP, - CSS_RIGHT, - CSS_BOTTOM, - CSS_START, - CSS_END, - CSS_POSITION_COUNT -} css_position_t; - -typedef enum { - CSS_MEASURE_MODE_UNDEFINED = 0, - CSS_MEASURE_MODE_EXACTLY, - CSS_MEASURE_MODE_AT_MOST -} css_measure_mode_t; - -typedef enum { - CSS_WIDTH = 0, - CSS_HEIGHT -} css_dimension_t; - -typedef struct { - float position[4]; - float dimensions[2]; - css_direction_t direction; - - // Instead of recomputing the entire layout every single time, we - // cache some information to break early when nothing changed - bool should_update; - float last_requested_dimensions[2]; - float last_parent_max_width; - float last_parent_max_height; - float last_dimensions[2]; - float last_position[2]; - css_direction_t last_direction; -} css_layout_t; - -typedef struct { - float dimensions[2]; -} css_dim_t; - -typedef struct { - css_direction_t direction; - css_flex_direction_t flex_direction; - css_justify_t justify_content; - css_align_t align_content; - css_align_t align_items; - css_align_t align_self; - css_position_type_t position_type; - css_wrap_type_t flex_wrap; - float flex; - float margin[6]; - float position[4]; - /** - * You should skip all the rules that contain negative values for the - * following attributes. For example: - * {padding: 10, paddingLeft: -5} - * should output: - * {left: 10 ...} - * the following two are incorrect: - * {left: -5 ...} - * {left: 0 ...} - */ - float padding[6]; - float border[6]; - float dimensions[2]; - float minDimensions[2]; - float maxDimensions[2]; -} css_style_t; - -typedef struct css_node css_node_t; -struct css_node { - css_style_t style; - css_layout_t layout; - int children_count; - int line_index; - - css_node_t *next_absolute_child; - css_node_t *next_flex_child; - - css_dim_t (*measure)(void *context, float width, css_measure_mode_t widthMode, float height, css_measure_mode_t heightMode); - void (*print)(void *context); - struct css_node* (*get_child)(void *context, int i); - bool (*is_dirty)(void *context); - void *context; -}; - -// Lifecycle of nodes and children -css_node_t *new_css_node(void); -void init_css_node(css_node_t *node); -void free_css_node(css_node_t *node); - -// Print utilities -typedef enum { - CSS_PRINT_LAYOUT = 1, - CSS_PRINT_STYLE = 2, - CSS_PRINT_CHILDREN = 4, -} css_print_options_t; -void print_css_node(css_node_t *node, css_print_options_t options); - -bool isUndefined(float value); - -// Function that computes the layout! -void layoutNode(css_node_t *node, float maxWidth, float maxHeight, css_direction_t parentDirection); - -// Reset the calculated layout values for a given node. You should call this before `layoutNode`. -void resetNodeLayout(css_node_t *node); - -#endif http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9acc1bc4/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.h b/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.h index 651af7c..ac8700e 100644 --- a/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.h +++ b/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.h @@ -20,15 +20,9 @@ #import "WXComponent.h" #import "WXSDKInstance.h" #import "WXUtility.h" -#import "WXLayoutDefine.h" #import "WXCoreLayout.h" #define FlexUndefined NAN -//#define USE_FLEX - - - - #ifdef __cplusplus extern "C" { @@ -41,44 +35,28 @@ extern "C" { @interface WXComponent () { @package - /** - * Layout - */ -//#ifndef USE_FLEX - css_node_t *_cssNode; -//#else #ifdef __cplusplus WeexCore::WXCoreLayoutNode *_flexCssNode; #endif // __cplusplus -//#endif //USE_FLEX BOOL _isLayoutDirty; CGRect _calculatedFrame; CGPoint _absolutePosition; WXPositionType _positionType; } -//#ifndef USE_FLEX /** * @abstract Return the css node used to layout. * * @warning Subclasses must not override this. */ -@property(nonatomic, readonly, assign) css_node_t *cssNode; -//#else #ifdef __cplusplus @property(nonatomic, readonly, assign) WeexCore::WXCoreLayoutNode *flexCssNode; #endif -//#endif @end @interface WXComponent (Layout) -//#ifndef USE_FLEX -//#else - (void)_insertChildCssNode:(WXComponent*)subcomponent atIndex:(NSInteger)index; - (void)_rmChildCssNode:(WXComponent*)subcomponent; - (NSInteger) getActualNodeIndex:(WXComponent*)subcomponent atIndex:(NSInteger) index; -+ (void) setUseFlex:(BOOL) useFlex; -+ (BOOL) isUseFlex; -//#endif @end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9acc1bc4/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.mm ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.mm b/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.mm index 01c36ec..d1aa7d0 100644 --- a/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.mm +++ b/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.mm @@ -32,7 +32,6 @@ bool flexIsUndefined(float value) { return isnan(value); } -static BOOL sUseFlex = TRUE; @implementation WXComponent (Layout) @@ -45,13 +44,12 @@ static BOOL sUseFlex = TRUE; { _isLayoutDirty = YES; WXComponent *supercomponent = [self supercomponent]; - if ([WXComponent isUseFlex]) { - //protet nil ptr - if (self.flexCssNode) { - self.flexCssNode->markDirty(); - }else{ - WXLogError(@"flexCssNode is nil"); - } + + //protet nil ptr + if (self.flexCssNode) { + self.flexCssNode->markDirty(); + }else{ + WXLogError(@"flexCssNode is nil"); } if(supercomponent){ @@ -78,36 +76,6 @@ static BOOL sUseFlex = TRUE; - (void)_initCSSNodeWithStyles:(NSDictionary *)styles { -//#ifndef USE_FLEX - if (! [WXComponent isUseFlex]) { - _cssNode = new_css_node(); - - _cssNode->print = cssNodePrint; - _cssNode->get_child = cssNodeGetChild; - _cssNode->is_dirty = cssNodeIsDirty; - if ([self measureBlock]) { - _cssNode->measure = cssNodeMeasure; - } - _cssNode->context = (__bridge void *)self; - - [self _recomputeCSSNodeChildren]; - [self _fillCSSNode:styles isUpdate:NO]; - - // To be in conformity with Android/Web, hopefully remove this in the future. - if ([self.ref isEqualToString:WX_SDK_ROOT_REF]) { - if (isUndefined(_cssNode->style.dimensions[CSS_HEIGHT]) && self.weexInstance.frame.size.height) { - _cssNode->style.dimensions[CSS_HEIGHT] = self.weexInstance.frame.size.height; - } - - if (isUndefined(_cssNode->style.dimensions[CSS_WIDTH]) && self.weexInstance.frame.size.width) { - _cssNode->style.dimensions[CSS_WIDTH] = self.weexInstance.frame.size.width; - } - } - } - -//#else - else - { _flexCssNode = new WeexCore::WXCoreLayoutNode(); if ([self measureBlock]) { _flexCssNode->setMeasureFunc(flexCssNodeMeasure); @@ -125,8 +93,6 @@ static BOOL sUseFlex = TRUE; _flexCssNode->setStyleWidth(self.weexInstance.frame.size.width,NO); } } - } -//#endif } - (void)_updateCSSNodeStyles:(NSDictionary *)styles @@ -141,13 +107,6 @@ static BOOL sUseFlex = TRUE; - (void)_recomputeCSSNodeChildren { -//#ifndef USE_FLEX - if (![WXComponent isUseFlex]) { - _cssNode->children_count = (int)[self _childrenCountForLayout]; - } -//#else - -//#endif } - (NSUInteger)_childrenCountForLayout @@ -216,45 +175,6 @@ static BOOL sUseFlex = TRUE; { WXAssertComponentThread(); -//#ifndef USE_FLEX - if (![WXComponent isUseFlex]) - { - if (!_cssNode->layout.should_update) { - return; - } - _cssNode->layout.should_update = false; - _isLayoutDirty = NO; - - CGRect newFrame = CGRectMake(isnan(WXRoundPixelValue(_cssNode->layout.position[CSS_LEFT]))?0:WXRoundPixelValue(_cssNode->layout.position[CSS_LEFT]), - isnan(WXRoundPixelValue(_cssNode->layout.position[CSS_TOP]))?0:WXRoundPixelValue(_cssNode->layout.position[CSS_TOP]), - isnan(WXRoundPixelValue(_cssNode->layout.dimensions[CSS_WIDTH]))?0:WXRoundPixelValue(_cssNode->layout.dimensions[CSS_WIDTH]), - isnan(WXRoundPixelValue(_cssNode->layout.dimensions[CSS_HEIGHT]))?0:WXRoundPixelValue(_cssNode->layout.dimensions[CSS_HEIGHT])); - - BOOL isFrameChanged = NO; - if (!CGRectEqualToRect(newFrame, _calculatedFrame)) { - isFrameChanged = YES; - _calculatedFrame = newFrame; - [dirtyComponents addObject:self]; - } - - _cssNode->layout.dimensions[CSS_WIDTH] = CSS_UNDEFINED; - _cssNode->layout.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - _cssNode->layout.position[CSS_LEFT] = 0; - _cssNode->layout.position[CSS_TOP] = 0; - - [self _frameDidCalculated:isFrameChanged]; - NSArray * subcomponents = [_subcomponents copy]; - for (WXComponent *subcomponent in subcomponents) { - [subcomponent _calculateFrameWithSuperAbsolutePosition:superAbsolutePosition gatherDirtyComponents:dirtyComponents]; - } -#ifdef DEBUG - WXLogDebug(@"flexLayout -> newFrame ,type:%@,ref:%@, parentRef:%@,size :%@ ,instance:%@",self.type,self.ref,self.supercomponent.ref,NSStringFromCGRect(newFrame),self.weexInstance.instanceId); -#endif - } - -//#else - else - { if (self.flexCssNode->hasNewLayout()) { self.flexCssNode->setHasNewLayout(false); _isLayoutDirty = NO; @@ -283,8 +203,6 @@ static BOOL sUseFlex = TRUE; for (WXComponent *subcomponent in subcomponents) { [subcomponent _calculateFrameWithSuperAbsolutePosition:superAbsolutePosition gatherDirtyComponents:dirtyComponents]; } - } -//#endif } - (void)_layoutDidFinish @@ -297,46 +215,8 @@ static BOOL sUseFlex = TRUE; [self layoutDidFinish]; } -//#ifndef USE_FLEX - -#define WX_STYLE_FILL_CSS_NODE(key, cssProp, type)\ -do {\ - id value = styles[@#key];\ - if (value) {\ - typeof(_cssNode->style.cssProp) convertedValue = (typeof(_cssNode->style.cssProp))[WXConvert type:value];\ - _cssNode->style.cssProp = convertedValue;\ - [self setNeedsLayout];\ - }\ -} while(0); - -#define WX_STYLE_FILL_CSS_NODE_PIXEL(key, cssProp)\ -do {\ - id value = styles[@#key];\ - if (value) {\ - CGFloat pixel = [self WXPixelType:value];\ - if (isnan(pixel)) {\ - WXLogError(@"Invalid NaN value for style:%@, ref:%@", @#key, self.ref);\ - } else {\ - _cssNode->style.cssProp = pixel;\ - [self setNeedsLayout];\ - }\ - }\ -} while(0); - -#define WX_STYLE_FILL_CSS_NODE_ALL_DIRECTION(key, cssProp)\ -do {\ - WX_STYLE_FILL_CSS_NODE_PIXEL(key, cssProp[CSS_TOP])\ - WX_STYLE_FILL_CSS_NODE_PIXEL(key, cssProp[CSS_LEFT])\ - WX_STYLE_FILL_CSS_NODE_PIXEL(key, cssProp[CSS_RIGHT])\ - WX_STYLE_FILL_CSS_NODE_PIXEL(key, cssProp[CSS_BOTTOM])\ -} while(0); - -//#else - #define WX_STYLE_FLEX_NODE_JUDGE_LEGAL(key) styles[key]&&!isnan([WXConvert WXPixelType:styles[key] scaleFactor:self.weexInstance.pixelScaleFactor]) -//#endif - - (CGFloat)WXPixelType:(id)value { return [WXConvert WXPixelType:value scaleFactor:self.weexInstance.pixelScaleFactor]; @@ -344,58 +224,6 @@ do {\ - (void)_fillCSSNode:(NSDictionary *)styles isUpdate:(BOOL)isUpdate { -//#ifndef USE_FLEX - if(![WXComponent isUseFlex]) - { - WX_STYLE_FILL_CSS_NODE(direction, direction, css_direction_t) - // flex - WX_STYLE_FILL_CSS_NODE(flex, flex, CGFloat) - WX_STYLE_FILL_CSS_NODE(flexDirection, flex_direction, css_flex_direction_t) - WX_STYLE_FILL_CSS_NODE(alignItems, align_items, css_align_t) - WX_STYLE_FILL_CSS_NODE(alignSelf, align_self, css_align_t) - WX_STYLE_FILL_CSS_NODE(flexWrap, flex_wrap, css_wrap_type_t) - WX_STYLE_FILL_CSS_NODE(justifyContent, justify_content, css_justify_t) - - // position - WX_STYLE_FILL_CSS_NODE(position, position_type, css_position_type_t) - WX_STYLE_FILL_CSS_NODE_PIXEL(top, position[CSS_TOP]) - WX_STYLE_FILL_CSS_NODE_PIXEL(left, position[CSS_LEFT]) - WX_STYLE_FILL_CSS_NODE_PIXEL(right, position[CSS_RIGHT]) - WX_STYLE_FILL_CSS_NODE_PIXEL(bottom, position[CSS_BOTTOM]) - - // dimension - WX_STYLE_FILL_CSS_NODE_PIXEL(width, dimensions[CSS_WIDTH]) - WX_STYLE_FILL_CSS_NODE_PIXEL(height, dimensions[CSS_HEIGHT]) - WX_STYLE_FILL_CSS_NODE_PIXEL(minWidth, minDimensions[CSS_WIDTH]) - WX_STYLE_FILL_CSS_NODE_PIXEL(minHeight, minDimensions[CSS_HEIGHT]) - WX_STYLE_FILL_CSS_NODE_PIXEL(maxWidth, maxDimensions[CSS_WIDTH]) - WX_STYLE_FILL_CSS_NODE_PIXEL(maxHeight, maxDimensions[CSS_HEIGHT]) - - // margin - WX_STYLE_FILL_CSS_NODE_ALL_DIRECTION(margin, margin) - WX_STYLE_FILL_CSS_NODE_PIXEL(marginTop, margin[CSS_TOP]) - WX_STYLE_FILL_CSS_NODE_PIXEL(marginLeft, margin[CSS_LEFT]) - WX_STYLE_FILL_CSS_NODE_PIXEL(marginRight, margin[CSS_RIGHT]) - WX_STYLE_FILL_CSS_NODE_PIXEL(marginBottom, margin[CSS_BOTTOM]) - - // border - WX_STYLE_FILL_CSS_NODE_ALL_DIRECTION(borderWidth, border) - WX_STYLE_FILL_CSS_NODE_PIXEL(borderTopWidth, border[CSS_TOP]) - WX_STYLE_FILL_CSS_NODE_PIXEL(borderLeftWidth, border[CSS_LEFT]) - WX_STYLE_FILL_CSS_NODE_PIXEL(borderRightWidth, border[CSS_RIGHT]) - WX_STYLE_FILL_CSS_NODE_PIXEL(borderBottomWidth, border[CSS_BOTTOM]) - - // padding - WX_STYLE_FILL_CSS_NODE_ALL_DIRECTION(padding, padding) - WX_STYLE_FILL_CSS_NODE_PIXEL(paddingTop, padding[CSS_TOP]) - WX_STYLE_FILL_CSS_NODE_PIXEL(paddingLeft, padding[CSS_LEFT]) - WX_STYLE_FILL_CSS_NODE_PIXEL(paddingRight, padding[CSS_RIGHT]) - WX_STYLE_FILL_CSS_NODE_PIXEL(paddingBottom, padding[CSS_BOTTOM]) - } - -//#else - else - { // flex if (styles[@"flex"]) { _flexCssNode->setFlex([WXConvert CGFloat:styles[@"flex"]]); @@ -534,9 +362,6 @@ do {\ } [self setNeedsLayout]; - } - -//#endif } -(CGFloat)judgePropValuePropValue:(NSString *)propValue defaultValue:(CGFloat)defaultValue{ @@ -547,26 +372,6 @@ do {\ return defaultValue; } -//#ifndef USE_FLEX - -#define WX_STYLE_RESET_CSS_NODE(key, cssProp, defaultValue)\ -do {\ - if (styles && [styles containsObject:@#key]) {\ - _cssNode->style.cssProp = defaultValue;\ - [self setNeedsLayout];\ - }\ -} while(0); - -#define WX_STYLE_RESET_CSS_NODE_ALL_DIRECTION(key, cssProp, defaultValue)\ -do {\ - WX_STYLE_RESET_CSS_NODE(key, cssProp[CSS_TOP], defaultValue)\ - WX_STYLE_RESET_CSS_NODE(key, cssProp[CSS_LEFT], defaultValue)\ - WX_STYLE_RESET_CSS_NODE(key, cssProp[CSS_RIGHT], defaultValue)\ - WX_STYLE_RESET_CSS_NODE(key, cssProp[CSS_BOTTOM], defaultValue)\ -} while(0); - -//#else - #define WX_FLEX_STYLE_RESET_CSS_NODE(key, defaultValue)\ do {\ WX_FLEX_STYLE_RESET_CSS_NODE_GIVEN_KEY(key,key,defaultValue)\ @@ -595,88 +400,34 @@ do {\ }\ } while(0); -//#endif - - (void)_resetCSSNode:(NSArray *)styles { -//#ifndef USE_FLEX - if(![WXComponent isUseFlex]) - { - WX_STYLE_RESET_CSS_NODE(direction, direction, CSS_DIRECTION_LTR) - // flex - WX_STYLE_RESET_CSS_NODE(flex, flex, 0.0) - WX_STYLE_RESET_CSS_NODE(flexDirection, flex_direction, CSS_FLEX_DIRECTION_COLUMN) - WX_STYLE_RESET_CSS_NODE(alignItems, align_items, CSS_ALIGN_STRETCH) - WX_STYLE_RESET_CSS_NODE(alignSelf, align_self, CSS_ALIGN_AUTO) - WX_STYLE_RESET_CSS_NODE(flexWrap, flex_wrap, CSS_NOWRAP) - WX_STYLE_RESET_CSS_NODE(justifyContent, justify_content, CSS_JUSTIFY_FLEX_START) - - // position - WX_STYLE_RESET_CSS_NODE(position, position_type, CSS_POSITION_RELATIVE) - WX_STYLE_RESET_CSS_NODE(top, position[CSS_TOP], CSS_UNDEFINED) - WX_STYLE_RESET_CSS_NODE(left, position[CSS_LEFT], CSS_UNDEFINED) - WX_STYLE_RESET_CSS_NODE(right, position[CSS_RIGHT], CSS_UNDEFINED) - WX_STYLE_RESET_CSS_NODE(bottom, position[CSS_BOTTOM], CSS_UNDEFINED) - - // dimension - WX_STYLE_RESET_CSS_NODE(width, dimensions[CSS_WIDTH], CSS_UNDEFINED) - WX_STYLE_RESET_CSS_NODE(height, dimensions[CSS_HEIGHT], CSS_UNDEFINED) - WX_STYLE_RESET_CSS_NODE(minWidth, minDimensions[CSS_WIDTH], CSS_UNDEFINED) - WX_STYLE_RESET_CSS_NODE(minHeight, minDimensions[CSS_HEIGHT], CSS_UNDEFINED) - WX_STYLE_RESET_CSS_NODE(maxWidth, maxDimensions[CSS_WIDTH], CSS_UNDEFINED) - WX_STYLE_RESET_CSS_NODE(maxHeight, maxDimensions[CSS_HEIGHT], CSS_UNDEFINED) - - // margin - WX_STYLE_RESET_CSS_NODE_ALL_DIRECTION(margin, margin, 0.0) - WX_STYLE_RESET_CSS_NODE(marginTop, margin[CSS_TOP], 0.0) - WX_STYLE_RESET_CSS_NODE(marginLeft, margin[CSS_LEFT], 0.0) - WX_STYLE_RESET_CSS_NODE(marginRight, margin[CSS_RIGHT], 0.0) - WX_STYLE_RESET_CSS_NODE(marginBottom, margin[CSS_BOTTOM], 0.0) - - // border - WX_STYLE_RESET_CSS_NODE_ALL_DIRECTION(borderWidth, border, 0.0) - WX_STYLE_RESET_CSS_NODE(borderTopWidth, border[CSS_TOP], 0.0) - WX_STYLE_RESET_CSS_NODE(borderLeftWidth, border[CSS_LEFT], 0.0) - WX_STYLE_RESET_CSS_NODE(borderRightWidth, border[CSS_RIGHT], 0.0) - WX_STYLE_RESET_CSS_NODE(borderBottomWidth, border[CSS_BOTTOM], 0.0) - - // padding - WX_STYLE_RESET_CSS_NODE_ALL_DIRECTION(padding, padding, 0.0) - WX_STYLE_RESET_CSS_NODE(paddingTop, padding[CSS_TOP], 0.0) - WX_STYLE_RESET_CSS_NODE(paddingLeft, padding[CSS_LEFT], 0.0) - WX_STYLE_RESET_CSS_NODE(paddingRight, padding[CSS_RIGHT], 0.0) - WX_STYLE_RESET_CSS_NODE(paddingBottom, padding[CSS_BOTTOM], 0.0) - } - -//#else - else - { if (styles.count<=0) { return; } WX_FLEX_STYLE_RESET_CSS_NODE(flex, @0.0) - WX_FLEX_STYLE_RESET_CSS_NODE(flexDirection, @(CSS_FLEX_DIRECTION_COLUMN)) - WX_FLEX_STYLE_RESET_CSS_NODE(alignItems, @(CSS_ALIGN_STRETCH)) - WX_FLEX_STYLE_RESET_CSS_NODE(alignSelf, @(CSS_ALIGN_AUTO)) - WX_FLEX_STYLE_RESET_CSS_NODE(flexWrap, @(CSS_NOWRAP)) - WX_FLEX_STYLE_RESET_CSS_NODE(justifyContent, @(CSS_JUSTIFY_FLEX_START)) + WX_FLEX_STYLE_RESET_CSS_NODE(flexDirection, @(WeexCore::kFlexDirectionColumn)) + WX_FLEX_STYLE_RESET_CSS_NODE(alignItems, @(WeexCore::kAlignItemsStretch)) + WX_FLEX_STYLE_RESET_CSS_NODE(alignSelf, @(WeexCore::kAlignSelfAuto)) + WX_FLEX_STYLE_RESET_CSS_NODE(flexWrap, @(WeexCore::kNoWrap)) + WX_FLEX_STYLE_RESET_CSS_NODE(justifyContent, @(WeexCore::kJustifyFlexStart)) // position - WX_FLEX_STYLE_RESET_CSS_NODE(position, @(CSS_POSITION_RELATIVE)) - WX_FLEX_STYLE_RESET_CSS_NODE(top, @(CSS_UNDEFINED)) - WX_FLEX_STYLE_RESET_CSS_NODE(left, @(CSS_UNDEFINED)) - WX_FLEX_STYLE_RESET_CSS_NODE(right, @(CSS_UNDEFINED)) - WX_FLEX_STYLE_RESET_CSS_NODE(bottom, @(CSS_UNDEFINED)) + WX_FLEX_STYLE_RESET_CSS_NODE(position, @(WeexCore::kRelative)) + WX_FLEX_STYLE_RESET_CSS_NODE(top, @(NAN)) + WX_FLEX_STYLE_RESET_CSS_NODE(left, @(NAN)) + WX_FLEX_STYLE_RESET_CSS_NODE(right, @(NAN)) + WX_FLEX_STYLE_RESET_CSS_NODE(bottom, @(NAN)) // dimension - WX_FLEX_STYLE_RESET_CSS_NODE(width, @(CSS_UNDEFINED)) - WX_FLEX_STYLE_RESET_CSS_NODE(height, @(CSS_UNDEFINED)) - WX_FLEX_STYLE_RESET_CSS_NODE(minWidth, @(CSS_UNDEFINED)) - WX_FLEX_STYLE_RESET_CSS_NODE(minHeight, @(CSS_UNDEFINED)) - WX_FLEX_STYLE_RESET_CSS_NODE(maxWidth, @(CSS_UNDEFINED)) - WX_FLEX_STYLE_RESET_CSS_NODE(maxHeight, @(CSS_UNDEFINED)) + WX_FLEX_STYLE_RESET_CSS_NODE(width, @(NAN)) + WX_FLEX_STYLE_RESET_CSS_NODE(height, @(NAN)) + WX_FLEX_STYLE_RESET_CSS_NODE(minWidth, @(NAN)) + WX_FLEX_STYLE_RESET_CSS_NODE(minHeight, @(NAN)) + WX_FLEX_STYLE_RESET_CSS_NODE(maxWidth, @(NAN)) + WX_FLEX_STYLE_RESET_CSS_NODE(maxHeight, @(NAN)) // margin WX_FLEX_STYLE_RESET_CSS_NODE_GIVEN_DIRECTION_KEY(margin @@ -713,81 +464,10 @@ do {\ WX_FLEX_STYLE_RESET_CSS_NODE(paddingLeft, @(0.0)) WX_FLEX_STYLE_RESET_CSS_NODE(paddingRight, @(0.0)) WX_FLEX_STYLE_RESET_CSS_NODE(paddingBottom, @(0.0)) - } - - -//#endif -} - -#pragma mark CSS Node Override -//#ifndef USE_FLEX -#if defined __cplusplus -extern "C" { -#endif -static void cssNodePrint(void *context) -{ - WXComponent *component = (__bridge WXComponent *)context; - // TODO: - printf("%s:%s ", component.ref.UTF8String, component->_type.UTF8String); } -static css_node_t * cssNodeGetChild(void *context, int i) -{ - WXComponent *component = (__bridge WXComponent *)context; - NSArray *subcomponents = component->_subcomponents; - for (int j = 0; j <= i && j < subcomponents.count; j++) { - WXComponent *child = subcomponents[j]; - if (!child->_isNeedJoinLayoutSystem) { - i++; - } - } - - if(i >= 0 && i < subcomponents.count){ - WXComponent *child = subcomponents[i]; -// WXLogInfo(@"FlexLayout -- P:%@ -> C:%@",component,(__bridge WXComponent *)child->_cssNode->context); - return child->_cssNode; - } - - WXAssert(NO, @"Can not find component:%@'s css node child at index: %ld, totalCount:%ld", component, i, subcomponents.count); - return NULL; -} - -static bool cssNodeIsDirty(void *context) -{ - WXAssertComponentThread(); - - WXComponent *component = (__bridge WXComponent *)context; - BOOL needsLayout = [component needsLayout]; - - return needsLayout; -} - -static css_dim_t cssNodeMeasure(void *context, float width, css_measure_mode_t widthMode, float height, css_measure_mode_t heightMode) -{ - WXComponent *component = (__bridge WXComponent *)context; - CGSize (^measureBlock)(CGSize) = [component measureBlock]; - - if (!measureBlock) { - return (css_dim_t){NAN, NAN}; - } - - CGSize constrainedSize = CGSizeMake(width, height); - CGSize resultSize = measureBlock(constrainedSize); -#ifdef DEBUG - WXLogDebug(@"flexLayout -> measureblock %@, resultSize:%@", - component.type, - NSStringFromCGSize(resultSize) - ); -#endif - - return (css_dim_t){(float)resultSize.width, (float)resultSize.height}; -} -#if defined __cplusplus -}; -#endif - -//#else +#pragma mark CSS Node Override static WeexCore::WXCoreSize flexCssNodeMeasure(WeexCore::WXCoreLayoutNode *node, float width, WeexCore::MeasureMode widthMeasureMode,float height, WeexCore::MeasureMode heightMeasureMode){ @@ -957,17 +637,5 @@ static WeexCore::WXCoreSize flexCssNodeMeasure(WeexCore::WXCoreLayoutNode *node, } -+ (void) setUseFlex:(BOOL)useFlex -{ - sUseFlex =useFlex; -} - - -+ (BOOL) isUseFlex -{ - return sUseFlex; -} - -//#endif @end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9acc1bc4/ios/sdk/WeexSDK/Sources/Layout/WXLayoutDefine.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Layout/WXLayoutDefine.h b/ios/sdk/WeexSDK/Sources/Layout/WXLayoutDefine.h deleted file mode 100644 index 93f43e9..0000000 --- a/ios/sdk/WeexSDK/Sources/Layout/WXLayoutDefine.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#if defined __cplusplus -extern "C" { -#endif - -#define WX_LAYOUT_NAMESPACE wx_ - -#ifdef WX_LAYOUT_NAMESPACE - // prefix all layout symbols with "wx_" to prevent conflict - #define WX_NAMESPACE_PREFIX_INNER(namespace, symbol) namespace ## symbol - #define WX_NAMESPACE_PREFIX(namespace, symbol) WX_NAMESPACE_PREFIX_INNER(namespace, symbol) - #define WX_LAYOUT_PREFIX(symbol) WX_NAMESPACE_PREFIX(WX_LAYOUT_NAMESPACE, symbol) - - #define css_direction_t WX_LAYOUT_PREFIX(css_direction_t) - #define css_flex_direction_t WX_LAYOUT_PREFIX(css_flex_direction_t) - #define css_justify_t WX_LAYOUT_PREFIX(css_justify_t) - #define css_align_t WX_LAYOUT_PREFIX(css_align_t) - #define css_position_type_t WX_LAYOUT_PREFIX(css_position_type_t) - #define css_wrap_type_t WX_LAYOUT_PREFIX(css_wrap_type_t) - #define css_position_t WX_LAYOUT_PREFIX(css_position_t) - #define css_dimension_t WX_LAYOUT_PREFIX(css_dimension_t) - #define css_layout_t WX_LAYOUT_PREFIX(css_layout_t) - #define css_dim_t WX_LAYOUT_PREFIX(css_dim_t) - #define css_style_t WX_LAYOUT_PREFIX(css_style_t) - #define css_node WX_LAYOUT_PREFIX(css_node) - #define css_node_t WX_LAYOUT_PREFIX(css_node_t) - #define new_css_node WX_LAYOUT_PREFIX(new_css_node) - #define init_css_node WX_LAYOUT_PREFIX(init_css_node) - #define free_css_node WX_LAYOUT_PREFIX(free_css_node) - #define css_print_options_t WX_LAYOUT_PREFIX(css_print_options_t) - #define print_css_node WX_LAYOUT_PREFIX(print_css_node) - #define layoutNode WX_LAYOUT_PREFIX(layoutNode) - #define isUndefined WX_LAYOUT_PREFIX(isUndefined) - #define resetNodeLayout WX_LAYOUT_PREFIX(resetNodeLayout) - -#endif - - -#import "Layout.h" - -#if defined __cplusplus -}; -#endif - - http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9acc1bc4/ios/sdk/WeexSDK/Sources/Layout/WXScrollerComponent+Layout.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Layout/WXScrollerComponent+Layout.h b/ios/sdk/WeexSDK/Sources/Layout/WXScrollerComponent+Layout.h index 9af5170..4904741 100644 --- a/ios/sdk/WeexSDK/Sources/Layout/WXScrollerComponent+Layout.h +++ b/ios/sdk/WeexSDK/Sources/Layout/WXScrollerComponent+Layout.h @@ -23,24 +23,16 @@ @interface WXScrollerComponent () { -//#ifndef USE_FLEX - css_node_t *_scrollerCSSNode; -//#else #ifdef __cplusplus WeexCore::WXCoreLayoutNode *_flexScrollerCSSNode; #endif -//#endif } @end @interface WXScrollerComponent (FlexLayout) -//#ifndef USE_FLEX -@property (nonatomic, readonly, assign) css_node_t *scrollerCSSNode; -//#else #ifdef __cplusplus @property (nonatomic, readonly, assign) WeexCore::WXCoreLayoutNode *flexScrollerCSSNode; #endif -//#endif @end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9acc1bc4/ios/sdk/WeexSDK/Sources/Layout/WXScrollerComponent+Layout.mm ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Layout/WXScrollerComponent+Layout.mm b/ios/sdk/WeexSDK/Sources/Layout/WXScrollerComponent+Layout.mm index 6eb8c9d..3c7edc7 100644 --- a/ios/sdk/WeexSDK/Sources/Layout/WXScrollerComponent+Layout.mm +++ b/ios/sdk/WeexSDK/Sources/Layout/WXScrollerComponent+Layout.mm @@ -22,12 +22,6 @@ @implementation WXScrollerComponent (FlexLayout) -//#ifndef USE_FLEX -- (css_node_t *)scrollerCSSNode -{ - return _scrollerCSSNode; -} -//#else - (WeexCore::WXCoreLayoutNode *)flexScrollerCSSNode{ return _flexScrollerCSSNode; } @@ -49,5 +43,4 @@ #endif } -//#endif @end
