From 89bc6557656759ab23d18c7c9e48bae6315d2e2e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 5 Apr 2021 22:40:07 +0200 Subject: [PATCH] LibGfx: Add Gfx::Painter::draw_ui_text() This function draw text while interpreting "&" as "underline the next character" and "&&" as "&". --- Userland/Libraries/LibGfx/Painter.cpp | 45 +++++++++++++++++++++++++++ Userland/Libraries/LibGfx/Painter.h | 1 + 2 files changed, 46 insertions(+) diff --git a/Userland/Libraries/LibGfx/Painter.cpp b/Userland/Libraries/LibGfx/Painter.cpp index 34108efa18..c4ad9e79c7 100644 --- a/Userland/Libraries/LibGfx/Painter.cpp +++ b/Userland/Libraries/LibGfx/Painter.cpp @@ -1806,4 +1806,49 @@ void Painter::blit_tiled(const IntRect& dst_rect, const Gfx::Bitmap& bitmap, con } } +void Gfx::Painter::draw_ui_text(const StringView& text, const Gfx::IntRect& rect, const Gfx::Font& font, Gfx::Color color) +{ + auto parse_ampersand_string = [](const StringView& raw_text, Optional& underline_offset) -> String { + if (raw_text.is_empty()) + return String::empty(); + + StringBuilder builder; + + for (size_t i = 0; i < raw_text.length(); ++i) { + if (raw_text[i] == '&') { + if (i != (raw_text.length() - 1) && raw_text[i + 1] == '&') + builder.append(raw_text[i]); + else if (!underline_offset.has_value()) + underline_offset = i; + continue; + } + builder.append(raw_text[i]); + } + return builder.to_string(); + }; + + Optional underline_offset; + auto name_to_draw = parse_ampersand_string(text, underline_offset); + + Gfx::IntRect text_rect { 0, 0, font.width(name_to_draw), font.glyph_height() }; + text_rect.center_within(rect); + + draw_text(text_rect, name_to_draw, font, Gfx::TextAlignment::CenterLeft, color); + + if (underline_offset.has_value()) { + Utf8View utf8_view { name_to_draw }; + int width = 0; + for (auto it = utf8_view.begin(); it != utf8_view.end(); ++it) { + if (utf8_view.byte_offset_of(it) >= underline_offset.value()) { + int y = text_rect.bottom() + 2; + int x1 = text_rect.left() + width; + int x2 = x1 + font.glyph_or_emoji_width(*it); + draw_line({ x1, y }, { x2, y }, Color::Black); + break; + } + width += font.glyph_or_emoji_width(*it); + } + } +} + } diff --git a/Userland/Libraries/LibGfx/Painter.h b/Userland/Libraries/LibGfx/Painter.h index b7b6d003d7..f7798d97b9 100644 --- a/Userland/Libraries/LibGfx/Painter.h +++ b/Userland/Libraries/LibGfx/Painter.h @@ -85,6 +85,7 @@ public: void draw_text(Function, const IntRect&, const StringView&, const Font&, TextAlignment = TextAlignment::TopLeft, TextElision = TextElision::None); void draw_text(Function, const IntRect&, const Utf8View&, const Font&, TextAlignment = TextAlignment::TopLeft, TextElision = TextElision::None); void draw_text(Function, const IntRect&, const Utf32View&, const Font&, TextAlignment = TextAlignment::TopLeft, TextElision = TextElision::None); + void draw_ui_text(const StringView&, const Gfx::IntRect&, const Gfx::Font&, Gfx::Color); void draw_glyph(const IntPoint&, u32, Color); void draw_glyph(const IntPoint&, u32, const Font&, Color); void draw_emoji(const IntPoint&, const Gfx::Bitmap&, const Font&);