From 5ccb2409451571e9d9473f09e08b1e16b99859a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Offenh=C3=A4user?= Date: Tue, 28 Mar 2023 14:51:51 +0200 Subject: [PATCH] LibGfx: Don't render OpenType glyphs that have no outline The spec tells us that for glyph offsets in the "loca" table, if an offset appears twice in a row, the index of the first one refers to a glyph without an outline (such as the space character). We didn't check for this, which would cause us to render a glyph outline where there should have been nothing. --- Userland/Libraries/LibGfx/Font/OpenType/Font.cpp | 11 +++++++++-- Userland/Libraries/LibGfx/Font/OpenType/Glyf.cpp | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp index 8dc47a2e9e..f2d20adaf8 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp @@ -699,8 +699,15 @@ RefPtr Font::rasterize_glyph(u32 glyph_id, float x_scale, float y_s if (glyph_id >= glyph_count()) { glyph_id = 0; } - auto glyph_offset = m_loca->get_glyph_offset(glyph_id); - auto glyph = m_glyf->glyph(glyph_offset); + + auto glyph_offset0 = m_loca->get_glyph_offset(glyph_id); + auto glyph_offset1 = m_loca->get_glyph_offset(glyph_id + 1); + + // If a glyph has no outline, then loca[n] = loca [n+1]. + if (glyph_offset0 == glyph_offset1) + return nullptr; + + auto glyph = m_glyf->glyph(glyph_offset0); i16 ascender = 0; i16 descender = 0; diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Glyf.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Glyf.cpp index 2758add798..07eed2650a 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Glyf.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Glyf.cpp @@ -208,7 +208,8 @@ Optional Loca::from_slice(ReadonlyBytes slice, u32 num_glyphs, IndexToLocF u32 Loca::get_glyph_offset(u32 glyph_id) const { - VERIFY(glyph_id < m_num_glyphs); + // NOTE: The value of n is numGlyphs + 1. + VERIFY(glyph_id <= m_num_glyphs); switch (m_index_to_loc_format) { case IndexToLocFormat::Offset16: return ((u32)be_u16(m_slice.offset_pointer(glyph_id * 2))) * 2;