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; }
|
bool is_empty() const { return m_length == 0; }
|
||||||
size_t length() const { return m_length; }
|
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
|
Utf32View substring_view(size_t offset, size_t length) const
|
||||||
{
|
{
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
|
|
|
@ -65,7 +65,7 @@ Utf8CodepointIterator Utf8View::end() const
|
||||||
return { end_ptr(), 0 };
|
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 >= begin_ptr());
|
||||||
ASSERT(it.m_ptr <= end_ptr());
|
ASSERT(it.m_ptr <= end_ptr());
|
||||||
|
|
|
@ -76,10 +76,15 @@ public:
|
||||||
|
|
||||||
const unsigned char* bytes() const { return begin_ptr(); }
|
const unsigned char* bytes() const { return begin_ptr(); }
|
||||||
int byte_length() const { return m_string.length(); }
|
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;
|
Utf8View substring_view(int byte_offset, int byte_length) const;
|
||||||
bool is_empty() const { return m_string.is_empty(); }
|
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(size_t& valid_bytes) const;
|
||||||
bool validate() 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("...");
|
int new_width = font.width("...");
|
||||||
if (new_width < text_width) {
|
if (new_width < text_width) {
|
||||||
size_t offset = 0;
|
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);
|
int glyph_width = font.glyph_or_emoji_width(code_point);
|
||||||
// NOTE: Glyph spacing should not be added after the last glyph on the line,
|
// 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,
|
// 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())
|
if (width_with_this_glyph_included > rect.width())
|
||||||
break;
|
break;
|
||||||
new_width += glyph_width + glyph_spacing;
|
new_width += glyph_width + glyph_spacing;
|
||||||
offset++;
|
offset = text.iterator_offset(it);
|
||||||
}
|
}
|
||||||
apply_elision(final_text, elided_text, offset);
|
apply_elision(final_text, elided_text, offset);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue