Fix layout for absolutely positioned nodes with absolutely positioned parents that have border and/or padding
This commit is contained in:
@@ -244,6 +244,10 @@ static float getPaddingAndBorder(css_node_t *node, int location) {
|
|||||||
return getPadding(node, location) + getBorder(node, location);
|
return getPadding(node, location) + getBorder(node, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float getBorderAxis(css_node_t *node, css_flex_direction_t axis) {
|
||||||
|
return getBorder(node, leading[axis]) + getBorder(node, trailing[axis]);
|
||||||
|
}
|
||||||
|
|
||||||
static float getMarginAxis(css_node_t *node, css_flex_direction_t axis) {
|
static float getMarginAxis(css_node_t *node, css_flex_direction_t axis) {
|
||||||
return getMargin(node, leading[axis]) + getMargin(node, trailing[axis]);
|
return getMargin(node, leading[axis]) + getMargin(node, trailing[axis]);
|
||||||
}
|
}
|
||||||
@@ -812,7 +816,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
|
|||||||
isPosDefined(child, trailing[axis])) {
|
isPosDefined(child, trailing[axis])) {
|
||||||
child->layout.dimensions[dim[axis]] = fmaxf(
|
child->layout.dimensions[dim[axis]] = fmaxf(
|
||||||
boundAxis(child, axis, node->layout.dimensions[dim[axis]] -
|
boundAxis(child, axis, node->layout.dimensions[dim[axis]] -
|
||||||
getPaddingAndBorderAxis(node, axis) -
|
getBorderAxis(node, axis) -
|
||||||
getMarginAxis(child, axis) -
|
getMarginAxis(child, axis) -
|
||||||
getPosition(child, leading[axis]) -
|
getPosition(child, leading[axis]) -
|
||||||
getPosition(child, trailing[axis])
|
getPosition(child, trailing[axis])
|
||||||
|
@@ -125,6 +125,10 @@ var computeLayout = (function() {
|
|||||||
return getPadding(node, location) + getBorder(node, location);
|
return getPadding(node, location) + getBorder(node, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBorderAxis(node, axis) {
|
||||||
|
return getBorder(node, leading[axis]) + getBorder(node, trailing[axis]);
|
||||||
|
}
|
||||||
|
|
||||||
function getMarginAxis(node, axis) {
|
function getMarginAxis(node, axis) {
|
||||||
return getMargin(node, leading[axis]) + getMargin(node, trailing[axis]);
|
return getMargin(node, leading[axis]) + getMargin(node, trailing[axis]);
|
||||||
}
|
}
|
||||||
@@ -703,7 +707,7 @@ var computeLayout = (function() {
|
|||||||
isPosDefined(child, trailing[axis])) {
|
isPosDefined(child, trailing[axis])) {
|
||||||
child.layout[dim[axis]] = fmaxf(
|
child.layout[dim[axis]] = fmaxf(
|
||||||
boundAxis(child, axis, node.layout[dim[axis]] -
|
boundAxis(child, axis, node.layout[dim[axis]] -
|
||||||
getPaddingAndBorderAxis(node, axis) -
|
getBorderAxis(node, axis) -
|
||||||
getMarginAxis(child, axis) -
|
getMarginAxis(child, axis) -
|
||||||
getPosition(child, leading[axis]) -
|
getPosition(child, leading[axis]) -
|
||||||
getPosition(child, trailing[axis])
|
getPosition(child, trailing[axis])
|
||||||
|
@@ -4754,6 +4754,134 @@ int main()
|
|||||||
|
|
||||||
test("should layout minHeight without a flex child", root_node, root_layout);
|
test("should layout minHeight without a flex child", root_node, root_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
css_node_t *root_node = new_test_css_node();
|
||||||
|
{
|
||||||
|
css_node_t *node_0 = root_node;
|
||||||
|
node_0->style.dimensions[CSS_WIDTH] = 400;
|
||||||
|
node_0->style.dimensions[CSS_HEIGHT] = 400;
|
||||||
|
init_css_node_children(node_0, 1);
|
||||||
|
{
|
||||||
|
css_node_t *node_1;
|
||||||
|
node_1 = node_0->get_child(node_0->context, 0);
|
||||||
|
node_1->style.position_type = CSS_POSITION_ABSOLUTE;
|
||||||
|
node_1->style.padding[CSS_LEFT] = 10;
|
||||||
|
node_1->style.padding[CSS_TOP] = 10;
|
||||||
|
node_1->style.padding[CSS_RIGHT] = 10;
|
||||||
|
node_1->style.padding[CSS_BOTTOM] = 10;
|
||||||
|
node_1->style.position[CSS_LEFT] = 100;
|
||||||
|
node_1->style.position[CSS_TOP] = 100;
|
||||||
|
node_1->style.position[CSS_RIGHT] = 100;
|
||||||
|
node_1->style.position[CSS_BOTTOM] = 100;
|
||||||
|
init_css_node_children(node_1, 1);
|
||||||
|
{
|
||||||
|
css_node_t *node_2;
|
||||||
|
node_2 = node_1->get_child(node_1->context, 0);
|
||||||
|
node_2->style.position_type = CSS_POSITION_ABSOLUTE;
|
||||||
|
node_2->style.position[CSS_LEFT] = 10;
|
||||||
|
node_2->style.position[CSS_TOP] = 10;
|
||||||
|
node_2->style.position[CSS_RIGHT] = 10;
|
||||||
|
node_2->style.position[CSS_BOTTOM] = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
css_node_t *root_layout = new_test_css_node();
|
||||||
|
{
|
||||||
|
css_node_t *node_0 = root_layout;
|
||||||
|
node_0->layout.position[CSS_TOP] = 0;
|
||||||
|
node_0->layout.position[CSS_LEFT] = 0;
|
||||||
|
node_0->layout.dimensions[CSS_WIDTH] = 400;
|
||||||
|
node_0->layout.dimensions[CSS_HEIGHT] = 400;
|
||||||
|
init_css_node_children(node_0, 1);
|
||||||
|
{
|
||||||
|
css_node_t *node_1;
|
||||||
|
node_1 = node_0->get_child(node_0->context, 0);
|
||||||
|
node_1->layout.position[CSS_TOP] = 100;
|
||||||
|
node_1->layout.position[CSS_LEFT] = 100;
|
||||||
|
node_1->layout.dimensions[CSS_WIDTH] = 200;
|
||||||
|
node_1->layout.dimensions[CSS_HEIGHT] = 200;
|
||||||
|
init_css_node_children(node_1, 1);
|
||||||
|
{
|
||||||
|
css_node_t *node_2;
|
||||||
|
node_2 = node_1->get_child(node_1->context, 0);
|
||||||
|
node_2->layout.position[CSS_TOP] = 10;
|
||||||
|
node_2->layout.position[CSS_LEFT] = 10;
|
||||||
|
node_2->layout.dimensions[CSS_WIDTH] = 180;
|
||||||
|
node_2->layout.dimensions[CSS_HEIGHT] = 180;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test("should layout absolutely positioned node with absolutely positioned padded parent", root_node, root_layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
css_node_t *root_node = new_test_css_node();
|
||||||
|
{
|
||||||
|
css_node_t *node_0 = root_node;
|
||||||
|
node_0->style.dimensions[CSS_WIDTH] = 400;
|
||||||
|
node_0->style.dimensions[CSS_HEIGHT] = 400;
|
||||||
|
init_css_node_children(node_0, 1);
|
||||||
|
{
|
||||||
|
css_node_t *node_1;
|
||||||
|
node_1 = node_0->get_child(node_0->context, 0);
|
||||||
|
node_1->style.position_type = CSS_POSITION_ABSOLUTE;
|
||||||
|
node_1->style.padding[CSS_LEFT] = 10;
|
||||||
|
node_1->style.padding[CSS_TOP] = 10;
|
||||||
|
node_1->style.padding[CSS_RIGHT] = 10;
|
||||||
|
node_1->style.padding[CSS_BOTTOM] = 10;
|
||||||
|
node_1->style.border[CSS_LEFT] = 1;
|
||||||
|
node_1->style.border[CSS_TOP] = 1;
|
||||||
|
node_1->style.border[CSS_RIGHT] = 1;
|
||||||
|
node_1->style.border[CSS_BOTTOM] = 1;
|
||||||
|
node_1->style.position[CSS_LEFT] = 100;
|
||||||
|
node_1->style.position[CSS_TOP] = 100;
|
||||||
|
node_1->style.position[CSS_RIGHT] = 100;
|
||||||
|
node_1->style.position[CSS_BOTTOM] = 100;
|
||||||
|
init_css_node_children(node_1, 1);
|
||||||
|
{
|
||||||
|
css_node_t *node_2;
|
||||||
|
node_2 = node_1->get_child(node_1->context, 0);
|
||||||
|
node_2->style.position_type = CSS_POSITION_ABSOLUTE;
|
||||||
|
node_2->style.position[CSS_LEFT] = 10;
|
||||||
|
node_2->style.position[CSS_TOP] = 10;
|
||||||
|
node_2->style.position[CSS_RIGHT] = 10;
|
||||||
|
node_2->style.position[CSS_BOTTOM] = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
css_node_t *root_layout = new_test_css_node();
|
||||||
|
{
|
||||||
|
css_node_t *node_0 = root_layout;
|
||||||
|
node_0->layout.position[CSS_TOP] = 0;
|
||||||
|
node_0->layout.position[CSS_LEFT] = 0;
|
||||||
|
node_0->layout.dimensions[CSS_WIDTH] = 400;
|
||||||
|
node_0->layout.dimensions[CSS_HEIGHT] = 400;
|
||||||
|
init_css_node_children(node_0, 1);
|
||||||
|
{
|
||||||
|
css_node_t *node_1;
|
||||||
|
node_1 = node_0->get_child(node_0->context, 0);
|
||||||
|
node_1->layout.position[CSS_TOP] = 100;
|
||||||
|
node_1->layout.position[CSS_LEFT] = 100;
|
||||||
|
node_1->layout.dimensions[CSS_WIDTH] = 200;
|
||||||
|
node_1->layout.dimensions[CSS_HEIGHT] = 200;
|
||||||
|
init_css_node_children(node_1, 1);
|
||||||
|
{
|
||||||
|
css_node_t *node_2;
|
||||||
|
node_2 = node_1->get_child(node_1->context, 0);
|
||||||
|
node_2->layout.position[CSS_TOP] = 11;
|
||||||
|
node_2->layout.position[CSS_LEFT] = 11;
|
||||||
|
node_2->layout.dimensions[CSS_WIDTH] = 178;
|
||||||
|
node_2->layout.dimensions[CSS_HEIGHT] = 178;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test("should layout absolutely positioned node with absolutely positioned padded and bordered parent", root_node, root_layout);
|
||||||
|
}
|
||||||
/** END_GENERATED **/
|
/** END_GENERATED **/
|
||||||
return tests_finished();
|
return tests_finished();
|
||||||
}
|
}
|
||||||
|
@@ -1552,5 +1552,50 @@ describe('Layout', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should layout absolutely positioned node with absolutely positioned padded parent', function() {
|
||||||
|
testLayout(
|
||||||
|
{style: {width: 400, height: 400}, children: [
|
||||||
|
{style: {position: 'absolute', top: 100, left: 100, right: 100, bottom: 100, padding: 10}, children: [
|
||||||
|
{style: {position: 'absolute', top: 10, left: 10, right: 10, bottom: 10}}
|
||||||
|
]},
|
||||||
|
]},
|
||||||
|
{width: 400, height: 400, top: 0, left: 0, children: [
|
||||||
|
{width: 200, height: 200, top: 100, left: 100, children: [
|
||||||
|
{width: 180, height: 180, top: 10, left: 10}
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should layout absolutely positioned node with absolutely positioned padded and bordered parent', function() {
|
||||||
|
testLayout(
|
||||||
|
{style: {width: 400, height: 400}, children: [
|
||||||
|
{style: {position: 'absolute', top: 100, left: 100, right: 100, bottom: 100, padding: 10, borderWidth: 1}, children: [
|
||||||
|
{style: {position: 'absolute', top: 10, left: 10, right: 10, bottom: 10}}
|
||||||
|
]},
|
||||||
|
]},
|
||||||
|
{width: 400, height: 400, top: 0, left: 0, children: [
|
||||||
|
{width: 200, height: 200, top: 100, left: 100, children: [
|
||||||
|
{width: 178, height: 178, top: 11, left: 11}
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should layout absolutely positioned node with padded flex 1 parent', function() {
|
||||||
|
testLayout(
|
||||||
|
{style: {width: 400, height: 400}, children: [
|
||||||
|
{style: {flex: 1, padding: 10}, children: [
|
||||||
|
{style: {position: 'absolute', top: 10, left: 10, right: 10, bottom: 10}}
|
||||||
|
]},
|
||||||
|
]},
|
||||||
|
{width: 400, height: 400, top: 0, left: 0, children: [
|
||||||
|
{width: 400, height: 400, top: 0, left: 0, children: [
|
||||||
|
{width: 380, height: 380, top: 10, left: 10}
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -178,6 +178,10 @@ public class LayoutEngine {
|
|||||||
return getPadding(node, position) + getBorder(node, position);
|
return getPadding(node, position) + getBorder(node, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static float getBorderAxis(CSSNode node, CSSFlexDirection axis) {
|
||||||
|
return getBorder(node, getLeading(axis)) + getBorder(node, getTrailing(axis));
|
||||||
|
}
|
||||||
|
|
||||||
private static float getMarginAxis(CSSNode node, CSSFlexDirection axis) {
|
private static float getMarginAxis(CSSNode node, CSSFlexDirection axis) {
|
||||||
return getMargin(node, getLeading(axis)) + getMargin(node, getTrailing(axis));
|
return getMargin(node, getLeading(axis)) + getMargin(node, getTrailing(axis));
|
||||||
}
|
}
|
||||||
@@ -757,7 +761,7 @@ public class LayoutEngine {
|
|||||||
isPosDefined(child, getTrailing(axis))) {
|
isPosDefined(child, getTrailing(axis))) {
|
||||||
setLayoutDimension(child, getDim(axis), Math.max(
|
setLayoutDimension(child, getDim(axis), Math.max(
|
||||||
boundAxis(child, axis, getLayoutDimension(node, getDim(axis)) -
|
boundAxis(child, axis, getLayoutDimension(node, getDim(axis)) -
|
||||||
getPaddingAndBorderAxis(node, axis) -
|
getBorderAxis(node, axis) -
|
||||||
getMarginAxis(child, axis) -
|
getMarginAxis(child, axis) -
|
||||||
getPosition(child, getLeading(axis)) -
|
getPosition(child, getLeading(axis)) -
|
||||||
getPosition(child, getTrailing(axis))
|
getPosition(child, getTrailing(axis))
|
||||||
|
@@ -5073,5 +5073,137 @@ public class LayoutEngineTest {
|
|||||||
|
|
||||||
test("should layout minHeight without a flex child", root_node, root_layout);
|
test("should layout minHeight without a flex child", root_node, root_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase122()
|
||||||
|
{
|
||||||
|
TestCSSNode root_node = new TestCSSNode();
|
||||||
|
{
|
||||||
|
TestCSSNode node_0 = root_node;
|
||||||
|
node_0.style.width = 400;
|
||||||
|
node_0.style.height = 400;
|
||||||
|
addChildren(node_0, 1);
|
||||||
|
{
|
||||||
|
TestCSSNode node_1;
|
||||||
|
node_1 = node_0.getChildAt(0);
|
||||||
|
node_1.style.positionType = CSSPositionType.ABSOLUTE;
|
||||||
|
node_1.style.padding[Spacing.LEFT] = 10;
|
||||||
|
node_1.style.padding[Spacing.TOP] = 10;
|
||||||
|
node_1.style.padding[Spacing.RIGHT] = 10;
|
||||||
|
node_1.style.padding[Spacing.BOTTOM] = 10;
|
||||||
|
node_1.style.positionLeft = 100;
|
||||||
|
node_1.style.positionTop = 100;
|
||||||
|
node_1.style.positionRight = 100;
|
||||||
|
node_1.style.positionBottom = 100;
|
||||||
|
addChildren(node_1, 1);
|
||||||
|
{
|
||||||
|
TestCSSNode node_2;
|
||||||
|
node_2 = node_1.getChildAt(0);
|
||||||
|
node_2.style.positionType = CSSPositionType.ABSOLUTE;
|
||||||
|
node_2.style.positionLeft = 10;
|
||||||
|
node_2.style.positionTop = 10;
|
||||||
|
node_2.style.positionRight = 10;
|
||||||
|
node_2.style.positionBottom = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TestCSSNode root_layout = new TestCSSNode();
|
||||||
|
{
|
||||||
|
TestCSSNode node_0 = root_layout;
|
||||||
|
node_0.layout.y = 0;
|
||||||
|
node_0.layout.x = 0;
|
||||||
|
node_0.layout.width = 400;
|
||||||
|
node_0.layout.height = 400;
|
||||||
|
addChildren(node_0, 1);
|
||||||
|
{
|
||||||
|
TestCSSNode node_1;
|
||||||
|
node_1 = node_0.getChildAt(0);
|
||||||
|
node_1.layout.y = 100;
|
||||||
|
node_1.layout.x = 100;
|
||||||
|
node_1.layout.width = 200;
|
||||||
|
node_1.layout.height = 200;
|
||||||
|
addChildren(node_1, 1);
|
||||||
|
{
|
||||||
|
TestCSSNode node_2;
|
||||||
|
node_2 = node_1.getChildAt(0);
|
||||||
|
node_2.layout.y = 10;
|
||||||
|
node_2.layout.x = 10;
|
||||||
|
node_2.layout.width = 180;
|
||||||
|
node_2.layout.height = 180;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test("should layout absolutely positioned node with absolutely positioned padded parent", root_node, root_layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase123()
|
||||||
|
{
|
||||||
|
TestCSSNode root_node = new TestCSSNode();
|
||||||
|
{
|
||||||
|
TestCSSNode node_0 = root_node;
|
||||||
|
node_0.style.width = 400;
|
||||||
|
node_0.style.height = 400;
|
||||||
|
addChildren(node_0, 1);
|
||||||
|
{
|
||||||
|
TestCSSNode node_1;
|
||||||
|
node_1 = node_0.getChildAt(0);
|
||||||
|
node_1.style.positionType = CSSPositionType.ABSOLUTE;
|
||||||
|
node_1.style.padding[Spacing.LEFT] = 10;
|
||||||
|
node_1.style.padding[Spacing.TOP] = 10;
|
||||||
|
node_1.style.padding[Spacing.RIGHT] = 10;
|
||||||
|
node_1.style.padding[Spacing.BOTTOM] = 10;
|
||||||
|
node_1.style.border[Spacing.LEFT] = 1;
|
||||||
|
node_1.style.border[Spacing.TOP] = 1;
|
||||||
|
node_1.style.border[Spacing.RIGHT] = 1;
|
||||||
|
node_1.style.border[Spacing.BOTTOM] = 1;
|
||||||
|
node_1.style.positionLeft = 100;
|
||||||
|
node_1.style.positionTop = 100;
|
||||||
|
node_1.style.positionRight = 100;
|
||||||
|
node_1.style.positionBottom = 100;
|
||||||
|
addChildren(node_1, 1);
|
||||||
|
{
|
||||||
|
TestCSSNode node_2;
|
||||||
|
node_2 = node_1.getChildAt(0);
|
||||||
|
node_2.style.positionType = CSSPositionType.ABSOLUTE;
|
||||||
|
node_2.style.positionLeft = 10;
|
||||||
|
node_2.style.positionTop = 10;
|
||||||
|
node_2.style.positionRight = 10;
|
||||||
|
node_2.style.positionBottom = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TestCSSNode root_layout = new TestCSSNode();
|
||||||
|
{
|
||||||
|
TestCSSNode node_0 = root_layout;
|
||||||
|
node_0.layout.y = 0;
|
||||||
|
node_0.layout.x = 0;
|
||||||
|
node_0.layout.width = 400;
|
||||||
|
node_0.layout.height = 400;
|
||||||
|
addChildren(node_0, 1);
|
||||||
|
{
|
||||||
|
TestCSSNode node_1;
|
||||||
|
node_1 = node_0.getChildAt(0);
|
||||||
|
node_1.layout.y = 100;
|
||||||
|
node_1.layout.x = 100;
|
||||||
|
node_1.layout.width = 200;
|
||||||
|
node_1.layout.height = 200;
|
||||||
|
addChildren(node_1, 1);
|
||||||
|
{
|
||||||
|
TestCSSNode node_2;
|
||||||
|
node_2 = node_1.getChildAt(0);
|
||||||
|
node_2.layout.y = 11;
|
||||||
|
node_2.layout.x = 11;
|
||||||
|
node_2.layout.width = 178;
|
||||||
|
node_2.layout.height = 178;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test("should layout absolutely positioned node with absolutely positioned padded and bordered parent", root_node, root_layout);
|
||||||
|
}
|
||||||
/** END_GENERATED **/
|
/** END_GENERATED **/
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user