summaryrefslogtreecommitdiff
path: root/Libraries/LibWeb
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-12-03 19:18:01 +0100
committerAndreas Kling <kling@serenityos.org>2020-12-03 21:45:46 +0100
commit311e1039b51cbeedec7298761d0d6b82ab61f4ff (patch)
tree16fcb52e72f4086516aab9b63dfc7adc41b29dfb /Libraries/LibWeb
parentd129e68da8938b653900f453c9c242579e4f580c (diff)
downloadserenity-311e1039b51cbeedec7298761d0d6b82ab61f4ff.zip
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!)
Diffstat (limited to 'Libraries/LibWeb')
-rw-r--r--Libraries/LibWeb/Layout/BlockBox.cpp14
-rw-r--r--Libraries/LibWeb/Layout/LineBoxFragment.cpp4
-rw-r--r--Libraries/LibWeb/Layout/LineBoxFragment.h2
-rw-r--r--Libraries/LibWeb/Layout/TextNode.cpp72
-rw-r--r--Libraries/LibWeb/Layout/TextNode.h2
5 files changed, 48 insertions, 46 deletions
diff --git a/Libraries/LibWeb/Layout/BlockBox.cpp b/Libraries/LibWeb/Layout/BlockBox.cpp
index 376213d771..2fbebba10a 100644
--- a/Libraries/LibWeb/Layout/BlockBox.cpp
+++ b/Libraries/LibWeb/Layout/BlockBox.cpp
@@ -57,17 +57,15 @@ void BlockBox::paint(PaintContext& context, PaintPhase phase)
if (!children_are_inline())
return;
- // FIXME: Inline backgrounds etc.
- if (phase == PaintPhase::Foreground) {
- for (auto& line_box : m_line_boxes) {
- for (auto& fragment : line_box.fragments()) {
- if (context.should_show_line_box_borders())
- context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Green);
- fragment.paint(context);
- }
+ for (auto& line_box : m_line_boxes) {
+ for (auto& fragment : line_box.fragments()) {
+ if (context.should_show_line_box_borders())
+ context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Green);
+ fragment.paint(context, phase);
}
}
+ // FIXME: Merge this loop with the above somehow..
if (phase == PaintPhase::FocusOutline) {
for (auto& line_box : m_line_boxes) {
for (auto& fragment : line_box.fragments()) {
diff --git a/Libraries/LibWeb/Layout/LineBoxFragment.cpp b/Libraries/LibWeb/Layout/LineBoxFragment.cpp
index 2c4be7f141..4918f56789 100644
--- a/Libraries/LibWeb/Layout/LineBoxFragment.cpp
+++ b/Libraries/LibWeb/Layout/LineBoxFragment.cpp
@@ -34,7 +34,7 @@
namespace Web::Layout {
-void LineBoxFragment::paint(PaintContext& context)
+void LineBoxFragment::paint(PaintContext& context, PaintPhase phase)
{
for (auto* ancestor = layout_node().parent(); ancestor; ancestor = ancestor->parent()) {
if (!ancestor->is_visible())
@@ -42,7 +42,7 @@ void LineBoxFragment::paint(PaintContext& context)
}
if (is<TextNode>(layout_node()))
- downcast<TextNode>(layout_node()).paint_fragment(context, *this);
+ downcast<TextNode>(layout_node()).paint_fragment(context, *this, phase);
}
bool LineBoxFragment::ends_in_whitespace() const
diff --git a/Libraries/LibWeb/Layout/LineBoxFragment.h b/Libraries/LibWeb/Layout/LineBoxFragment.h
index 2c6662e8b4..5e91dff564 100644
--- a/Libraries/LibWeb/Layout/LineBoxFragment.h
+++ b/Libraries/LibWeb/Layout/LineBoxFragment.h
@@ -61,7 +61,7 @@ public:
float absolute_x() const { return absolute_rect().x(); }
- void paint(PaintContext&);
+ void paint(PaintContext&, PaintPhase);
bool ends_in_whitespace() const;
bool is_justifiable_whitespace() const;
diff --git a/Libraries/LibWeb/Layout/TextNode.cpp b/Libraries/LibWeb/Layout/TextNode.cpp
index 4030d40aa1..3846627fa0 100644
--- a/Libraries/LibWeb/Layout/TextNode.cpp
+++ b/Libraries/LibWeb/Layout/TextNode.cpp
@@ -66,44 +66,48 @@ const String& TextNode::text_for_style(const CSS::StyleProperties& style) const
return dom_node().data();
}
-void TextNode::paint_fragment(PaintContext& context, const LineBoxFragment& fragment) const
+void TextNode::paint_fragment(PaintContext& context, const LineBoxFragment& fragment, PaintPhase phase) const
{
auto& painter = context.painter();
- painter.set_font(specified_style().font());
-
- auto background_color = specified_style().property(CSS::PropertyID::BackgroundColor);
- if (background_color.has_value() && background_color.value()->is_color())
- painter.fill_rect(enclosing_int_rect(fragment.absolute_rect()), background_color.value()->to_color(document()));
-
- auto color = specified_style().color_or_fallback(CSS::PropertyID::Color, document(), context.palette().base_text());
- auto text_decoration = specified_style().string_or_fallback(CSS::PropertyID::TextDecoration, "none");
-
- if (document().inspected_node() == &dom_node())
- context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Magenta);
-
- bool is_underline = text_decoration == "underline";
- if (is_underline)
- 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);
-
- // FIXME: text-transform should be done already in layout, since uppercase glyphs may be wider than lowercase, etc.
- auto text = m_text_for_rendering;
- auto text_transform = specified_style().string_or_fallback(CSS::PropertyID::TextTransform, "none");
- if (text_transform == "uppercase")
- text = m_text_for_rendering.to_uppercase();
- if (text_transform == "lowercase")
- text = m_text_for_rendering.to_lowercase();
-
- painter.draw_text(enclosing_int_rect(fragment.absolute_rect()), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::TopLeft, color);
-
- auto selection_rect = fragment.selection_rect(specified_style().font());
- if (!selection_rect.is_empty()) {
- painter.fill_rect(enclosing_int_rect(selection_rect), context.palette().selection());
- Gfx::PainterStateSaver saver(painter);
- painter.add_clip_rect(enclosing_int_rect(selection_rect));
- painter.draw_text(enclosing_int_rect(fragment.absolute_rect()), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::TopLeft, context.palette().selection_text());
+
+ if (phase == PaintPhase::Background) {
+ auto background_color = specified_style().property(CSS::PropertyID::BackgroundColor);
+ if (background_color.has_value() && background_color.value()->is_color())
+ painter.fill_rect(enclosing_int_rect(fragment.absolute_rect()), background_color.value()->to_color(document()));
}
- paint_cursor_if_needed(context, fragment);
+ if (phase == PaintPhase::Foreground) {
+ painter.set_font(specified_style().font());
+ auto color = specified_style().color_or_fallback(CSS::PropertyID::Color, document(), context.palette().base_text());
+ auto text_decoration = specified_style().string_or_fallback(CSS::PropertyID::TextDecoration, "none");
+
+ if (document().inspected_node() == &dom_node())
+ context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Magenta);
+
+ bool is_underline = text_decoration == "underline";
+ if (is_underline)
+ 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);
+
+ // FIXME: text-transform should be done already in layout, since uppercase glyphs may be wider than lowercase, etc.
+ auto text = m_text_for_rendering;
+ auto text_transform = specified_style().string_or_fallback(CSS::PropertyID::TextTransform, "none");
+ if (text_transform == "uppercase")
+ text = m_text_for_rendering.to_uppercase();
+ if (text_transform == "lowercase")
+ text = m_text_for_rendering.to_lowercase();
+
+ painter.draw_text(enclosing_int_rect(fragment.absolute_rect()), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::CenterLeft, color);
+
+ auto selection_rect = fragment.selection_rect(specified_style().font());
+ if (!selection_rect.is_empty()) {
+ painter.fill_rect(enclosing_int_rect(selection_rect), context.palette().selection());
+ Gfx::PainterStateSaver saver(painter);
+ painter.add_clip_rect(enclosing_int_rect(selection_rect));
+ painter.draw_text(enclosing_int_rect(fragment.absolute_rect()), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::CenterLeft, context.palette().selection_text());
+ }
+
+ paint_cursor_if_needed(context, fragment);
+ }
}
void TextNode::paint_cursor_if_needed(PaintContext& context, const LineBoxFragment& fragment) const
diff --git a/Libraries/LibWeb/Layout/TextNode.h b/Libraries/LibWeb/Layout/TextNode.h
index cf15d391fe..298acfd58a 100644
--- a/Libraries/LibWeb/Layout/TextNode.h
+++ b/Libraries/LibWeb/Layout/TextNode.h
@@ -46,7 +46,7 @@ public:
virtual const char* class_name() const override { return "TextNode"; }
virtual bool is_text() const final { return true; }
- void paint_fragment(PaintContext&, const LineBoxFragment&) const;
+ void paint_fragment(PaintContext&, const LineBoxFragment&, PaintPhase) const;
virtual void split_into_lines(BlockBox& container, LayoutMode) override;