Skip to content

Commit 311e103

Browse files
committed
LibWeb: Paint line box fragments during all paint phases
Fragment painting was very limited by only being called during the foreground paint phase. We now paint fragments as part of every phase (and the phase is passed to paint_fragment() of course!)
1 parent d129e68 commit 311e103

File tree

5 files changed

+48
-46
lines changed

5 files changed

+48
-46
lines changed

Libraries/LibWeb/Layout/BlockBox.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,15 @@ void BlockBox::paint(PaintContext& context, PaintPhase phase)
5757
if (!children_are_inline())
5858
return;
5959

60-
// FIXME: Inline backgrounds etc.
61-
if (phase == PaintPhase::Foreground) {
62-
for (auto& line_box : m_line_boxes) {
63-
for (auto& fragment : line_box.fragments()) {
64-
if (context.should_show_line_box_borders())
65-
context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Green);
66-
fragment.paint(context);
67-
}
60+
for (auto& line_box : m_line_boxes) {
61+
for (auto& fragment : line_box.fragments()) {
62+
if (context.should_show_line_box_borders())
63+
context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Green);
64+
fragment.paint(context, phase);
6865
}
6966
}
7067

68+
// FIXME: Merge this loop with the above somehow..
7169
if (phase == PaintPhase::FocusOutline) {
7270
for (auto& line_box : m_line_boxes) {
7371
for (auto& fragment : line_box.fragments()) {

Libraries/LibWeb/Layout/LineBoxFragment.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@
3434

3535
namespace Web::Layout {
3636

37-
void LineBoxFragment::paint(PaintContext& context)
37+
void LineBoxFragment::paint(PaintContext& context, PaintPhase phase)
3838
{
3939
for (auto* ancestor = layout_node().parent(); ancestor; ancestor = ancestor->parent()) {
4040
if (!ancestor->is_visible())
4141
return;
4242
}
4343

4444
if (is<TextNode>(layout_node()))
45-
downcast<TextNode>(layout_node()).paint_fragment(context, *this);
45+
downcast<TextNode>(layout_node()).paint_fragment(context, *this, phase);
4646
}
4747

4848
bool LineBoxFragment::ends_in_whitespace() const

Libraries/LibWeb/Layout/LineBoxFragment.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class LineBoxFragment : public Weakable<LineBoxFragment> {
6161

6262
float absolute_x() const { return absolute_rect().x(); }
6363

64-
void paint(PaintContext&);
64+
void paint(PaintContext&, PaintPhase);
6565

6666
bool ends_in_whitespace() const;
6767
bool is_justifiable_whitespace() const;

Libraries/LibWeb/Layout/TextNode.cpp

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -66,44 +66,48 @@ const String& TextNode::text_for_style(const CSS::StyleProperties& style) const
6666
return dom_node().data();
6767
}
6868

69-
void TextNode::paint_fragment(PaintContext& context, const LineBoxFragment& fragment) const
69+
void TextNode::paint_fragment(PaintContext& context, const LineBoxFragment& fragment, PaintPhase phase) const
7070
{
7171
auto& painter = context.painter();
72-
painter.set_font(specified_style().font());
73-
74-
auto background_color = specified_style().property(CSS::PropertyID::BackgroundColor);
75-
if (background_color.has_value() && background_color.value()->is_color())
76-
painter.fill_rect(enclosing_int_rect(fragment.absolute_rect()), background_color.value()->to_color(document()));
77-
78-
auto color = specified_style().color_or_fallback(CSS::PropertyID::Color, document(), context.palette().base_text());
79-
auto text_decoration = specified_style().string_or_fallback(CSS::PropertyID::TextDecoration, "none");
80-
81-
if (document().inspected_node() == &dom_node())
82-
context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Magenta);
83-
84-
bool is_underline = text_decoration == "underline";
85-
if (is_underline)
86-
painter.draw_line(enclosing_int_rect(fragment.absolute_rect()).bottom_left().translated(0, 1), enclosing_int_rect(fragment.absolute_rect()).bottom_right().translated(0, 1), color);
87-
88-
// FIXME: text-transform should be done already in layout, since uppercase glyphs may be wider than lowercase, etc.
89-
auto text = m_text_for_rendering;
90-
auto text_transform = specified_style().string_or_fallback(CSS::PropertyID::TextTransform, "none");
91-
if (text_transform == "uppercase")
92-
text = m_text_for_rendering.to_uppercase();
93-
if (text_transform == "lowercase")
94-
text = m_text_for_rendering.to_lowercase();
95-
96-
painter.draw_text(enclosing_int_rect(fragment.absolute_rect()), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::TopLeft, color);
97-
98-
auto selection_rect = fragment.selection_rect(specified_style().font());
99-
if (!selection_rect.is_empty()) {
100-
painter.fill_rect(enclosing_int_rect(selection_rect), context.palette().selection());
101-
Gfx::PainterStateSaver saver(painter);
102-
painter.add_clip_rect(enclosing_int_rect(selection_rect));
103-
painter.draw_text(enclosing_int_rect(fragment.absolute_rect()), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::TopLeft, context.palette().selection_text());
72+
73+
if (phase == PaintPhase::Background) {
74+
auto background_color = specified_style().property(CSS::PropertyID::BackgroundColor);
75+
if (background_color.has_value() && background_color.value()->is_color())
76+
painter.fill_rect(enclosing_int_rect(fragment.absolute_rect()), background_color.value()->to_color(document()));
10477
}
10578

106-
paint_cursor_if_needed(context, fragment);
79+
if (phase == PaintPhase::Foreground) {
80+
painter.set_font(specified_style().font());
81+
auto color = specified_style().color_or_fallback(CSS::PropertyID::Color, document(), context.palette().base_text());
82+
auto text_decoration = specified_style().string_or_fallback(CSS::PropertyID::TextDecoration, "none");
83+
84+
if (document().inspected_node() == &dom_node())
85+
context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Magenta);
86+
87+
bool is_underline = text_decoration == "underline";
88+
if (is_underline)
89+
painter.draw_line(enclosing_int_rect(fragment.absolute_rect()).bottom_left().translated(0, 1), enclosing_int_rect(fragment.absolute_rect()).bottom_right().translated(0, 1), color);
90+
91+
// FIXME: text-transform should be done already in layout, since uppercase glyphs may be wider than lowercase, etc.
92+
auto text = m_text_for_rendering;
93+
auto text_transform = specified_style().string_or_fallback(CSS::PropertyID::TextTransform, "none");
94+
if (text_transform == "uppercase")
95+
text = m_text_for_rendering.to_uppercase();
96+
if (text_transform == "lowercase")
97+
text = m_text_for_rendering.to_lowercase();
98+
99+
painter.draw_text(enclosing_int_rect(fragment.absolute_rect()), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::CenterLeft, color);
100+
101+
auto selection_rect = fragment.selection_rect(specified_style().font());
102+
if (!selection_rect.is_empty()) {
103+
painter.fill_rect(enclosing_int_rect(selection_rect), context.palette().selection());
104+
Gfx::PainterStateSaver saver(painter);
105+
painter.add_clip_rect(enclosing_int_rect(selection_rect));
106+
painter.draw_text(enclosing_int_rect(fragment.absolute_rect()), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::CenterLeft, context.palette().selection_text());
107+
}
108+
109+
paint_cursor_if_needed(context, fragment);
110+
}
107111
}
108112

109113
void TextNode::paint_cursor_if_needed(PaintContext& context, const LineBoxFragment& fragment) const

Libraries/LibWeb/Layout/TextNode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class TextNode : public Node {
4646
virtual const char* class_name() const override { return "TextNode"; }
4747
virtual bool is_text() const final { return true; }
4848

49-
void paint_fragment(PaintContext&, const LineBoxFragment&) const;
49+
void paint_fragment(PaintContext&, const LineBoxFragment&, PaintPhase) const;
5050

5151
virtual void split_into_lines(BlockBox& container, LayoutMode) override;
5252

0 commit comments

Comments
 (0)