Skip to content

Commit fd4888e

Browse files
AtkinsSJgmta
authored andcommitted
LibWeb/Layout: Honor hanging and each-line in text-indent
1 parent c4b9e7e commit fd4888e

File tree

4 files changed

+129
-7
lines changed

4 files changed

+129
-7
lines changed

Libraries/LibWeb/Layout/LineBuilder.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ LineBuilder::LineBuilder(InlineFormattingContext& context, LayoutState& layout_s
1919
{
2020
auto text_indent = m_context.containing_block().computed_values().text_indent();
2121
m_text_indent = text_indent.length_percentage.to_px(m_context.containing_block(), m_containing_block_used_values.content_width());
22+
m_text_indent_each_line = text_indent.each_line;
23+
m_text_indent_hanging = text_indent.hanging;
2224
begin_new_line(false);
2325
}
2426

@@ -37,15 +39,15 @@ void LineBuilder::break_line(ForcedBreak forced_break, Optional<CSSPixels> next_
3739
bool floats_intrude_at_current_y = false;
3840
do {
3941
m_containing_block_used_values.line_boxes.append(LineBox(m_direction, m_writing_mode));
40-
begin_new_line(true, break_count == 0);
42+
begin_new_line(true, break_count == 0, forced_break);
4143
break_count++;
4244
floats_intrude_at_current_y = m_context.any_floats_intrude_at_block_offset(m_current_block_offset);
4345
} while (floats_intrude_at_current_y
4446
&& (!m_context.can_fit_new_line_at_block_offset(m_current_block_offset)
4547
|| (next_item_width.value_or(0) > m_available_width_for_current_line)));
4648
}
4749

48-
void LineBuilder::begin_new_line(bool increment_y, bool is_first_break_in_sequence)
50+
void LineBuilder::begin_new_line(bool increment_y, bool is_first_break_in_sequence, ForcedBreak forced_break)
4951
{
5052
if (increment_y) {
5153
if (is_first_break_in_sequence) {
@@ -66,13 +68,19 @@ void LineBuilder::begin_new_line(bool increment_y, bool is_first_break_in_sequen
6668
}
6769
}
6870
recalculate_available_space();
69-
ensure_last_line_box().m_original_available_width = m_available_width_for_current_line;
71+
auto& line_box = ensure_last_line_box();
72+
line_box.m_original_available_width = m_available_width_for_current_line;
7073
m_max_height_on_current_line = 0;
7174
m_last_line_needs_update = true;
7275

73-
// FIXME: Support text-indent with "each-line".
74-
if (m_containing_block_used_values.line_boxes.size() <= 1)
75-
ensure_last_line_box().m_inline_length += m_text_indent;
76+
bool should_indent = m_containing_block_used_values.line_boxes.size() <= 1
77+
|| (m_text_indent_each_line && forced_break == ForcedBreak::Yes);
78+
79+
if (m_text_indent_hanging)
80+
should_indent = !should_indent;
81+
82+
if (should_indent)
83+
line_box.m_inline_length += m_text_indent;
7684
}
7785

7886
LineBox& LineBuilder::ensure_last_line_box()

Libraries/LibWeb/Layout/LineBuilder.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class LineBuilder {
4848
void did_introduce_clearance(CSSPixels);
4949

5050
private:
51-
void begin_new_line(bool increment_y, bool is_first_break_in_sequence = true);
51+
void begin_new_line(bool increment_y, bool is_first_break_in_sequence = true, ForcedBreak = ForcedBreak::No);
5252

5353
bool should_break(CSSPixels next_item_width);
5454

@@ -61,6 +61,8 @@ class LineBuilder {
6161
CSSPixels m_current_block_offset { 0 };
6262
CSSPixels m_max_height_on_current_line { 0 };
6363
CSSPixels m_text_indent { 0 };
64+
bool m_text_indent_hanging : 1 { false };
65+
bool m_text_indent_each_line : 1 { false };
6466
CSS::Direction m_direction { CSS::Direction::Ltr };
6567
CSS::WritingMode m_writing_mode { CSS::WritingMode::HorizontalTb };
6668

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>text-indent 'each-line' and 'hanging' modifiers</title>
6+
7+
<link rel="stylesheet" href="../../../../../../data/fonts/ahem.css" />
8+
<style>
9+
div { width:80px; font: 10px Ahem; background-color:lightgray; }
10+
.indent { color: blue; padding-left:4em; }
11+
</style>
12+
</head>
13+
<body>
14+
All black boxes should be left-aligned. All blue boxes should be right-aligned.
15+
16+
<div>
17+
<span class="indent">xxxx</span><br>xxxx<br>xxxx
18+
</div>
19+
<br>
20+
<div>
21+
<span class="indent">xxxx</span> xxxx xxxx
22+
</div>
23+
<br>
24+
<div>
25+
<span class="indent">xxxx</span><br><span class="indent">xxxx</span><br><span class="indent">xxxx</span>
26+
</div>
27+
<br>
28+
<div>
29+
<span class="indent">xxxx</span> xxxx<br><span class="indent">xxxx</span>
30+
</div>
31+
<br>
32+
<div>
33+
xxxx<br><span class="indent">xxxx</span><br><span class="indent">xxxx</span>
34+
</div>
35+
<br>
36+
<div>
37+
xxxx <span class="indent">xxxx</span> <span class="indent">xxxx</span>
38+
</div>
39+
<br>
40+
<div>
41+
xxxx<br>xxxx<br>xxxx
42+
</div>
43+
<br>
44+
<div>
45+
xxxx <span class="indent">xxxx</span><br>xxxx
46+
</div>
47+
</body>
48+
</html>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>text-indent 'each-line' and 'hanging' modifiers</title>
6+
<link rel="author" title="Jaehun Lim" href="mailto:ljaehun.lim@samsung.com">
7+
<link rel="help" href="https://drafts.csswg.org/css-text-3/#text-indent-property">
8+
<link rel="match" href="../../../../../expected/wpt-import/css/css-text/text-indent/reference/text-indent-each-line-hanging-ref.html">
9+
<meta name="assert" content="'each-line' and 'hanging' properly works">
10+
11+
<link rel="stylesheet" href="../../../../../data/fonts/ahem.css" />
12+
<style>
13+
div { width:80px; font: 10px Ahem; background-color:lightgray; }
14+
.normal { text-indent: 4em; }
15+
.eachline { text-indent: 4em each-line; }
16+
.hanging { text-indent: 4em hanging; }
17+
.eachlinehanging { text-indent: 4em each-line hanging; }
18+
.indent { color: blue; }
19+
</style>
20+
</head>
21+
<body>
22+
All black boxes should be left-aligned. All blue boxes should be right-aligned.
23+
24+
<!-- normal text-indent -->
25+
<div class="normal">
26+
<span class="indent">xxxx</span> xxxx<br>xxxx
27+
</div>
28+
<br>
29+
<!-- each-line with a soft wrap break -->
30+
<div class="eachline">
31+
<span class="indent">xxxx</span> xxxx xxxx
32+
</div>
33+
<br>
34+
<!-- each-line with a forced line break -->
35+
<div class="eachline">
36+
<span class="indent">xxxx</span><br><span class="indent">xxxx</span><br><span class="indent">xxxx</span>
37+
</div>
38+
<br>
39+
<!-- each-line with a soft wrap break and a forced line break -->
40+
<div class="eachline">
41+
<span class="indent">xxxx</span> xxxx<br><span class="indent">xxxx</span>
42+
</div>
43+
<br>
44+
<!-- normal text-indent with hanging -->
45+
<div class="hanging">
46+
xxxx <span class="indent">xxxx</span><br><span class="indent">xxxx</span>
47+
</div>
48+
<br>
49+
<!-- each-line and hanging with a soft wrap break -->
50+
<div class="eachlinehanging">
51+
xxxx <span class="indent">xxxx</span> <span class="indent">xxxx</span>
52+
</div>
53+
<br>
54+
<!-- each-line and hanging with a forced line break -->
55+
<div class="eachlinehanging">
56+
xxxx<br>xxxx<br>xxxx
57+
</div>
58+
<br>
59+
<!-- each-line and hanging with a soft wrap break and a forced line break -->
60+
<div class="eachlinehanging">
61+
xxxx <span class="indent">xxxx</span><br>xxxx
62+
</div>
63+
</body>
64+
</html>

0 commit comments

Comments
 (0)