summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGUI
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2023-03-03 14:40:56 -0500
committerAndreas Kling <kling@serenityos.org>2023-03-03 22:49:12 +0100
commit4463de3d109ce953e420c6347a863285fa7c83a2 (patch)
tree865e48bf6a2188b0c6f870cdda855028f87650bc /Userland/Libraries/LibGUI
parentc7736ef41017288b2bb8d41cf51f2b1366ed5a35 (diff)
downloadserenity-4463de3d109ce953e420c6347a863285fa7c83a2.zip
LibGUI: Compute syntax-highlighted visual text spans using float rects
For vector fonts in particular, we need to take care to compute offsets using floating point math. For example, with Berkeley Mono at font size 16, with syntax highlighting enabled, we are currently truncating these offsets to integers. This results in a leftward-drift when we paint the text. This changes the rect in which we paint syntax-highlighted text spans to a float rect. As we traverse the spans, we now no longer truncate any of the text offsets, and we draw the text in the correct positions. This is likely not a complete solution. TextEditor blindly casts ints to floats all over, and we will want to make all of these (hundred+) float- aware. But this should be a step in the right direction and makes vector fonts immediately more comfortable to use.
Diffstat (limited to 'Userland/Libraries/LibGUI')
-rw-r--r--Userland/Libraries/LibGUI/TextEditor.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp
index 75c4399c3d..3f801aa1c9 100644
--- a/Userland/Libraries/LibGUI/TextEditor.cpp
+++ b/Userland/Libraries/LibGUI/TextEditor.cpp
@@ -497,17 +497,35 @@ void TextEditor::paint_event(PaintEvent& event)
// NOTE: This lambda and TextEditor::text_width_for_font() are used to substitute all glyphs with m_substitution_code_point if necessary.
// Painter::draw_text() and Gfx::Font::width() should not be called directly, but using this lambda and TextEditor::text_width_for_font().
- auto draw_text = [&](Gfx::IntRect const& rect, auto const& raw_text, Gfx::Font const& font, Gfx::TextAlignment alignment, Gfx::TextAttributes attributes, bool substitute = true) {
+ auto draw_text = [&](auto const& rect, auto const& raw_text, Gfx::Font const& font, Gfx::TextAlignment alignment, Gfx::TextAttributes attributes, bool substitute = true) {
if (m_substitution_code_point.has_value() && substitute) {
painter.draw_text(rect, substitution_code_point_view(raw_text.length()), font, alignment, attributes.color);
} else {
painter.draw_text(rect, raw_text, font, alignment, attributes.color);
}
if (attributes.underline) {
+ auto bottom_left = [&]() {
+ auto point = rect.bottom_left().translated(0, 1);
+
+ if constexpr (IsSame<RemoveCVReference<decltype(rect)>, Gfx::IntRect>)
+ return point;
+ else
+ return point.template to_type<int>();
+ };
+
+ auto bottom_right = [&]() {
+ auto point = rect.bottom_right().translated(0, 1);
+
+ if constexpr (IsSame<RemoveCVReference<decltype(rect)>, Gfx::IntRect>)
+ return point;
+ else
+ return point.template to_type<int>();
+ };
+
if (attributes.underline_style == Gfx::TextAttributes::UnderlineStyle::Solid)
- painter.draw_line(rect.bottom_left().translated(0, 1), rect.bottom_right().translated(0, 1), attributes.underline_color.value_or(attributes.color));
+ painter.draw_line(bottom_left(), bottom_right(), attributes.underline_color.value_or(attributes.color));
if (attributes.underline_style == Gfx::TextAttributes::UnderlineStyle::Wavy)
- painter.draw_triangle_wave(rect.bottom_left().translated(0, 1), rect.bottom_right().translated(0, 1), attributes.underline_color.value_or(attributes.color), 2);
+ painter.draw_triangle_wave(bottom_left(), bottom_right(), attributes.underline_color.value_or(attributes.color), 2);
}
};
@@ -651,7 +669,7 @@ void TextEditor::paint_event(PaintEvent& event)
draw_text(visual_line_rect, visual_line_text, font(), m_text_alignment, unspanned_text_attributes);
} else {
size_t next_column = 0;
- Gfx::IntRect span_rect = { visual_line_rect.location(), { 0, line_height() } };
+ Gfx::FloatRect span_rect = { visual_line_rect.location(), { 0, line_height() } };
auto draw_text_helper = [&](size_t start, size_t end, Gfx::Font const& font, Gfx::TextAttributes text_attributes) {
size_t length = end - start;
@@ -660,7 +678,7 @@ void TextEditor::paint_event(PaintEvent& event)
auto text = visual_line_text.substring_view(start, length);
span_rect.set_width(font.width(text) + font.glyph_spacing());
if (text_attributes.background_color.has_value()) {
- painter.fill_rect(span_rect, text_attributes.background_color.value());
+ painter.fill_rect(span_rect.to_type<int>(), text_attributes.background_color.value());
}
draw_text(span_rect, text, font, m_text_alignment, text_attributes);
span_rect.translate_by(span_rect.width(), 0);