summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/Layout
diff options
context:
space:
mode:
authorTobias Christiansen <tobi@tobyase.de>2021-07-28 16:44:26 +0200
committerAndreas Kling <kling@serenityos.org>2021-07-29 11:07:56 +0200
commit4c17f389dbb4a431f4e93736a9d54ae3c3ff798c (patch)
treea2800c5690196a41e2453a3cce98a7eff10f147a /Userland/Libraries/LibWeb/Layout
parentb7ca269b4d0142c30b0920402340b3718e226494 (diff)
downloadserenity-4c17f389dbb4a431f4e93736a9d54ae3c3ff798c.zip
LibWeb: Add proper support for text-decoration-line property values
The code handling the rendering of the text-decoration-line got moved into its own function to reduce clutter. The CSS property text-decoration-line now supports underline, overline and line-through.
Diffstat (limited to 'Userland/Libraries/LibWeb/Layout')
-rw-r--r--Userland/Libraries/LibWeb/Layout/TextNode.cpp39
-rw-r--r--Userland/Libraries/LibWeb/Layout/TextNode.h1
2 files changed, 38 insertions, 2 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/TextNode.cpp b/Userland/Libraries/LibWeb/Layout/TextNode.cpp
index a9dfd44669..6b5e0bbdb4 100644
--- a/Userland/Libraries/LibWeb/Layout/TextNode.cpp
+++ b/Userland/Libraries/LibWeb/Layout/TextNode.cpp
@@ -36,6 +36,42 @@ static bool is_all_whitespace(const StringView& string)
return true;
}
+void TextNode::paint_text_decoration(Gfx::Painter& painter, LineBoxFragment const& fragment) const
+{
+ Gfx::IntPoint line_start_point {};
+ Gfx::IntPoint line_end_point {};
+
+ auto& font = fragment.layout_node().font();
+ auto fragment_box = enclosing_int_rect(fragment.absolute_rect());
+ auto glyph_height = font.glyph_height();
+ auto baseline = fragment_box.height() / 2 - (glyph_height + 4) / 2 + glyph_height;
+
+ switch (computed_values().text_decoration_line()) {
+ case CSS::TextDecorationLine::None:
+ return;
+ break;
+ case CSS::TextDecorationLine::Underline:
+ line_start_point = fragment_box.top_left().translated(0, baseline + 2);
+ line_end_point = fragment_box.top_right().translated(0, baseline + 2);
+ break;
+ case CSS::TextDecorationLine::Overline:
+ line_start_point = fragment_box.top_left().translated(0, baseline - glyph_height);
+ line_end_point = fragment_box.top_right().translated(0, baseline - glyph_height);
+ break;
+ case CSS::TextDecorationLine::LineThrough: {
+ auto x_height = font.x_height();
+ line_start_point = fragment_box.top_left().translated(0, baseline - x_height / 2);
+ line_end_point = fragment_box.top_right().translated(0, baseline - x_height / 2);
+ break;
+ } break;
+ case CSS::TextDecorationLine::Blink:
+ // Conforming user agents may simply not blink the text
+ break;
+ }
+
+ painter.draw_line(line_start_point, line_end_point, computed_values().color());
+}
+
void TextNode::paint_fragment(PaintContext& context, const LineBoxFragment& fragment, PaintPhase phase) const
{
auto& painter = context.painter();
@@ -50,8 +86,7 @@ void TextNode::paint_fragment(PaintContext& context, const LineBoxFragment& frag
if (document().inspected_node() == &dom_node())
context.painter().draw_rect(enclosing_int_rect(fragment.absolute_rect()), Color::Magenta);
- if (computed_values().text_decoration_line() == CSS::TextDecorationLine::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), computed_values().color());
+ paint_text_decoration(painter, fragment);
// FIXME: text-transform should be done already in layout, since uppercase glyphs may be wider than lowercase, etc.
auto text = m_text_for_rendering;
diff --git a/Userland/Libraries/LibWeb/Layout/TextNode.h b/Userland/Libraries/LibWeb/Layout/TextNode.h
index 82c9570a76..d6b89b78bd 100644
--- a/Userland/Libraries/LibWeb/Layout/TextNode.h
+++ b/Userland/Libraries/LibWeb/Layout/TextNode.h
@@ -63,6 +63,7 @@ private:
virtual void handle_mousemove(Badge<EventHandler>, const Gfx::IntPoint&, unsigned button, unsigned modifiers) override;
void split_into_lines_by_rules(InlineFormattingContext&, LayoutMode, bool do_collapse, bool do_wrap_lines, bool do_wrap_breaks);
void paint_cursor_if_needed(PaintContext&, const LineBoxFragment&) const;
+ void paint_text_decoration(Gfx::Painter&, LineBoxFragment const&) const;
String m_text_for_rendering;
};