mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibGfx+AK: Make text elision work with multi-byte characters
This was causing WindowServer and Taskbar to crash sometimes when the stars aligned and we tried cutting off a string ending with "..." right on top of an emoji. :^)
This commit is contained in:
parent
9af33e2e4b
commit
13594b7146
Notes:
sideshowbarker
2024-07-19 00:28:56 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/13594b7146c
4 changed files with 17 additions and 4 deletions
|
@ -105,6 +105,13 @@ public:
|
|||
bool is_empty() const { return m_length == 0; }
|
||||
size_t length() const { return m_length; }
|
||||
|
||||
size_t iterator_offset(const Utf32CodepointIterator& it) const
|
||||
{
|
||||
ASSERT(it.m_ptr >= m_code_points);
|
||||
ASSERT(it.m_ptr < m_code_points + m_length);
|
||||
return ((ptrdiff_t)it.m_ptr - (ptrdiff_t)m_code_points) / sizeof(u32);
|
||||
}
|
||||
|
||||
Utf32View substring_view(size_t offset, size_t length) const
|
||||
{
|
||||
if (length == 0)
|
||||
|
|
|
@ -65,7 +65,7 @@ Utf8CodepointIterator Utf8View::end() const
|
|||
return { end_ptr(), 0 };
|
||||
}
|
||||
|
||||
int Utf8View::byte_offset_of(const Utf8CodepointIterator& it) const
|
||||
size_t Utf8View::byte_offset_of(const Utf8CodepointIterator& it) const
|
||||
{
|
||||
ASSERT(it.m_ptr >= begin_ptr());
|
||||
ASSERT(it.m_ptr <= end_ptr());
|
||||
|
|
|
@ -76,10 +76,15 @@ public:
|
|||
|
||||
const unsigned char* bytes() const { return begin_ptr(); }
|
||||
int byte_length() const { return m_string.length(); }
|
||||
int byte_offset_of(const Utf8CodepointIterator&) const;
|
||||
size_t byte_offset_of(const Utf8CodepointIterator&) const;
|
||||
Utf8View substring_view(int byte_offset, int byte_length) const;
|
||||
bool is_empty() const { return m_string.is_empty(); }
|
||||
|
||||
size_t iterator_offset(const Utf8CodepointIterator& it) const
|
||||
{
|
||||
return byte_offset_of(it);
|
||||
}
|
||||
|
||||
bool validate(size_t& valid_bytes) const;
|
||||
bool validate() const
|
||||
{
|
||||
|
|
|
@ -918,7 +918,8 @@ void draw_text_line(const IntRect& a_rect, const TextType& text, const Font& fon
|
|||
int new_width = font.width("...");
|
||||
if (new_width < text_width) {
|
||||
size_t offset = 0;
|
||||
for (auto code_point : text) {
|
||||
for (auto it = text.begin(); it != text.end(); ++it) {
|
||||
auto code_point = *it;
|
||||
int glyph_width = font.glyph_or_emoji_width(code_point);
|
||||
// NOTE: Glyph spacing should not be added after the last glyph on the line,
|
||||
// but since we are here because the last glyph does not actually fit on the line,
|
||||
|
@ -927,7 +928,7 @@ void draw_text_line(const IntRect& a_rect, const TextType& text, const Font& fon
|
|||
if (width_with_this_glyph_included > rect.width())
|
||||
break;
|
||||
new_width += glyph_width + glyph_spacing;
|
||||
offset++;
|
||||
offset = text.iterator_offset(it);
|
||||
}
|
||||
apply_elision(final_text, elided_text, offset);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue