summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-06-29 12:43:45 +0200
committerAndreas Kling <kling@serenityos.org>2020-06-29 12:47:21 +0200
commit53573f6fb1f90e6aebaad4032fd0b7448c27bf12 (patch)
treed5e6661c615ce92d007c67e8d974952a23d1e0e1 /Libraries
parent12cbc4ad0d57b7f403e0a27b491b098f1431a283 (diff)
downloadserenity-53573f6fb1f90e6aebaad4032fd0b7448c27bf12.zip
LibWeb: Clamp text fragment selection to the fragment
Also add 1px of width to partial fragment selections, since that ends up looking nicer during interactive mouse selection.
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibWeb/Layout/LineBoxFragment.cpp24
1 files changed, 14 insertions, 10 deletions
diff --git a/Libraries/LibWeb/Layout/LineBoxFragment.cpp b/Libraries/LibWeb/Layout/LineBoxFragment.cpp
index 8dd26b31c3..7efbd69867 100644
--- a/Libraries/LibWeb/Layout/LineBoxFragment.cpp
+++ b/Libraries/LibWeb/Layout/LineBoxFragment.cpp
@@ -85,6 +85,9 @@ int LineBoxFragment::text_index_at(float x) const
float relative_x = x - absolute_x();
float glyph_spacing = font.glyph_spacing();
+ if (relative_x < 0)
+ return 0;
+
float width_so_far = 0;
for (auto it = view.begin(); it != view.end(); ++it) {
float glyph_width = font.glyph_or_emoji_width(*it);
@@ -105,6 +108,7 @@ Gfx::FloatRect LineBoxFragment::selection_rect(const Gfx::Font& font) const
const auto start_index = m_start;
const auto end_index = m_start + m_length;
+ auto text = this->text();
if (&layout_node() == selection.start().layout_node && &layout_node() == selection.end().layout_node) {
// we are in the start/end node (both the same)
@@ -113,10 +117,10 @@ Gfx::FloatRect LineBoxFragment::selection_rect(const Gfx::Font& font) const
if (end_index < selection.start().index_in_node)
return {};
- auto selection_start_in_this_fragment = selection.start().index_in_node - m_start;
- auto selection_end_in_this_fragment = selection.end().index_in_node - m_start + 1;
- auto pixel_distance_to_first_selected_character = font.width(text().substring_view(0, selection_start_in_this_fragment));
- auto pixel_width_of_selection = font.width(text().substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment));
+ auto selection_start_in_this_fragment = max(0, selection.start().index_in_node - m_start);
+ auto selection_end_in_this_fragment = min(m_length, selection.end().index_in_node - m_start + 1);
+ auto pixel_distance_to_first_selected_character = font.width(text.substring_view(0, selection_start_in_this_fragment));
+ auto pixel_width_of_selection = font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment)) + 1;
auto rect = absolute_rect();
rect.set_x(rect.x() + pixel_distance_to_first_selected_character);
@@ -129,10 +133,10 @@ Gfx::FloatRect LineBoxFragment::selection_rect(const Gfx::Font& font) const
if (end_index < selection.start().index_in_node)
return {};
- auto selection_start_in_this_fragment = selection.start().index_in_node - m_start;
+ auto selection_start_in_this_fragment = max(0, selection.start().index_in_node - m_start);
auto selection_end_in_this_fragment = m_length;
- auto pixel_distance_to_first_selected_character = font.width(text().substring_view(0, selection_start_in_this_fragment));
- auto pixel_width_of_selection = font.width(text().substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment));
+ auto pixel_distance_to_first_selected_character = font.width(text.substring_view(0, selection_start_in_this_fragment));
+ auto pixel_width_of_selection = font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment)) + 1;
auto rect = absolute_rect();
rect.set_x(rect.x() + pixel_distance_to_first_selected_character);
@@ -146,9 +150,9 @@ Gfx::FloatRect LineBoxFragment::selection_rect(const Gfx::Font& font) const
return {};
auto selection_start_in_this_fragment = 0;
- auto selection_end_in_this_fragment = selection.end().index_in_node + 1;
- auto pixel_distance_to_first_selected_character = font.width(text().substring_view(0, selection_start_in_this_fragment));
- auto pixel_width_of_selection = font.width(text().substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment));
+ auto selection_end_in_this_fragment = min(selection.end().index_in_node + 1, m_length);
+ auto pixel_distance_to_first_selected_character = font.width(text.substring_view(0, selection_start_in_this_fragment));
+ auto pixel_width_of_selection = font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment)) + 1;
auto rect = absolute_rect();
rect.set_x(rect.x() + pixel_distance_to_first_selected_character);