diff --git a/Libraries/LibWeb/Layout/TextNode.cpp b/Libraries/LibWeb/Layout/TextNode.cpp index b401a9fa4b..4502abecba 100644 --- a/Libraries/LibWeb/Layout/TextNode.cpp +++ b/Libraries/LibWeb/Layout/TextNode.cpp @@ -631,10 +631,12 @@ bool TextNode::ChunkIterator::is_at_line_break_opportunity() const VERIFY_NOT_REACHED(); } -Gfx::Font const& TextNode::ChunkIterator::font_for_space(size_t at_index) const +Gfx::Font const& TextNode::ChunkIterator::font_for_space(size_t at_index, u32 space_code_point) const { + auto has_glyph = [&](Gfx::Font const& font) { return font.contains_glyph(space_code_point); }; + // 1. Prefer the last non-whitespace font in this node/run. - if (m_last_non_whitespace_font && !m_last_non_whitespace_font->is_emoji_font()) + if (m_last_non_whitespace_font && !m_last_non_whitespace_font->is_emoji_font() && has_glyph(*m_last_non_whitespace_font)) return *m_last_non_whitespace_font; // 2. Look ahead to the next non-space to infer the base font of this run. @@ -642,7 +644,7 @@ Gfx::Font const& TextNode::ChunkIterator::font_for_space(size_t at_index) const auto cp = m_view.code_point_at(i); if (!is_interword_space(cp) && cp != '\t' && cp != '\n') { auto const& font = m_font_cascade_list.font_for_code_point(cp); - if (!font.is_emoji_font()) + if (!font.is_emoji_font() && has_glyph(font)) return font; // Text is coming from an emoji face; we'll fall back to (3). break; @@ -650,8 +652,8 @@ Gfx::Font const& TextNode::ChunkIterator::font_for_space(size_t at_index) const i = m_grapheme_segmenter.next_boundary(i).value_or(m_view.length_in_code_units()); } - // 3. No text around (leading/trailing/all spaces) — pick the first *text* face in the cascade. - return m_font_cascade_list.first_text_face(); + // 3. No text around (leading/trailing/all spaces) — pick a font with the glyph from the cascade. + return m_font_cascade_list.font_for_code_point(space_code_point); } Optional TextNode::ChunkIterator::next_without_peek() @@ -677,7 +679,7 @@ Optional TextNode::ChunkIterator::next_without_peek() auto const& expected_font_for = [&](u32 cp) -> Gfx::Font const& { return is_interword_space(cp) - ? font_for_space(m_current_index) + ? font_for_space(m_current_index, cp) : m_font_cascade_list.font_for_code_point(cp); }; @@ -749,7 +751,7 @@ Optional TextNode::ChunkIterator::next_without_peek() // Otherwise, commit the whitespace! m_current_index = next_grapheme_boundary(); can_break_at_current_position = is_at_line_break_opportunity(); - auto const& space_font = font_for_space(m_current_index); + auto const& space_font = font_for_space(m_current_index, code_point); if (auto result = try_commit_chunk(start_of_chunk, m_current_index, false, broken_on_tab, false, space_font, text_type); result.has_value()) return result.release_value(); continue; diff --git a/Libraries/LibWeb/Layout/TextNode.h b/Libraries/LibWeb/Layout/TextNode.h index 2764ee04a0..366b7099ad 100644 --- a/Libraries/LibWeb/Layout/TextNode.h +++ b/Libraries/LibWeb/Layout/TextNode.h @@ -60,7 +60,7 @@ public: Optional try_commit_chunk(size_t start, size_t end, bool has_breaking_newline, bool has_breaking_tab, bool can_break_after, Gfx::Font const&, Gfx::GlyphRun::TextType) const; [[nodiscard]] bool is_at_line_break_opportunity() const; - [[nodiscard]] Gfx::Font const& font_for_space(size_t at_index) const; + [[nodiscard]] Gfx::Font const& font_for_space(size_t at_index, u32 space_code_point) const; bool const m_should_wrap_lines; bool const m_should_respect_linebreaks; diff --git a/Tests/LibWeb/Assets/HashSansNoSpace.woff b/Tests/LibWeb/Assets/HashSansNoSpace.woff new file mode 100644 index 0000000000..7cfbc1c531 Binary files /dev/null and b/Tests/LibWeb/Assets/HashSansNoSpace.woff differ diff --git a/Tests/LibWeb/Text/expected/font-cascade-space-fallback.txt b/Tests/LibWeb/Text/expected/font-cascade-space-fallback.txt new file mode 100644 index 0000000000..f8450fbed8 --- /dev/null +++ b/Tests/LibWeb/Text/expected/font-cascade-space-fallback.txt @@ -0,0 +1 @@ +space matches fallback: true diff --git a/Tests/LibWeb/Text/input/font-cascade-space-fallback.html b/Tests/LibWeb/Text/input/font-cascade-space-fallback.html new file mode 100644 index 0000000000..67b5af3f1d --- /dev/null +++ b/Tests/LibWeb/Text/input/font-cascade-space-fallback.html @@ -0,0 +1,37 @@ + + + +
+ AB + A B +   +
+