LibWeb: Use the ASCII line segmenter for eligible text

This commit is contained in:
Tim Ledbetter 2026-04-27 16:25:50 +01:00 committed by Jelle Raaijmakers
parent f161215f53
commit 78b47109af
3 changed files with 20 additions and 7 deletions

View file

@ -146,8 +146,9 @@ WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t coun
if (m_grapheme_segmenter)
m_grapheme_segmenter->set_segmented_text(m_data);
if (m_line_segmenter)
m_line_segmenter->set_segmented_text(m_data);
// The line segmenter may be the ASCII fast-path variant, which only accepts a subset of inputs; let the
// lazy getter re-pick the implementation against the new data.
m_line_segmenter = nullptr;
if (m_word_segmenter)
m_word_segmenter->set_segmented_text(m_data);
@ -190,8 +191,12 @@ Unicode::Segmenter& CharacterData::grapheme_segmenter() const
Unicode::Segmenter& CharacterData::line_segmenter() const
{
if (!m_line_segmenter) {
m_line_segmenter = document().line_segmenter().clone();
m_line_segmenter->set_segmented_text(m_data);
if (auto ascii = Unicode::Segmenter::try_create_for_ascii_line(m_data.utf16_view())) {
m_line_segmenter = ascii.release_nonnull();
} else {
m_line_segmenter = document().line_segmenter().clone();
m_line_segmenter->set_segmented_text(m_data);
}
}
return *m_line_segmenter;

View file

@ -6,6 +6,7 @@
#include <AK/Utf16View.h>
#include <LibGfx/TextLayout.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Text.h>
#include <LibWeb/GraphemeEdgeTracker.h>
#include <LibWeb/Layout/TextNode.h>
@ -38,7 +39,9 @@ static float measure_text_width(Layout::TextNode const& text_node, Utf16View con
auto grapheme_segmenter = text_node.grapheme_segmenter().clone();
grapheme_segmenter->set_segmented_text(text);
auto line_segmenter = text_node.line_segmenter().clone();
// NB: The text node's cached line segmenter may be the ASCII fast-path variant, which only accepts a subset
// of inputs; route through the document's ICU segmenter so arbitrary subviews are handled.
auto line_segmenter = text_node.document().line_segmenter().clone();
line_segmenter->set_segmented_text(text);
Layout::TextNode::ChunkIterator iterator { text_node, text, *grapheme_segmenter, *line_segmenter, CSS::WordBreak::Normal, false, false };

View file

@ -416,8 +416,13 @@ Unicode::Segmenter& TextNode::grapheme_segmenter() const
Unicode::Segmenter& TextNode::line_segmenter() const
{
if (!m_line_segmenter) {
m_line_segmenter = document().line_segmenter().clone();
m_line_segmenter->set_segmented_text(text_for_rendering());
auto const& text = text_for_rendering();
if (auto ascii = Unicode::Segmenter::try_create_for_ascii_line(text.utf16_view())) {
m_line_segmenter = ascii.release_nonnull();
} else {
m_line_segmenter = document().line_segmenter().clone();
m_line_segmenter->set_segmented_text(text);
}
}
return *m_line_segmenter;