mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 17:52:34 -10:00
LibGfx: Don't try to paint glyphs that aren't in a font
Fixes https://github.com/LadybirdBrowser/ladybird/issues/88 (cherry picked from commit fbc42e7d4282053414c7cf85a3ef7a74e07f4d46; amended to handle bitmap fonts)
This commit is contained in:
1 parent
8129847375
commit
9e6666237b
7 files changed
+24
-18
No files matched your search
@@ -25,12 +25,12 @@ void GlyphAtlas::update(HashMap<Gfx::Font const*, HashTable<u32>> 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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -282,11 +282,12 @@ ErrorOr<void> BitmapFont::write_to_file(NonnullOwnPtr<Core::File> file)
|
||||
return {};
|
||||
}
|
||||
|
||||
Glyph BitmapFont::glyph(u32 code_point) const
|
||||
Optional<Glyph> BitmapFont::glyph(u32 code_point) const
|
||||
{
|
||||
// Note: Until all fonts support the 0xFFFD replacement
|
||||
// character, fall back to painting '?' if necessary.
|
||||
auto index = glyph_index(code_point).value_or('?');
|
||||
auto maybe_index = glyph_index(code_point);
|
||||
if (!maybe_index.has_value())
|
||||
return {};
|
||||
auto index = maybe_index.release_value();
|
||||
auto width = m_glyph_widths[index];
|
||||
auto glyph_byte_count = m_glyph_height * GlyphBitmap::bytes_per_row();
|
||||
return Glyph(
|
||||
|
||||
@@ -60,8 +60,8 @@ public:
|
||||
virtual u8 slope() const override { return m_slope; }
|
||||
void set_slope(u8 slope) { m_slope = slope; }
|
||||
|
||||
Glyph glyph(u32 code_point) const override;
|
||||
Glyph glyph(u32 code_point, GlyphSubpixelOffset) const override { return glyph(code_point); }
|
||||
Optional<Glyph> glyph(u32 code_point) const override;
|
||||
Optional<Glyph> glyph(u32 code_point, GlyphSubpixelOffset) const override { return glyph(code_point); }
|
||||
Optional<Glyph> glyph_for_postscript_name(StringView, GlyphSubpixelOffset) const override { return {}; }
|
||||
|
||||
float glyph_left_bearing(u32) const override { return 0; }
|
||||
|
||||
@@ -173,8 +173,8 @@ public:
|
||||
virtual u16 width() 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> glyph(u32 code_point) const = 0;
|
||||
virtual Optional<Glyph> glyph(u32 code_point, GlyphSubpixelOffset) const = 0;
|
||||
virtual Optional<Glyph> glyph_for_postscript_name(StringView, GlyphSubpixelOffset) const = 0;
|
||||
virtual bool contains_glyph(u32 code_point) const = 0;
|
||||
virtual bool contains_glyph_for_postscript_name(StringView name) const = 0;
|
||||
|
||||
@@ -99,19 +99,21 @@ bool ScaledFont::append_glyph_path_to(Gfx::Path& path, u32 glyph_id) const
|
||||
return success;
|
||||
}
|
||||
|
||||
Gfx::Glyph ScaledFont::glyph(u32 code_point) const
|
||||
Optional<Gfx::Glyph> ScaledFont::glyph(u32 code_point) const
|
||||
{
|
||||
return glyph(code_point, GlyphSubpixelOffset { 0, 0 });
|
||||
}
|
||||
|
||||
Glyph ScaledFont::glyph_for_id(u32 id, GlyphSubpixelOffset subpixel_offset) const
|
||||
Optional<Glyph> ScaledFont::glyph_for_id(u32 id, GlyphSubpixelOffset subpixel_offset) const
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
Gfx::Glyph ScaledFont::glyph(u32 code_point, GlyphSubpixelOffset subpixel_offset) const
|
||||
Optional<Gfx::Glyph> ScaledFont::glyph(u32 code_point, GlyphSubpixelOffset subpixel_offset) const
|
||||
{
|
||||
auto id = glyph_id_for_code_point(code_point);
|
||||
return glyph_for_id(id, subpixel_offset);
|
||||
|
||||
@@ -42,10 +42,10 @@ public:
|
||||
virtual u8 slope() const override { return m_font->slope(); }
|
||||
virtual u16 width() const override { return m_font->width(); }
|
||||
virtual u16 weight() const override { return m_font->weight(); }
|
||||
virtual Gfx::Glyph glyph(u32 code_point) const override;
|
||||
virtual Optional<Gfx::Glyph> glyph(u32 code_point) const override;
|
||||
virtual float glyph_left_bearing(u32 code_point) const override;
|
||||
Optional<float> glyph_left_bearing_for_postscript_name(StringView) const override;
|
||||
virtual Glyph glyph(u32 code_point, GlyphSubpixelOffset) const override;
|
||||
virtual Optional<Glyph> glyph(u32 code_point, GlyphSubpixelOffset) const override;
|
||||
Optional<Glyph> glyph_for_postscript_name(StringView, GlyphSubpixelOffset) const override;
|
||||
virtual bool contains_glyph(u32 code_point) const override { return m_font->glyph_id_for_code_point(code_point) > 0; }
|
||||
virtual bool contains_glyph_for_postscript_name(StringView name) const override { return m_font->glyph_id_for_postscript_name(name).has_value(); }
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
virtual bool has_color_bitmaps() const override { return m_font->has_color_bitmaps(); }
|
||||
|
||||
private:
|
||||
Glyph glyph_for_id(u32 id, GlyphSubpixelOffset) const;
|
||||
Optional<Glyph> glyph_for_id(u32 id, GlyphSubpixelOffset) const;
|
||||
|
||||
NonnullRefPtr<VectorFont> m_font;
|
||||
float m_x_scale { 0.0f };
|
||||
|
||||
@@ -1364,7 +1364,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();
|
||||
draw_glyph_internal(point, glyph_position, top_left, glyph, color);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user