Add support for measure mode
This commit is contained in:
9
TestResult.xml
Normal file
9
TestResult.xml
Normal file
@@ -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
dist/css-layout.h
vendored
30
dist/css-layout.h
vendored
@@ -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
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -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] +
|
||||
@@ -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) {
|
||||
|
BIN
dist/css-layout.jar
vendored
BIN
dist/css-layout.jar
vendored
Binary file not shown.
24
dist/css-layout.js
vendored
24
dist/css-layout.js
vendored
@@ -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',
|
||||
@@ -110,7 +114,7 @@ var computeLayout = (function() {
|
||||
}
|
||||
|
||||
function isUndefined(value) {
|
||||
return value === undefined;
|
||||
return value === undefined || isNaN(value);
|
||||
}
|
||||
|
||||
function isRowDirection(flexDirection) {
|
||||
@@ -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
|
||||
@@ -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 +
|
||||
|
2
dist/css-layout.min.js
vendored
2
dist/css-layout.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/css-layout.min.js.map
vendored
2
dist/css-layout.min.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -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')
|
||||
@@ -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);
|
||||
});
|
||||
|
@@ -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')
|
||||
|
@@ -82,11 +82,11 @@ 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);
|
||||
@@ -94,7 +94,7 @@ css_dim_t measure(void *context, float width, float 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);
|
||||
@@ -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 {
|
||||
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
@@ -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
|
||||
|
18
src/Layout.c
18
src/Layout.c
@@ -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
|
||||
@@ -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] +
|
||||
|
@@ -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
|
||||
@@ -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);
|
||||
|
@@ -34,6 +34,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',
|
||||
@@ -91,7 +95,7 @@ var computeLayout = (function() {
|
||||
}
|
||||
|
||||
function isUndefined(value) {
|
||||
return value === undefined;
|
||||
return value === undefined || isNaN(value);
|
||||
}
|
||||
|
||||
function isRowDirection(flexDirection) {
|
||||
@@ -482,26 +486,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
|
||||
@@ -516,7 +534,9 @@ var computeLayout = (function() {
|
||||
/*(c)!node->context,*/
|
||||
/*(java)!layoutContext.measureOutput,*/
|
||||
width,
|
||||
height
|
||||
widthMode,
|
||||
height,
|
||||
heightMode
|
||||
);
|
||||
if (isRowUndefined) {
|
||||
node.layout.width = measureDim.width +
|
||||
|
@@ -226,7 +226,7 @@ namespace Facebook.CSSLayout.Tests
|
||||
root.calculateLayout();
|
||||
markLayoutAppliedForTree(root);
|
||||
|
||||
c1.setMeasureFunction((node, width, height) => new MeasureOutput(100, 20));
|
||||
c1.setMeasureFunction((node, width, widthMode, height, heightMode) => new MeasureOutput(100, 20));
|
||||
|
||||
root.calculateLayout();
|
||||
|
||||
|
@@ -25,11 +25,11 @@ public class LayoutEngineTest
|
||||
const int DIMENSION_HEIGHT = CSSLayout.DIMENSION_HEIGHT;
|
||||
const int DIMENSION_WIDTH = CSSLayout.DIMENSION_WIDTH;
|
||||
|
||||
static readonly MeasureFunction sTestMeasureFunction = (node, width, height) =>
|
||||
static readonly MeasureFunction sTestMeasureFunction = (node, width, widthMode, height, heightMode) =>
|
||||
{
|
||||
TestCSSNode testNode = (TestCSSNode) node;
|
||||
if (testNode.context.Equals(TestConstants.SMALL_TEXT)) {
|
||||
if (CSSConstants.IsUndefined(width)) {
|
||||
if (widthMode == CSSMeasureMode.Undefined) {
|
||||
width = 10000000;
|
||||
}
|
||||
return new MeasureOutput(
|
||||
@@ -46,14 +46,20 @@ public class LayoutEngineTest
|
||||
? TestConstants.SMALL_HEIGHT
|
||||
: TestConstants.BIG_HEIGHT);
|
||||
} else if (testNode.context.Equals(TestConstants.MEASURE_WITH_RATIO_2)) {
|
||||
if (width > 0) {
|
||||
if (widthMode != CSSMeasureMode.Undefined) {
|
||||
return new MeasureOutput(width, width * 2);
|
||||
} else if (height > 0) {
|
||||
} else if (heightMode != CSSMeasureMode.Undefined) {
|
||||
return new MeasureOutput(height * 2, height);
|
||||
} else {
|
||||
return new MeasureOutput(99999, 99999);
|
||||
}
|
||||
} else if (testNode.context.Equals(TestConstants.MEASURE_WITH_MATCH_PARENT)) {
|
||||
if (widthMode == CSSMeasureMode.Undefined) {
|
||||
width = 99999;
|
||||
}
|
||||
if (heightMode == CSSMeasureMode.Undefined) {
|
||||
height = 99999;
|
||||
}
|
||||
return new MeasureOutput(width, height);
|
||||
} else {
|
||||
throw new Exception("Got unknown test: " + testNode.context);
|
||||
|
18
src/csharp/Facebook.CSSLayout/CSSMeasureMode.cs
Normal file
18
src/csharp/Facebook.CSSLayout/CSSMeasureMode.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace Facebook.CSSLayout
|
||||
{
|
||||
public enum CSSMeasureMode
|
||||
{
|
||||
Undefined,
|
||||
Exactly,
|
||||
AtMost,
|
||||
}
|
||||
}
|
@@ -17,7 +17,7 @@ namespace Facebook.CSSLayout
|
||||
* Should measure the given node and put the result in the given MeasureOutput.
|
||||
*/
|
||||
|
||||
public delegate MeasureOutput MeasureFunction(CSSNode node, float width, float height);
|
||||
public delegate MeasureOutput MeasureFunction(CSSNode node, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode);
|
||||
|
||||
/**
|
||||
* A CSS Node. It has a style object you can manipulate at {@link #style}. After calling
|
||||
@@ -140,13 +140,13 @@ namespace Facebook.CSSLayout
|
||||
get { return mMeasureFunction != null; }
|
||||
}
|
||||
|
||||
internal MeasureOutput measure(MeasureOutput measureOutput, float width, float height)
|
||||
internal MeasureOutput measure(MeasureOutput measureOutput, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode)
|
||||
{
|
||||
if (!IsMeasureDefined)
|
||||
{
|
||||
throw new Exception("Measure function isn't defined!");
|
||||
}
|
||||
return Assertions.assertNotNull(mMeasureFunction)(this, width, height);
|
||||
return Assertions.assertNotNull(mMeasureFunction)(this, width, widthMode, height, heightMode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -45,6 +45,7 @@
|
||||
<Compile Include="CSSDirection.cs" />
|
||||
<Compile Include="CSSFlexDirection.cs" />
|
||||
<Compile Include="CSSJustify.cs" />
|
||||
<Compile Include="CSSMeasureMode.cs" />
|
||||
<Compile Include="CSSLayout.cs" />
|
||||
<Compile Include="CSSLayoutContext.cs" />
|
||||
<Compile Include="CSSNode.cs" />
|
||||
@@ -67,4 +68,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
@@ -282,26 +282,40 @@ namespace Facebook.CSSLayout
|
||||
boolean isResolvedRowDimDefined = (!float.IsNaN(node.layout.dimensions[dim[resolvedRowAxis]]) && node.layout.dimensions[dim[resolvedRowAxis]] >= 0.0);
|
||||
|
||||
float width = CSSConstants.Undefined;
|
||||
CSSMeasureMode widthMode = CSSMeasureMode.Undefined;
|
||||
if ((!float.IsNaN(node.style.dimensions[dim[resolvedRowAxis]]) && node.style.dimensions[dim[resolvedRowAxis]] >= 0.0)) {
|
||||
width = node.style.dimensions[DIMENSION_WIDTH];
|
||||
widthMode = CSSMeasureMode.Exactly;
|
||||
} else if (isResolvedRowDimDefined) {
|
||||
width = node.layout.dimensions[dim[resolvedRowAxis]];
|
||||
widthMode = CSSMeasureMode.Exactly;
|
||||
} else {
|
||||
width = parentMaxWidth -
|
||||
(node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]));
|
||||
widthMode = CSSMeasureMode.AtMost;
|
||||
}
|
||||
width -= paddingAndBorderAxisResolvedRow;
|
||||
if (float.IsNaN(width)) {
|
||||
widthMode = CSSMeasureMode.Undefined;
|
||||
}
|
||||
|
||||
float height = CSSConstants.Undefined;
|
||||
CSSMeasureMode heightMode = CSSMeasureMode.Undefined;
|
||||
if ((!float.IsNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
|
||||
height = node.style.dimensions[DIMENSION_HEIGHT];
|
||||
heightMode = CSSMeasureMode.Exactly;
|
||||
} else if ((!float.IsNaN(node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
|
||||
height = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]];
|
||||
heightMode = CSSMeasureMode.Exactly;
|
||||
} else {
|
||||
height = parentMaxHeight -
|
||||
(node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]));
|
||||
heightMode = CSSMeasureMode.AtMost;
|
||||
}
|
||||
height -= ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])));
|
||||
if (float.IsNaN(height)) {
|
||||
heightMode = CSSMeasureMode.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
|
||||
@@ -316,7 +330,9 @@ namespace Facebook.CSSLayout
|
||||
|
||||
layoutContext.measureOutput,
|
||||
width,
|
||||
height
|
||||
widthMode,
|
||||
height,
|
||||
heightMode
|
||||
);
|
||||
if (isRowUndefined) {
|
||||
node.layout.dimensions[DIMENSION_WIDTH] = measureDim.width +
|
||||
|
15
src/java/src/com/facebook/csslayout/CSSMeasureMode.java
Normal file
15
src/java/src/com/facebook/csslayout/CSSMeasureMode.java
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package com.facebook.csslayout;
|
||||
|
||||
public enum CSSMeasureMode {
|
||||
UNDEFINED,
|
||||
EXACTLY,
|
||||
AT_MOST,
|
||||
}
|
@@ -53,7 +53,7 @@ public class CSSNode {
|
||||
*
|
||||
* NB: measure is NOT guaranteed to be threadsafe/re-entrant safe!
|
||||
*/
|
||||
public void measure(CSSNode node, float width, float height, MeasureOutput measureOutput);
|
||||
public void measure(CSSNode node, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode, MeasureOutput measureOutput);
|
||||
}
|
||||
|
||||
// VisibleForTesting
|
||||
@@ -125,13 +125,13 @@ public class CSSNode {
|
||||
return mMeasureFunction != null;
|
||||
}
|
||||
|
||||
/*package*/ MeasureOutput measure(MeasureOutput measureOutput, float width, float height) {
|
||||
/*package*/ MeasureOutput measure(MeasureOutput measureOutput, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode) {
|
||||
if (!isMeasureDefined()) {
|
||||
throw new RuntimeException("Measure function isn't defined!");
|
||||
}
|
||||
measureOutput.height = CSSConstants.UNDEFINED;
|
||||
measureOutput.width = CSSConstants.UNDEFINED;
|
||||
Assertions.assertNotNull(mMeasureFunction).measure(this, width, height, measureOutput);
|
||||
Assertions.assertNotNull(mMeasureFunction).measure(this, width, widthMode, height, heightMode, measureOutput);
|
||||
return measureOutput;
|
||||
}
|
||||
|
||||
|
@@ -258,26 +258,40 @@ public class LayoutEngine {
|
||||
boolean isResolvedRowDimDefined = (!Float.isNaN(node.layout.dimensions[dim[resolvedRowAxis]]) && node.layout.dimensions[dim[resolvedRowAxis]] >= 0.0);
|
||||
|
||||
float width = CSSConstants.UNDEFINED;
|
||||
CSSMeasureMode widthMode = CSSMeasureMode.UNDEFINED;
|
||||
if ((!Float.isNaN(node.style.dimensions[dim[resolvedRowAxis]]) && node.style.dimensions[dim[resolvedRowAxis]] >= 0.0)) {
|
||||
width = node.style.dimensions[DIMENSION_WIDTH];
|
||||
widthMode = CSSMeasureMode.EXACTLY;
|
||||
} else if (isResolvedRowDimDefined) {
|
||||
width = node.layout.dimensions[dim[resolvedRowAxis]];
|
||||
widthMode = CSSMeasureMode.EXACTLY;
|
||||
} else {
|
||||
width = parentMaxWidth -
|
||||
(node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]));
|
||||
widthMode = CSSMeasureMode.AT_MOST;
|
||||
}
|
||||
width -= paddingAndBorderAxisResolvedRow;
|
||||
if (Float.isNaN(width)) {
|
||||
widthMode = CSSMeasureMode.UNDEFINED;
|
||||
}
|
||||
|
||||
float height = CSSConstants.UNDEFINED;
|
||||
CSSMeasureMode heightMode = CSSMeasureMode.UNDEFINED;
|
||||
if ((!Float.isNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
|
||||
height = node.style.dimensions[DIMENSION_HEIGHT];
|
||||
heightMode = CSSMeasureMode.EXACTLY;
|
||||
} else if ((!Float.isNaN(node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
|
||||
height = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]];
|
||||
heightMode = CSSMeasureMode.EXACTLY;
|
||||
} else {
|
||||
height = parentMaxHeight -
|
||||
(node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]));
|
||||
heightMode = CSSMeasureMode.AT_MOST;
|
||||
}
|
||||
height -= ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])));
|
||||
if (Float.isNaN(height)) {
|
||||
heightMode = CSSMeasureMode.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
|
||||
@@ -292,7 +306,9 @@ public class LayoutEngine {
|
||||
|
||||
layoutContext.measureOutput,
|
||||
width,
|
||||
height
|
||||
widthMode,
|
||||
height,
|
||||
heightMode
|
||||
);
|
||||
if (isRowUndefined) {
|
||||
node.layout.dimensions[DIMENSION_WIDTH] = measureDim.width +
|
||||
|
@@ -223,7 +223,7 @@ public class LayoutCachingTest {
|
||||
|
||||
c1.setMeasureFunction(new CSSNode.MeasureFunction() {
|
||||
@Override
|
||||
public void measure(CSSNode node, float width, float height, MeasureOutput measureOutput) {
|
||||
public void measure(CSSNode node, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode, MeasureOutput measureOutput) {
|
||||
measureOutput.width = 100;
|
||||
measureOutput.height = 20;
|
||||
}
|
||||
|
@@ -27,16 +27,16 @@ public class LayoutEngineTest {
|
||||
new CSSNode.MeasureFunction() {
|
||||
|
||||
@Override
|
||||
public void measure(CSSNode node, float width, float height, MeasureOutput measureOutput) {
|
||||
public void measure(CSSNode node, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode, MeasureOutput measureOutput) {
|
||||
TestCSSNode testNode = (TestCSSNode) node;
|
||||
if (testNode.context.equals(TestConstants.SMALL_TEXT)) {
|
||||
if (CSSConstants.isUndefined(width)) {
|
||||
if (widthMode == CSSMeasureMode.UNDEFINED) {
|
||||
width = 10000000;
|
||||
}
|
||||
measureOutput.width = Math.min(width, TestConstants.SMALL_WIDTH);
|
||||
measureOutput.height = TestConstants.SMALL_HEIGHT;
|
||||
} else if (testNode.context.equals(TestConstants.LONG_TEXT)) {
|
||||
if (CSSConstants.isUndefined(width)) {
|
||||
if (widthMode == CSSMeasureMode.UNDEFINED) {
|
||||
width = 10000000;
|
||||
}
|
||||
measureOutput.width = width >= TestConstants.BIG_WIDTH ?
|
||||
@@ -44,10 +44,10 @@ public class LayoutEngineTest {
|
||||
measureOutput.height = width >= TestConstants.BIG_WIDTH ?
|
||||
TestConstants.SMALL_HEIGHT : TestConstants.BIG_HEIGHT;
|
||||
} else if (testNode.context.equals(TestConstants.MEASURE_WITH_RATIO_2)) {
|
||||
if (width > 0) {
|
||||
if (widthMode != CSSMeasureMode.UNDEFINED) {
|
||||
measureOutput.width = width;
|
||||
measureOutput.height = width * 2;
|
||||
} else if (height > 0) {
|
||||
} else if (heightMode != CSSMeasureMode.UNDEFINED) {
|
||||
measureOutput.width = height * 2;
|
||||
measureOutput.height = height;
|
||||
} else {
|
||||
@@ -55,6 +55,12 @@ public class LayoutEngineTest {
|
||||
measureOutput.height = 99999;
|
||||
}
|
||||
} else if (testNode.context.equals(TestConstants.MEASURE_WITH_MATCH_PARENT)) {
|
||||
if (widthMode == CSSMeasureMode.UNDEFINED) {
|
||||
width = 99999;
|
||||
}
|
||||
if (heightMode == CSSMeasureMode.UNDEFINED) {
|
||||
height = 99999;
|
||||
}
|
||||
measureOutput.width = width;
|
||||
measureOutput.height = height;
|
||||
} else {
|
||||
|
@@ -170,6 +170,11 @@ function printLayout(test) {
|
||||
'nowrap': 'CSS_NOWRAP',
|
||||
'wrap': 'CSS_WRAP'
|
||||
});
|
||||
addEnum(node, 'measureMode', 'measure_mode', {
|
||||
'undefined': 'CSS_MEASURE_MODE_UNDEFINED',
|
||||
'exactly': 'CSS_MEASURE_MODE_EXACTLY',
|
||||
'at-most': 'CSS_MEASURE_MODE_AT_MOST'
|
||||
});
|
||||
addFloat(node, 'flex', 'flex');
|
||||
addFloat(node, 'width', 'dimensions[CSS_WIDTH]');
|
||||
addFloat(node, 'height', 'dimensions[CSS_HEIGHT]');
|
||||
|
Reference in New Issue
Block a user