Skip to content

Commit

Permalink
Merge pull request #163 from emilsjolander/measuremode
Browse files Browse the repository at this point in the history
Add support for measure mode
  • Loading branch information
emilsjolander committed Apr 6, 2016
2 parents 68e0b0c + 7bd6b2b commit b0d00ad
Show file tree
Hide file tree
Showing 26 changed files with 237 additions and 45 deletions.
9 changes: 9 additions & 0 deletions TestResult.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!--This file represents the results of running a test suite-->
<test-results name="src/csharp/Facebook.CSSLayout.Tests/bin/Release/Facebook.CSSLayout.Tests.dll" total="0" failures="0" not-run="0" date="2016-04-01" time="11:01:04">
<environment nunit-version="2.4.8.0" clr-version="4.0.30319.17020" os-version="Unix 15.4.0.0" platform="Unix" cwd="/Users/emilsj/css-layout" machine-name="emilsj-pro" user="emilsj" user-domain="emilsj-pro" />
<culture-info current-culture="en-US" current-uiculture="en-US" />
<test-suite name="src/csharp/Facebook.CSSLayout.Tests/bin/Release/Facebook.CSSLayout.Tests.dll" success="True" time="0.001" asserts="0">
<results />
</test-suite>
</test-results>
30 changes: 26 additions & 4 deletions dist/css-layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ typedef enum {
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
Expand Down Expand Up @@ -144,7 +150,7 @@ struct css_node {
css_node_t *next_absolute_child;
css_node_t *next_flex_child;

css_dim_t (*measure)(void *context, float width, float height);
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);
Expand Down Expand Up @@ -734,26 +740,40 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
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
Expand All @@ -768,7 +788,9 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
node->context,

width,
height
widthMode,
height,
heightMode
);
if (isRowUndefined) {
node->layout.dimensions[CSS_WIDTH] = measureDim.dimensions[CSS_WIDTH] +
Expand Down Expand Up @@ -1447,8 +1469,8 @@ void layoutNode(css_node_t *node, float parentMaxWidth, float parentMaxHeight, c
!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_parent_max_width, parentMaxWidth) &&
eq(layout->last_parent_max_height, parentMaxHeight) &&
eq(layout->last_direction, direction);

if (skipLayout) {
Expand Down
Binary file modified dist/css-layout.jar
Binary file not shown.
24 changes: 22 additions & 2 deletions dist/css-layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ var computeLayout = (function() {
var CSS_POSITION_RELATIVE = 'relative';
var CSS_POSITION_ABSOLUTE = 'absolute';

var CSS_MEASURE_MODE_UNDEFINED = 'undefined';
var CSS_MEASURE_MODE_EXACTLY = 'exactly';
var CSS_MEASURE_MODE_AT_MOST = 'at-most';

var leading = {
'row': 'left',
'row-reverse': 'right',
Expand Down Expand Up @@ -110,7 +114,7 @@ var computeLayout = (function() {
}

function isUndefined(value) {
return value === undefined;
return value === undefined || isNaN(value);
}

function isRowDirection(flexDirection) {
Expand Down Expand Up @@ -501,26 +505,40 @@ var computeLayout = (function() {
var/*bool*/ isResolvedRowDimDefined = isLayoutDimDefined(node, resolvedRowAxis);

var/*float*/ width = CSS_UNDEFINED;
var/*css_measure_mode_t*/ widthMode = CSS_MEASURE_MODE_UNDEFINED;
if (isStyleDimDefined(node, resolvedRowAxis)) {
width = node.style.width;
widthMode = CSS_MEASURE_MODE_EXACTLY;
} else if (isResolvedRowDimDefined) {
width = node.layout[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;
}

var/*float*/ height = CSS_UNDEFINED;
var/*css_measure_mode_t*/ heightMode = CSS_MEASURE_MODE_UNDEFINED;
if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {
height = node.style.height;
heightMode = CSS_MEASURE_MODE_EXACTLY;
} else if (isLayoutDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {
height = node.layout[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
Expand All @@ -535,7 +553,9 @@ var computeLayout = (function() {
/*(c)!node->context,*/
/*(java)!layoutContext.measureOutput,*/
width,
height
widthMode,
height,
heightMode
);
if (isRowUndefined) {
node.layout.width = measureDim.width +
Expand Down
2 changes: 1 addition & 1 deletion dist/css-layout.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/css-layout.min.js.map

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/CSharpTranspiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ function __transpileToCSharpCommon(code) {
return code
.replace(/CSS_UNDEFINED/g, 'CSSConstants.UNDEFINED')
.replace(/CSS_JUSTIFY_/g, 'CSSJustify.')
.replace(/CSS_MEASURE_MODE_/g, 'CSSMeasureMode.')
.replace(/CSS_ALIGN_/g, 'CSSAlign.')
.replace(/CSS_POSITION_/g, 'CSSPositionType.')
.replace(/css_flex_direction_t/g, 'CSSFlexDirection')
.replace(/css_direction_t/g, 'CSSDirection')
.replace(/css_align_t/g, 'CSSAlign')
.replace(/css_justify_t/g, 'CSSJustify')
.replace(/css_measure_mode_t/g, 'CSSMeasureMode')
.replace(/css_dim_t/g, 'MeasureOutput')
.replace(/bool/g, 'boolean')
.replace(/style\[dim/g, 'style.dimensions[dim')
Expand Down Expand Up @@ -56,7 +58,7 @@ function __transpileToCSharpCommon(code) {

// additional case conversions

.replace(/(CSSConstants|CSSWrap|CSSJustify|CSSAlign|CSSPositionType)\.([_A-Z]+)/g,
.replace(/(CSSConstants|CSSWrap|CSSJustify|CSSMeasureMode|CSSAlign|CSSPositionType)\.([_A-Z]+)/g,
function(str, match1, match2) {
return match1 + '.' + constantToPascalCase(match2);
});
Expand Down
2 changes: 2 additions & 0 deletions src/JavaTranspiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ function __transpileToJavaCommon(code) {
return code
.replace(/CSS_UNDEFINED/g, 'CSSConstants.UNDEFINED')
.replace(/CSS_JUSTIFY_/g, 'CSSJustify.')
.replace(/CSS_MEASURE_MODE_/g, 'CSSMeasureMode.')
.replace(/CSS_ALIGN_/g, 'CSSAlign.')
.replace(/CSS_POSITION_/g, 'CSSPositionType.')
.replace(/css_flex_direction_t/g, 'CSSFlexDirection')
.replace(/css_direction_t/g, 'CSSDirection')
.replace(/css_align_t/g, 'CSSAlign')
.replace(/css_justify_t/g, 'CSSJustify')
.replace(/css_measure_mode_t/g, 'CSSMeasureMode')
.replace(/css_dim_t/g, 'MeasureOutput')
.replace(/bool/g, 'boolean')
.replace(/style\[dim/g, 'style.dimensions[dim')
Expand Down
16 changes: 11 additions & 5 deletions src/Layout-test-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,19 @@ static bool are_layout_equal(css_node_t *a, css_node_t *b) {
return true;
}

css_dim_t measure(void *context, float width, float height) {
css_dim_t measure(void *context, float width, css_measure_mode_t widthMode, float height, css_measure_mode_t heightMode) {
const char *text = (const char *)context;
css_dim_t dim;
if (strcmp(text, SMALL_TEXT) == 0) {
if (width != width) {
if (widthMode == CSS_MEASURE_MODE_UNDEFINED) {
width = 1000000;
}
dim.dimensions[CSS_WIDTH] = fminf(SMALL_WIDTH, width);
dim.dimensions[CSS_HEIGHT] = SMALL_HEIGHT;
return dim;
}
if (strcmp(text, LONG_TEXT) == 0) {
if (width != width) {
if (widthMode == CSS_MEASURE_MODE_UNDEFINED) {
width = 1000000;
}
dim.dimensions[CSS_WIDTH] = width >= BIG_WIDTH ? BIG_WIDTH : fmaxf(BIG_MIN_WIDTH, width);
Expand All @@ -103,10 +103,10 @@ css_dim_t measure(void *context, float width, float height) {
}

if (strcmp(text, MEASURE_WITH_RATIO_2) == 0) {
if (width > 0) {
if (widthMode != CSS_MEASURE_MODE_UNDEFINED) {
dim.dimensions[CSS_WIDTH] = width;
dim.dimensions[CSS_HEIGHT] = width * 2;
} else if (height > 0) {
} else if (heightMode != CSS_MEASURE_MODE_UNDEFINED) {
dim.dimensions[CSS_WIDTH] = height * 2;
dim.dimensions[CSS_HEIGHT] = height;
} else {
Expand All @@ -117,6 +117,12 @@ css_dim_t measure(void *context, float width, float height) {
}

if (strcmp(text, MEASURE_WITH_MATCH_PARENT) == 0) {
if (widthMode == CSS_MEASURE_MODE_UNDEFINED) {
width = 99999;
}
if (heightMode == CSS_MEASURE_MODE_UNDEFINED) {
height = 99999;
}
dim.dimensions[CSS_WIDTH] = width;
dim.dimensions[CSS_HEIGHT] = height;
return dim;
Expand Down
2 changes: 1 addition & 1 deletion src/Layout-test-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@

void test(const char *name, css_node_t *style, css_node_t *expected_layout);
int tests_finished(void);
css_dim_t measure(void *context, float width, float height);
css_dim_t measure(void *context, float width, css_measure_mode_t widthMode, float height, css_measure_mode_t heightMode);
void init_css_node_children(css_node_t *node, int children_count);
css_node_t *new_test_css_node(void);
18 changes: 12 additions & 6 deletions src/Layout-test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,8 @@ var layoutTestUtils = (function() {
computeDOMLayout: computeDOMLayout,
reduceTest: reduceTest,
text: function(text) {
var fn = function(width, height) {
if (width === undefined || isNaN(width)) {
var fn = function(width, widthMode, height, heightMode) {
if (widthMode === 'undefined') {
width = Infinity;
}

Expand All @@ -522,10 +522,10 @@ var layoutTestUtils = (function() {
return fn;
},
measureWithRatio2: function() {
var fn = function(width, height) {
if (width > 0) {
var fn = function(width, widthMode, height, heightMode) {
if (widthMode !== 'undefined') {
height = width * 2;
} else if (height > 0) {
} else if (heightMode !== 'undefined') {
width = height * 2;
} else {
// This should be Infinity, but it would be pain to transpile,
Expand All @@ -540,7 +540,13 @@ var layoutTestUtils = (function() {
return fn;
},
measureWithMatchParent: function() {
var fn = function(width, height) {
var fn = function(width, widthMode, height, heightMode) {
if (widthMode === 'undefined') {
width = 99999;
}
if (heightMode === 'undefined') {
height = 99999;
}
return {width: width, height: height};
};
// This is necessary for transpiled tests, see previous comment
Expand Down
18 changes: 17 additions & 1 deletion src/Layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,26 +557,40 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
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
Expand All @@ -591,7 +605,9 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
node->context,

width,
height
widthMode,
height,
heightMode
);
if (isRowUndefined) {
node->layout.dimensions[CSS_WIDTH] = measureDim.dimensions[CSS_WIDTH] +
Expand Down
8 changes: 7 additions & 1 deletion src/Layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ typedef enum {
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
Expand Down Expand Up @@ -140,7 +146,7 @@ struct css_node {
css_node_t *next_absolute_child;
css_node_t *next_flex_child;

css_dim_t (*measure)(void *context, float width, float height);
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);
Expand Down
Loading

0 comments on commit b0d00ad

Please sign in to comment.