diff --git a/weasyprint/layout/flex.py b/weasyprint/layout/flex.py index 3d610a50f..7a6579321 100644 --- a/weasyprint/layout/flex.py +++ b/weasyprint/layout/flex.py @@ -593,7 +593,6 @@ def flex_layout(context, box, max_position_y, skip_stack, containing_block, # else: Cross size has been set by step 7 # Step 12 - # TODO: handle rtl original_position_axis = ( box.content_box_x() if axis == 'width' else box.content_box_y()) @@ -650,33 +649,62 @@ def flex_layout(context, box, max_position_y, skip_stack, containing_block, child.margin_bottom = free_space free_space = 0 - if justify_content == 'flex-end': - position_axis += free_space - elif justify_content == 'center': - position_axis += free_space / 2 - elif justify_content == 'space-around': - position_axis += free_space / len(line) / 2 - elif justify_content == 'space-evenly': - position_axis += free_space / (len(line) + 1) + if (box.style['direction'] == 'rtl' and + box.style['flex_direction'].startswith('row')): + if justify_content == 'flex-end': + position_axis -= free_space + elif justify_content == 'center': + position_axis -= free_space / 2 + elif justify_content == 'space-around': + position_axis -= free_space / len(line) / 2 + elif justify_content == 'space-evenly': + position_axis -= free_space / (len(line) - 1) - for i, child in line: - if axis == 'width': - child.position_x = position_axis - if justify_content == 'stretch': - child.width += free_space / len(line) - else: - child.position_y = position_axis - position_axis += ( - child.margin_width() if axis == 'width' - else child.margin_height()) - if justify_content == 'space-around': - position_axis += free_space / len(line) - elif justify_content == 'space-between': - if len(line) > 1: - position_axis += free_space / (len(line) - 1) + for i, child in line: + if axis == 'width': + child.position_x = position_axis + if justify_content == 'stretch': + child.width -= free_space / len(line) + else: + child.position_y = position_axis + position_axis -= ( + child.margin_width() if axis == 'width' + else child.margin_height()) + if justify_content == 'space-around': + position_axis -= free_space / len(line) + elif justify_content == 'space-between': + if len(line) > 1: + position_axis -= free_space / (len(line) + 1) + elif justify_content == 'space-evenly': + position_axis -= free_space / (len(line) - 1) + else: + if justify_content == 'flex-end': + position_axis += free_space + elif justify_content == 'center': + position_axis += free_space / 2 + elif justify_content == 'space-around': + position_axis += free_space / len(line) / 2 elif justify_content == 'space-evenly': position_axis += free_space / (len(line) + 1) + for i, child in line: + if axis == 'width': + child.position_x = position_axis + if justify_content == 'stretch': + child.width += free_space / len(line) + else: + child.position_y = position_axis + position_axis += ( + child.margin_width() if axis == 'width' + else child.margin_height()) + if justify_content == 'space-around': + position_axis += free_space / len(line) + elif justify_content == 'space-between': + if len(line) > 1: + position_axis += free_space / (len(line) - 1) + elif justify_content == 'space-evenly': + position_axis += free_space / (len(line) + 1) + # Step 13 position_cross = ( box.content_box_y() if cross == 'height' diff --git a/weasyprint/tests/test_layout/test_flex.py b/weasyprint/tests/test_layout/test_flex.py index e0c3be1cd..18e75bc5b 100644 --- a/weasyprint/tests/test_layout/test_flex.py +++ b/weasyprint/tests/test_layout/test_flex.py @@ -37,6 +37,33 @@ def test_flex_direction_row(): assert div_1.position_x < div_2.position_x < div_3.position_x +@assert_no_logs +def test_flex_direction_row_rtl(): + page, = render_pages(''' +
+
A
+
B
+
C
+
+ ''') + html, = page.children + body, = html.children + article, = body.children + div_1, div_2, div_3 = article.children + assert div_1.children[0].children[0].text == 'A' + assert div_2.children[0].children[0].text == 'B' + assert div_3.children[0].children[0].text == 'C' + assert ( + div_1.position_y == + div_2.position_y == + div_3.position_y == + article.position_y) + assert ( + div_1.position_x + div_1.width == + article.position_x + article.width) + assert div_1.position_x > div_2.position_x > div_3.position_x + + @assert_no_logs def test_flex_direction_row_reverse(): page, = render_pages(''' @@ -64,6 +91,32 @@ def test_flex_direction_row_reverse(): assert div_1.position_x < div_2.position_x < div_3.position_x +@assert_no_logs +def test_flex_direction_row_reverse_rtl(): + page, = render_pages(''' +
+
A
+
B
+
C
+
+ ''') + html, = page.children + body, = html.children + article, = body.children + div_1, div_2, div_3 = article.children + assert div_1.children[0].children[0].text == 'C' + assert div_2.children[0].children[0].text == 'B' + assert div_3.children[0].children[0].text == 'A' + assert ( + div_1.position_y == + div_2.position_y == + div_3.position_y == + article.position_y) + assert div_3.position_x == article.position_x + assert div_1.position_x > div_2.position_x > div_3.position_x + + @assert_no_logs def test_flex_direction_column(): page, = render_pages(''' @@ -89,6 +142,32 @@ def test_flex_direction_column(): assert div_1.position_y < div_2.position_y < div_3.position_y +@assert_no_logs +def test_flex_direction_column_rtl(): + page, = render_pages(''' +
+
A
+
B
+
C
+
+ ''') + html, = page.children + body, = html.children + article, = body.children + div_1, div_2, div_3 = article.children + assert div_1.children[0].children[0].text == 'A' + assert div_2.children[0].children[0].text == 'B' + assert div_3.children[0].children[0].text == 'C' + assert ( + div_1.position_x == + div_2.position_x == + div_3.position_x == + article.position_x) + assert div_1.position_y == article.position_y + assert div_1.position_y < div_2.position_y < div_3.position_y + + @assert_no_logs def test_flex_direction_column_reverse(): page, = render_pages(''' @@ -116,6 +195,34 @@ def test_flex_direction_column_reverse(): assert div_1.position_y < div_2.position_y < div_3.position_y +@assert_no_logs +def test_flex_direction_column_reverse_rtl(): + page, = render_pages(''' +
+
A
+
B
+
C
+
+ ''') + html, = page.children + body, = html.children + article, = body.children + div_1, div_2, div_3 = article.children + assert div_1.children[0].children[0].text == 'C' + assert div_2.children[0].children[0].text == 'B' + assert div_3.children[0].children[0].text == 'A' + assert ( + div_1.position_x == + div_2.position_x == + div_3.position_x == + article.position_x) + assert ( + div_3.position_y + div_3.height == + article.position_y + article.height) + assert div_1.position_y < div_2.position_y < div_3.position_y + + @assert_no_logs def test_flex_row_wrap(): page, = render_pages('''