From fbc42e7d4282053414c7cf85a3ef7a74e07f4d46 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 16 Jun 2024 09:44:26 +0200 Subject: [PATCH] LibGfx: Don't try to paint glyphs that aren't in a font Fixes https://github.com/LadybirdBrowser/ladybird/issues/88 --- Userland/Libraries/LibAccelGfx/GlyphAtlas.cpp | 6 +++--- Userland/Libraries/LibGfx/Font/Font.h | 6 +++--- Userland/Libraries/LibGfx/Font/ScaledFont.cpp | 6 ++++-- Userland/Libraries/LibGfx/Font/ScaledFont.h | 4 ++-- Userland/Libraries/LibGfx/Painter.cpp | 5 ++++- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Userland/Libraries/LibAccelGfx/GlyphAtlas.cpp b/Userland/Libraries/LibAccelGfx/GlyphAtlas.cpp index 65f8a741124..62383a33ee5 100644 --- a/Userland/Libraries/LibAccelGfx/GlyphAtlas.cpp +++ b/Userland/Libraries/LibAccelGfx/GlyphAtlas.cpp @@ -25,12 +25,12 @@ void GlyphAtlas::update(HashMap> const& unique_ for (auto const& [font, code_points] : unique_glyphs) { for (auto const& code_point : code_points) { auto glyph = font->glyph(code_point); + if (!glyph.has_value()) + continue; auto atlas_key = GlyphsTextureKey { font, code_point }; if (!m_glyphs_texture_map.contains(atlas_key)) need_to_rebuild_texture = true; - if (glyph.bitmap()) { - glyph_bitmaps.set(atlas_key, *glyph.bitmap()); - } + glyph_bitmaps.set(atlas_key, *glyph->bitmap()); } } diff --git a/Userland/Libraries/LibGfx/Font/Font.h b/Userland/Libraries/LibGfx/Font/Font.h index bfa29c64dbc..b31ddbc0110 100644 --- a/Userland/Libraries/LibGfx/Font/Font.h +++ b/Userland/Libraries/LibGfx/Font/Font.h @@ -32,7 +32,7 @@ public: bool is_color_bitmap() const { return m_color_bitmap; } - RefPtr bitmap() const { return m_bitmap; } + [[nodiscard]] NonnullRefPtr bitmap() const { return m_bitmap; } float left_bearing() const { return m_left_bearing; } float advance() const { return m_advance; } float ascent() const { return m_ascent; } @@ -116,8 +116,8 @@ public: virtual int pixel_size_rounded_up() const = 0; virtual u16 weight() const = 0; - virtual Glyph glyph(u32 code_point) const = 0; - virtual Glyph glyph(u32 code_point, GlyphSubpixelOffset) const = 0; + virtual Optional glyph(u32 code_point) const = 0; + virtual Optional glyph(u32 code_point, GlyphSubpixelOffset) const = 0; virtual bool contains_glyph(u32 code_point) const = 0; virtual float glyph_left_bearing(u32 code_point) const = 0; diff --git a/Userland/Libraries/LibGfx/Font/ScaledFont.cpp b/Userland/Libraries/LibGfx/Font/ScaledFont.cpp index 34941783916..c731c5c9b7d 100644 --- a/Userland/Libraries/LibGfx/Font/ScaledFont.cpp +++ b/Userland/Libraries/LibGfx/Font/ScaledFont.cpp @@ -80,15 +80,17 @@ bool ScaledFont::append_glyph_path_to(Gfx::Path& path, u32 glyph_id) const return m_font->append_glyph_path_to(path, glyph_id, m_x_scale, m_y_scale); } -Gfx::Glyph ScaledFont::glyph(u32 code_point) const +Optional ScaledFont::glyph(u32 code_point) const { return glyph(code_point, GlyphSubpixelOffset { 0, 0 }); } -Gfx::Glyph ScaledFont::glyph(u32 code_point, GlyphSubpixelOffset subpixel_offset) const +Optional ScaledFont::glyph(u32 code_point, GlyphSubpixelOffset subpixel_offset) const { auto id = glyph_id_for_code_point(code_point); auto bitmap = rasterize_glyph(id, subpixel_offset); + if (!bitmap) + return {}; auto metrics = glyph_metrics(id); return Gfx::Glyph(*bitmap, metrics.left_side_bearing, metrics.advance_width, metrics.ascender, m_font->has_color_bitmaps()); } diff --git a/Userland/Libraries/LibGfx/Font/ScaledFont.h b/Userland/Libraries/LibGfx/Font/ScaledFont.h index 475727ed8b6..aa1f1ffeb3c 100644 --- a/Userland/Libraries/LibGfx/Font/ScaledFont.h +++ b/Userland/Libraries/LibGfx/Font/ScaledFont.h @@ -37,9 +37,9 @@ public: virtual Gfx::FontPixelMetrics pixel_metrics() const override; virtual u8 slope() const override { return m_font->slope(); } virtual u16 weight() const override { return m_font->weight(); } - virtual Gfx::Glyph glyph(u32 code_point) const override; + virtual Optional glyph(u32 code_point) const override; virtual float glyph_left_bearing(u32 code_point) const override; - virtual Glyph glyph(u32 code_point, GlyphSubpixelOffset) const override; + virtual Optional glyph(u32 code_point, GlyphSubpixelOffset) const override; virtual bool contains_glyph(u32 code_point) const override { return m_font->glyph_id_for_code_point(code_point) > 0; } virtual float glyph_width(u32 code_point) const override; virtual float glyph_or_emoji_width(Utf8CodePointIterator&) const override; diff --git a/Userland/Libraries/LibGfx/Painter.cpp b/Userland/Libraries/LibGfx/Painter.cpp index d12962cebf1..3477fd479e0 100644 --- a/Userland/Libraries/LibGfx/Painter.cpp +++ b/Userland/Libraries/LibGfx/Painter.cpp @@ -849,7 +849,10 @@ FLATTEN void Painter::draw_glyph(FloatPoint point, u32 code_point, Font const& f { auto top_left = point + FloatPoint(font.glyph_left_bearing(code_point), 0); auto glyph_position = Gfx::GlyphRasterPosition::get_nearest_fit_for(top_left); - auto glyph = font.glyph(code_point, glyph_position.subpixel_offset); + auto maybe_glyph = font.glyph(code_point, glyph_position.subpixel_offset); + if (!maybe_glyph.has_value()) + return; + auto glyph = maybe_glyph.release_value(); if (glyph.is_color_bitmap()) { float scaled_width = glyph.advance();