diff --git a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt index 9aa2f958276..f20ac98e237 100644 --- a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt +++ b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt @@ -200,6 +200,7 @@ text-decoration-style: solid text-decoration-thickness: auto text-indent: 0px text-justify: auto +text-overflow: clip text-shadow: none text-transform: none top: auto diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index d35073c888e..39c5930e943 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -337,6 +337,44 @@ void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode) // putting it on the next line. if (is_whitespace && next_width > 0 && line_builder.break_if_needed(item.border_box_width() + next_width)) break; + } else if (text_node.computed_values().text_overflow() == CSS::TextOverflow::Ellipsis + && text_node.computed_values().overflow_x() != CSS::Overflow::Visible) { + // We may need to do an ellipsis if the text is too long for the container + constexpr u32 ellipsis_codepoint = 0x2026; + if (m_available_space.has_value() + && item.width.to_double() > m_available_space.value().width.to_px_or_zero().to_double()) { + // Do the ellipsis + auto& glyph_run = item.glyph_run; + + auto available_width = m_available_space.value().width.to_px_or_zero().to_double(); + auto ellipsis_width = glyph_run->font().glyph_width(ellipsis_codepoint); + auto max_text_width = available_width - ellipsis_width; + + auto& glyphs = glyph_run->glyphs(); + auto last_glyph_index = 0; + auto last_glyph_position = Gfx::FloatPoint(); + + for (auto const& glyph_or_emoji : glyphs) { + auto this_position = Gfx::FloatPoint(); + glyph_or_emoji.visit( + [&](Gfx::DrawGlyph glyph) { + this_position = glyph.position; + }, + [&](Gfx::DrawEmoji emoji) { + this_position = emoji.position; + }); + if (this_position.x() > max_text_width) + break; + + last_glyph_index++; + last_glyph_position = this_position; + } + + auto remove_item_count = glyphs.size() - last_glyph_index; + glyphs.remove(last_glyph_index - 1, remove_item_count); + + glyphs.append(Gfx::DrawGlyph(last_glyph_position, ellipsis_codepoint)); + } } line_builder.append_text_chunk( text_node, @@ -414,5 +452,4 @@ void InlineFormattingContext::set_vertical_float_clearance(CSSPixels vertical_fl { m_vertical_float_clearance = vertical_float_clearance; } - }