diff options
Diffstat (limited to 'Userland/Libraries/LibWeb/Layout')
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/TextNode.cpp | 39 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/TextNode.h | 1 |
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; }; |